Merge remote-tracking branch 'ralph/feature/rpz' into rpz

This commit is contained in:
Ralph Dolmans 2019-09-09 17:11:26 +02:00
commit 2b5cd8e9b4
44 changed files with 8021 additions and 4034 deletions

1
.gitignore vendored
View file

@ -1,5 +1,6 @@
*.lo *.lo
*.o *.o
cscope.out
/.libs/ /.libs/
/Makefile /Makefile
/autom4te.cache/ /autom4te.cache/

View file

@ -110,6 +110,7 @@ iterator/iter_delegpt.c iterator/iter_donotq.c iterator/iter_fwd.c \
iterator/iter_hints.c iterator/iter_priv.c iterator/iter_resptype.c \ iterator/iter_hints.c iterator/iter_priv.c iterator/iter_resptype.c \
iterator/iter_scrub.c iterator/iter_utils.c services/listen_dnsport.c \ 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/localzone.c services/mesh.c services/modstack.c services/view.c \
services/rpz.c \
services/outbound_list.c services/outside_network.c util/alloc.c \ services/outbound_list.c services/outside_network.c util/alloc.c \
util/config_file.c util/configlexer.c util/configparser.c \ util/config_file.c util/configlexer.c util/configparser.c \
util/shm_side/shm_main.c services/authzone.c \ util/shm_side/shm_main.c services/authzone.c \
@ -135,7 +136,7 @@ outbound_list.lo alloc.lo config_file.lo configlexer.lo configparser.lo \
fptr_wlist.lo edns.lo locks.lo log.lo mini_event.lo module.lo net_help.lo \ fptr_wlist.lo edns.lo locks.lo log.lo mini_event.lo module.lo net_help.lo \
random.lo rbtree.lo regional.lo rtt.lo dnstree.lo lookup3.lo lruhash.lo \ random.lo rbtree.lo regional.lo rtt.lo dnstree.lo lookup3.lo lruhash.lo \
slabhash.lo tcp_conn_limit.lo timehist.lo tube.lo winsock_event.lo \ slabhash.lo tcp_conn_limit.lo timehist.lo tube.lo winsock_event.lo \
autotrust.lo val_anchor.lo \ autotrust.lo val_anchor.lo rpz.lo \
validator.lo val_kcache.lo val_kentry.lo val_neg.lo val_nsec3.lo val_nsec.lo \ validator.lo val_kcache.lo val_kentry.lo val_neg.lo val_nsec3.lo val_nsec.lo \
val_secalgo.lo val_sigcrypt.lo val_utils.lo dns64.lo cachedb.lo redis.lo authzone.lo \ val_secalgo.lo val_sigcrypt.lo val_utils.lo dns64.lo cachedb.lo redis.lo authzone.lo \
$(SUBNET_OBJ) $(PYTHONMOD_OBJ) $(CHECKLOCK_OBJ) $(DNSTAP_OBJ) $(DNSCRYPT_OBJ) \ $(SUBNET_OBJ) $(PYTHONMOD_OBJ) $(CHECKLOCK_OBJ) $(DNSTAP_OBJ) $(DNSCRYPT_OBJ) \
@ -694,10 +695,10 @@ iterator.lo iterator.o: $(srcdir)/iterator/iterator.c config.h $(srcdir)/iterato
$(srcdir)/validator/val_neg.h $(srcdir)/services/cache/dns.h $(srcdir)/services/cache/infra.h \ $(srcdir)/validator/val_neg.h $(srcdir)/services/cache/dns.h $(srcdir)/services/cache/infra.h \
$(srcdir)/util/rtt.h $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \ $(srcdir)/util/rtt.h $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
$(srcdir)/services/authzone.h $(srcdir)/services/mesh.h \ $(srcdir)/services/authzone.h $(srcdir)/services/mesh.h \
$(srcdir)/services/modstack.h $(srcdir)/util/net_help.h $(srcdir)/util/regional.h $(srcdir)/util/data/dname.h \ $(srcdir)/services/modstack.h $(srcdir)/services/rpz.h $(srcdir)/services/localzone.h $(srcdir)/services/view.h \
$(srcdir)/util/data/msgencode.h $(srcdir)/util/fptr_wlist.h $(srcdir)/util/tube.h $(srcdir)/util/config_file.h \ $(srcdir)/sldns/sbuffer.h $(srcdir)/util/config_file.h $(srcdir)/util/net_help.h $(srcdir)/util/regional.h \
$(srcdir)/util/random.h $(srcdir)/sldns/wire2str.h $(srcdir)/sldns/str2wire.h $(srcdir)/sldns/parseutil.h \ $(srcdir)/util/data/dname.h $(srcdir)/util/data/msgencode.h $(srcdir)/util/fptr_wlist.h $(srcdir)/util/tube.h \
$(srcdir)/sldns/sbuffer.h $(srcdir)/util/random.h $(srcdir)/sldns/wire2str.h $(srcdir)/sldns/str2wire.h $(srcdir)/sldns/parseutil.h
iter_delegpt.lo iter_delegpt.o: $(srcdir)/iterator/iter_delegpt.c config.h $(srcdir)/iterator/iter_delegpt.h \ iter_delegpt.lo iter_delegpt.o: $(srcdir)/iterator/iter_delegpt.c config.h $(srcdir)/iterator/iter_delegpt.h \
$(srcdir)/util/log.h $(srcdir)/services/cache/dns.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h \ $(srcdir)/util/log.h $(srcdir)/services/cache/dns.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h \
$(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/regional.h \ $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/regional.h \
@ -757,7 +758,7 @@ localzone.lo localzone.o: $(srcdir)/services/localzone.c config.h $(srcdir)/serv
$(srcdir)/util/rbtree.h $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/util/storage/dnstree.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/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)/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)/sldns/rrdef.h $(srcdir)/services/view.h $(srcdir)/sldns/sbuffer.h $(srcdir)/sldns/str2wire.h \
$(srcdir)/util/regional.h $(srcdir)/util/config_file.h $(srcdir)/util/data/dname.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/data/msgencode.h $(srcdir)/util/net_help.h $(srcdir)/util/netevent.h \
$(srcdir)/dnscrypt/dnscrypt.h $(srcdir)/util/as112.h $(srcdir)/dnscrypt/dnscrypt.h $(srcdir)/util/as112.h
@ -783,12 +784,20 @@ modstack.lo modstack.o: $(srcdir)/services/modstack.c config.h $(srcdir)/service
$(srcdir)/services/view.h $(PYTHONMOD_HEADER) $(srcdir)/ipsecmod/ipsecmod.h \ $(srcdir)/services/view.h $(PYTHONMOD_HEADER) $(srcdir)/ipsecmod/ipsecmod.h \
$(srcdir)/edns-subnet/subnetmod.h $(srcdir)/util/alloc.h $(srcdir)/util/net_help.h \ $(srcdir)/edns-subnet/subnetmod.h $(srcdir)/util/alloc.h $(srcdir)/util/net_help.h \
$(srcdir)/util/storage/slabhash.h $(srcdir)/edns-subnet/addrtree.h $(srcdir)/edns-subnet/edns-subnet.h \ $(srcdir)/util/storage/slabhash.h $(srcdir)/edns-subnet/addrtree.h $(srcdir)/edns-subnet/edns-subnet.h \
$(srcdir)/ipset/ipset.h $(srcdir)/ipset/ipset.h $(srcdir)/sldns/sbuffer.h
view.lo view.o: $(srcdir)/services/view.c config.h $(srcdir)/services/view.h $(srcdir)/util/rbtree.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/locks.h $(srcdir)/util/log.h $(srcdir)/services/localzone.h $(srcdir)/util/storage/dnstree.h \
$(srcdir)/util/module.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/data/msgreply.h \ $(srcdir)/util/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)/util/data/packed_rrset.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h \
$(srcdir)/sldns/rrdef.h $(srcdir)/util/config_file.h $(srcdir)/sldns/rrdef.h $(srcdir)/sldns/sbuffer.h $(srcdir)/util/config_file.h
rpz.lo rpz.o: $(srcdir)/services/rpz.c config.h $(srcdir)/services/rpz.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/sbuffer.h $(srcdir)/util/config_file.h \
$(srcdir)/services/authzone.h $(srcdir)/services/mesh.h $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
$(srcdir)/services/modstack.h $(srcdir)/sldns/wire2str.h \
$(srcdir)/sldns/str2wire.h $(srcdir)/util/data/dname.h $(srcdir)/util/net_help.h $(srcdir)/util/regional.h
outbound_list.lo outbound_list.o: $(srcdir)/services/outbound_list.c config.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)/services/outbound_list.h $(srcdir)/services/outside_network.h $(srcdir)/util/rbtree.h \
$(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \ $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
@ -802,8 +811,7 @@ outside_network.lo outside_network.o: $(srcdir)/services/outside_network.c confi
$(srcdir)/services/outbound_list.h $(srcdir)/util/module.h $(srcdir)/util/data/msgparse.h \ $(srcdir)/services/outbound_list.h $(srcdir)/util/module.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)/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/tube.h \ $(srcdir)/util/net_help.h $(srcdir)/util/random.h $(srcdir)/util/fptr_wlist.h $(srcdir)/util/tube.h \
$(srcdir)/services/mesh.h $(srcdir)/services/modstack.h $(srcdir)/sldns/sbuffer.h $(srcdir)/dnstap/dnstap.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 \ 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/regional.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/storage/lruhash.h \
$(srcdir)/util/fptr_wlist.h $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \ $(srcdir)/util/fptr_wlist.h $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
@ -842,28 +850,30 @@ authzone.lo authzone.o: $(srcdir)/services/authzone.c config.h $(srcdir)/service
$(srcdir)/dnscrypt/dnscrypt.h $(srcdir)/util/data/msgparse.h \ $(srcdir)/dnscrypt/dnscrypt.h $(srcdir)/util/data/msgparse.h \
$(srcdir)/util/storage/lruhash.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/module.h \ $(srcdir)/util/storage/lruhash.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/module.h \
$(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/services/modstack.h \ $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/services/modstack.h \
$(srcdir)/util/data/dname.h $(srcdir)/util/data/msgencode.h $(srcdir)/util/regional.h $(srcdir)/util/net_help.h \ $(srcdir)/services/rpz.h $(srcdir)/services/localzone.h $(srcdir)/util/storage/dnstree.h \
$(srcdir)/util/config_file.h $(srcdir)/util/random.h $(srcdir)/services/cache/dns.h \ $(srcdir)/services/view.h $(srcdir)/sldns/sbuffer.h $(srcdir)/util/config_file.h $(srcdir)/util/data/dname.h \
$(srcdir)/services/outside_network.h \ $(srcdir)/util/data/msgencode.h $(srcdir)/util/regional.h $(srcdir)/util/net_help.h $(srcdir)/util/random.h \
$(srcdir)/services/listen_dnsport.h $(srcdir)/sldns/sbuffer.h $(srcdir)/sldns/str2wire.h \ $(srcdir)/services/cache/dns.h $(srcdir)/services/outside_network.h \
$(srcdir)/sldns/wire2str.h $(srcdir)/sldns/parseutil.h $(srcdir)/sldns/keyraw.h \ $(srcdir)/services/listen_dnsport.h $(srcdir)/sldns/str2wire.h $(srcdir)/sldns/wire2str.h \
$(srcdir)/validator/val_nsec3.h $(srcdir)/validator/val_secalgo.h $(srcdir)/sldns/parseutil.h $(srcdir)/sldns/keyraw.h $(srcdir)/validator/val_nsec3.h \
$(srcdir)/validator/val_secalgo.h
fptr_wlist.lo fptr_wlist.o: $(srcdir)/util/fptr_wlist.c config.h $(srcdir)/util/fptr_wlist.h \ fptr_wlist.lo fptr_wlist.o: $(srcdir)/util/fptr_wlist.c config.h $(srcdir)/util/fptr_wlist.h \
$(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \ $(srcdir)/util/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/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)/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)/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)/services/outside_network.h \ $(srcdir)/services/modstack.h $(srcdir)/util/mini_event.h $(srcdir)/util/rbtree.h \
$(srcdir)/services/localzone.h $(srcdir)/util/storage/dnstree.h \ $(srcdir)/services/outside_network.h $(srcdir)/services/localzone.h \
$(srcdir)/services/view.h $(srcdir)/services/authzone.h $(srcdir)/services/cache/infra.h $(srcdir)/util/rtt.h \ $(srcdir)/util/storage/dnstree.h $(srcdir)/services/view.h $(srcdir)/sldns/sbuffer.h \
$(srcdir)/services/cache/rrset.h $(srcdir)/util/storage/slabhash.h $(srcdir)/dns64/dns64.h \ $(srcdir)/services/authzone.h $(srcdir)/services/rpz.h $(srcdir)/util/config_file.h \
$(srcdir)/iterator/iterator.h $(srcdir)/services/outbound_list.h $(srcdir)/iterator/iter_fwd.h \ $(srcdir)/services/cache/infra.h $(srcdir)/util/rtt.h $(srcdir)/services/cache/rrset.h \
$(srcdir)/validator/validator.h $(srcdir)/validator/val_utils.h $(srcdir)/validator/val_anchor.h \ $(srcdir)/util/storage/slabhash.h $(srcdir)/dns64/dns64.h $(srcdir)/iterator/iterator.h \
$(srcdir)/validator/val_nsec3.h $(srcdir)/validator/val_sigcrypt.h $(srcdir)/validator/val_kentry.h \ $(srcdir)/services/outbound_list.h $(srcdir)/iterator/iter_fwd.h $(srcdir)/validator/validator.h \
$(srcdir)/validator/val_neg.h $(srcdir)/validator/autotrust.h $(srcdir)/libunbound/libworker.h \ $(srcdir)/validator/val_utils.h $(srcdir)/validator/val_anchor.h $(srcdir)/validator/val_nsec3.h \
$(srcdir)/libunbound/context.h $(srcdir)/util/alloc.h $(srcdir)/libunbound/unbound.h \ $(srcdir)/validator/val_sigcrypt.h $(srcdir)/validator/val_kentry.h $(srcdir)/validator/val_neg.h \
$(srcdir)/libunbound/unbound-event.h $(srcdir)/libunbound/worker.h $(srcdir)/sldns/sbuffer.h \ $(srcdir)/validator/autotrust.h $(srcdir)/libunbound/libworker.h $(srcdir)/libunbound/context.h \
$(srcdir)/util/config_file.h $(srcdir)/respip/respip.h $(PYTHONMOD_HEADER) \ $(srcdir)/util/alloc.h $(srcdir)/libunbound/unbound.h $(srcdir)/libunbound/unbound-event.h \
$(srcdir)/libunbound/worker.h $(srcdir)/respip/respip.h $(PYTHONMOD_HEADER) \
$(srcdir)/ipsecmod/ipsecmod.h $(srcdir)/edns-subnet/subnetmod.h $(srcdir)/util/net_help.h \ $(srcdir)/ipsecmod/ipsecmod.h $(srcdir)/edns-subnet/subnetmod.h $(srcdir)/util/net_help.h \
$(srcdir)/edns-subnet/addrtree.h $(srcdir)/edns-subnet/edns-subnet.h $(srcdir)/ipset/ipset.h $(srcdir)/edns-subnet/addrtree.h $(srcdir)/edns-subnet/edns-subnet.h $(srcdir)/ipset/ipset.h
locks.lo locks.o: $(srcdir)/util/locks.c config.h $(srcdir)/util/locks.h $(srcdir)/util/log.h locks.lo locks.o: $(srcdir)/util/locks.c config.h $(srcdir)/util/locks.h $(srcdir)/util/log.h
@ -879,14 +889,12 @@ netevent.lo netevent.o: $(srcdir)/util/netevent.c config.h $(srcdir)/util/neteve
$(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/data/msgparse.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)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/tube.h $(srcdir)/services/mesh.h \
$(srcdir)/services/modstack.h $(srcdir)/sldns/sbuffer.h $(srcdir)/sldns/str2wire.h $(srcdir)/dnstap/dnstap.h \ $(srcdir)/services/modstack.h $(srcdir)/sldns/sbuffer.h $(srcdir)/sldns/str2wire.h $(srcdir)/dnstap/dnstap.h \
$(srcdir)/services/listen_dnsport.h \ $(srcdir)/services/listen_dnsport.h
net_help.lo net_help.o: $(srcdir)/util/net_help.c config.h $(srcdir)/util/net_help.h $(srcdir)/util/log.h \ 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/dname.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/module.h \
$(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/data/msgparse.h \ $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/data/msgparse.h \
$(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/regional.h $(srcdir)/util/config_file.h \ $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/regional.h $(srcdir)/util/config_file.h \
$(srcdir)/sldns/parseutil.h $(srcdir)/sldns/wire2str.h \ $(srcdir)/sldns/parseutil.h $(srcdir)/sldns/wire2str.h
random.lo random.o: $(srcdir)/util/random.c config.h $(srcdir)/util/random.h $(srcdir)/util/log.h 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 \ rbtree.lo rbtree.o: $(srcdir)/util/rbtree.c config.h $(srcdir)/util/log.h $(srcdir)/util/fptr_wlist.h \
$(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \ $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
@ -921,7 +929,7 @@ tcp_conn_limit.lo tcp_conn_limit.o: $(srcdir)/util/tcp_conn_limit.c config.h $(s
$(srcdir)/util/storage/dnstree.h $(srcdir)/util/rbtree.h $(srcdir)/util/locks.h $(srcdir)/services/localzone.h \ $(srcdir)/util/storage/dnstree.h $(srcdir)/util/rbtree.h $(srcdir)/util/locks.h $(srcdir)/services/localzone.h \
$(srcdir)/util/module.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/data/msgreply.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)/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/rrdef.h $(srcdir)/services/view.h $(srcdir)/sldns/sbuffer.h $(srcdir)/sldns/str2wire.h
timehist.lo timehist.o: $(srcdir)/util/timehist.c config.h $(srcdir)/util/timehist.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 \ tube.lo tube.o: $(srcdir)/util/tube.c config.h $(srcdir)/util/tube.h $(srcdir)/util/log.h $(srcdir)/util/net_help.h \
$(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \ $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
@ -951,8 +959,7 @@ autotrust.lo autotrust.o: $(srcdir)/validator/autotrust.c config.h $(srcdir)/val
$(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \ $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
$(srcdir)/services/modstack.h $(srcdir)/services/cache/rrset.h $(srcdir)/util/storage/slabhash.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)/validator/val_kcache.h $(srcdir)/sldns/sbuffer.h $(srcdir)/sldns/wire2str.h $(srcdir)/sldns/str2wire.h \
$(srcdir)/sldns/keyraw.h \ $(srcdir)/sldns/keyraw.h
val_anchor.lo val_anchor.o: $(srcdir)/validator/val_anchor.c config.h $(srcdir)/validator/val_anchor.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/rbtree.h $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/validator/val_sigcrypt.h \
$(srcdir)/util/data/packed_rrset.h $(srcdir)/util/storage/lruhash.h $(srcdir)/sldns/pkthdr.h \ $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/storage/lruhash.h $(srcdir)/sldns/pkthdr.h \
@ -979,13 +986,11 @@ val_kcache.lo val_kcache.o: $(srcdir)/validator/val_kcache.c config.h $(srcdir)/
val_kentry.lo val_kentry.o: $(srcdir)/validator/val_kentry.c config.h $(srcdir)/validator/val_kentry.h \ val_kentry.lo val_kentry.o: $(srcdir)/validator/val_kentry.c config.h $(srcdir)/validator/val_kentry.h \
$(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/util/data/packed_rrset.h \ $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/util/data/packed_rrset.h \
$(srcdir)/util/data/dname.h $(srcdir)/util/storage/lookup3.h $(srcdir)/util/regional.h $(srcdir)/util/net_help.h \ $(srcdir)/util/data/dname.h $(srcdir)/util/storage/lookup3.h $(srcdir)/util/regional.h $(srcdir)/util/net_help.h \
$(srcdir)/sldns/rrdef.h $(srcdir)/sldns/keyraw.h \ $(srcdir)/sldns/rrdef.h $(srcdir)/sldns/keyraw.h
val_neg.lo val_neg.o: $(srcdir)/validator/val_neg.c config.h $(srcdir)/validator/val_neg.h $(srcdir)/util/locks.h \
val_neg.lo val_neg.o: $(srcdir)/validator/val_neg.c config.h \ $(srcdir)/util/log.h $(srcdir)/util/rbtree.h $(srcdir)/validator/val_nsec.h $(srcdir)/util/data/packed_rrset.h \
$(srcdir)/validator/val_neg.h $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/util/rbtree.h \ $(srcdir)/util/storage/lruhash.h $(srcdir)/validator/val_nsec3.h $(srcdir)/validator/val_utils.h \
$(srcdir)/validator/val_nsec.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/storage/lruhash.h \ $(srcdir)/sldns/pkthdr.h $(srcdir)/util/data/dname.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/net_help.h \
$(srcdir)/validator/val_nsec3.h $(srcdir)/validator/val_utils.h $(srcdir)/sldns/pkthdr.h \
$(srcdir)/util/data/dname.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/net_help.h \
$(srcdir)/util/config_file.h $(srcdir)/services/cache/rrset.h $(srcdir)/util/storage/slabhash.h \ $(srcdir)/util/config_file.h $(srcdir)/services/cache/rrset.h $(srcdir)/util/storage/slabhash.h \
$(srcdir)/services/cache/dns.h $(srcdir)/sldns/rrdef.h $(srcdir)/sldns/sbuffer.h $(srcdir)/services/cache/dns.h $(srcdir)/sldns/rrdef.h $(srcdir)/sldns/sbuffer.h
val_nsec3.lo val_nsec3.o: $(srcdir)/validator/val_nsec3.c config.h $(srcdir)/validator/val_nsec3.h \ val_nsec3.lo val_nsec3.o: $(srcdir)/validator/val_nsec3.c config.h $(srcdir)/validator/val_nsec3.h \
@ -1003,17 +1008,15 @@ val_nsec.lo val_nsec.o: $(srcdir)/validator/val_nsec.c config.h $(srcdir)/valida
val_secalgo.lo val_secalgo.o: $(srcdir)/validator/val_secalgo.c config.h $(srcdir)/util/data/packed_rrset.h \ val_secalgo.lo val_secalgo.o: $(srcdir)/validator/val_secalgo.c config.h $(srcdir)/util/data/packed_rrset.h \
$(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/validator/val_secalgo.h \ $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/validator/val_secalgo.h \
$(srcdir)/validator/val_nsec3.h $(srcdir)/util/rbtree.h $(srcdir)/sldns/rrdef.h $(srcdir)/sldns/keyraw.h \ $(srcdir)/validator/val_nsec3.h $(srcdir)/util/rbtree.h $(srcdir)/sldns/rrdef.h $(srcdir)/sldns/keyraw.h \
$(srcdir)/sldns/sbuffer.h \ $(srcdir)/sldns/sbuffer.h
val_sigcrypt.lo val_sigcrypt.o: $(srcdir)/validator/val_sigcrypt.c config.h \ val_sigcrypt.lo val_sigcrypt.o: $(srcdir)/validator/val_sigcrypt.c config.h \
$(srcdir)/validator/val_sigcrypt.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/storage/lruhash.h \ $(srcdir)/validator/val_sigcrypt.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/storage/lruhash.h \
$(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/sldns/pkthdr.h $(srcdir)/validator/val_secalgo.h \ $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/sldns/pkthdr.h $(srcdir)/validator/val_secalgo.h \
$(srcdir)/validator/validator.h $(srcdir)/util/module.h $(srcdir)/util/data/msgreply.h \ $(srcdir)/validator/validator.h $(srcdir)/util/module.h $(srcdir)/util/data/msgreply.h \
$(srcdir)/util/data/msgparse.h $(srcdir)/sldns/rrdef.h $(srcdir)/validator/val_utils.h \ $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/rrdef.h $(srcdir)/validator/val_utils.h \
$(srcdir)/util/data/dname.h $(srcdir)/util/rbtree.h $(srcdir)/util/net_help.h $(srcdir)/util/regional.h \ $(srcdir)/util/data/dname.h $(srcdir)/util/rbtree.h $(srcdir)/util/net_help.h $(srcdir)/util/regional.h \
$(srcdir)/util/config_file.h $(srcdir)/sldns/keyraw.h \ $(srcdir)/util/config_file.h $(srcdir)/sldns/keyraw.h $(srcdir)/sldns/sbuffer.h $(srcdir)/sldns/parseutil.h \
$(srcdir)/sldns/sbuffer.h $(srcdir)/sldns/parseutil.h $(srcdir)/sldns/wire2str.h \ $(srcdir)/sldns/wire2str.h
val_utils.lo val_utils.o: $(srcdir)/validator/val_utils.c config.h $(srcdir)/validator/val_utils.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)/util/data/packed_rrset.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h \
$(srcdir)/sldns/pkthdr.h $(srcdir)/validator/validator.h $(srcdir)/util/module.h $(srcdir)/util/data/msgreply.h \ $(srcdir)/sldns/pkthdr.h $(srcdir)/validator/validator.h $(srcdir)/util/module.h $(srcdir)/util/data/msgreply.h \
@ -1059,7 +1062,7 @@ respip.lo respip.o: $(srcdir)/respip/respip.c config.h $(srcdir)/services/localz
$(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/util/storage/dnstree.h $(srcdir)/util/module.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/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)/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)/sldns/sbuffer.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/fptr_wlist.h $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
$(srcdir)/util/tube.h $(srcdir)/services/mesh.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 $(srcdir)/services/modstack.h $(srcdir)/util/net_help.h $(srcdir)/util/regional.h $(srcdir)/respip/respip.h
@ -1099,8 +1102,7 @@ unitdname.lo unitdname.o: $(srcdir)/testcode/unitdname.c config.h $(srcdir)/util
$(srcdir)/sldns/str2wire.h $(srcdir)/sldns/rrdef.h $(srcdir)/sldns/str2wire.h $(srcdir)/sldns/rrdef.h
unitlruhash.lo unitlruhash.o: $(srcdir)/testcode/unitlruhash.c config.h $(srcdir)/testcode/unitmain.h \ unitlruhash.lo unitlruhash.o: $(srcdir)/testcode/unitlruhash.c config.h $(srcdir)/testcode/unitmain.h \
$(srcdir)/util/log.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/storage/slabhash.h $(srcdir)/util/log.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/storage/slabhash.h
unitmain.lo unitmain.o: $(srcdir)/testcode/unitmain.c config.h \ unitmain.lo unitmain.o: $(srcdir)/testcode/unitmain.c config.h $(srcdir)/sldns/rrdef.h $(srcdir)/sldns/keyraw.h \
$(srcdir)/sldns/rrdef.h $(srcdir)/sldns/keyraw.h \
$(srcdir)/util/log.h $(srcdir)/testcode/unitmain.h $(srcdir)/util/alloc.h $(srcdir)/util/locks.h $(srcdir)/util/net_help.h \ $(srcdir)/util/log.h $(srcdir)/testcode/unitmain.h $(srcdir)/util/alloc.h $(srcdir)/util/locks.h $(srcdir)/util/net_help.h \
$(srcdir)/util/config_file.h $(srcdir)/util/rtt.h $(srcdir)/util/timehist.h $(srcdir)/iterator/iterator.h \ $(srcdir)/util/config_file.h $(srcdir)/util/rtt.h $(srcdir)/util/timehist.h $(srcdir)/iterator/iterator.h \
$(srcdir)/services/outbound_list.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/storage/lruhash.h \ $(srcdir)/services/outbound_list.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/storage/lruhash.h \
@ -1108,7 +1110,7 @@ unitmain.lo unitmain.o: $(srcdir)/testcode/unitmain.c config.h \
$(srcdir)/sldns/pkthdr.h $(srcdir)/libunbound/unbound.h $(srcdir)/services/cache/infra.h \ $(srcdir)/sldns/pkthdr.h $(srcdir)/libunbound/unbound.h $(srcdir)/services/cache/infra.h \
$(srcdir)/util/storage/dnstree.h $(srcdir)/util/rbtree.h $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \ $(srcdir)/util/storage/dnstree.h $(srcdir)/util/rbtree.h $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
$(srcdir)/util/random.h $(srcdir)/respip/respip.h \ $(srcdir)/util/random.h $(srcdir)/respip/respip.h \
$(srcdir)/services/localzone.h $(srcdir)/services/view.h $(srcdir)/services/localzone.h $(srcdir)/services/view.h $(srcdir)/sldns/sbuffer.h
unitmsgparse.lo unitmsgparse.o: $(srcdir)/testcode/unitmsgparse.c config.h $(srcdir)/util/log.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)/testcode/unitmain.h $(srcdir)/util/data/msgparse.h $(srcdir)/util/storage/lruhash.h \
$(srcdir)/util/locks.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/data/msgreply.h \ $(srcdir)/util/locks.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/data/msgreply.h \
@ -1150,60 +1152,61 @@ unitauth.lo unitauth.o: $(srcdir)/testcode/unitauth.c config.h $(srcdir)/service
$(srcdir)/dnscrypt/dnscrypt.h $(srcdir)/util/data/msgparse.h \ $(srcdir)/dnscrypt/dnscrypt.h $(srcdir)/util/data/msgparse.h \
$(srcdir)/util/storage/lruhash.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/module.h \ $(srcdir)/util/storage/lruhash.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/module.h \
$(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/services/modstack.h \ $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/services/modstack.h \
$(srcdir)/testcode/unitmain.h $(srcdir)/util/regional.h $(srcdir)/util/net_help.h $(srcdir)/util/config_file.h \ $(srcdir)/services/rpz.h $(srcdir)/services/localzone.h $(srcdir)/util/storage/dnstree.h \
$(srcdir)/services/cache/dns.h $(srcdir)/sldns/str2wire.h $(srcdir)/sldns/wire2str.h $(srcdir)/sldns/sbuffer.h $(srcdir)/services/view.h $(srcdir)/sldns/sbuffer.h $(srcdir)/util/config_file.h $(srcdir)/testcode/unitmain.h \
$(srcdir)/util/regional.h $(srcdir)/util/net_help.h $(srcdir)/services/cache/dns.h $(srcdir)/sldns/str2wire.h \
$(srcdir)/sldns/wire2str.h
acl_list.lo acl_list.o: $(srcdir)/daemon/acl_list.c config.h $(srcdir)/daemon/acl_list.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/storage/dnstree.h $(srcdir)/util/rbtree.h $(srcdir)/services/view.h $(srcdir)/util/locks.h \
$(srcdir)/util/log.h $(srcdir)/util/regional.h $(srcdir)/util/config_file.h $(srcdir)/util/net_help.h \ $(srcdir)/util/log.h $(srcdir)/util/regional.h $(srcdir)/util/config_file.h $(srcdir)/util/net_help.h \
$(srcdir)/services/localzone.h $(srcdir)/util/module.h $(srcdir)/util/storage/lruhash.h \ $(srcdir)/services/localzone.h $(srcdir)/util/module.h $(srcdir)/util/storage/lruhash.h \
$(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/data/msgparse.h \ $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/data/msgparse.h \
$(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/sldns/str2wire.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/sldns/sbuffer.h $(srcdir)/sldns/str2wire.h
cachedump.lo cachedump.o: $(srcdir)/daemon/cachedump.c config.h \ cachedump.lo cachedump.o: $(srcdir)/daemon/cachedump.c config.h $(srcdir)/daemon/cachedump.h \
$(srcdir)/daemon/cachedump.h $(srcdir)/daemon/remote.h $(srcdir)/daemon/worker.h $(srcdir)/libunbound/worker.h \ $(srcdir)/daemon/remote.h $(srcdir)/daemon/worker.h $(srcdir)/libunbound/worker.h $(srcdir)/sldns/sbuffer.h \
$(srcdir)/sldns/sbuffer.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/storage/lruhash.h \
$(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
$(srcdir)/util/alloc.h $(srcdir)/util/data/msgreply.h \
$(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/daemon/stats.h \
$(srcdir)/util/timehist.h $(srcdir)/libunbound/unbound.h $(srcdir)/util/module.h $(srcdir)/dnstap/dnstap.h \
$(srcdir)/services/cache/rrset.h $(srcdir)/util/storage/slabhash.h \
$(srcdir)/services/cache/dns.h $(srcdir)/services/cache/infra.h $(srcdir)/util/storage/dnstree.h \
$(srcdir)/util/rbtree.h $(srcdir)/util/rtt.h $(srcdir)/util/regional.h $(srcdir)/util/net_help.h \
$(srcdir)/util/data/dname.h $(srcdir)/iterator/iterator.h $(srcdir)/services/outbound_list.h \
$(srcdir)/iterator/iter_delegpt.h $(srcdir)/iterator/iter_utils.h $(srcdir)/iterator/iter_resptype.h \
$(srcdir)/iterator/iter_fwd.h $(srcdir)/iterator/iter_hints.h $(srcdir)/sldns/wire2str.h \
$(srcdir)/sldns/str2wire.h
daemon.lo daemon.o: $(srcdir)/daemon/daemon.c config.h \
$(srcdir)/daemon/daemon.h $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/util/alloc.h $(srcdir)/services/modstack.h \
$(srcdir)/daemon/worker.h \
$(srcdir)/libunbound/worker.h $(srcdir)/sldns/sbuffer.h $(srcdir)/util/data/packed_rrset.h \
$(srcdir)/util/storage/lruhash.h $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
$(srcdir)/util/data/msgreply.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h \
$(srcdir)/daemon/stats.h $(srcdir)/util/timehist.h $(srcdir)/libunbound/unbound.h $(srcdir)/util/module.h \
$(srcdir)/dnstap/dnstap.h $(srcdir)/daemon/remote.h \
$(srcdir)/daemon/acl_list.h $(srcdir)/util/storage/dnstree.h $(srcdir)/util/rbtree.h $(srcdir)/services/view.h \
$(srcdir)/util/config_file.h $(srcdir)/util/shm_side/shm_main.h $(srcdir)/util/storage/lookup3.h \
$(srcdir)/util/storage/slabhash.h $(srcdir)/util/tcp_conn_limit.h $(srcdir)/services/listen_dnsport.h \
$(srcdir)/services/cache/rrset.h $(srcdir)/services/cache/infra.h $(srcdir)/util/rtt.h \
$(srcdir)/services/localzone.h $(srcdir)/services/authzone.h $(srcdir)/services/mesh.h $(srcdir)/util/random.h \
$(srcdir)/util/tube.h $(srcdir)/util/net_help.h $(srcdir)/sldns/keyraw.h $(srcdir)/respip/respip.h
remote.lo remote.o: $(srcdir)/daemon/remote.c config.h \
$(srcdir)/daemon/remote.h \
$(srcdir)/daemon/worker.h $(srcdir)/libunbound/worker.h $(srcdir)/sldns/sbuffer.h \
$(srcdir)/util/data/packed_rrset.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h \ $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h \
$(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \ $(srcdir)/util/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)/util/alloc.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h \
$(srcdir)/sldns/rrdef.h $(srcdir)/daemon/stats.h $(srcdir)/util/timehist.h $(srcdir)/libunbound/unbound.h \ $(srcdir)/sldns/rrdef.h $(srcdir)/daemon/stats.h $(srcdir)/util/timehist.h $(srcdir)/libunbound/unbound.h \
$(srcdir)/util/module.h $(srcdir)/dnstap/dnstap.h $(srcdir)/daemon/daemon.h \ $(srcdir)/util/module.h $(srcdir)/dnstap/dnstap.h \
$(srcdir)/services/cache/rrset.h $(srcdir)/util/storage/slabhash.h $(srcdir)/services/cache/dns.h \
$(srcdir)/services/cache/infra.h $(srcdir)/util/storage/dnstree.h $(srcdir)/util/rbtree.h $(srcdir)/util/rtt.h \
$(srcdir)/util/regional.h $(srcdir)/util/net_help.h $(srcdir)/util/data/dname.h $(srcdir)/iterator/iterator.h \
$(srcdir)/services/outbound_list.h $(srcdir)/iterator/iter_delegpt.h $(srcdir)/iterator/iter_utils.h \
$(srcdir)/iterator/iter_resptype.h $(srcdir)/iterator/iter_fwd.h $(srcdir)/iterator/iter_hints.h \
$(srcdir)/sldns/wire2str.h $(srcdir)/sldns/str2wire.h
daemon.lo daemon.o: $(srcdir)/daemon/daemon.c config.h $(srcdir)/daemon/daemon.h $(srcdir)/util/locks.h \
$(srcdir)/util/log.h $(srcdir)/util/alloc.h $(srcdir)/services/modstack.h \
$(srcdir)/daemon/worker.h $(srcdir)/libunbound/worker.h \
$(srcdir)/sldns/sbuffer.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/storage/lruhash.h \
$(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h $(srcdir)/util/data/msgreply.h \
$(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/daemon/stats.h \
$(srcdir)/util/timehist.h $(srcdir)/libunbound/unbound.h $(srcdir)/util/module.h $(srcdir)/dnstap/dnstap.h \
$(srcdir)/daemon/remote.h $(srcdir)/daemon/acl_list.h $(srcdir)/util/storage/dnstree.h $(srcdir)/util/rbtree.h \
$(srcdir)/services/view.h $(srcdir)/util/config_file.h $(srcdir)/util/shm_side/shm_main.h \
$(srcdir)/util/storage/lookup3.h $(srcdir)/util/storage/slabhash.h $(srcdir)/util/tcp_conn_limit.h \
$(srcdir)/services/listen_dnsport.h $(srcdir)/services/cache/rrset.h $(srcdir)/services/cache/infra.h \
$(srcdir)/util/rtt.h $(srcdir)/services/localzone.h $(srcdir)/services/authzone.h $(srcdir)/services/mesh.h \
$(srcdir)/services/rpz.h $(srcdir)/util/random.h $(srcdir)/util/tube.h $(srcdir)/util/net_help.h $(srcdir)/sldns/keyraw.h \
$(srcdir)/respip/respip.h
remote.lo remote.o: $(srcdir)/daemon/remote.c config.h $(srcdir)/daemon/remote.h $(srcdir)/daemon/worker.h \
$(srcdir)/libunbound/worker.h $(srcdir)/sldns/sbuffer.h $(srcdir)/util/data/packed_rrset.h \
$(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/util/netevent.h \
$(srcdir)/dnscrypt/dnscrypt.h $(srcdir)/util/alloc.h \
$(srcdir)/util/data/msgreply.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h \
$(srcdir)/daemon/stats.h $(srcdir)/util/timehist.h $(srcdir)/libunbound/unbound.h $(srcdir)/util/module.h \
$(srcdir)/dnstap/dnstap.h $(srcdir)/daemon/daemon.h \
$(srcdir)/services/modstack.h $(srcdir)/daemon/cachedump.h $(srcdir)/util/config_file.h \ $(srcdir)/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/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/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)/util/rbtree.h $(srcdir)/util/rtt.h $(srcdir)/services/mesh.h $(srcdir)/services/localzone.h \
$(srcdir)/services/view.h $(srcdir)/services/authzone.h $(srcdir)/util/fptr_wlist.h $(srcdir)/util/tube.h \ $(srcdir)/services/view.h $(srcdir)/services/authzone.h $(srcdir)/services/rpz.h $(srcdir)/util/fptr_wlist.h \
$(srcdir)/util/data/dname.h $(srcdir)/validator/validator.h $(srcdir)/validator/val_utils.h \ $(srcdir)/util/tube.h $(srcdir)/util/data/dname.h $(srcdir)/validator/validator.h \
$(srcdir)/validator/val_kcache.h $(srcdir)/validator/val_kentry.h $(srcdir)/validator/val_anchor.h \ $(srcdir)/validator/val_utils.h $(srcdir)/validator/val_kcache.h $(srcdir)/validator/val_kentry.h \
$(srcdir)/iterator/iterator.h $(srcdir)/services/outbound_list.h $(srcdir)/iterator/iter_fwd.h \ $(srcdir)/validator/val_anchor.h $(srcdir)/iterator/iterator.h $(srcdir)/services/outbound_list.h \
$(srcdir)/iterator/iter_hints.h $(srcdir)/iterator/iter_delegpt.h $(srcdir)/services/outside_network.h \ $(srcdir)/iterator/iter_fwd.h $(srcdir)/iterator/iter_hints.h $(srcdir)/iterator/iter_delegpt.h \
$(srcdir)/sldns/str2wire.h $(srcdir)/sldns/parseutil.h $(srcdir)/sldns/wire2str.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 \ stats.lo stats.o: $(srcdir)/daemon/stats.c config.h $(srcdir)/daemon/stats.h $(srcdir)/util/timehist.h \
$(srcdir)/libunbound/unbound.h $(srcdir)/daemon/worker.h $(srcdir)/libunbound/worker.h $(srcdir)/sldns/sbuffer.h \ $(srcdir)/libunbound/unbound.h $(srcdir)/daemon/worker.h $(srcdir)/libunbound/worker.h $(srcdir)/sldns/sbuffer.h \
$(srcdir)/util/data/packed_rrset.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h \ $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h \
@ -1215,20 +1218,19 @@ stats.lo stats.o: $(srcdir)/daemon/stats.c config.h $(srcdir)/daemon/stats.h $(s
$(srcdir)/util/tube.h $(srcdir)/util/net_help.h $(srcdir)/validator/validator.h $(srcdir)/validator/val_utils.h \ $(srcdir)/util/tube.h $(srcdir)/util/net_help.h $(srcdir)/validator/validator.h $(srcdir)/validator/val_utils.h \
$(srcdir)/iterator/iterator.h $(srcdir)/services/outbound_list.h $(srcdir)/services/cache/rrset.h \ $(srcdir)/iterator/iterator.h $(srcdir)/services/outbound_list.h $(srcdir)/services/cache/rrset.h \
$(srcdir)/util/storage/slabhash.h $(srcdir)/services/cache/infra.h $(srcdir)/util/storage/dnstree.h \ $(srcdir)/util/storage/slabhash.h $(srcdir)/services/cache/infra.h $(srcdir)/util/storage/dnstree.h \
$(srcdir)/util/rtt.h $(srcdir)/services/authzone.h $(srcdir)/validator/val_kcache.h \ $(srcdir)/util/rtt.h $(srcdir)/services/authzone.h $(srcdir)/services/rpz.h $(srcdir)/services/localzone.h \
$(srcdir)/validator/val_neg.h $(srcdir)/edns-subnet/subnetmod.h $(srcdir)/edns-subnet/addrtree.h \ $(srcdir)/services/view.h $(srcdir)/validator/val_kcache.h $(srcdir)/validator/val_neg.h
$(srcdir)/edns-subnet/subnetmod.h $(srcdir)/edns-subnet/addrtree.h \
$(srcdir)/edns-subnet/edns-subnet.h \ $(srcdir)/edns-subnet/edns-subnet.h \
unbound.lo unbound.o: $(srcdir)/daemon/unbound.c config.h $(srcdir)/util/log.h $(srcdir)/daemon/daemon.h \ unbound.lo unbound.o: $(srcdir)/daemon/unbound.c config.h $(srcdir)/util/log.h $(srcdir)/daemon/daemon.h \
$(srcdir)/util/locks.h $(srcdir)/util/alloc.h $(srcdir)/services/modstack.h \ $(srcdir)/util/locks.h $(srcdir)/util/alloc.h $(srcdir)/services/modstack.h \
$(srcdir)/daemon/remote.h \ $(srcdir)/daemon/remote.h $(srcdir)/util/config_file.h \
$(srcdir)/util/config_file.h $(srcdir)/util/storage/slabhash.h $(srcdir)/util/storage/lruhash.h \ $(srcdir)/util/storage/slabhash.h $(srcdir)/util/storage/lruhash.h $(srcdir)/services/listen_dnsport.h \
$(srcdir)/services/listen_dnsport.h $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \ $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h $(srcdir)/services/cache/rrset.h \
$(srcdir)/services/cache/rrset.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/services/cache/infra.h \ $(srcdir)/util/data/packed_rrset.h $(srcdir)/services/cache/infra.h $(srcdir)/util/storage/dnstree.h \
$(srcdir)/util/storage/dnstree.h $(srcdir)/util/rbtree.h $(srcdir)/util/rtt.h $(srcdir)/util/data/msgreply.h \ $(srcdir)/util/rbtree.h $(srcdir)/util/rtt.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/fptr_wlist.h \
$(srcdir)/util/fptr_wlist.h $(srcdir)/util/module.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h \ $(srcdir)/util/module.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h \
$(srcdir)/sldns/rrdef.h $(srcdir)/util/tube.h $(srcdir)/services/mesh.h $(srcdir)/util/net_help.h \ $(srcdir)/util/tube.h $(srcdir)/services/mesh.h $(srcdir)/util/net_help.h $(srcdir)/util/ub_event.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 \ 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/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/data/packed_rrset.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h \
@ -1236,12 +1238,12 @@ worker.lo worker.o: $(srcdir)/daemon/worker.c config.h $(srcdir)/util/log.h $(sr
$(srcdir)/util/alloc.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h \ $(srcdir)/util/alloc.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h \
$(srcdir)/sldns/rrdef.h $(srcdir)/daemon/stats.h $(srcdir)/util/timehist.h $(srcdir)/libunbound/unbound.h \ $(srcdir)/sldns/rrdef.h $(srcdir)/daemon/stats.h $(srcdir)/util/timehist.h $(srcdir)/libunbound/unbound.h \
$(srcdir)/util/module.h $(srcdir)/dnstap/dnstap.h $(srcdir)/daemon/daemon.h \ $(srcdir)/util/module.h $(srcdir)/dnstap/dnstap.h $(srcdir)/daemon/daemon.h \
$(srcdir)/services/modstack.h $(srcdir)/daemon/remote.h \ $(srcdir)/services/modstack.h $(srcdir)/daemon/remote.h $(srcdir)/daemon/acl_list.h \
$(srcdir)/daemon/acl_list.h $(srcdir)/util/storage/dnstree.h $(srcdir)/util/rbtree.h $(srcdir)/services/view.h \ $(srcdir)/util/storage/dnstree.h $(srcdir)/util/rbtree.h $(srcdir)/services/view.h $(srcdir)/util/config_file.h \
$(srcdir)/util/config_file.h $(srcdir)/util/regional.h $(srcdir)/util/storage/slabhash.h \ $(srcdir)/util/regional.h $(srcdir)/util/storage/slabhash.h $(srcdir)/services/listen_dnsport.h \
$(srcdir)/services/listen_dnsport.h $(srcdir)/services/outside_network.h \ $(srcdir)/services/outside_network.h $(srcdir)/services/outbound_list.h \
$(srcdir)/services/outbound_list.h $(srcdir)/services/cache/rrset.h $(srcdir)/services/cache/infra.h \ $(srcdir)/services/cache/rrset.h $(srcdir)/services/cache/infra.h $(srcdir)/util/rtt.h \
$(srcdir)/util/rtt.h $(srcdir)/services/cache/dns.h $(srcdir)/services/authzone.h $(srcdir)/services/mesh.h \ $(srcdir)/services/cache/dns.h $(srcdir)/services/authzone.h $(srcdir)/services/mesh.h $(srcdir)/services/rpz.h \
$(srcdir)/services/localzone.h $(srcdir)/util/data/msgencode.h $(srcdir)/util/data/dname.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)/util/edns.h $(srcdir)/iterator/iter_fwd.h \ $(srcdir)/util/fptr_wlist.h $(srcdir)/util/tube.h $(srcdir)/util/edns.h $(srcdir)/iterator/iter_fwd.h \
$(srcdir)/iterator/iter_hints.h $(srcdir)/validator/autotrust.h $(srcdir)/validator/val_anchor.h \ $(srcdir)/iterator/iter_hints.h $(srcdir)/validator/autotrust.h $(srcdir)/validator/val_anchor.h \
@ -1250,9 +1252,8 @@ worker.lo worker.o: $(srcdir)/daemon/worker.c config.h $(srcdir)/util/log.h $(sr
testbound.lo testbound.o: $(srcdir)/testcode/testbound.c config.h $(srcdir)/testcode/testpkts.h \ testbound.lo testbound.o: $(srcdir)/testcode/testbound.c config.h $(srcdir)/testcode/testpkts.h \
$(srcdir)/testcode/replay.h $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \ $(srcdir)/testcode/replay.h $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
$(srcdir)/util/rbtree.h $(srcdir)/testcode/fake_event.h \ $(srcdir)/util/rbtree.h $(srcdir)/testcode/fake_event.h \
$(srcdir)/daemon/remote.h \ $(srcdir)/daemon/remote.h $(srcdir)/util/config_file.h $(srcdir)/sldns/keyraw.h $(srcdir)/daemon/unbound.c \
$(srcdir)/util/config_file.h $(srcdir)/sldns/keyraw.h $(srcdir)/daemon/unbound.c $(srcdir)/util/log.h \ $(srcdir)/util/log.h $(srcdir)/daemon/daemon.h $(srcdir)/util/locks.h $(srcdir)/util/alloc.h $(srcdir)/services/modstack.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)/util/storage/slabhash.h $(srcdir)/util/storage/lruhash.h \
$(srcdir)/services/listen_dnsport.h $(srcdir)/services/cache/rrset.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/data/packed_rrset.h $(srcdir)/services/cache/infra.h $(srcdir)/util/storage/dnstree.h \
@ -1269,12 +1270,12 @@ worker.lo worker.o: $(srcdir)/daemon/worker.c config.h $(srcdir)/util/log.h $(sr
$(srcdir)/util/alloc.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h \ $(srcdir)/util/alloc.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h \
$(srcdir)/sldns/rrdef.h $(srcdir)/daemon/stats.h $(srcdir)/util/timehist.h $(srcdir)/libunbound/unbound.h \ $(srcdir)/sldns/rrdef.h $(srcdir)/daemon/stats.h $(srcdir)/util/timehist.h $(srcdir)/libunbound/unbound.h \
$(srcdir)/util/module.h $(srcdir)/dnstap/dnstap.h $(srcdir)/daemon/daemon.h \ $(srcdir)/util/module.h $(srcdir)/dnstap/dnstap.h $(srcdir)/daemon/daemon.h \
$(srcdir)/services/modstack.h $(srcdir)/daemon/remote.h \ $(srcdir)/services/modstack.h $(srcdir)/daemon/remote.h $(srcdir)/daemon/acl_list.h \
$(srcdir)/daemon/acl_list.h $(srcdir)/util/storage/dnstree.h $(srcdir)/util/rbtree.h $(srcdir)/services/view.h \ $(srcdir)/util/storage/dnstree.h $(srcdir)/util/rbtree.h $(srcdir)/services/view.h $(srcdir)/util/config_file.h \
$(srcdir)/util/config_file.h $(srcdir)/util/regional.h $(srcdir)/util/storage/slabhash.h \ $(srcdir)/util/regional.h $(srcdir)/util/storage/slabhash.h $(srcdir)/services/listen_dnsport.h \
$(srcdir)/services/listen_dnsport.h $(srcdir)/services/outside_network.h \ $(srcdir)/services/outside_network.h $(srcdir)/services/outbound_list.h \
$(srcdir)/services/outbound_list.h $(srcdir)/services/cache/rrset.h $(srcdir)/services/cache/infra.h \ $(srcdir)/services/cache/rrset.h $(srcdir)/services/cache/infra.h $(srcdir)/util/rtt.h \
$(srcdir)/util/rtt.h $(srcdir)/services/cache/dns.h $(srcdir)/services/authzone.h $(srcdir)/services/mesh.h \ $(srcdir)/services/cache/dns.h $(srcdir)/services/authzone.h $(srcdir)/services/mesh.h $(srcdir)/services/rpz.h \
$(srcdir)/services/localzone.h $(srcdir)/util/data/msgencode.h $(srcdir)/util/data/dname.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)/util/edns.h $(srcdir)/iterator/iter_fwd.h \ $(srcdir)/util/fptr_wlist.h $(srcdir)/util/tube.h $(srcdir)/util/edns.h $(srcdir)/iterator/iter_fwd.h \
$(srcdir)/iterator/iter_hints.h $(srcdir)/validator/autotrust.h $(srcdir)/validator/val_anchor.h \ $(srcdir)/iterator/iter_hints.h $(srcdir)/validator/autotrust.h $(srcdir)/validator/val_anchor.h \
@ -1285,21 +1286,21 @@ acl_list.lo acl_list.o: $(srcdir)/daemon/acl_list.c config.h $(srcdir)/daemon/ac
$(srcdir)/util/log.h $(srcdir)/util/regional.h $(srcdir)/util/config_file.h $(srcdir)/util/net_help.h \ $(srcdir)/util/log.h $(srcdir)/util/regional.h $(srcdir)/util/config_file.h $(srcdir)/util/net_help.h \
$(srcdir)/services/localzone.h $(srcdir)/util/module.h $(srcdir)/util/storage/lruhash.h \ $(srcdir)/services/localzone.h $(srcdir)/util/module.h $(srcdir)/util/storage/lruhash.h \
$(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/data/msgparse.h \ $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/data/msgparse.h \
$(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/sldns/str2wire.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/sldns/sbuffer.h $(srcdir)/sldns/str2wire.h
daemon.lo daemon.o: $(srcdir)/daemon/daemon.c config.h \ daemon.lo daemon.o: $(srcdir)/daemon/daemon.c config.h $(srcdir)/daemon/daemon.h $(srcdir)/util/locks.h \
$(srcdir)/daemon/daemon.h $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/util/alloc.h $(srcdir)/services/modstack.h \ $(srcdir)/util/log.h $(srcdir)/util/alloc.h $(srcdir)/services/modstack.h \
$(srcdir)/daemon/worker.h \ $(srcdir)/daemon/worker.h $(srcdir)/libunbound/worker.h \
$(srcdir)/libunbound/worker.h $(srcdir)/sldns/sbuffer.h $(srcdir)/util/data/packed_rrset.h \ $(srcdir)/sldns/sbuffer.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/storage/lruhash.h \
$(srcdir)/util/storage/lruhash.h $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \ $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h $(srcdir)/util/data/msgreply.h \
$(srcdir)/util/data/msgreply.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h \ $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/daemon/stats.h \
$(srcdir)/daemon/stats.h $(srcdir)/util/timehist.h $(srcdir)/libunbound/unbound.h $(srcdir)/util/module.h \ $(srcdir)/util/timehist.h $(srcdir)/libunbound/unbound.h $(srcdir)/util/module.h $(srcdir)/dnstap/dnstap.h \
$(srcdir)/dnstap/dnstap.h $(srcdir)/daemon/remote.h \ $(srcdir)/daemon/remote.h $(srcdir)/daemon/acl_list.h $(srcdir)/util/storage/dnstree.h $(srcdir)/util/rbtree.h \
$(srcdir)/daemon/acl_list.h $(srcdir)/util/storage/dnstree.h $(srcdir)/util/rbtree.h $(srcdir)/services/view.h \ $(srcdir)/services/view.h $(srcdir)/util/config_file.h $(srcdir)/util/shm_side/shm_main.h \
$(srcdir)/util/config_file.h $(srcdir)/util/shm_side/shm_main.h $(srcdir)/util/storage/lookup3.h \ $(srcdir)/util/storage/lookup3.h $(srcdir)/util/storage/slabhash.h $(srcdir)/util/tcp_conn_limit.h \
$(srcdir)/util/storage/slabhash.h $(srcdir)/util/tcp_conn_limit.h $(srcdir)/services/listen_dnsport.h \ $(srcdir)/services/listen_dnsport.h $(srcdir)/services/cache/rrset.h $(srcdir)/services/cache/infra.h \
$(srcdir)/services/cache/rrset.h $(srcdir)/services/cache/infra.h $(srcdir)/util/rtt.h \ $(srcdir)/util/rtt.h $(srcdir)/services/localzone.h $(srcdir)/services/authzone.h $(srcdir)/services/mesh.h \
$(srcdir)/services/localzone.h $(srcdir)/services/authzone.h $(srcdir)/services/mesh.h $(srcdir)/util/random.h \ $(srcdir)/services/rpz.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 $(srcdir)/respip/respip.h
stats.lo stats.o: $(srcdir)/daemon/stats.c config.h $(srcdir)/daemon/stats.h $(srcdir)/util/timehist.h \ stats.lo stats.o: $(srcdir)/daemon/stats.c config.h $(srcdir)/daemon/stats.h $(srcdir)/util/timehist.h \
$(srcdir)/libunbound/unbound.h $(srcdir)/daemon/worker.h $(srcdir)/libunbound/worker.h $(srcdir)/sldns/sbuffer.h \ $(srcdir)/libunbound/unbound.h $(srcdir)/daemon/worker.h $(srcdir)/libunbound/worker.h $(srcdir)/sldns/sbuffer.h \
$(srcdir)/util/data/packed_rrset.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h \ $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h \
@ -1311,10 +1312,10 @@ stats.lo stats.o: $(srcdir)/daemon/stats.c config.h $(srcdir)/daemon/stats.h $(s
$(srcdir)/util/tube.h $(srcdir)/util/net_help.h $(srcdir)/validator/validator.h $(srcdir)/validator/val_utils.h \ $(srcdir)/util/tube.h $(srcdir)/util/net_help.h $(srcdir)/validator/validator.h $(srcdir)/validator/val_utils.h \
$(srcdir)/iterator/iterator.h $(srcdir)/services/outbound_list.h $(srcdir)/services/cache/rrset.h \ $(srcdir)/iterator/iterator.h $(srcdir)/services/outbound_list.h $(srcdir)/services/cache/rrset.h \
$(srcdir)/util/storage/slabhash.h $(srcdir)/services/cache/infra.h $(srcdir)/util/storage/dnstree.h \ $(srcdir)/util/storage/slabhash.h $(srcdir)/services/cache/infra.h $(srcdir)/util/storage/dnstree.h \
$(srcdir)/util/rtt.h $(srcdir)/services/authzone.h $(srcdir)/validator/val_kcache.h \ $(srcdir)/util/rtt.h $(srcdir)/services/authzone.h $(srcdir)/services/rpz.h $(srcdir)/services/localzone.h \
$(srcdir)/validator/val_neg.h $(srcdir)/edns-subnet/subnetmod.h $(srcdir)/edns-subnet/addrtree.h \ $(srcdir)/services/view.h $(srcdir)/validator/val_kcache.h $(srcdir)/validator/val_neg.h \
$(srcdir)/edns-subnet/edns-subnet.h \ $(srcdir)/edns-subnet/subnetmod.h $(srcdir)/edns-subnet/addrtree.h \
$(srcdir)/edns-subnet/edns-subnet.h
replay.lo replay.o: $(srcdir)/testcode/replay.c config.h $(srcdir)/util/log.h $(srcdir)/util/net_help.h \ replay.lo replay.o: $(srcdir)/testcode/replay.c config.h $(srcdir)/util/log.h $(srcdir)/util/net_help.h \
$(srcdir)/util/config_file.h $(srcdir)/testcode/replay.h $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \ $(srcdir)/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/testpkts.h $(srcdir)/util/rbtree.h \
@ -1354,9 +1355,10 @@ 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)/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)/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)/validator/validator.h $(srcdir)/validator/val_utils.h $(srcdir)/services/localzone.h \
$(srcdir)/services/view.h $(srcdir)/services/authzone.h $(srcdir)/services/mesh.h $(srcdir)/util/netevent.h \ $(srcdir)/services/view.h $(srcdir)/sldns/sbuffer.h $(srcdir)/services/authzone.h $(srcdir)/services/mesh.h \
$(srcdir)/dnscrypt/dnscrypt.h $(srcdir)/services/modstack.h \ $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
$(srcdir)/respip/respip.h $(srcdir)/sldns/sbuffer.h $(PYTHONMOD_HEADER) \ $(srcdir)/services/modstack.h $(srcdir)/services/rpz.h $(srcdir)/respip/respip.h \
$(srcdir)/sldns/sbuffer.h $(PYTHONMOD_HEADER) \
$(srcdir)/edns-subnet/subnet-whitelist.h $(srcdir)/edns-subnet/subnet-whitelist.h
worker_cb.lo worker_cb.o: $(srcdir)/smallapp/worker_cb.c config.h $(srcdir)/libunbound/context.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)/util/locks.h $(srcdir)/util/log.h $(srcdir)/util/alloc.h $(srcdir)/util/rbtree.h $(srcdir)/services/modstack.h \
@ -1372,10 +1374,10 @@ context.lo context.o: $(srcdir)/libunbound/context.c config.h $(srcdir)/libunbou
$(srcdir)/util/storage/lruhash.h $(srcdir)/util/module.h $(srcdir)/util/data/msgreply.h \ $(srcdir)/util/storage/lruhash.h $(srcdir)/util/module.h $(srcdir)/util/data/msgreply.h \
$(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/config_file.h \ $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/config_file.h \
$(srcdir)/util/net_help.h $(srcdir)/services/localzone.h $(srcdir)/util/storage/dnstree.h \ $(srcdir)/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/view.h $(srcdir)/sldns/sbuffer.h $(srcdir)/services/cache/rrset.h \
$(srcdir)/services/cache/infra.h $(srcdir)/util/rtt.h $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \ $(srcdir)/util/storage/slabhash.h $(srcdir)/services/cache/infra.h $(srcdir)/util/rtt.h \
$(srcdir)/services/authzone.h $(srcdir)/services/mesh.h \ $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
$(srcdir)/sldns/sbuffer.h $(srcdir)/services/authzone.h $(srcdir)/services/mesh.h $(srcdir)/services/rpz.h
libunbound.lo libunbound.o: $(srcdir)/libunbound/libunbound.c $(srcdir)/libunbound/unbound.h \ libunbound.lo libunbound.o: $(srcdir)/libunbound/libunbound.c $(srcdir)/libunbound/unbound.h \
$(srcdir)/libunbound/unbound-event.h config.h $(srcdir)/libunbound/context.h $(srcdir)/util/locks.h \ $(srcdir)/libunbound/unbound-event.h config.h $(srcdir)/libunbound/context.h $(srcdir)/util/locks.h \
$(srcdir)/util/log.h $(srcdir)/util/alloc.h $(srcdir)/util/rbtree.h $(srcdir)/services/modstack.h \ $(srcdir)/util/log.h $(srcdir)/util/alloc.h $(srcdir)/util/rbtree.h $(srcdir)/services/modstack.h \
@ -1384,61 +1386,55 @@ 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/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)/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/localzone.h $(srcdir)/util/storage/dnstree.h $(srcdir)/services/view.h \
$(srcdir)/services/cache/infra.h $(srcdir)/util/rtt.h $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \ $(srcdir)/sldns/sbuffer.h $(srcdir)/services/cache/infra.h $(srcdir)/util/rtt.h $(srcdir)/util/netevent.h \
$(srcdir)/services/cache/rrset.h \ $(srcdir)/dnscrypt/dnscrypt.h $(srcdir)/services/cache/rrset.h \
$(srcdir)/util/storage/slabhash.h $(srcdir)/services/authzone.h $(srcdir)/services/mesh.h \ $(srcdir)/util/storage/slabhash.h $(srcdir)/services/authzone.h $(srcdir)/services/mesh.h \
$(srcdir)/sldns/sbuffer.h $(srcdir)/services/rpz.h
libworker.lo libworker.o: $(srcdir)/libunbound/libworker.c config.h \ libworker.lo libworker.o: $(srcdir)/libunbound/libworker.c config.h $(srcdir)/libunbound/libworker.h \
$(srcdir)/libunbound/libworker.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/storage/lruhash.h \ $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h \
$(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/libunbound/context.h $(srcdir)/util/alloc.h $(srcdir)/util/rbtree.h \ $(srcdir)/libunbound/context.h $(srcdir)/util/alloc.h $(srcdir)/util/rbtree.h $(srcdir)/services/modstack.h \
$(srcdir)/services/modstack.h $(srcdir)/libunbound/unbound.h $(srcdir)/libunbound/unbound-event.h \ $(srcdir)/libunbound/unbound.h $(srcdir)/libunbound/unbound-event.h $(srcdir)/libunbound/worker.h \
$(srcdir)/libunbound/worker.h $(srcdir)/sldns/sbuffer.h $(srcdir)/services/outside_network.h \ $(srcdir)/sldns/sbuffer.h $(srcdir)/services/outside_network.h $(srcdir)/util/netevent.h \
$(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \ $(srcdir)/dnscrypt/dnscrypt.h \
$(srcdir)/services/mesh.h $(srcdir)/util/data/msgparse.h \ $(srcdir)/services/mesh.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h \
$(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/module.h $(srcdir)/util/data/msgreply.h \ $(srcdir)/util/module.h $(srcdir)/util/data/msgreply.h $(srcdir)/services/localzone.h \
$(srcdir)/services/localzone.h $(srcdir)/util/storage/dnstree.h $(srcdir)/services/view.h \ $(srcdir)/util/storage/dnstree.h $(srcdir)/services/view.h $(srcdir)/services/cache/rrset.h \
$(srcdir)/services/cache/rrset.h $(srcdir)/util/storage/slabhash.h $(srcdir)/services/outbound_list.h \ $(srcdir)/util/storage/slabhash.h $(srcdir)/services/outbound_list.h $(srcdir)/services/authzone.h \
$(srcdir)/services/authzone.h $(srcdir)/util/fptr_wlist.h $(srcdir)/util/tube.h $(srcdir)/util/regional.h \ $(srcdir)/services/rpz.h $(srcdir)/util/config_file.h $(srcdir)/util/fptr_wlist.h $(srcdir)/util/tube.h \
$(srcdir)/util/random.h $(srcdir)/util/config_file.h $(srcdir)/util/storage/lookup3.h $(srcdir)/util/net_help.h \ $(srcdir)/util/regional.h $(srcdir)/util/random.h $(srcdir)/util/storage/lookup3.h $(srcdir)/util/net_help.h \
$(srcdir)/util/data/dname.h $(srcdir)/util/data/msgencode.h $(srcdir)/iterator/iter_fwd.h \ $(srcdir)/util/data/dname.h $(srcdir)/util/data/msgencode.h $(srcdir)/iterator/iter_fwd.h \
$(srcdir)/iterator/iter_hints.h $(srcdir)/sldns/str2wire.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 \ unbound-host.lo unbound-host.o: $(srcdir)/smallapp/unbound-host.c config.h $(srcdir)/libunbound/unbound.h \
$(srcdir)/sldns/rrdef.h $(srcdir)/sldns/wire2str.h \ $(srcdir)/sldns/rrdef.h $(srcdir)/sldns/wire2str.h
asynclook.lo asynclook.o: $(srcdir)/testcode/asynclook.c config.h $(srcdir)/libunbound/unbound.h \ asynclook.lo asynclook.o: $(srcdir)/testcode/asynclook.c config.h $(srcdir)/libunbound/unbound.h \
$(srcdir)/libunbound/context.h $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/util/alloc.h $(srcdir)/util/rbtree.h \ $(srcdir)/libunbound/context.h $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/util/alloc.h $(srcdir)/util/rbtree.h \
$(srcdir)/services/modstack.h $(srcdir)/libunbound/unbound-event.h $(srcdir)/util/data/packed_rrset.h \ $(srcdir)/services/modstack.h $(srcdir)/libunbound/unbound-event.h $(srcdir)/util/data/packed_rrset.h \
$(srcdir)/util/storage/lruhash.h $(srcdir)/sldns/rrdef.h \ $(srcdir)/util/storage/lruhash.h $(srcdir)/sldns/rrdef.h
streamtcp.lo streamtcp.o: $(srcdir)/testcode/streamtcp.c config.h $(srcdir)/util/locks.h $(srcdir)/util/log.h \ streamtcp.lo streamtcp.o: $(srcdir)/testcode/streamtcp.c config.h $(srcdir)/util/locks.h $(srcdir)/util/log.h \
$(srcdir)/util/net_help.h $(srcdir)/util/data/msgencode.h $(srcdir)/util/data/msgparse.h \ $(srcdir)/util/net_help.h $(srcdir)/util/data/msgencode.h $(srcdir)/util/data/msgparse.h \
$(srcdir)/util/storage/lruhash.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/data/msgreply.h \ $(srcdir)/util/storage/lruhash.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/data/msgreply.h \
$(srcdir)/util/data/packed_rrset.h $(srcdir)/util/data/dname.h $(srcdir)/sldns/sbuffer.h \ $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/data/dname.h $(srcdir)/sldns/sbuffer.h \
$(srcdir)/sldns/str2wire.h $(srcdir)/sldns/wire2str.h \ $(srcdir)/sldns/str2wire.h $(srcdir)/sldns/wire2str.h
perf.lo perf.o: $(srcdir)/testcode/perf.c config.h $(srcdir)/util/log.h $(srcdir)/util/locks.h $(srcdir)/util/net_help.h \ perf.lo perf.o: $(srcdir)/testcode/perf.c config.h $(srcdir)/util/log.h $(srcdir)/util/locks.h $(srcdir)/util/net_help.h \
$(srcdir)/util/data/msgencode.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/storage/lruhash.h \ $(srcdir)/util/data/msgencode.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/storage/lruhash.h \
$(srcdir)/util/data/packed_rrset.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h \ $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h \
$(srcdir)/sldns/rrdef.h $(srcdir)/sldns/sbuffer.h $(srcdir)/sldns/wire2str.h $(srcdir)/sldns/str2wire.h $(srcdir)/sldns/rrdef.h $(srcdir)/sldns/sbuffer.h $(srcdir)/sldns/wire2str.h $(srcdir)/sldns/str2wire.h
delayer.lo delayer.o: $(srcdir)/testcode/delayer.c config.h $(srcdir)/util/net_help.h $(srcdir)/util/log.h \ 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 $(srcdir)/util/config_file.h $(srcdir)/sldns/sbuffer.h
unbound-control.lo unbound-control.o: $(srcdir)/smallapp/unbound-control.c config.h \ unbound-control.lo unbound-control.o: $(srcdir)/smallapp/unbound-control.c config.h $(srcdir)/util/log.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)/util/shm_side/shm_main.h $(srcdir)/libunbound/unbound.h $(srcdir)/daemon/stats.h \ $(srcdir)/libunbound/unbound.h $(srcdir)/daemon/stats.h $(srcdir)/util/timehist.h $(srcdir)/sldns/wire2str.h \
$(srcdir)/util/timehist.h $(srcdir)/sldns/wire2str.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/pkthdr.h
unbound-anchor.lo unbound-anchor.o: $(srcdir)/smallapp/unbound-anchor.c config.h $(srcdir)/libunbound/unbound.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 \ $(srcdir)/sldns/rrdef.h $(srcdir)/sldns/parseutil.h
petal.lo petal.o: $(srcdir)/testcode/petal.c config.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 \ 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/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)/util/data/packed_rrset.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h \
$(srcdir)/sldns/rrdef.h $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \ $(srcdir)/sldns/rrdef.h $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
$(srcdir)/util/net_help.h $(srcdir)/services/cache/dns.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)/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 \ 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/daemon.h $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/util/alloc.h $(srcdir)/services/modstack.h \
$(srcdir)/daemon/worker.h \ $(srcdir)/daemon/worker.h \
@ -1446,8 +1442,8 @@ win_svc.lo win_svc.o: $(srcdir)/winrc/win_svc.c config.h $(srcdir)/winrc/win_svc
$(srcdir)/util/storage/lruhash.h $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.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)/util/data/msgreply.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h \
$(srcdir)/daemon/stats.h $(srcdir)/util/timehist.h $(srcdir)/libunbound/unbound.h $(srcdir)/util/module.h \ $(srcdir)/daemon/stats.h $(srcdir)/util/timehist.h $(srcdir)/libunbound/unbound.h $(srcdir)/util/module.h \
$(srcdir)/dnstap/dnstap.h $(srcdir)/daemon/remote.h \ $(srcdir)/dnstap/dnstap.h $(srcdir)/daemon/remote.h $(srcdir)/util/config_file.h $(srcdir)/util/ub_event.h \
$(srcdir)/util/config_file.h $(srcdir)/util/ub_event.h $(srcdir)/util/net_help.h $(srcdir)/util/net_help.h
w_inst.lo w_inst.o: $(srcdir)/winrc/w_inst.c config.h $(srcdir)/winrc/w_inst.h $(srcdir)/winrc/win_svc.h 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 \ unbound-service-install.lo unbound-service-install.o: $(srcdir)/winrc/unbound-service-install.c config.h \
$(srcdir)/winrc/w_inst.h $(srcdir)/winrc/w_inst.h
@ -1455,14 +1451,11 @@ unbound-service-remove.lo unbound-service-remove.o: $(srcdir)/winrc/unbound-serv
$(srcdir)/winrc/w_inst.h $(srcdir)/winrc/w_inst.h
anchor-update.lo anchor-update.o: $(srcdir)/winrc/anchor-update.c config.h $(srcdir)/libunbound/unbound.h \ anchor-update.lo anchor-update.o: $(srcdir)/winrc/anchor-update.c config.h $(srcdir)/libunbound/unbound.h \
$(srcdir)/sldns/rrdef.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/wire2str.h $(srcdir)/sldns/rrdef.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/wire2str.h
keyraw.lo keyraw.o: $(srcdir)/sldns/keyraw.c config.h $(srcdir)/sldns/keyraw.h \ keyraw.lo keyraw.o: $(srcdir)/sldns/keyraw.c config.h $(srcdir)/sldns/keyraw.h $(srcdir)/sldns/rrdef.h
$(srcdir)/sldns/rrdef.h \
sbuffer.lo sbuffer.o: $(srcdir)/sldns/sbuffer.c config.h $(srcdir)/sldns/sbuffer.h sbuffer.lo sbuffer.o: $(srcdir)/sldns/sbuffer.c config.h $(srcdir)/sldns/sbuffer.h
wire2str.lo wire2str.o: $(srcdir)/sldns/wire2str.c config.h $(srcdir)/sldns/wire2str.h $(srcdir)/sldns/str2wire.h \ wire2str.lo wire2str.o: $(srcdir)/sldns/wire2str.c config.h $(srcdir)/sldns/wire2str.h $(srcdir)/sldns/str2wire.h \
$(srcdir)/sldns/rrdef.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/parseutil.h $(srcdir)/sldns/sbuffer.h \ $(srcdir)/sldns/rrdef.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/parseutil.h $(srcdir)/sldns/sbuffer.h \
$(srcdir)/sldns/keyraw.h \ $(srcdir)/sldns/keyraw.h
parse.lo parse.o: $(srcdir)/sldns/parse.c config.h $(srcdir)/sldns/parse.h $(srcdir)/sldns/parseutil.h \ parse.lo parse.o: $(srcdir)/sldns/parse.c config.h $(srcdir)/sldns/parse.h $(srcdir)/sldns/parseutil.h \
$(srcdir)/sldns/sbuffer.h $(srcdir)/sldns/sbuffer.h
parseutil.lo parseutil.o: $(srcdir)/sldns/parseutil.c config.h $(srcdir)/sldns/parseutil.h parseutil.lo parseutil.o: $(srcdir)/sldns/parseutil.c config.h $(srcdir)/sldns/parseutil.h
@ -1482,11 +1475,9 @@ snprintf.lo snprintf.o: $(srcdir)/compat/snprintf.c config.h
strlcat.lo strlcat.o: $(srcdir)/compat/strlcat.c config.h strlcat.lo strlcat.o: $(srcdir)/compat/strlcat.c config.h
strlcpy.lo strlcpy.o: $(srcdir)/compat/strlcpy.c config.h strlcpy.lo strlcpy.o: $(srcdir)/compat/strlcpy.c config.h
strptime.lo strptime.o: $(srcdir)/compat/strptime.c config.h strptime.lo strptime.o: $(srcdir)/compat/strptime.c config.h
getentropy_linux.lo getentropy_linux.o: $(srcdir)/compat/getentropy_linux.c config.h \ getentropy_linux.lo getentropy_linux.o: $(srcdir)/compat/getentropy_linux.c config.h
getentropy_osx.lo getentropy_osx.o: $(srcdir)/compat/getentropy_osx.c config.h getentropy_osx.lo getentropy_osx.o: $(srcdir)/compat/getentropy_osx.c config.h
getentropy_solaris.lo getentropy_solaris.o: $(srcdir)/compat/getentropy_solaris.c config.h \ getentropy_solaris.lo getentropy_solaris.o: $(srcdir)/compat/getentropy_solaris.c config.h
getentropy_win.lo getentropy_win.o: $(srcdir)/compat/getentropy_win.c getentropy_win.lo getentropy_win.o: $(srcdir)/compat/getentropy_win.c
explicit_bzero.lo explicit_bzero.o: $(srcdir)/compat/explicit_bzero.c config.h explicit_bzero.lo explicit_bzero.o: $(srcdir)/compat/explicit_bzero.c config.h
arc4random.lo arc4random.o: $(srcdir)/compat/arc4random.c config.h $(srcdir)/compat/chacha_private.h arc4random.lo arc4random.o: $(srcdir)/compat/arc4random.c config.h $(srcdir)/compat/chacha_private.h

View file

@ -619,7 +619,8 @@ daemon_fork(struct daemon* daemon)
have_view_respip_cfg; have_view_respip_cfg;
/* read auth zonefiles */ /* read auth zonefiles */
if(!auth_zones_apply_cfg(daemon->env->auth_zones, daemon->cfg, 1)) if(!auth_zones_apply_cfg(daemon->env->auth_zones, daemon->cfg, 1,
&daemon->use_rpz))
fatal_exit("auth_zones could not be setup"); fatal_exit("auth_zones could not be setup");
/* setup modules */ /* setup modules */
@ -631,6 +632,12 @@ daemon_fork(struct daemon* daemon)
if(daemon->use_response_ip && if(daemon->use_response_ip &&
modstack_find(&daemon->mods, "respip") < 0) modstack_find(&daemon->mods, "respip") < 0)
fatal_exit("response-ip options require respip module"); fatal_exit("response-ip options require respip module");
/* RPZ response ip triggers don't work as expected without the respip
* module. To avoid run-time operational surprise we reject such
* configuration. */
if(daemon->use_rpz &&
modstack_find(&daemon->mods, "respip") < 0)
fatal_exit("RPZ requires the respip module");
/* first create all the worker structures, so we can pass /* first create all the worker structures, so we can pass
* them to the newly created threads. * them to the newly created threads.

View file

@ -132,6 +132,8 @@ struct daemon {
struct respip_set* respip_set; struct respip_set* respip_set;
/** some response-ip tags or actions are configured if true */ /** some response-ip tags or actions are configured if true */
int use_response_ip; int use_response_ip;
/** some RPZ policies are configured */
int use_rpz;
#ifdef USE_DNSCRYPT #ifdef USE_DNSCRYPT
/** the dnscrypt environment */ /** the dnscrypt environment */
struct dnsc_env* dnscenv; struct dnsc_env* dnscenv;

View file

@ -69,6 +69,7 @@
#include "services/mesh.h" #include "services/mesh.h"
#include "services/localzone.h" #include "services/localzone.h"
#include "services/authzone.h" #include "services/authzone.h"
#include "services/rpz.h"
#include "util/storage/slabhash.h" #include "util/storage/slabhash.h"
#include "util/fptr_wlist.h" #include "util/fptr_wlist.h"
#include "util/data/dname.h" #include "util/data/dname.h"
@ -1045,6 +1046,16 @@ print_ext(RES* ssl, struct ub_stats_info* s)
(unsigned)s->svr.infra_cache_count)) return 0; (unsigned)s->svr.infra_cache_count)) return 0;
if(!ssl_printf(ssl, "key.cache.count"SQ"%u\n", if(!ssl_printf(ssl, "key.cache.count"SQ"%u\n",
(unsigned)s->svr.key_cache_count)) return 0; (unsigned)s->svr.key_cache_count)) return 0;
/* applied RPZ actions */
for(i=0; i<UB_STATS_RPZ_ACTION_NUM; i++) {
if((enum rpz_action)s->svr.rpz_action[i] == RPZ_NO_OVERRIDE_ACTION)
continue;
if(inhibit_zero && s->svr.rpz_action[i] == 0)
continue;
if(!ssl_printf(ssl, "num.rpz.action.%s"SQ"%lu\n",
rpz_action_to_string(i),
(unsigned long)s->svr.rpz_action[i])) return 0;
}
#ifdef USE_DNSCRYPT #ifdef USE_DNSCRYPT
if(!ssl_printf(ssl, "dnscrypt_shared_secret.cache.count"SQ"%u\n", if(!ssl_printf(ssl, "dnscrypt_shared_secret.cache.count"SQ"%u\n",
(unsigned)s->svr.shared_secret_cache_count)) return 0; (unsigned)s->svr.shared_secret_cache_count)) return 0;

View file

@ -273,6 +273,8 @@ server_stats_compile(struct worker* worker, struct ub_stats_info* s, int reset)
s->svr.ans_rcode_nodata += (long long)worker->env.mesh->ans_nodata; s->svr.ans_rcode_nodata += (long long)worker->env.mesh->ans_nodata;
for(i=0; i<16; i++) for(i=0; i<16; i++)
s->svr.ans_rcode[i] += (long long)worker->env.mesh->ans_rcode[i]; s->svr.ans_rcode[i] += (long long)worker->env.mesh->ans_rcode[i];
for(i=0; i<UB_STATS_RPZ_ACTION_NUM; i++)
s->svr.rpz_action[i] += (long long)worker->env.mesh->rpz_action[i];
timehist_export(worker->env.mesh->histogram, s->svr.hist, timehist_export(worker->env.mesh->histogram, s->svr.hist,
NUM_BUCKETS_HIST); NUM_BUCKETS_HIST);
/* values from outside network */ /* values from outside network */
@ -446,6 +448,8 @@ void server_stats_add(struct ub_stats_info* total, struct ub_stats_info* a)
total->svr.ans_rcode[i] += a->svr.ans_rcode[i]; total->svr.ans_rcode[i] += a->svr.ans_rcode[i];
for(i=0; i<NUM_BUCKETS_HIST; i++) for(i=0; i<NUM_BUCKETS_HIST; i++)
total->svr.hist[i] += a->svr.hist[i]; total->svr.hist[i] += a->svr.hist[i];
for(i=0; i<UB_STATS_RPZ_ACTION_NUM; i++)
total->svr.rpz_action[i] += a->svr.rpz_action[i];
} }
total->mesh_num_states += a->mesh_num_states; total->mesh_num_states += a->mesh_num_states;

View file

@ -61,6 +61,7 @@
#include "services/authzone.h" #include "services/authzone.h"
#include "services/mesh.h" #include "services/mesh.h"
#include "services/localzone.h" #include "services/localzone.h"
#include "services/rpz.h"
#include "util/data/msgparse.h" #include "util/data/msgparse.h"
#include "util/data/msgencode.h" #include "util/data/msgencode.h"
#include "util/data/dname.h" #include "util/data/dname.h"
@ -572,9 +573,10 @@ static int
apply_respip_action(struct worker* worker, const struct query_info* qinfo, apply_respip_action(struct worker* worker, const struct query_info* qinfo,
struct respip_client_info* cinfo, struct reply_info* rep, struct respip_client_info* cinfo, struct reply_info* rep,
struct comm_reply* repinfo, struct ub_packed_rrset_key** alias_rrset, struct comm_reply* repinfo, struct ub_packed_rrset_key** alias_rrset,
struct reply_info** encode_repp) struct reply_info** encode_repp, struct auth_zones* az)
{ {
struct respip_action_info actinfo = {respip_none, NULL}; struct respip_action_info actinfo = {0};
actinfo.action = respip_none;
if(qinfo->qtype != LDNS_RR_TYPE_A && if(qinfo->qtype != LDNS_RR_TYPE_A &&
qinfo->qtype != LDNS_RR_TYPE_AAAA && qinfo->qtype != LDNS_RR_TYPE_AAAA &&
@ -582,7 +584,7 @@ apply_respip_action(struct worker* worker, const struct query_info* qinfo,
return 1; return 1;
if(!respip_rewrite_reply(qinfo, cinfo, rep, encode_repp, &actinfo, if(!respip_rewrite_reply(qinfo, cinfo, rep, encode_repp, &actinfo,
alias_rrset, 0, worker->scratchpad)) alias_rrset, 0, worker->scratchpad, az))
return 0; return 0;
/* xxx_deny actions mean dropping the reply, unless the original reply /* xxx_deny actions mean dropping the reply, unless the original reply
@ -595,9 +597,20 @@ apply_respip_action(struct worker* worker, const struct query_info* qinfo,
/* If address info is returned, it means the action should be an /* If address info is returned, it means the action should be an
* 'inform' variant and the information should be logged. */ * 'inform' variant and the information should be logged. */
if(actinfo.addrinfo) { if(actinfo.addrinfo) {
respip_inform_print(actinfo.addrinfo, qinfo->qname, respip_inform_print(&actinfo, qinfo->qname,
qinfo->qtype, qinfo->qclass, qinfo->local_alias, qinfo->qtype, qinfo->qclass, qinfo->local_alias,
repinfo); repinfo);
if(worker->stats.extended && actinfo.rpz_used) {
if(actinfo.rpz_disabled)
worker->stats.rpz_action[RPZ_DISABLED_ACTION] +=
actinfo.rpz_disabled;
if(actinfo.rpz_cname_override)
worker->stats.rpz_action[RPZ_CNAME_OVERRIDE_ACTION]++;
else
worker->stats.rpz_action[
respip_action_to_rpz_action(actinfo.action)]++;
}
} }
return 1; return 1;
@ -709,13 +722,15 @@ answer_from_cache(struct worker* worker, struct query_info* qinfo,
(int)(flags&LDNS_RCODE_MASK), edns, repinfo, worker->scratchpad)) (int)(flags&LDNS_RCODE_MASK), edns, repinfo, worker->scratchpad))
goto bail_out; goto bail_out;
*alias_rrset = NULL; /* avoid confusion if caller set it to non-NULL */ *alias_rrset = NULL; /* avoid confusion if caller set it to non-NULL */
if(worker->daemon->use_response_ip && !partial_rep && if((worker->daemon->use_response_ip || worker->daemon->use_rpz) &&
!apply_respip_action(worker, qinfo, cinfo, rep, repinfo, alias_rrset, !partial_rep && !apply_respip_action(worker, qinfo, cinfo, rep,
&encode_rep)) { repinfo, alias_rrset,
&encode_rep, worker->env.auth_zones)) {
goto bail_out; goto bail_out;
} else if(partial_rep && } else if(partial_rep &&
!respip_merge_cname(partial_rep, qinfo, rep, cinfo, !respip_merge_cname(partial_rep, qinfo, rep, cinfo,
must_validate, &encode_rep, worker->scratchpad)) { must_validate, &encode_rep, worker->scratchpad,
worker->env.auth_zones)) {
goto bail_out; goto bail_out;
} }
if(encode_rep != rep) if(encode_rep != rep)
@ -1364,6 +1379,18 @@ worker_handle_request(struct comm_point* c, void* arg, int error,
server_stats_insrcode(&worker->stats, c->buffer); server_stats_insrcode(&worker->stats, c->buffer);
goto send_reply; goto send_reply;
} }
if(worker->env.auth_zones &&
rpz_apply_qname_trigger(worker->env.auth_zones,
&worker->env, &qinfo, &edns, c->buffer, worker->scratchpad,
repinfo, acladdr->taglist, acladdr->taglen, &worker->stats)) {
regional_free_all(worker->scratchpad);
if(sldns_buffer_limit(c->buffer) == 0) {
comm_point_drop_reply(repinfo);
return 0;
}
server_stats_insrcode(&worker->stats, c->buffer);
goto send_reply;
}
if(worker->env.auth_zones && if(worker->env.auth_zones &&
auth_zones_answer(worker->env.auth_zones, &worker->env, auth_zones_answer(worker->env.auth_zones, &worker->env,
&qinfo, &edns, repinfo, c->buffer, worker->scratchpad)) { &qinfo, &edns, repinfo, c->buffer, worker->scratchpad)) {
@ -1434,7 +1461,7 @@ worker_handle_request(struct comm_point* c, void* arg, int error,
/* If we may apply IP-based actions to the answer, build the client /* If we may apply IP-based actions to the answer, build the client
* information. As this can be expensive, skip it if there is * information. As this can be expensive, skip it if there is
* absolutely no possibility of it. */ * absolutely no possibility of it. */
if(worker->daemon->use_response_ip && if((worker->daemon->use_response_ip || worker->daemon->use_rpz) &&
(qinfo.qtype == LDNS_RR_TYPE_A || (qinfo.qtype == LDNS_RR_TYPE_A ||
qinfo.qtype == LDNS_RR_TYPE_AAAA || qinfo.qtype == LDNS_RR_TYPE_AAAA ||
qinfo.qtype == LDNS_RR_TYPE_ANY)) { qinfo.qtype == LDNS_RR_TYPE_ANY)) {

View file

@ -1006,3 +1006,17 @@ remote-control:
# name-v6: "list-v6" # name-v6: "list-v6"
# #
# Response Policy Zones
# RPZ policies. Applied in order of configuration. QNAME and Response IP
# Address trigger are the only supported triggers. Supported actions are:
# NXDOMAIN, NODATA, PASSTHRU, DROP and Local Data. Polices can be loaded from
# file or using zone transfer. The respip module needs to be added to the
# module-config, e.g.: module-config: "respip validator iterator".
# rpz:
# name: "rpz.example.com"
# zonefile: "rpz.example.com"
# rpz-action-override: cname
# rpz-cname-override: www.example.org
# rpz-log: yes
# rpz-log-name: "example policy"
# tags: "example"

View file

@ -2080,6 +2080,59 @@ If this timeout expires Unbound closes the connection, treats it as
if the Redis server does not have the requested data, and will try to if the Redis server does not have the requested data, and will try to
re-establish a new connection later. re-establish a new connection later.
This option defaults to 100 milliseconds. This option defaults to 100 milliseconds.
.SS Response Policy Zone Options
.LP
Response Policy Zones are configured with \fBrpz:\fR, and each one must have a
\fBname:\fR. There can be multiple ones, by listing multiple rpz clauses, each
with a different name. RPZ clauses are applied in order of configuration. The
\fBrespip\fR module needs to be added to the \fBmodule-config\fR, e.g.:
\fBmodule-config: "respip validator itarator"\fR.
.P
Only the QNAME and Response IP Address triggers are supported. The supported RPZ
actions are: NXDOMAIN, NODATA, PASSTHRU, DROP and Local Data. RPZ QNAME triggers
are applied after
\fBlocal-zones\fR and before \fBauth-zones\fR.
.TP
.B name: \fI<zone name>
Name of the authority zone.
.TP
.B master: \fI<IP address or host name>
Where to download a copy of the zone from, with AXFR and IXFR. Multiple
masters can be specified. They are all tried if one fails.
.TP
.B allow\-notify: \fI<IP address or host name or netblockIP/prefix>
With allow\-notify you can specify additional sources of notifies.
When notified, the server attempts to first probe and then zone transfer.
If the notify is from a master, it first attempts that master. Otherwise
other masters are attempted. If there are no masters, but only urls, the
file is downloaded when notified. The masters from master: statements are
allowed notify by default.
.TP
.B zonefile: \fI<filename>
The filename where the zone is stored. If not given then no zonefile is used.
If the file does not exist or is empty, unbound will attempt to fetch zone
data (eg. from the master servers).
.TP
.B rpz\-action\-override: \fI<action>
Always use this RPZ action for matching triggers from this zone. Possible action
are: nxdomain, nodata, passthru, drop, disabled and cname.
.TP
.B rpz\-cname\-override: \fI<domain>
The CNAME target domain to use if the cname action is configured for
\fBrpz\-action\-override\fR.
.TP
.B rpz\-log: \fI<yes or no>
Log all applied RPZ actions. Default is no.
.TP
.B rpz\-log\-name: \fI<name>
Specify a string to be part of the log line, for easy referencing.
.TP
.B tags: \fI<list of tags>
Limit the policies from this RPZ clause to clients with a matching tag. Tags
need to be defined in \fBdefine\-tag\fR and can be assiged to client addresses
using \fBaccess\-control\-tag\fR. Enclose list of tags in quotes ("") and put
spaces between tags. If no tags are specified the policies from this clause will
be applied for all clients.
.SH "MEMORY CONTROL EXAMPLE" .SH "MEMORY CONTROL EXAMPLE"
In the example config settings below memory usage is reduced. Some service 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 levels are lower, notable very large data and a high TCP load are no longer

View file

@ -55,6 +55,7 @@
int int
context_finalize(struct ub_ctx* ctx) context_finalize(struct ub_ctx* ctx)
{ {
int is_rpz;
struct config_file* cfg = ctx->env->cfg; struct config_file* cfg = ctx->env->cfg;
verbosity = cfg->verbosity; verbosity = cfg->verbosity;
if(ctx_logfile_overridden && !ctx->logfile_override) { if(ctx_logfile_overridden && !ctx->logfile_override) {
@ -76,7 +77,7 @@ context_finalize(struct ub_ctx* ctx)
return UB_NOMEM; return UB_NOMEM;
if(!local_zones_apply_cfg(ctx->local_zones, cfg)) if(!local_zones_apply_cfg(ctx->local_zones, cfg))
return UB_INITFAIL; return UB_INITFAIL;
if(!auth_zones_apply_cfg(ctx->env->auth_zones, cfg, 1)) if(!auth_zones_apply_cfg(ctx->env->auth_zones, cfg, 1i, &is_rpz))
return UB_INITFAIL; return UB_INITFAIL;
if(!slabhash_is_size(ctx->env->msg_cache, cfg->msg_cache_size, if(!slabhash_is_size(ctx->env->msg_cache, cfg->msg_cache_size,
cfg->msg_cache_slabs)) { cfg->msg_cache_slabs)) {

View file

@ -654,6 +654,8 @@ struct ub_shm_stat_info {
#define UB_STATS_OPCODE_NUM 16 #define UB_STATS_OPCODE_NUM 16
/** number of histogram buckets */ /** number of histogram buckets */
#define UB_STATS_BUCKET_NUM 40 #define UB_STATS_BUCKET_NUM 40
/** number of RPZ actions */
#define UB_STATS_RPZ_ACTION_NUM 10
/** per worker statistics. */ /** per worker statistics. */
struct ub_server_stats { struct ub_server_stats {
@ -785,6 +787,8 @@ struct ub_server_stats {
long long mem_stream_wait; long long mem_stream_wait;
/** number of TLS connection resume */ /** number of TLS connection resume */
long long qtls_resume; long long qtls_resume;
/** RPZ action stats */
long long rpz_action[UB_STATS_RPZ_ACTION_NUM];
}; };
/** /**

View file

@ -12,6 +12,7 @@
#include "config.h" #include "config.h"
#include "services/localzone.h" #include "services/localzone.h"
#include "services/authzone.h"
#include "services/cache/dns.h" #include "services/cache/dns.h"
#include "sldns/str2wire.h" #include "sldns/str2wire.h"
#include "util/config_file.h" #include "util/config_file.h"
@ -25,30 +26,6 @@
#include "services/view.h" #include "services/view.h"
#include "sldns/rrdef.h" #include "sldns/rrdef.h"
/**
* Conceptual set of IP addresses for response AAAA or A records that should
* trigger special actions.
*/
struct respip_set {
struct regional* region;
struct rbtree_type ip_tree;
char* const* tagname; /* shallow copy of tag names, for logging */
int num_tags; /* number of tagname entries */
};
/** An address span with response control information */
struct resp_addr {
/** node in address tree */
struct addr_tree_node node;
/** tag bitlist */
uint8_t* taglist;
/** length of the taglist (in bytes) */
size_t taglen;
/** action for this address span */
enum respip_action action;
/** "local data" for this node */
struct ub_packed_rrset_key* data;
};
/** Subset of resp_addr.node, used for inform-variant logging */ /** Subset of resp_addr.node, used for inform-variant logging */
struct respip_addr_info { struct respip_addr_info {
@ -88,6 +65,7 @@ respip_set_create(void)
return NULL; return NULL;
} }
addr_tree_init(&set->ip_tree); addr_tree_init(&set->ip_tree);
lock_rw_init(&set->lock);
return set; return set;
} }
@ -96,6 +74,7 @@ respip_set_delete(struct respip_set* set)
{ {
if(!set) if(!set)
return; return;
lock_rw_destroy(&set->lock);
regional_destroy(set->region); regional_destroy(set->region);
free(set); free(set);
} }
@ -108,12 +87,49 @@ respip_set_get_tree(struct respip_set* set)
return &set->ip_tree; return &set->ip_tree;
} }
struct resp_addr*
respip_sockaddr_find_or_create(struct respip_set* set, struct sockaddr_storage* addr,
socklen_t addrlen, int net, int create, const char* ipstr)
{
struct resp_addr* node;
node = (struct resp_addr*)addr_tree_find(&set->ip_tree, addr, addrlen, net);
if(!node && create) {
node = regional_alloc_zero(set->region, sizeof(*node));
if(!node) {
log_err("out of memory");
return NULL;
}
lock_rw_init(&node->lock);
node->action = respip_none;
if(!addr_tree_insert(&set->ip_tree, &node->node, addr,
addrlen, net)) {
/* We know we didn't find it, so this should be
* impossible. */
log_warn("unexpected: duplicate address: %s", ipstr);
}
}
return node;
}
void
respip_sockaddr_delete(struct respip_set* set, struct resp_addr* node)
{
struct resp_addr* prev;
prev = (struct resp_addr*)rbtree_previous((struct rbnode_type*)node);
lock_rw_destroy(&node->lock);
rbtree_delete(&set->ip_tree, node);
/* no free'ing, all allocated in region */
if(!prev)
addr_tree_init_parents((rbtree_type*)set);
else
addr_tree_init_parents_node(&prev->node);
}
/** returns the node in the address tree for the specified netblock string; /** returns the node in the address tree for the specified netblock string;
* non-existent node will be created if 'create' is true */ * non-existent node will be created if 'create' is true */
static struct resp_addr* static struct resp_addr*
respip_find_or_create(struct respip_set* set, const char* ipstr, int create) respip_find_or_create(struct respip_set* set, const char* ipstr, int create)
{ {
struct resp_addr* node;
struct sockaddr_storage addr; struct sockaddr_storage addr;
int net; int net;
socklen_t addrlen; socklen_t addrlen;
@ -122,22 +138,8 @@ respip_find_or_create(struct respip_set* set, const char* ipstr, int create)
log_err("cannot parse netblock: '%s'", ipstr); log_err("cannot parse netblock: '%s'", ipstr);
return NULL; return NULL;
} }
node = (struct resp_addr*)addr_tree_find(&set->ip_tree, &addr, addrlen, net); return respip_sockaddr_find_or_create(set, &addr, addrlen, net, create,
if(!node && create) { ipstr);
node = regional_alloc_zero(set->region, sizeof(*node));
if(!node) {
log_err("out of memory");
return NULL;
}
node->action = respip_none;
if(!addr_tree_insert(&set->ip_tree, &node->node, &addr,
addrlen, net)) {
/* We know we didn't find it, so this should be
* impossible. */
log_warn("unexpected: duplicate address: %s", ipstr);
}
}
return node;
} }
static int static int
@ -191,6 +193,10 @@ respip_action_cfg(struct respip_set* set, const char* ipstr,
action = respip_always_refuse; action = respip_always_refuse;
else if(strcmp(actnstr, "always_nxdomain") == 0) else if(strcmp(actnstr, "always_nxdomain") == 0)
action = respip_always_nxdomain; action = respip_always_nxdomain;
else if(strcmp(actnstr, "always_nodata") == 0)
action = respip_always_nodata;
else if(strcmp(actnstr, "always_deny") == 0)
action = respip_always_deny;
else { else {
log_err("unknown response-ip action %s", actnstr); log_err("unknown response-ip action %s", actnstr);
return 0; return 0;
@ -232,8 +238,43 @@ new_rrset(struct regional* region, uint16_t rrtype, uint16_t rrclass)
} }
/** enter local data as resource records into a response-ip node */ /** enter local data as resource records into a response-ip node */
static int
int
respip_enter_rr(struct regional* region, struct resp_addr* raddr, respip_enter_rr(struct regional* region, struct resp_addr* raddr,
uint16_t rrtype, uint16_t rrclass, time_t ttl, uint8_t* rdata,
size_t rdata_len, const char* rrstr, const char* netblockstr)
{
struct packed_rrset_data* pd;
struct sockaddr* sa;
sa = (struct sockaddr*)&raddr->node.addr;
if (rrtype == LDNS_RR_TYPE_CNAME && raddr->data) {
log_err("CNAME response-ip data (%s) can not co-exist with other "
"response-ip data for netblock %s", rrstr, netblockstr);
return 0;
} else if (raddr->data &&
raddr->data->rk.type == htons(LDNS_RR_TYPE_CNAME)) {
log_err("response-ip data (%s) can not be added; CNAME response-ip "
"data already in place for netblock %s", rrstr, netblockstr);
return 0;
} else if((rrtype != LDNS_RR_TYPE_CNAME) &&
((sa->sa_family == AF_INET && rrtype != LDNS_RR_TYPE_A) ||
(sa->sa_family == AF_INET6 && rrtype != LDNS_RR_TYPE_AAAA))) {
log_err("response-ip data %s record type does not correspond "
"to netblock %s address family", rrstr, netblockstr);
return 0;
}
if(!raddr->data) {
raddr->data = new_rrset(region, rrtype, rrclass);
if(!raddr->data)
return 0;
}
pd = raddr->data->entry.data;
return rrset_insert_rr(region, pd, rdata, rdata_len, ttl, rrstr);
}
static int
respip_enter_rrstr(struct regional* region, struct resp_addr* raddr,
const char* rrstr, const char* netblock) const char* rrstr, const char* netblock)
{ {
uint8_t* nm; uint8_t* nm;
@ -244,8 +285,6 @@ respip_enter_rr(struct regional* region, struct resp_addr* raddr,
size_t rdata_len = 0; size_t rdata_len = 0;
char buf[65536]; char buf[65536];
char bufshort[64]; char bufshort[64];
struct packed_rrset_data* pd;
struct sockaddr* sa;
int ret; int ret;
if(raddr->action != respip_redirect if(raddr->action != respip_redirect
&& raddr->action != respip_inform_redirect) { && raddr->action != respip_inform_redirect) {
@ -265,31 +304,8 @@ respip_enter_rr(struct regional* region, struct resp_addr* raddr,
return 0; return 0;
} }
free(nm); free(nm);
sa = (struct sockaddr*)&raddr->node.addr; return respip_enter_rr(region, raddr, rrtype, rrclass, ttl, rdata,
if (rrtype == LDNS_RR_TYPE_CNAME && raddr->data) { rdata_len, rrstr, netblock);
log_err("CNAME response-ip data (%s) can not co-exist with other "
"response-ip data for netblock %s", rrstr, netblock);
return 0;
} else if (raddr->data &&
raddr->data->rk.type == htons(LDNS_RR_TYPE_CNAME)) {
log_err("response-ip data (%s) can not be added; CNAME response-ip "
"data already in place for netblock %s", rrstr, netblock);
return 0;
} else if((rrtype != LDNS_RR_TYPE_CNAME) &&
((sa->sa_family == AF_INET && rrtype != LDNS_RR_TYPE_A) ||
(sa->sa_family == AF_INET6 && rrtype != LDNS_RR_TYPE_AAAA))) {
log_err("response-ip data %s record type does not correspond "
"to netblock %s address family", rrstr, netblock);
return 0;
}
if(!raddr->data) {
raddr->data = new_rrset(region, rrtype, rrclass);
if(!raddr->data)
return 0;
}
pd = raddr->data->entry.data;
return rrset_insert_rr(region, pd, rdata, rdata_len, ttl, rrstr);
} }
static int static int
@ -303,7 +319,7 @@ respip_data_cfg(struct respip_set* set, const char* ipstr, const char* rrstr)
"response-ip node for %s not found", rrstr, ipstr); "response-ip node for %s not found", rrstr, ipstr);
return 0; return 0;
} }
return respip_enter_rr(set->region, node, rrstr, ipstr); return respip_enter_rrstr(set->region, node, rrstr, ipstr);
} }
static int static int
@ -558,9 +574,10 @@ rdata2sockaddr(const struct packed_rrset_data* rd, uint16_t rtype, size_t i,
* rep->rrsets for the RRset that contains the matching IP address record * rep->rrsets for the RRset that contains the matching IP address record
* (the index is normally 0, but can be larger than that if this is a CNAME * (the index is normally 0, but can be larger than that if this is a CNAME
* chain or type-ANY response). * chain or type-ANY response).
* Returns resp_addr holding read lock.
*/ */
static const struct resp_addr* static struct resp_addr*
respip_addr_lookup(const struct reply_info *rep, struct rbtree_type* iptree, respip_addr_lookup(const struct reply_info *rep, struct respip_set* rs,
size_t* rrset_id) size_t* rrset_id)
{ {
size_t i; size_t i;
@ -568,6 +585,7 @@ respip_addr_lookup(const struct reply_info *rep, struct rbtree_type* iptree,
struct sockaddr_storage ss; struct sockaddr_storage ss;
socklen_t addrlen; socklen_t addrlen;
lock_rw_rdlock(&rs->lock);
for(i=0; i<rep->an_numrrsets; i++) { for(i=0; i<rep->an_numrrsets; i++) {
size_t j; size_t j;
const struct packed_rrset_data* rd; const struct packed_rrset_data* rd;
@ -579,15 +597,17 @@ respip_addr_lookup(const struct reply_info *rep, struct rbtree_type* iptree,
for(j = 0; j < rd->count; j++) { for(j = 0; j < rd->count; j++) {
if(!rdata2sockaddr(rd, rtype, j, &ss, &addrlen)) if(!rdata2sockaddr(rd, rtype, j, &ss, &addrlen))
continue; continue;
ra = (struct resp_addr*)addr_tree_lookup(iptree, &ss, ra = (struct resp_addr*)addr_tree_lookup(&rs->ip_tree,
addrlen); &ss, addrlen);
if(ra) { if(ra) {
*rrset_id = i; *rrset_id = i;
lock_rw_rdlock(&ra->lock);
lock_rw_unlock(&rs->lock);
return ra; return ra;
} }
} }
} }
lock_rw_unlock(&rs->lock);
return NULL; return NULL;
} }
@ -636,8 +656,8 @@ make_new_reply_info(const struct reply_info* rep, struct regional* region,
* Note that this function distinguishes error conditions from "success but * Note that this function distinguishes error conditions from "success but
* not overridden". This is because we want to avoid accidentally applying * not overridden". This is because we want to avoid accidentally applying
* the "no data" action in case of error. * the "no data" action in case of error.
* @param raddr: address span that requires an action
* @param action: action to apply * @param action: action to apply
* @param data: RRset to use for override
* @param qtype: original query type * @param qtype: original query type
* @param rep: original reply message * @param rep: original reply message
* @param rrset_id: the rrset ID in 'rep' to which the action should apply * @param rrset_id: the rrset ID in 'rep' to which the action should apply
@ -652,14 +672,15 @@ make_new_reply_info(const struct reply_info* rep, struct regional* region,
* @return 1 if overridden, 0 if not overridden, -1 on error. * @return 1 if overridden, 0 if not overridden, -1 on error.
*/ */
static int static int
respip_data_answer(const struct resp_addr* raddr, enum respip_action action, respip_data_answer(enum respip_action action,
struct ub_packed_rrset_key* data,
uint16_t qtype, const struct reply_info* rep, uint16_t qtype, const struct reply_info* rep,
size_t rrset_id, struct reply_info** new_repp, int tag, size_t rrset_id, struct reply_info** new_repp, int tag,
struct config_strlist** tag_datas, size_t tag_datas_size, struct config_strlist** tag_datas, size_t tag_datas_size,
char* const* tagname, int num_tags, char* const* tagname, int num_tags,
struct ub_packed_rrset_key** redirect_rrsetp, struct regional* region) struct ub_packed_rrset_key** redirect_rrsetp, struct regional* region)
{ {
struct ub_packed_rrset_key* rp = raddr->data; struct ub_packed_rrset_key* rp = data;
struct reply_info* new_rep; struct reply_info* new_rep;
*redirect_rrsetp = NULL; *redirect_rrsetp = NULL;
@ -697,7 +718,7 @@ respip_data_answer(const struct resp_addr* raddr, enum respip_action action,
* to replace the rrset's dname. Note that, unlike local data, we * to replace the rrset's dname. Note that, unlike local data, we
* rename the dname for other actions than redirect. This is because * rename the dname for other actions than redirect. This is because
* response-ip-data isn't associated to any specific name. */ * response-ip-data isn't associated to any specific name. */
if(rp == raddr->data) { if(rp == data) {
rp = copy_rrset(rp, region); rp = copy_rrset(rp, region);
if(!rp) if(!rp)
return -1; return -1;
@ -755,6 +776,7 @@ respip_nodata_answer(uint16_t qtype, enum respip_action action,
return 1; return 1;
} else if(action == respip_static || action == respip_redirect || } else if(action == respip_static || action == respip_redirect ||
action == respip_always_nxdomain || action == respip_always_nxdomain ||
action == respip_always_nodata ||
action == respip_inform_redirect) { action == respip_inform_redirect) {
/* Since we don't know about other types of the owner name, /* Since we don't know about other types of the owner name,
* we generally return NOERROR/NODATA unless an NXDOMAIN action * we generally return NOERROR/NODATA unless an NXDOMAIN action
@ -788,16 +810,22 @@ populate_action_info(struct respip_action_info* actinfo,
enum respip_action action, const struct resp_addr* raddr, enum respip_action action, const struct resp_addr* raddr,
const struct ub_packed_rrset_key* ATTR_UNUSED(rrset), const struct ub_packed_rrset_key* ATTR_UNUSED(rrset),
int ATTR_UNUSED(tag), const struct respip_set* ATTR_UNUSED(ipset), int ATTR_UNUSED(tag), const struct respip_set* ATTR_UNUSED(ipset),
int ATTR_UNUSED(action_only), struct regional* region) int ATTR_UNUSED(action_only), struct regional* region, int rpz_used,
int rpz_log, char* log_name, int rpz_cname_override)
{ {
if(action == respip_none || !raddr) if(action == respip_none || !raddr)
return 1; return 1;
actinfo->action = action; actinfo->action = action;
actinfo->rpz_used = rpz_used;
actinfo->rpz_log = rpz_log;
actinfo->log_name = log_name;
actinfo->rpz_cname_override = rpz_cname_override;
/* for inform variants, make a copy of the matched address block for /* for inform variants, make a copy of the matched address block for
* later logging. We make a copy to proactively avoid disruption if * later logging. We make a copy to proactively avoid disruption if
* and when we allow a dynamic update to the respip tree. */ * and when we allow a dynamic update to the respip tree. */
if(action == respip_inform || action == respip_inform_deny) { if(action == respip_inform || action == respip_inform_deny ||
rpz_used) {
struct respip_addr_info* a = struct respip_addr_info* a =
regional_alloc_zero(region, sizeof(*a)); regional_alloc_zero(region, sizeof(*a));
if(!a) { if(!a) {
@ -813,12 +841,36 @@ populate_action_info(struct respip_action_info* actinfo,
return 1; return 1;
} }
static int
respip_use_rpz(struct resp_addr* raddr, struct rpz* r,
enum respip_action* action,
struct ub_packed_rrset_key** data, int* rpz_log, char** log_name,
int* rpz_cname_override, struct regional* region)
{
if(r->action_override == RPZ_DISABLED_ACTION) {
return 0;
}
else if(r->action_override == RPZ_NO_OVERRIDE_ACTION)
*action = raddr->action;
else
*action = rpz_action_to_respip_action(r->action_override);
if(r->action_override == RPZ_CNAME_OVERRIDE_ACTION &&
r->cname_override) {
*data = r->cname_override;
*rpz_cname_override = 1;
}
*rpz_log = r->log;
if(r->log_name)
*log_name = regional_strdup(region, r->log_name);
return 1;
}
int int
respip_rewrite_reply(const struct query_info* qinfo, respip_rewrite_reply(const struct query_info* qinfo,
const struct respip_client_info* cinfo, const struct reply_info* rep, const struct respip_client_info* cinfo, const struct reply_info* rep,
struct reply_info** new_repp, struct respip_action_info* actinfo, struct reply_info** new_repp, struct respip_action_info* actinfo,
struct ub_packed_rrset_key** alias_rrset, int search_only, struct ub_packed_rrset_key** alias_rrset, int search_only,
struct regional* region) struct regional* region, struct auth_zones* az)
{ {
const uint8_t* ctaglist; const uint8_t* ctaglist;
size_t ctaglen; size_t ctaglen;
@ -831,9 +883,15 @@ respip_rewrite_reply(const struct query_info* qinfo,
size_t rrset_id = 0; size_t rrset_id = 0;
enum respip_action action = respip_none; enum respip_action action = respip_none;
int tag = -1; int tag = -1;
const struct resp_addr* raddr = NULL; struct resp_addr* raddr = NULL;
int ret = 1; int ret = 1;
struct ub_packed_rrset_key* redirect_rrset = NULL; struct ub_packed_rrset_key* redirect_rrset = NULL;
struct rpz* r;
struct ub_packed_rrset_key* data = NULL;
int rpz_used = 0;
int rpz_log = 0;
int rpz_cname_override = 0;
char* log_name = NULL;
if(!cinfo) if(!cinfo)
goto done; goto done;
@ -860,7 +918,7 @@ respip_rewrite_reply(const struct query_info* qinfo,
lock_rw_rdlock(&view->lock); lock_rw_rdlock(&view->lock);
if(view->respip_set) { if(view->respip_set) {
if((raddr = respip_addr_lookup(rep, if((raddr = respip_addr_lookup(rep,
&view->respip_set->ip_tree, &rrset_id))) { view->respip_set, &rrset_id))) {
/** for per-view respip directives the action /** for per-view respip directives the action
* can only be direct (i.e. not tag-based) */ * can only be direct (i.e. not tag-based) */
action = raddr->action; action = raddr->action;
@ -869,7 +927,7 @@ respip_rewrite_reply(const struct query_info* qinfo,
if(!raddr && !view->isfirst) if(!raddr && !view->isfirst)
goto done; goto done;
} }
if(!raddr && ipset && (raddr = respip_addr_lookup(rep, &ipset->ip_tree, if(!raddr && ipset && (raddr = respip_addr_lookup(rep, ipset,
&rrset_id))) { &rrset_id))) {
action = (enum respip_action)local_data_find_tag_action( action = (enum respip_action)local_data_find_tag_action(
raddr->taglist, raddr->taglen, ctaglist, ctaglen, raddr->taglist, raddr->taglen, ctaglist, ctaglen,
@ -877,6 +935,26 @@ respip_rewrite_reply(const struct query_info* qinfo,
(enum localzone_type)raddr->action, &tag, (enum localzone_type)raddr->action, &tag,
ipset->tagname, ipset->num_tags); ipset->tagname, ipset->num_tags);
} }
lock_rw_rdlock(&az->rpz_lock);
for(r = az->rpz_first; r && !raddr; r = r->next) {
if(!r->taglist || taglist_intersect(r->taglist,
r->taglistlen, ctaglist, ctaglen)) {
if((raddr = respip_addr_lookup(rep,
r->respip_set, &rrset_id))) {
}
if(raddr) {
if(!respip_use_rpz(raddr, r, &action, &data,
&rpz_log, &log_name, &rpz_cname_override,
region)) {
lock_rw_unlock(&raddr->lock);
raddr = NULL;
actinfo->rpz_disabled++;
}
rpz_used = 1;
}
}
}
lock_rw_unlock(&az->rpz_lock);
if(raddr && !search_only) { if(raddr && !search_only) {
int result = 0; int result = 0;
@ -885,10 +963,13 @@ respip_rewrite_reply(const struct query_info* qinfo,
if(action != respip_always_refuse if(action != respip_always_refuse
&& action != respip_always_transparent && action != respip_always_transparent
&& action != respip_always_nxdomain && action != respip_always_nxdomain
&& (result = respip_data_answer(raddr, action, && action != respip_always_nodata
qinfo->qtype, rep, rrset_id, new_repp, tag, tag_datas, && action != respip_always_deny
tag_datas_size, ipset->tagname, ipset->num_tags, && (result = respip_data_answer(action,
&redirect_rrset, region)) < 0) { (data) ? data : raddr->data, qinfo->qtype, rep,
rrset_id, new_repp, tag, tag_datas, tag_datas_size,
ipset->tagname, ipset->num_tags, &redirect_rrset,
region)) < 0) {
ret = 0; ret = 0;
goto done; goto done;
} }
@ -919,8 +1000,11 @@ respip_rewrite_reply(const struct query_info* qinfo,
*alias_rrset = redirect_rrset; *alias_rrset = redirect_rrset;
/* on success, populate respip result structure */ /* on success, populate respip result structure */
ret = populate_action_info(actinfo, action, raddr, ret = populate_action_info(actinfo, action, raddr,
redirect_rrset, tag, ipset, search_only, region); redirect_rrset, tag, ipset, search_only, region,
rpz_used, rpz_log, log_name, rpz_cname_override);
} }
if(raddr)
lock_rw_unlock(&raddr->lock);
return ret; return ret;
} }
@ -975,14 +1059,15 @@ respip_operate(struct module_qstate* qstate, enum module_ev event, int id,
qstate->qinfo.qtype == LDNS_RR_TYPE_AAAA || qstate->qinfo.qtype == LDNS_RR_TYPE_AAAA ||
qstate->qinfo.qtype == LDNS_RR_TYPE_ANY) && qstate->qinfo.qtype == LDNS_RR_TYPE_ANY) &&
qstate->return_msg && qstate->return_msg->rep) { qstate->return_msg && qstate->return_msg->rep) {
struct respip_action_info actinfo = {respip_none, NULL};
struct reply_info* new_rep = qstate->return_msg->rep; struct reply_info* new_rep = qstate->return_msg->rep;
struct ub_packed_rrset_key* alias_rrset = NULL; struct ub_packed_rrset_key* alias_rrset = NULL;
struct respip_action_info actinfo = {0};
actinfo.action = respip_none;
if(!respip_rewrite_reply(&qstate->qinfo, if(!respip_rewrite_reply(&qstate->qinfo,
qstate->client_info, qstate->return_msg->rep, qstate->client_info, qstate->return_msg->rep,
&new_rep, &actinfo, &alias_rrset, 0, &new_rep, &actinfo, &alias_rrset, 0,
qstate->region)) { qstate->region, qstate->env->auth_zones)) {
goto servfail; goto servfail;
} }
if(actinfo.action != respip_none) { if(actinfo.action != respip_none) {
@ -998,9 +1083,11 @@ respip_operate(struct module_qstate* qstate, enum module_ev event, int id,
} else { } else {
qstate->respip_action_info = NULL; qstate->respip_action_info = NULL;
} }
if (new_rep == qstate->return_msg->rep && if (actinfo.action == respip_always_deny ||
(new_rep == qstate->return_msg->rep &&
(actinfo.action == respip_deny || (actinfo.action == respip_deny ||
actinfo.action == respip_inform_deny)) { actinfo.action == respip_deny ||
actinfo.action == respip_inform_deny))) {
/* for deny-variant actions (unless response-ip /* for deny-variant actions (unless response-ip
* data is applied), mark the query state so * data is applied), mark the query state so
* the response will be dropped for all * the response will be dropped for all
@ -1028,14 +1115,16 @@ int
respip_merge_cname(struct reply_info* base_rep, respip_merge_cname(struct reply_info* base_rep,
const struct query_info* qinfo, const struct reply_info* tgt_rep, const struct query_info* qinfo, const struct reply_info* tgt_rep,
const struct respip_client_info* cinfo, int must_validate, const struct respip_client_info* cinfo, int must_validate,
struct reply_info** new_repp, struct regional* region) struct reply_info** new_repp, struct regional* region,
struct auth_zones* az)
{ {
struct reply_info* new_rep; struct reply_info* new_rep;
struct reply_info* tmp_rep = NULL; /* just a placeholder */ struct reply_info* tmp_rep = NULL; /* just a placeholder */
struct ub_packed_rrset_key* alias_rrset = NULL; /* ditto */ struct ub_packed_rrset_key* alias_rrset = NULL; /* ditto */
uint16_t tgt_rcode; uint16_t tgt_rcode;
size_t i, j; size_t i, j;
struct respip_action_info actinfo = {respip_none, NULL}; struct respip_action_info actinfo = {0};
actinfo.action = respip_none;
/* If the query for the CNAME target would result in an unusual rcode, /* If the query for the CNAME target would result in an unusual rcode,
* we generally translate it as a failure for the base query * we generally translate it as a failure for the base query
@ -1054,7 +1143,7 @@ respip_merge_cname(struct reply_info* base_rep,
/* see if the target reply would be subject to a response-ip action. */ /* see if the target reply would be subject to a response-ip action. */
if(!respip_rewrite_reply(qinfo, cinfo, tgt_rep, &tmp_rep, &actinfo, if(!respip_rewrite_reply(qinfo, cinfo, tgt_rep, &tmp_rep, &actinfo,
&alias_rrset, 1, region)) &alias_rrset, 1, region, az))
return 0; return 0;
if(actinfo.action != respip_none) { if(actinfo.action != respip_none) {
log_info("CNAME target of redirect response-ip action would " log_info("CNAME target of redirect response-ip action would "
@ -1106,7 +1195,8 @@ respip_inform_super(struct module_qstate* qstate, int id,
if(!respip_merge_cname(super->return_msg->rep, &qstate->qinfo, if(!respip_merge_cname(super->return_msg->rep, &qstate->qinfo,
qstate->return_msg->rep, super->client_info, qstate->return_msg->rep, super->client_info,
super->env->need_to_validate, &new_rep, super->region)) super->env->need_to_validate, &new_rep, super->region,
qstate->env->auth_zones))
goto fail; goto fail;
super->return_msg->rep = new_rep; super->return_msg->rep = new_rep;
return; return;
@ -1165,12 +1255,15 @@ respip_set_is_empty(const struct respip_set* set)
} }
void void
respip_inform_print(struct respip_addr_info* respip_addr, uint8_t* qname, respip_inform_print(struct respip_action_info* respip_actinfo, uint8_t* qname,
uint16_t qtype, uint16_t qclass, struct local_rrset* local_alias, uint16_t qtype, uint16_t qclass, struct local_rrset* local_alias,
struct comm_reply* repinfo) struct comm_reply* repinfo)
{ {
char srcip[128], respip[128], txt[512]; char srcip[128], respip[128], txt[512];
unsigned port; unsigned port;
struct respip_addr_info* respip_addr = respip_actinfo->addrinfo;
size_t txtlen = 0;
char* actionstr = NULL;
if(local_alias) if(local_alias)
qname = local_alias->rrset->rk.dname; qname = local_alias->rrset->rk.dname;
@ -1180,7 +1273,25 @@ respip_inform_print(struct respip_addr_info* respip_addr, uint8_t* qname,
addr_to_str(&repinfo->addr, repinfo->addrlen, srcip, sizeof(srcip)); addr_to_str(&repinfo->addr, repinfo->addrlen, srcip, sizeof(srcip));
addr_to_str(&respip_addr->addr, respip_addr->addrlen, addr_to_str(&respip_addr->addr, respip_addr->addrlen,
respip, sizeof(respip)); respip, sizeof(respip));
snprintf(txt, sizeof(txt), "%s/%d inform %s@%u", respip, if(respip_actinfo->rpz_log) {
respip_addr->net, srcip, port); txtlen += snprintf(txt+txtlen, sizeof(txt)-txtlen, "%s",
"RPZ applied ");
if(respip_actinfo->rpz_cname_override)
actionstr = strdup(
rpz_action_to_string(RPZ_CNAME_OVERRIDE_ACTION));
else
actionstr = strdup(rpz_action_to_string(
respip_action_to_rpz_action(
respip_actinfo->action)));
}
if(respip_actinfo->log_name) {
txtlen += snprintf(txt+txtlen, sizeof(txt)-txtlen,
"[%s] ", respip_actinfo->log_name);
}
snprintf(txt+txtlen, sizeof(txt)-txtlen,
"%s/%d %s %s@%u", respip, respip_addr->net,
(actionstr) ? actionstr : "inform", srcip, port);
if(actionstr)
free(actionstr);
log_nametypeclass(0, txt, qname, qtype, qclass); log_nametypeclass(0, txt, qname, qtype, qclass);
} }

View file

@ -14,23 +14,42 @@
#include "util/module.h" #include "util/module.h"
#include "services/localzone.h" #include "services/localzone.h"
#include "util/locks.h"
/** /**
* Set of response IP addresses with associated actions and tags. * Conceptual set of IP addresses for response AAAA or A records that should
* Forward declaration only here. Actual definition is hidden within the * trigger special actions.
* module.
*/ */
struct respip_set; struct respip_set {
struct regional* region;
struct rbtree_type ip_tree;
lock_rw_type lock; /* lock on the respip tree */
char* const* tagname; /* shallow copy of tag names, for logging */
int num_tags; /* number of tagname entries */
};
/** An address span with response control information */
struct resp_addr {
/** node in address tree */
struct addr_tree_node node;
/** lock on the node item */
lock_rw_type lock;
/** tag bitlist */
uint8_t* taglist;
/** length of the taglist (in bytes) */
size_t taglen;
/** action for this address span */
enum respip_action action;
/** "local data" for this node */
struct ub_packed_rrset_key* data;
};
/**
* 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. * Forward declaration for the structure that represents a tree of view data.
*/ */
struct views; struct views;
struct respip_addr_info; struct respip_addr_info;
@ -60,6 +79,11 @@ struct respip_client_info {
*/ */
struct respip_action_info { struct respip_action_info {
enum respip_action action; enum respip_action action;
int rpz_used;
int rpz_log;
int rpz_disabled;
char* log_name;
int rpz_cname_override;
struct respip_addr_info* addrinfo; /* set only for inform variants */ struct respip_addr_info* addrinfo; /* set only for inform variants */
}; };
@ -124,12 +148,14 @@ int respip_views_apply_cfg(struct views* vs, struct config_file* cfg,
* @param new_repp: pointer placeholder for the merged reply. will be intact * @param new_repp: pointer placeholder for the merged reply. will be intact
* on error. * on error.
* @param region: allocator to build *new_repp. * @param region: allocator to build *new_repp.
* @param az: auth zones containing RPZ information.
* @return 1 on success, 0 on error. * @return 1 on success, 0 on error.
*/ */
int respip_merge_cname(struct reply_info* base_rep, int respip_merge_cname(struct reply_info* base_rep,
const struct query_info* qinfo, const struct reply_info* tgt_rep, const struct query_info* qinfo, const struct reply_info* tgt_rep,
const struct respip_client_info* cinfo, int must_validate, const struct respip_client_info* cinfo, int must_validate,
struct reply_info** new_repp, struct regional* region); struct reply_info** new_repp, struct regional* region,
struct auth_zones* az);
/** /**
* See if any IP-based action should apply to any IP address of AAAA/A answer * See if any IP-based action should apply to any IP address of AAAA/A answer
@ -148,6 +174,7 @@ int respip_merge_cname(struct reply_info* base_rep,
* @param alias_rrset: must not be NULL. * @param alias_rrset: must not be NULL.
* @param search_only: if true, only check if an action would apply. actionp * @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. * will be set (or intact) accordingly but the modified reply won't be built.
* @param az: auth zones containing RPZ information.
* @param region: allocator to build *new_repp. * @param region: allocator to build *new_repp.
* @return 1 on success, 0 on error. * @return 1 on success, 0 on error.
*/ */
@ -156,7 +183,7 @@ int respip_rewrite_reply(const struct query_info* qinfo,
const struct reply_info *rep, struct reply_info** new_repp, const struct reply_info *rep, struct reply_info** new_repp,
struct respip_action_info* actinfo, struct respip_action_info* actinfo,
struct ub_packed_rrset_key** alias_rrset, struct ub_packed_rrset_key** alias_rrset,
int search_only, struct regional* region); int search_only, struct regional* region, struct auth_zones* az);
/** /**
* Get the response-ip function block. * Get the response-ip function block.
@ -213,7 +240,7 @@ int respip_set_is_empty(const struct respip_set* set);
/** /**
* print log information for a query subject to an inform or inform-deny * print log information for a query subject to an inform or inform-deny
* response-ip action. * response-ip action.
* @param respip_addr: response-ip information that causes the action * @param respip_actinfo: response-ip information that causes the action
* @param qname: query name in the context, will be ignored if local_alias is * @param qname: query name in the context, will be ignored if local_alias is
* non-NULL. * non-NULL.
* @param qtype: query type, in host byte order. * @param qtype: query type, in host byte order.
@ -223,8 +250,48 @@ int respip_set_is_empty(const struct respip_set* set);
* query name. * query name.
* @param repinfo: reply info containing the client's source address and port. * @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, void respip_inform_print(struct respip_action_info* respip_actinfo,
uint16_t qtype, uint16_t qclass, struct local_rrset* local_alias, uint8_t* qname, uint16_t qtype, uint16_t qclass,
struct comm_reply* repinfo); struct local_rrset* local_alias, struct comm_reply* repinfo);
/**
* Find resp_addr in tree, create and add to tree if it does not exist.
* @param set: struct containing the tree and region to alloc new node on.
* should hold write lock.
* @param addr: address to look up.
* @param addrlen: length of addr.
* @param net: netblock to lookup.
* @param create: create node if it does not exist when 1.
* @param ipstr: human redable ip string, for logging.
* @return newly created of found node, not holding lock.
*/
struct resp_addr*
respip_sockaddr_find_or_create(struct respip_set* set, struct sockaddr_storage* addr,
socklen_t addrlen, int net, int create, const char* ipstr);
/**
* Add RR to resp_addr's RRset. Create RRset is not existing.
* @param region: region to alloc RR(set).
* @param raddr: resp_addr containing RRset. Must hold write lock.
* @param rrtype: RR type.
* @param rrclass: RR class.
* @param ttl: TTL.
* @param rdata: RDATA.
* @param rdata_len: length of rdata.
* @param rrstr: RR as string, for logging
* @param netblockstr: netblock as string, for logging
* @return 0 on error
*/
int
respip_enter_rr(struct regional* region, struct resp_addr* raddr,
uint16_t rrtype, uint16_t rrclass, time_t ttl, uint8_t* rdata,
size_t rdata_len, const char* rrstr, const char* netblockstr);
/**
* Delete resp_addr node from tree.
* @param set: struct containing tree. Must hold write lock.
* @param node: node to delete. Must hold write lock.
*/
void
respip_sockaddr_delete(struct respip_set* set, struct resp_addr* node);
#endif /* RESPIP_RESPIP_H */ #endif /* RESPIP_RESPIP_H */

View file

@ -381,11 +381,25 @@ auth_data_del(rbnode_type* n, void* ATTR_UNUSED(arg))
/** delete an auth zone structure (tree remove must be done elsewhere) */ /** delete an auth zone structure (tree remove must be done elsewhere) */
static void static void
auth_zone_delete(struct auth_zone* z) auth_zone_delete(struct auth_zone* z, struct auth_zones* az)
{ {
if(!z) return; if(!z) return;
lock_rw_destroy(&z->lock); lock_rw_destroy(&z->lock);
traverse_postorder(&z->data, auth_data_del, NULL); traverse_postorder(&z->data, auth_data_del, NULL);
if(az && z->rpz) {
/* keep RPZ linked list intact */
lock_rw_wrlock(&az->rpz_lock);
if(z->rpz->prev)
z->rpz->prev->next = z->rpz->next;
else
az->rpz_first = z->rpz->next;
if(z->rpz->next)
z->rpz->next->prev = z->rpz->prev;
lock_rw_unlock(&az->rpz_lock);
}
if(z->rpz)
rpz_delete(z->rpz);
free(z->name); free(z->name);
free(z->zonefile); free(z->zonefile);
free(z); free(z);
@ -415,7 +429,7 @@ auth_zone_create(struct auth_zones* az, uint8_t* nm, size_t nmlen,
/* z lock protects all, except rbtree itself, which is az->lock */ /* z lock protects all, except rbtree itself, which is az->lock */
if(!rbtree_insert(&az->ztree, &z->node)) { if(!rbtree_insert(&az->ztree, &z->node)) {
lock_rw_unlock(&z->lock); lock_rw_unlock(&z->lock);
auth_zone_delete(z); auth_zone_delete(z, NULL);
log_warn("duplicate auth zone"); log_warn("duplicate auth zone");
return NULL; return NULL;
} }
@ -660,23 +674,6 @@ domain_remove_rrset(struct auth_data* node, uint16_t rr_type)
} }
} }
/** find an rr index in the rrset. returns true if found */
static int
az_rrset_find_rr(struct packed_rrset_data* d, uint8_t* rdata, size_t len,
size_t* index)
{
size_t i;
for(i=0; i<d->count; i++) {
if(d->rr_len[i] != len)
continue;
if(memcmp(d->rr_data[i], rdata, len) == 0) {
*index = i;
return 1;
}
}
return 0;
}
/** find an rrsig index in the rrset. returns true if found */ /** find an rrsig index in the rrset. returns true if found */
static int static int
az_rrset_find_rrsig(struct packed_rrset_data* d, uint8_t* rdata, size_t len, az_rrset_find_rrsig(struct packed_rrset_data* d, uint8_t* rdata, size_t len,
@ -726,58 +723,10 @@ rrsig_rdata_get_type_covered(uint8_t* rdata, size_t rdatalen)
static int static int
rrset_remove_rr(struct auth_rrset* rrset, size_t index) rrset_remove_rr(struct auth_rrset* rrset, size_t index)
{ {
struct packed_rrset_data* d, *old = rrset->data; struct packed_rrset_data* d =
size_t i; packed_rrset_remove_rr(rrset->data, index, NULL);
if(index >= old->count + old->rrsig_count) if(!d)
return 0; /* index out of bounds */
d = (struct packed_rrset_data*)calloc(1, packed_rrset_sizeof(old) - (
sizeof(size_t) + sizeof(uint8_t*) + sizeof(time_t) +
old->rr_len[index]));
if(!d) {
log_err("malloc failure");
return 0; return 0;
}
d->ttl = old->ttl;
d->count = old->count;
d->rrsig_count = old->rrsig_count;
if(index < d->count) d->count--;
else d->rrsig_count--;
d->trust = old->trust;
d->security = old->security;
/* set rr_len, needed for ptr_fixup */
d->rr_len = (size_t*)((uint8_t*)d +
sizeof(struct packed_rrset_data));
if(index > 0)
memmove(d->rr_len, old->rr_len, (index)*sizeof(size_t));
if(index+1 < old->count+old->rrsig_count)
memmove(&d->rr_len[index], &old->rr_len[index+1],
(old->count+old->rrsig_count - (index+1))*sizeof(size_t));
packed_rrset_ptr_fixup(d);
/* move over ttls */
if(index > 0)
memmove(d->rr_ttl, old->rr_ttl, (index)*sizeof(time_t));
if(index+1 < old->count+old->rrsig_count)
memmove(&d->rr_ttl[index], &old->rr_ttl[index+1],
(old->count+old->rrsig_count - (index+1))*sizeof(time_t));
/* move over rr_data */
for(i=0; i<d->count+d->rrsig_count; i++) {
size_t oldi;
if(i < index) oldi = i;
else oldi = i+1;
memmove(d->rr_data[i], old->rr_data[oldi], d->rr_len[i]);
}
/* recalc ttl (lowest of remaining RR ttls) */
if(d->count + d->rrsig_count > 0)
d->ttl = d->rr_ttl[0];
for(i=0; i<d->count+d->rrsig_count; i++) {
if(d->rr_ttl[i] < d->ttl)
d->ttl = d->rr_ttl[i];
}
free(rrset->data); free(rrset->data);
rrset->data = d; rrset->data = d;
return 1; return 1;
@ -1178,6 +1127,10 @@ az_insert_rr(struct auth_zone* z, uint8_t* rr, size_t rr_len,
log_err("cannot add RR to domain"); log_err("cannot add RR to domain");
return 0; return 0;
} }
if(z->rpz) {
rpz_insert_rr(z->rpz, z->namelen, dname, dname_len, rr_type, rr_class, rr_ttl, rdata,
rdatalen, rr, rr_len);
}
return 1; return 1;
} }
@ -1192,7 +1145,7 @@ az_domain_remove_rr(struct auth_data* node, uint16_t rr_type,
/* find the plain RR of the given type */ /* find the plain RR of the given type */
if((rrset=az_domain_rrset(node, rr_type))!= NULL) { if((rrset=az_domain_rrset(node, rr_type))!= NULL) {
if(az_rrset_find_rr(rrset->data, rdata, rdatalen, &index)) { if(packed_rrset_find_rr(rrset->data, rdata, rdatalen, &index)) {
if(rrset->data->count == 1 && if(rrset->data->count == 1 &&
rrset->data->rrsig_count == 0) { rrset->data->rrsig_count == 0) {
/* last RR, delete the rrset */ /* last RR, delete the rrset */
@ -1293,6 +1246,10 @@ az_remove_rr(struct auth_zone* z, uint8_t* rr, size_t rr_len,
(void)rbtree_delete(&z->data, node); (void)rbtree_delete(&z->data, node);
auth_data_delete(node); auth_data_delete(node);
} }
if(z->rpz) {
rpz_remove_rr(z->rpz, z->namelen, dname, dname_len, rr_type,
rr_class, rdata, rdatalen);
}
return 1; return 1;
} }
@ -1585,6 +1542,9 @@ auth_zone_read_zonefile(struct auth_zone* z, struct config_file* cfg)
/* clear the data tree */ /* clear the data tree */
traverse_postorder(&z->data, auth_data_del, NULL); traverse_postorder(&z->data, auth_data_del, NULL);
rbtree_init(&z->data, &auth_data_cmp); rbtree_init(&z->data, &auth_data_cmp);
/* clear the RPZ policies */
if(z->rpz)
rpz_clear(z->rpz);
memset(&state, 0, sizeof(state)); memset(&state, 0, sizeof(state));
/* default TTL to 3600 */ /* default TTL to 3600 */
@ -1604,6 +1564,9 @@ auth_zone_read_zonefile(struct auth_zone* z, struct config_file* cfg)
return 0; return 0;
} }
fclose(in); fclose(in);
if(z->rpz)
rpz_finish_config(z->rpz);
return 1; return 1;
} }
@ -1877,6 +1840,18 @@ auth_zones_cfg(struct auth_zones* az, struct config_auth* c)
z->for_downstream = c->for_downstream; z->for_downstream = c->for_downstream;
z->for_upstream = c->for_upstream; z->for_upstream = c->for_upstream;
z->fallback_enabled = c->fallback_enabled; z->fallback_enabled = c->fallback_enabled;
if(c->isrpz && !z->rpz){
if(!(z->rpz = rpz_create(c))){
fatal_exit("Could not setup RPZ zones");
return 0;
}
lock_rw_wrlock(&az->rpz_lock);
z->rpz->next = az->rpz_first;
if(az->rpz_first)
az->rpz_first->prev = z->rpz;
az->rpz_first = z->rpz;
lock_rw_unlock(&az->rpz_lock);
}
/* xfer zone */ /* xfer zone */
if(x) { if(x) {
@ -1947,14 +1922,14 @@ az_delete_deleted_zones(struct auth_zones* az)
auth_xfer_delete(xfr); auth_xfer_delete(xfr);
} }
(void)rbtree_delete(&az->ztree, &z->node); (void)rbtree_delete(&az->ztree, &z->node);
auth_zone_delete(z); auth_zone_delete(z, az);
z = next; z = next;
} }
lock_rw_unlock(&az->lock); lock_rw_unlock(&az->lock);
} }
int auth_zones_apply_cfg(struct auth_zones* az, struct config_file* cfg, int auth_zones_apply_cfg(struct auth_zones* az, struct config_file* cfg,
int setup) int setup, int* is_rpz)
{ {
struct config_auth* p; struct config_auth* p;
az_setall_deleted(az); az_setall_deleted(az);
@ -1963,6 +1938,7 @@ int auth_zones_apply_cfg(struct auth_zones* az, struct config_file* cfg,
log_warn("auth-zone without a name, skipped"); log_warn("auth-zone without a name, skipped");
continue; continue;
} }
*is_rpz = (*is_rpz || p->isrpz);
if(!auth_zones_cfg(az, p)) { if(!auth_zones_cfg(az, p)) {
log_err("cannot config auth zone %s", p->name); log_err("cannot config auth zone %s", p->name);
return 0; return 0;
@ -2063,7 +2039,7 @@ static void
auth_zone_del(rbnode_type* n, void* ATTR_UNUSED(arg)) auth_zone_del(rbnode_type* n, void* ATTR_UNUSED(arg))
{ {
struct auth_zone* z = (struct auth_zone*)n->key; struct auth_zone* z = (struct auth_zone*)n->key;
auth_zone_delete(z); auth_zone_delete(z, NULL);
} }
/** helper traverse to delete xfer zones */ /** helper traverse to delete xfer zones */
@ -4684,6 +4660,10 @@ apply_axfr(struct auth_xfer* xfr, struct auth_zone* z,
/* clear the data tree */ /* clear the data tree */
traverse_postorder(&z->data, auth_data_del, NULL); traverse_postorder(&z->data, auth_data_del, NULL);
rbtree_init(&z->data, &auth_data_cmp); rbtree_init(&z->data, &auth_data_cmp);
/* clear the RPZ policies */
if(z->rpz)
rpz_clear(z->rpz);
xfr->have_zone = 0; xfr->have_zone = 0;
xfr->serial = 0; xfr->serial = 0;
@ -4780,6 +4760,10 @@ apply_http(struct auth_xfer* xfr, struct auth_zone* z,
/* clear the data tree */ /* clear the data tree */
traverse_postorder(&z->data, auth_data_del, NULL); traverse_postorder(&z->data, auth_data_del, NULL);
rbtree_init(&z->data, &auth_data_cmp); rbtree_init(&z->data, &auth_data_cmp);
/* clear the RPZ policies */
if(z->rpz)
rpz_clear(z->rpz);
xfr->have_zone = 0; xfr->have_zone = 0;
xfr->serial = 0; xfr->serial = 0;
@ -4965,6 +4949,9 @@ xfr_process_chunk_list(struct auth_xfer* xfr, struct module_env* env,
if(xfr->have_zone) if(xfr->have_zone)
xfr->lease_time = *env->now; xfr->lease_time = *env->now;
if(z->rpz)
rpz_finish_config(z->rpz);
/* unlock */ /* unlock */
lock_rw_unlock(&z->lock); lock_rw_unlock(&z->lock);

View file

@ -46,6 +46,7 @@
#include "util/rbtree.h" #include "util/rbtree.h"
#include "util/locks.h" #include "util/locks.h"
#include "services/mesh.h" #include "services/mesh.h"
#include "services/rpz.h"
struct ub_packed_rrset_key; struct ub_packed_rrset_key;
struct regional; struct regional;
struct config_file; struct config_file;
@ -81,6 +82,11 @@ struct auth_zones {
size_t num_query_up; size_t num_query_up;
/** number of queries downstream */ /** number of queries downstream */
size_t num_query_down; size_t num_query_down;
/** first rpz item in linked list */
struct rpz* rpz_first;
/** rw lock for rpz linked list, needed when iterating or editing linked
* list. */
lock_rw_type rpz_lock;
}; };
/** /**
@ -126,6 +132,8 @@ struct auth_zone {
/** for upstream: this zone answers queries that unbound intends to /** for upstream: this zone answers queries that unbound intends to
* send upstream. */ * send upstream. */
int for_upstream; int for_upstream;
/** RPZ zones */
struct rpz* rpz;
/** zone has been deleted */ /** zone has been deleted */
int zone_deleted; int zone_deleted;
/** deletelist pointer, unused normally except during delete */ /** deletelist pointer, unused normally except during delete */
@ -460,10 +468,11 @@ struct auth_zones* auth_zones_create(void);
* @param az: auth zones structure * @param az: auth zones structure
* @param cfg: config to apply. * @param cfg: config to apply.
* @param setup: if true, also sets up values in the auth zones structure * @param setup: if true, also sets up values in the auth zones structure
* @param is_rpz: set to 1 if at least one RPZ zone is configured.
* @return false on failure. * @return false on failure.
*/ */
int auth_zones_apply_cfg(struct auth_zones* az, struct config_file* cfg, int auth_zones_apply_cfg(struct auth_zones* az, struct config_file* cfg,
int setup); int setup, int* is_rpz);
/** initial pick up of worker timeouts, ties events to worker event loop /** initial pick up of worker timeouts, ties events to worker event loop
* @param az: auth zones structure * @param az: auth zones structure

View file

@ -41,7 +41,6 @@
#include "config.h" #include "config.h"
#include "services/localzone.h" #include "services/localzone.h"
#include "sldns/str2wire.h" #include "sldns/str2wire.h"
#include "sldns/sbuffer.h"
#include "util/regional.h" #include "util/regional.h"
#include "util/config_file.h" #include "util/config_file.h"
#include "util/data/dname.h" #include "util/data/dname.h"
@ -395,9 +394,29 @@ rrset_insert_rr(struct regional* region, struct packed_rrset_data* pd,
return 1; return 1;
} }
/** find a data node by exact name */ /** Delete RR from local-zone RRset, wastes memory as the deleted RRs cannot be
static struct local_data* * free'd (regionally alloc'd) */
lz_find_node(struct local_zone* z, uint8_t* nm, size_t nmlen, int nmlabs) int
local_rrset_remove_rr(struct packed_rrset_data* pd, size_t index)
{
if(index >= pd->count) {
log_warn("Trying to remove RR with out of bound index");
return 0;
}
if(index - 1 < pd->count) {
/* not removing last element */
size_t nexti = index + 1;
size_t num = pd->count - nexti;
memcpy(pd->rr_len+index, pd->rr_len+nexti, sizeof(*pd->rr_len)*num);
memcpy(pd->rr_ttl+index, pd->rr_ttl+nexti, sizeof(*pd->rr_ttl)*num);
memcpy(pd->rr_data+index, pd->rr_data+nexti, sizeof(*pd->rr_data)*num);
}
pd->count--;
return 1;
}
struct local_data*
local_zone_find_data(struct local_zone* z, uint8_t* nm, size_t nmlen, int nmlabs)
{ {
struct local_data key; struct local_data key;
key.node.key = &key; key.node.key = &key;
@ -412,7 +431,7 @@ static int
lz_find_create_node(struct local_zone* z, uint8_t* nm, size_t nmlen, lz_find_create_node(struct local_zone* z, uint8_t* nm, size_t nmlen,
int nmlabs, struct local_data** res) int nmlabs, struct local_data** res)
{ {
struct local_data* ld = lz_find_node(z, nm, nmlen, nmlabs); struct local_data* ld = local_zone_find_data(z, nm, nmlen, nmlabs);
if(!ld) { if(!ld) {
/* create a domain name to store rr. */ /* create a domain name to store rr. */
ld = (struct local_data*)regional_alloc_zero(z->region, ld = (struct local_data*)regional_alloc_zero(z->region,
@ -443,42 +462,19 @@ lz_find_create_node(struct local_zone* z, uint8_t* nm, size_t nmlen,
return 1; return 1;
} }
/** enter data RR into auth zone */ int
static int local_zone_enter_rr(struct local_zone* z, uint8_t* nm, size_t nmlen,
lz_enter_rr_into_zone(struct local_zone* z, const char* rrstr) int nmlabs, uint16_t rrtype, uint16_t rrclass, time_t ttl,
uint8_t* rdata, size_t rdata_len, const char* rrstr)
{ {
uint8_t* nm;
size_t nmlen;
int nmlabs;
struct local_data* node; struct local_data* node;
struct local_rrset* rrset; struct local_rrset* rrset;
struct packed_rrset_data* pd; struct packed_rrset_data* pd;
uint16_t rrtype = 0, rrclass = 0;
time_t ttl = 0;
uint8_t rr[LDNS_RR_BUF_SIZE];
uint8_t* rdata;
size_t rdata_len;
if(!rrstr_get_rr_content(rrstr, &nm, &rrtype, &rrclass, &ttl, rr,
sizeof(rr), &rdata, &rdata_len)) {
log_err("bad local-data: %s", rrstr);
return 0;
}
log_assert(z->dclass == rrclass);
if((z->type == local_zone_redirect ||
z->type == local_zone_inform_redirect) &&
query_dname_compare(z->name, nm) != 0) {
log_err("local-data in redirect zone must reside at top of zone"
", not at %s", rrstr);
free(nm);
return 0;
}
nmlabs = dname_count_size_labels(nm, &nmlen);
if(!lz_find_create_node(z, nm, nmlen, nmlabs, &node)) { if(!lz_find_create_node(z, nm, nmlen, nmlabs, &node)) {
free(nm);
return 0; return 0;
} }
log_assert(node); log_assert(node);
free(nm);
/* Reject it if we would end up having CNAME and other data (including /* Reject it if we would end up having CNAME and other data (including
* another CNAME) for a redirect zone. */ * another CNAME) for a redirect zone. */
@ -520,6 +516,39 @@ lz_enter_rr_into_zone(struct local_zone* z, const char* rrstr)
return rrset_insert_rr(z->region, pd, rdata, rdata_len, ttl, rrstr); return rrset_insert_rr(z->region, pd, rdata, rdata_len, ttl, rrstr);
} }
/** enter data RR into auth zone */
int
lz_enter_rr_into_zone(struct local_zone* z, const char* rrstr)
{
uint8_t* nm;
size_t nmlen;
int nmlabs, ret;
uint16_t rrtype = 0, rrclass = 0;
time_t ttl = 0;
uint8_t rr[LDNS_RR_BUF_SIZE];
uint8_t* rdata;
size_t rdata_len;
if(!rrstr_get_rr_content(rrstr, &nm, &rrtype, &rrclass, &ttl, rr,
sizeof(rr), &rdata, &rdata_len)) {
log_err("bad local-data: %s", rrstr);
return 0;
}
log_assert(z->dclass == rrclass);
if((z->type == local_zone_redirect ||
z->type == local_zone_inform_redirect) &&
query_dname_compare(z->name, nm) != 0) {
log_err("local-data in redirect zone must reside at top of zone"
", not at %s", rrstr);
free(nm);
return 0;
}
nmlabs = dname_count_size_labels(nm, &nmlen);
ret = local_zone_enter_rr(z, nm, nmlen, nmlabs, rrtype, rrclass, ttl,
rdata, rdata_len, rrstr);
free(nm);
return ret;
}
/** enter a data RR into auth data; a zone for it must exist */ /** enter a data RR into auth data; a zone for it must exist */
static int static int
lz_enter_rr_str(struct local_zones* zones, const char* rr) lz_enter_rr_str(struct local_zones* zones, const char* rr)
@ -1113,6 +1142,22 @@ local_zones_find(struct local_zones* zones,
return (struct local_zone*)rbtree_search(&zones->ztree, &key); return (struct local_zone*)rbtree_search(&zones->ztree, &key);
} }
struct local_zone*
local_zones_find_le(struct local_zones* zones,
uint8_t* name, size_t len, int labs, uint16_t dclass,
int* exact)
{
struct local_zone key;
rbnode_type *node;
key.node.key = &key;
key.dclass = dclass;
key.name = name;
key.namelen = len;
key.namelabs = labs;
*exact = rbtree_find_less_equal(&zones->ztree, &key, &node);
return (struct local_zone*)node;
}
/** print all RRsets in local zone */ /** print all RRsets in local zone */
static void static void
local_zone_out(struct local_zone* z) local_zone_out(struct local_zone* z)
@ -1310,7 +1355,7 @@ find_tag_datas(struct query_info* qinfo, struct config_strlist* list,
} }
/** answer local data match */ /** answer local data match */
static int int
local_data_answer(struct local_zone* z, struct module_env* env, local_data_answer(struct local_zone* z, struct module_env* env,
struct query_info* qinfo, struct edns_data* edns, struct query_info* qinfo, struct edns_data* edns,
struct comm_reply* repinfo, sldns_buffer* buf, struct comm_reply* repinfo, sldns_buffer* buf,
@ -1370,6 +1415,7 @@ local_data_answer(struct local_zone* z, struct module_env* env,
regional_alloc_init(temp, lr->rrset, sizeof(*lr->rrset)); regional_alloc_init(temp, lr->rrset, sizeof(*lr->rrset));
if(!qinfo->local_alias->rrset) if(!qinfo->local_alias->rrset)
return 0; /* out of memory */ return 0; /* out of memory */
/* TODO local_alias->rrset change cnam etarget */
qinfo->local_alias->rrset->rk.dname = qinfo->qname; qinfo->local_alias->rrset->rk.dname = qinfo->qname;
qinfo->local_alias->rrset->rk.dname_len = qinfo->qname_len; qinfo->local_alias->rrset->rk.dname_len = qinfo->qname_len;
return 1; return 1;
@ -1416,26 +1462,15 @@ local_zone_does_not_cover(struct local_zone* z, struct query_info* qinfo,
return (lr == NULL); return (lr == NULL);
} }
/** int
* Answer in case where no exact match is found. local_zones_zone_answer(struct local_zone* z, struct module_env* env,
* @param z: zone for query.
* @param env: module environment.
* @param qinfo: query.
* @param edns: edns from query.
* @param repinfo: source address for checks. may be NULL.
* @param buf: buffer for answer.
* @param temp: temp region for encoding.
* @param ld: local data, if NULL, no such name exists in localdata.
* @param lz_type: type of the local zone.
* @return 1 if a reply is to be sent, 0 if not.
*/
static int
lz_zone_answer(struct local_zone* z, struct module_env* env,
struct query_info* qinfo, struct edns_data* edns, struct query_info* qinfo, struct edns_data* edns,
struct comm_reply* repinfo, sldns_buffer* buf, struct regional* temp, struct comm_reply* repinfo, sldns_buffer* buf, struct regional* temp,
struct local_data* ld, enum localzone_type lz_type) struct local_data* ld, enum localzone_type lz_type)
{ {
if(lz_type == local_zone_deny || lz_type == local_zone_inform_deny) { if(lz_type == local_zone_deny ||
lz_type == local_zone_always_deny ||
lz_type == local_zone_inform_deny) {
/** no reply at all, signal caller by clearing buffer. */ /** no reply at all, signal caller by clearing buffer. */
sldns_buffer_clear(buf); sldns_buffer_clear(buf);
sldns_buffer_flip(buf); sldns_buffer_flip(buf);
@ -1448,7 +1483,8 @@ lz_zone_answer(struct local_zone* z, struct module_env* env,
} else if(lz_type == local_zone_static || } else if(lz_type == local_zone_static ||
lz_type == local_zone_redirect || lz_type == local_zone_redirect ||
lz_type == local_zone_inform_redirect || lz_type == local_zone_inform_redirect ||
lz_type == local_zone_always_nxdomain) { lz_type == local_zone_always_nxdomain ||
lz_type == local_zone_always_nodata) {
/* for static, reply nodata or nxdomain /* for static, reply nodata or nxdomain
* for redirect, reply nodata */ * for redirect, reply nodata */
/* no additional section processing, /* no additional section processing,
@ -1457,7 +1493,8 @@ lz_zone_answer(struct local_zone* z, struct module_env* env,
* or using closest match for returning delegation downwards * or using closest match for returning delegation downwards
*/ */
int rcode = (ld || lz_type == local_zone_redirect || int rcode = (ld || lz_type == local_zone_redirect ||
lz_type == local_zone_inform_redirect)? lz_type == local_zone_inform_redirect ||
lz_type == local_zone_always_nodata)?
LDNS_RCODE_NOERROR:LDNS_RCODE_NXDOMAIN; LDNS_RCODE_NOERROR:LDNS_RCODE_NXDOMAIN;
if(z->soa) if(z->soa)
return local_encode(qinfo, env, edns, repinfo, buf, temp, return local_encode(qinfo, env, edns, repinfo, buf, temp,
@ -1640,6 +1677,8 @@ local_zones_answer(struct local_zones* zones, struct module_env* env,
if(lzt != local_zone_always_refuse if(lzt != local_zone_always_refuse
&& lzt != local_zone_always_transparent && lzt != local_zone_always_transparent
&& lzt != local_zone_always_nxdomain && lzt != local_zone_always_nxdomain
&& lzt != local_zone_always_nodata
&& lzt != local_zone_always_deny
&& local_data_answer(z, env, qinfo, edns, repinfo, buf, temp, labs, && local_data_answer(z, env, qinfo, edns, repinfo, buf, temp, labs,
&ld, lzt, tag, tag_datas, tag_datas_size, tagname, num_tags)) { &ld, lzt, tag, tag_datas, tag_datas_size, tagname, num_tags)) {
lock_rw_unlock(&z->lock); lock_rw_unlock(&z->lock);
@ -1647,7 +1686,7 @@ local_zones_answer(struct local_zones* zones, struct module_env* env,
* a local alias. */ * a local alias. */
return !qinfo->local_alias; return !qinfo->local_alias;
} }
r = lz_zone_answer(z, env, qinfo, edns, repinfo, buf, temp, ld, lzt); r = local_zones_zone_answer(z, env, qinfo, edns, repinfo, buf, temp, ld, lzt);
lock_rw_unlock(&z->lock); lock_rw_unlock(&z->lock);
return r && !qinfo->local_alias; /* see above */ return r && !qinfo->local_alias; /* see above */
} }
@ -1669,7 +1708,10 @@ const char* local_zone_type2str(enum localzone_type t)
case local_zone_always_transparent: return "always_transparent"; case local_zone_always_transparent: return "always_transparent";
case local_zone_always_refuse: return "always_refuse"; case local_zone_always_refuse: return "always_refuse";
case local_zone_always_nxdomain: return "always_nxdomain"; case local_zone_always_nxdomain: return "always_nxdomain";
case local_zone_always_nodata: return "always_nodata";
case local_zone_always_deny: return "always_deny";
case local_zone_noview: return "noview"; case local_zone_noview: return "noview";
case local_zone_invalid: return "invalid";
} }
return "badtyped"; return "badtyped";
} }
@ -1700,6 +1742,10 @@ int local_zone_str2type(const char* type, enum localzone_type* t)
*t = local_zone_always_refuse; *t = local_zone_always_refuse;
else if(strcmp(type, "always_nxdomain") == 0) else if(strcmp(type, "always_nxdomain") == 0)
*t = local_zone_always_nxdomain; *t = local_zone_always_nxdomain;
else if(strcmp(type, "always_nodata") == 0)
*t = local_zone_always_nodata;
else if(strcmp(type, "always_deny") == 0)
*t = local_zone_always_deny;
else if(strcmp(type, "noview") == 0) else if(strcmp(type, "noview") == 0)
*t = local_zone_noview; *t = local_zone_noview;
else if(strcmp(type, "nodefault") == 0) else if(strcmp(type, "nodefault") == 0)
@ -1843,7 +1889,7 @@ del_empty_term(struct local_zone* z, struct local_data* d,
return; return;
dname_remove_label(&name, &len); dname_remove_label(&name, &len);
labs--; labs--;
d = lz_find_node(z, name, len, labs); d = local_zone_find_data(z, name, len, labs);
} }
} }
@ -1876,7 +1922,7 @@ void local_zones_del_data(struct local_zones* zones,
z = local_zones_lookup(zones, name, len, labs, dclass, LDNS_RR_TYPE_DS); z = local_zones_lookup(zones, name, len, labs, dclass, LDNS_RR_TYPE_DS);
if(z) { if(z) {
lock_rw_wrlock(&z->lock); lock_rw_wrlock(&z->lock);
d = lz_find_node(z, name, len, labs); d = local_zone_find_data(z, name, len, labs);
if(d) { if(d) {
del_local_rrset(d, LDNS_RR_TYPE_DS); del_local_rrset(d, LDNS_RR_TYPE_DS);
del_empty_term(z, d, name, len, labs); del_empty_term(z, d, name, len, labs);
@ -1897,7 +1943,7 @@ void local_zones_del_data(struct local_zones* zones,
lock_rw_unlock(&zones->lock); lock_rw_unlock(&zones->lock);
/* find the domain */ /* find the domain */
d = lz_find_node(z, name, len, labs); d = local_zone_find_data(z, name, len, labs);
if(d) { if(d) {
/* no memory recycling for zone deletions ... */ /* no memory recycling for zone deletions ... */
d->rrsets = NULL; d->rrsets = NULL;

View file

@ -46,6 +46,7 @@
#include "util/storage/dnstree.h" #include "util/storage/dnstree.h"
#include "util/module.h" #include "util/module.h"
#include "services/view.h" #include "services/view.h"
#include "sldns/sbuffer.h"
struct packed_rrset_data; struct packed_rrset_data;
struct ub_packed_rrset_key; struct ub_packed_rrset_key;
struct regional; struct regional;
@ -91,8 +92,14 @@ enum localzone_type {
local_zone_always_refuse, local_zone_always_refuse,
/** answer with nxdomain, even when there is local data */ /** answer with nxdomain, even when there is local data */
local_zone_always_nxdomain, local_zone_always_nxdomain,
/** answer with noerror/nodata, even when there is local data */
local_zone_always_nodata,
/** drop query, even when there is local data */
local_zone_always_deny,
/** answer not from the view, but global or no-answer */ /** answer not from the view, but global or no-answer */
local_zone_noview local_zone_noview,
/** Invalid type, cannot be used to generate answer */
local_zone_invalid
}; };
/** /**
@ -310,6 +317,25 @@ int local_zones_answer(struct local_zones* zones, struct module_env* env,
struct config_strlist** tag_datas, size_t tag_datas_size, struct config_strlist** tag_datas, size_t tag_datas_size,
char** tagname, int num_tags, struct view* view); char** tagname, int num_tags, struct view* view);
/**
* Answer using the local zone only (not local data used).
* @param z: zone for query.
* @param env: module environment.
* @param qinfo: query.
* @param edns: edns from query.
* @param repinfo: source address for checks. may be NULL.
* @param buf: buffer for answer.
* @param temp: temp region for encoding.
* @param ld: local data, if NULL, no such name exists in localdata.
* @param lz_type: type of the local zone.
* @return 1 if a reply is to be sent, 0 if not.
*/
int
local_zones_zone_answer(struct local_zone* z, struct module_env* env,
struct query_info* qinfo, struct edns_data* edns,
struct comm_reply* repinfo, sldns_buffer* buf, struct regional* temp,
struct local_data* ld, enum localzone_type lz_type);
/** /**
* Parse the string into localzone type. * Parse the string into localzone type.
* *
@ -340,6 +366,22 @@ const char* local_zone_type2str(enum localzone_type t);
struct local_zone* local_zones_find(struct local_zones* zones, struct local_zone* local_zones_find(struct local_zones* zones,
uint8_t* name, size_t len, int labs, uint16_t dclass); uint8_t* name, size_t len, int labs, uint16_t dclass);
/**
* Find zone that with exactly or smaller name/class
* User must lock the tree or result zone.
* @param zones: the zones tree
* @param name: dname to lookup
* @param len: length of name.
* @param labs: labelcount of name.
* @param dclass: class to lookup.
* @param exact: 1 on return is this is an exact match.
* @return the exact or smaller local_zone or NULL.
*/
struct local_zone*
local_zones_find_le(struct local_zones* zones,
uint8_t* name, size_t len, int labs, uint16_t dclass,
int* exact);
/** /**
* Add a new zone. Caller must hold the zones lock. * Add a new zone. Caller must hold the zones lock.
* Adjusts the other zones as well (parent pointers) after insertion. * Adjusts the other zones as well (parent pointers) after insertion.
@ -473,6 +515,15 @@ int rrstr_get_rr_content(const char* str, uint8_t** nm, uint16_t* type,
int rrset_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); uint8_t* rdata, size_t rdata_len, time_t ttl, const char* rrstr);
/**
* Remove RR from rrset that is created using localzone's rrset_insert_rr.
* @param pd: the RRset containing the RR to remove
* @param index: index of RR to remove
* @return: 1 on success; 0 otherwise.
*/
int
local_rrset_remove_rr(struct packed_rrset_data* pd, size_t index);
/** /**
* Valid response ip actions for the IP-response-driven-action feature; * Valid response ip actions for the IP-response-driven-action feature;
* defined here instead of in the respip module to enable sharing of enum * defined here instead of in the respip module to enable sharing of enum
@ -501,6 +552,10 @@ enum respip_action {
respip_always_refuse = local_zone_always_refuse, respip_always_refuse = local_zone_always_refuse,
/** answer with 'no such domain' response */ /** answer with 'no such domain' response */
respip_always_nxdomain = local_zone_always_nxdomain, respip_always_nxdomain = local_zone_always_nxdomain,
/** answer with nodata response */
respip_always_nodata = local_zone_always_nodata,
/** answer with nodata response */
respip_always_deny = local_zone_always_deny,
/* The rest of the values are only possible as /* The rest of the values are only possible as
* access-control-tag-action */ * access-control-tag-action */
@ -513,6 +568,31 @@ enum respip_action {
respip_transparent = local_zone_transparent, respip_transparent = local_zone_transparent,
/** gives response data (if any), else nodata answer. */ /** gives response data (if any), else nodata answer. */
respip_typetransparent = local_zone_typetransparent, respip_typetransparent = local_zone_typetransparent,
/** type invalid */
respip_invalid = local_zone_invalid,
}; };
int
local_data_answer(struct local_zone* z, struct module_env* env,
struct query_info* qinfo, struct edns_data* edns,
struct comm_reply* repinfo, sldns_buffer* buf,
struct regional* temp, int labs, struct local_data** ldp,
enum localzone_type lz_type, int tag, struct config_strlist** tag_datas,
size_t tag_datas_size, char** tagname, int num_tags);
int
local_zone_enter_rr(struct local_zone* z, uint8_t* nm, size_t nmlen,
int nmlabs, uint16_t rrtype, uint16_t rrclass, time_t ttl,
uint8_t* rdata, size_t rdata_len, const char* rrstr);
/**
* Find a data node by exact name for a local zone
* @param z: local_zone containing data tree
* @param nm: name of local-data element to find
* @param nmlen: length of nm
* @param nmlabs: labs of nm
* @return local_data on exact match, NULL otherwise.
*/
struct local_data*
local_zone_find_data(struct local_zone* z, uint8_t* nm, size_t nmlen, int nmlabs);
#endif /* SERVICES_LOCALZONE_H */ #endif /* SERVICES_LOCALZONE_H */

View file

@ -1184,10 +1184,21 @@ void mesh_query_done(struct mesh_state* mstate)
* information should be logged for each client. */ * information should be logged for each client. */
if(mstate->s.respip_action_info && if(mstate->s.respip_action_info &&
mstate->s.respip_action_info->addrinfo) { mstate->s.respip_action_info->addrinfo) {
respip_inform_print(mstate->s.respip_action_info->addrinfo, respip_inform_print(mstate->s.respip_action_info,
r->qname, mstate->s.qinfo.qtype, r->qname, mstate->s.qinfo.qtype,
mstate->s.qinfo.qclass, r->local_alias, mstate->s.qinfo.qclass, r->local_alias,
&r->query_reply); &r->query_reply);
if(mstate->s.env->cfg->stat_extended &&
mstate->s.respip_action_info->rpz_used) {
if(mstate->s.respip_action_info->rpz_disabled)
mstate->s.env->mesh->rpz_action[RPZ_DISABLED_ACTION] +=
mstate->s.respip_action_info->rpz_disabled;
if(mstate->s.respip_action_info->rpz_cname_override)
mstate->s.env->mesh->rpz_action[RPZ_CNAME_OVERRIDE_ACTION]++;
else
mstate->s.env->mesh->rpz_action[respip_action_to_rpz_action(
mstate->s.respip_action_info->action)]++;
}
} }
/* if this query is determined to be dropped during the /* if this query is determined to be dropped during the
@ -1582,6 +1593,7 @@ mesh_stats_clear(struct mesh_area* mesh)
mesh->ans_secure = 0; mesh->ans_secure = 0;
mesh->ans_bogus = 0; mesh->ans_bogus = 0;
memset(&mesh->ans_rcode[0], 0, sizeof(size_t)*16); memset(&mesh->ans_rcode[0], 0, sizeof(size_t)*16);
memset(&mesh->rpz_action[0], 0, sizeof(size_t)*10);
mesh->ans_nodata = 0; mesh->ans_nodata = 0;
} }

View file

@ -51,6 +51,7 @@
#include "util/data/msgparse.h" #include "util/data/msgparse.h"
#include "util/module.h" #include "util/module.h"
#include "services/modstack.h" #include "services/modstack.h"
#include "services/rpz.h"
struct sldns_buffer; struct sldns_buffer;
struct mesh_state; struct mesh_state;
struct mesh_reply; struct mesh_reply;
@ -124,6 +125,8 @@ struct mesh_area {
size_t ans_rcode[16]; size_t ans_rcode[16];
/** (extended stats) rcode nodata in replies */ /** (extended stats) rcode nodata in replies */
size_t ans_nodata; size_t ans_nodata;
/** (extended stats) type of applied RPZ action */
size_t rpz_action[10];
/** backup of query if other operations recurse and need the /** backup of query if other operations recurse and need the
* network buffers */ * network buffers */

945
services/rpz.c Normal file
View file

@ -0,0 +1,945 @@
/*
* services/rpz.c - rpz service
*
* Copyright (c) 2019, 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 to enable RPZ service.
*/
#include "config.h"
#include "services/rpz.h"
#include "util/config_file.h"
#include "sldns/wire2str.h"
#include "sldns/str2wire.h"
#include "util/data/dname.h"
#include "util/net_help.h"
#include "util/log.h"
#include "util/data/dname.h"
#include "util/locks.h"
#include "util/regional.h"
const char*
rpz_action_to_string(enum rpz_action a)
{
switch(a) {
case RPZ_NXDOMAIN_ACTION: return "nxdomain";
case RPZ_NODATA_ACTION: return "nodata";
case RPZ_PASSTHRU_ACTION: return "passthru";
case RPZ_DROP_ACTION: return "drop";
case RPZ_TCP_ONLY_ACTION: return "tcp_only";
case RPZ_INVALID_ACTION: return "invalid";
case RPZ_LOCAL_DATA_ACTION: return "local_data";
case RPZ_DISABLED_ACTION: return "disabled";
case RPZ_CNAME_OVERRIDE_ACTION: return "cname_override";
case RPZ_NO_OVERRIDE_ACTION: return "no_override";
}
return "unknown";
}
static enum rpz_action
rpz_config_to_action(char* a)
{
if(strcmp(a, "nxdomain") == 0)
return RPZ_NXDOMAIN_ACTION;
else if(strcmp(a, "nodata") == 0)
return RPZ_NODATA_ACTION;
else if(strcmp(a, "passthru") == 0)
return RPZ_PASSTHRU_ACTION;
else if(strcmp(a, "drop") == 0)
return RPZ_DROP_ACTION;
else if(strcmp(a, "tcp_only") == 0)
return RPZ_TCP_ONLY_ACTION;
else if(strcmp(a, "cname") == 0)
return RPZ_CNAME_OVERRIDE_ACTION;
else if(strcmp(a, "disabled") == 0)
return RPZ_DISABLED_ACTION;
return RPZ_INVALID_ACTION;
}
/** string for RPZ trigger enum */
static const char*
rpz_trigger_to_string(enum rpz_trigger r)
{
switch(r) {
case RPZ_QNAME_TRIGGER: return "qname";
case RPZ_CLIENT_IP_TRIGGER: return "client_ip";
case RPZ_RESPONSE_IP_TRIGGER: return "response_ip";
case RPZ_NSDNAME_TRIGGER: return "nsdname";
case RPZ_NSIP_TRIGGER: return "nsip";
}
return "unknown";
}
/**
* Get the label that is just before the root label.
* @param dname: dname to work on
* @return: pointer to TLD label
*/
static uint8_t*
get_tld_label(uint8_t* dname)
{
uint8_t* prevlab = dname;
/* only root label */
if(*dname == 0)
return NULL;
while(*dname) {
dname = dname+*dname+1;
if(*dname != 0)
prevlab = dname;
}
return prevlab;
}
/**
* Classify RPZ action for RR type/rdata
* @param rr_type: the RR type
* @param rdatawl: RDATA with 2 bytes length
* @param rdatalen: the length of rdatawl (including its 2 bytes length)
* @return: the RPZ action
*/
static enum rpz_action
rpz_rr_to_action(uint16_t rr_type, uint8_t* rdatawl, size_t rdatalen)
{
char* endptr;
uint8_t* rdata;
int rdatalabs;
uint8_t* tldlab = NULL;
switch(rr_type) {
case LDNS_RR_TYPE_SOA:
case LDNS_RR_TYPE_NS:
case LDNS_RR_TYPE_DNAME:
/* all DNSSEC-related RRs must be ignored */
case LDNS_RR_TYPE_DNSKEY:
case LDNS_RR_TYPE_DS:
case LDNS_RR_TYPE_RRSIG:
case LDNS_RR_TYPE_NSEC:
case LDNS_RR_TYPE_NSEC3:
return RPZ_INVALID_ACTION;
case LDNS_RR_TYPE_CNAME:
break;
default:
return RPZ_LOCAL_DATA_ACTION;
}
/* use CNAME target to determine RPZ action */
log_assert(rr_type == LDNS_RR_TYPE_CNAME);
if(rdatalen < 3)
return RPZ_INVALID_ACTION;
rdata = rdatawl + 2; /* 2 bytes of rdata length */
if(dname_valid(rdata, rdatalen-2) != rdatalen-2)
return RPZ_INVALID_ACTION;
rdatalabs = dname_count_labels(rdata);
if(rdatalabs == 1)
return RPZ_NXDOMAIN_ACTION;
else if(rdatalabs == 2) {
if(dname_subdomain_c(rdata, (uint8_t*)&"\001*\000"))
return RPZ_NODATA_ACTION;
else if(dname_subdomain_c(rdata,
(uint8_t*)&"\014rpz-passthru\000"))
return RPZ_PASSTHRU_ACTION;
else if(dname_subdomain_c(rdata, (uint8_t*)&"\010rpz-drop\000"))
return RPZ_DROP_ACTION;
else if(dname_subdomain_c(rdata,
(uint8_t*)&"\014rpz-tcp-only\000"))
return RPZ_TCP_ONLY_ACTION;
}
/* all other TLDs starting with "rpz-" are invalid */
tldlab = get_tld_label(rdata);
if(tldlab && dname_lab_startswith(tldlab, "rpz-", &endptr))
return RPZ_INVALID_ACTION;
/* no special label found */
return RPZ_LOCAL_DATA_ACTION;
}
static enum localzone_type
rpz_action_to_localzone_type(enum rpz_action a)
{
switch(a) {
case RPZ_NXDOMAIN_ACTION: return local_zone_always_nxdomain;
case RPZ_NODATA_ACTION: return local_zone_always_nodata;
case RPZ_DROP_ACTION: return local_zone_always_deny;
case RPZ_PASSTHRU_ACTION: return local_zone_always_transparent;
case RPZ_LOCAL_DATA_ACTION:
case RPZ_CNAME_OVERRIDE_ACTION:
return local_zone_redirect;
case RPZ_INVALID_ACTION:
case RPZ_TCP_ONLY_ACTION:
default:
return local_zone_invalid;
}
}
enum respip_action
rpz_action_to_respip_action(enum rpz_action a)
{
switch(a) {
case RPZ_NXDOMAIN_ACTION: return respip_always_nxdomain;
case RPZ_NODATA_ACTION: return respip_always_nodata;
case RPZ_DROP_ACTION: return respip_always_deny;
case RPZ_PASSTHRU_ACTION: return respip_always_transparent;
case RPZ_LOCAL_DATA_ACTION:
case RPZ_CNAME_OVERRIDE_ACTION:
return respip_redirect;
case RPZ_INVALID_ACTION:
case RPZ_TCP_ONLY_ACTION:
default:
return respip_invalid;
}
}
static enum rpz_action
localzone_type_to_rpz_action(enum localzone_type lzt)
{
switch(lzt) {
case local_zone_always_nxdomain: return RPZ_NXDOMAIN_ACTION;
case local_zone_always_nodata: return RPZ_NODATA_ACTION;
case local_zone_always_deny: return RPZ_DROP_ACTION;
case local_zone_always_transparent: return RPZ_PASSTHRU_ACTION;
case local_zone_redirect: return RPZ_LOCAL_DATA_ACTION;
case local_zone_invalid:
default:
return RPZ_INVALID_ACTION;
}
}
enum rpz_action
respip_action_to_rpz_action(enum respip_action a)
{
switch(a) {
case respip_always_nxdomain: return RPZ_NXDOMAIN_ACTION;
case respip_always_nodata: return RPZ_NODATA_ACTION;
case respip_always_deny: return RPZ_DROP_ACTION;
case respip_always_transparent: return RPZ_PASSTHRU_ACTION;
case respip_redirect: return RPZ_LOCAL_DATA_ACTION;
case respip_invalid:
default:
return RPZ_INVALID_ACTION;
}
}
/**
* Get RPZ trigger for dname
* @param dname: dname containing RPZ trigger
* @return: RPZ trigger enum
*/
static enum rpz_trigger
rpz_dname_to_trigger(uint8_t* dname)
{
uint8_t* tldlab;
char* endptr;
tldlab = get_tld_label(dname);
if(!tldlab || !dname_lab_startswith(tldlab, "rpz-", &endptr))
return RPZ_QNAME_TRIGGER;
if(dname_subdomain_c(tldlab,
(uint8_t*)&"\015rpz-client-ip\000"))
return RPZ_CLIENT_IP_TRIGGER;
else if(dname_subdomain_c(tldlab, (uint8_t*)&"\006rpz-ip\000"))
return RPZ_RESPONSE_IP_TRIGGER;
else if(dname_subdomain_c(tldlab, (uint8_t*)&"\013rpz-nsdname\000"))
return RPZ_NSDNAME_TRIGGER;
else if(dname_subdomain_c(tldlab, (uint8_t*)&"\010rpz-nsip\000"))
return RPZ_NSIP_TRIGGER;
return RPZ_QNAME_TRIGGER;
}
void rpz_delete(struct rpz* r)
{
if(!r)
return;
local_zones_delete(r->local_zones);
respip_set_delete(r->respip_set);
regional_destroy(r->region);
free(r->taglist);
free(r->log_name);
free(r);
}
int
rpz_clear(struct rpz* r)
{
/* must hold write lock on auth_zone */
local_zones_delete(r->local_zones);
respip_set_delete(r->respip_set);
if(!(r->local_zones = local_zones_create())){
return 0;
}
if(!(r->respip_set = respip_set_create())) {
return 0;
}
return 1;
}
void
rpz_finish_config(struct rpz* r)
{
lock_rw_wrlock(&r->respip_set->lock);
addr_tree_init_parents(&r->respip_set->ip_tree);
lock_rw_unlock(&r->respip_set->lock);
}
/** new rrset containing CNAME override, does not yet contain a dname */
static struct ub_packed_rrset_key*
new_cname_override(struct regional* region, uint8_t* ct, size_t ctlen)
{
struct ub_packed_rrset_key* rrset;
struct packed_rrset_data* pd;
uint16_t rdlength = htons(ctlen);
rrset = (struct ub_packed_rrset_key*)regional_alloc_zero(region,
sizeof(*rrset));
if(!rrset) {
log_err("out of memory");
return NULL;
}
rrset->entry.key = rrset;
pd = (struct packed_rrset_data*)regional_alloc_zero(region, sizeof(*pd));
if(!pd) {
log_err("out of memory");
return NULL;
}
pd->trust = rrset_trust_prim_noglue;
pd->security = sec_status_insecure;
pd->count = 1;
pd->rr_len = regional_alloc_zero(region, sizeof(*pd->rr_len));
pd->rr_ttl = regional_alloc_zero(region, sizeof(*pd->rr_ttl));
pd->rr_data = regional_alloc_zero(region, sizeof(*pd->rr_data));
if(!pd->rr_len || !pd->rr_ttl || !pd->rr_data) {
log_err("out of memory");
return NULL;
}
pd->rr_len[0] = ctlen+2;
pd->rr_ttl[0] = 3600; /* TODO, what should this be? */
pd->rr_data[0] = regional_alloc_zero(region, 2 /* rdlength */ + ctlen);
if(!pd->rr_data[0]) {
log_err("out of memory");
return NULL;
}
memcpy(pd->rr_data[0], &rdlength, 2);
memcpy(pd->rr_data[0]+2, ct, ctlen);
rrset->entry.data = pd;
rrset->rk.type = htons(LDNS_RR_TYPE_CNAME);
rrset->rk.rrset_class = htons(LDNS_RR_CLASS_IN);
return rrset;
}
struct rpz*
rpz_create(struct config_auth* p)
{
struct rpz* r = calloc(1, sizeof(*r));
if(!r)
goto err;
r->region = regional_create_custom(sizeof(struct regional));
if(!r->region) {
goto err;
}
if(!(r->local_zones = local_zones_create())){
goto err;
}
if(!(r->respip_set = respip_set_create())) {
goto err;
}
r->taglistlen = p->rpz_taglistlen;
r->taglist = memdup(p->rpz_taglist, r->taglistlen);
if(p->rpz_action_override) {
r->action_override = rpz_config_to_action(p->rpz_action_override);
}
else
r->action_override = RPZ_NO_OVERRIDE_ACTION;
if(r->action_override == RPZ_CNAME_OVERRIDE_ACTION) {
uint8_t nm[LDNS_MAX_DOMAINLEN+1];
size_t nmlen = sizeof(nm);
if(!p->rpz_cname) {
log_err("RPZ override with cname action found, but not "
"rpz-cname-override configured");
goto err;
}
if(sldns_str2wire_dname_buf(p->rpz_cname, nm, &nmlen) != 0) {
log_err("cannot parse RPZ cname override: %s",
p->rpz_cname);
goto err;
}
r->cname_override = new_cname_override(r->region, nm, nmlen);
if(!r->cname_override) {
goto err;
}
}
r->log = p->rpz_log;
if(p->rpz_log_name)
r->log_name = strdup(p->rpz_log_name);
return r;
err:
if(r) {
if(r->local_zones)
local_zones_delete(r->local_zones);
if(r->respip_set)
respip_set_delete(r->respip_set);
if(r->taglist)
free(r->taglist);
free(r);
}
return NULL;
}
/** Remove RPZ zone name from dname */
static size_t
strip_dname_origin(uint8_t* dname, size_t dnamelen, size_t originlen,
uint8_t* newdname)
{
size_t newdnamelen;
if(dnamelen < originlen)
return 0;
newdnamelen = dnamelen - originlen;
memmove(newdname, dname, newdnamelen);
return newdnamelen + 1; /* + 1 for root label */
}
/** Insert RR into RPZ's local-zone */
static void
rpz_insert_qname_trigger(struct rpz* r, uint8_t* dname, size_t dnamelen,
enum rpz_action a, uint16_t rrtype, uint16_t rrclass, uint32_t ttl,
uint8_t* rdata, size_t rdata_len, uint8_t* rr, size_t rr_len)
{
struct local_zone* z;
enum localzone_type tp = local_zone_always_transparent;
int dnamelabs = dname_count_labels(dname);
char* rrstr;
int newzone = 0;
if(a == RPZ_TCP_ONLY_ACTION || a == RPZ_INVALID_ACTION) {
verbose(VERB_ALGO, "RPZ: skipping unsupported action: %s",
rpz_action_to_string(a));
free(dname);
return;
}
lock_rw_wrlock(&r->local_zones->lock);
/* exact match */
z = local_zones_find(r->local_zones, dname, dnamelen, dnamelabs,
LDNS_RR_CLASS_IN);
if(z && a != RPZ_LOCAL_DATA_ACTION) {
rrstr = sldns_wire2str_rr(rr, rr_len);
verbose(VERB_ALGO, "RPZ: skipping duplicate record: '%s'",
rrstr);
free(rrstr);
free(dname);
lock_rw_unlock(&r->local_zones->lock);
return;
}
if(!z) {
tp = rpz_action_to_localzone_type(a);
if(!(z = local_zones_add_zone(r->local_zones, dname, dnamelen,
dnamelabs, rrclass, tp))) {
log_warn("RPZ create failed");
lock_rw_unlock(&r->local_zones->lock);
/* dname will be free'd in failed local_zone_create() */
return;
}
newzone = 1;
}
if(a == RPZ_LOCAL_DATA_ACTION) {
rrstr = sldns_wire2str_rr(rr, rr_len);
local_zone_enter_rr(z, dname, dnamelen, dnamelabs,
rrtype, rrclass, ttl, rdata, rdata_len, rrstr);
free(rrstr);
}
if(!newzone)
free(dname);
lock_rw_unlock(&r->local_zones->lock);
return;
}
/** Insert RR into RPZ's respip_set */
static int
rpz_insert_response_ip_trigger(struct rpz* r, uint8_t* dname,
enum rpz_action a, uint16_t rrtype, uint16_t rrclass, uint32_t ttl,
uint8_t* rdata, size_t rdata_len, uint8_t* rr, size_t rr_len)
{
struct resp_addr* node;
struct sockaddr_storage addr;
socklen_t addrlen;
int net, af;
char* rrstr;
enum respip_action respa = rpz_action_to_respip_action(a);
if(a == RPZ_TCP_ONLY_ACTION || a == RPZ_INVALID_ACTION ||
respa == respip_invalid) {
verbose(VERB_ALGO, "RPZ: skipping unsupported action: %s",
rpz_action_to_string(a));
return 0;
}
if(!netblockdnametoaddr(dname, &addr, &addrlen, &net, &af))
return 0;
lock_rw_wrlock(&r->respip_set->lock);
rrstr = sldns_wire2str_rr(rr, rr_len);
if(!(node=respip_sockaddr_find_or_create(r->respip_set, &addr, addrlen,
net, 1, rrstr))) {
lock_rw_unlock(&r->respip_set->lock);
free(rrstr);
return 0;
}
lock_rw_wrlock(&node->lock);
lock_rw_unlock(&r->respip_set->lock);
node->action = respa;
if(a == RPZ_LOCAL_DATA_ACTION) {
respip_enter_rr(r->respip_set->region, node, rrtype,
rrclass, ttl, rdata, rdata_len, rrstr, "");
}
lock_rw_unlock(&node->lock);
free(rrstr);
return 1;
}
void
rpz_insert_rr(struct rpz* r, size_t aznamelen, uint8_t* dname,
size_t dnamelen, uint16_t rr_type, uint16_t rr_class, uint32_t rr_ttl,
uint8_t* rdatawl, size_t rdatalen, uint8_t* rr, size_t rr_len)
{
size_t policydnamelen;
/* name is free'd in local_zone delete */
uint8_t* policydname = calloc(1, LDNS_MAX_DOMAINLEN + 1);
enum rpz_trigger t;
enum rpz_action a;
a = rpz_rr_to_action(rr_type, rdatawl, rdatalen);
if(!(policydnamelen = strip_dname_origin(dname, dnamelen, aznamelen,
policydname))) {
free(policydname);
return;
}
t = rpz_dname_to_trigger(policydname);
if(t == RPZ_QNAME_TRIGGER) {
rpz_insert_qname_trigger(r, policydname, policydnamelen,
a, rr_type, rr_class, rr_ttl, rdatawl, rdatalen, rr,
rr_len);
}
else if(t == RPZ_RESPONSE_IP_TRIGGER) {
rpz_insert_response_ip_trigger(r, policydname,
a, rr_type, rr_class, rr_ttl, rdatawl, rdatalen, rr,
rr_len);
free(policydname);
}
else {
free(policydname);
verbose(VERB_ALGO, "RPZ: skipping unusupported trigger: %s",
rpz_trigger_to_string(t));
}
}
/**
* Find RPZ local-zone by qname.
* @param r: rpz containing local-zone tree
* @param qname: qname
* @param qname_len: length of qname
* @param qclass: qclass
* @param only_exact: if 1 only excact (non wildcard) matches are returned
* @param wr: get write lock for local-zone if 1, read lock if 0
* @return: NULL or local-zone holding rd or wr lock
*/
static struct local_zone*
rpz_find_zone(struct rpz* r, uint8_t* qname, size_t qname_len, uint16_t qclass,
int only_exact, int wr)
{
uint8_t* ce;
size_t ce_len, ce_labs;
uint8_t wc[LDNS_MAX_DOMAINLEN];
int exact;
struct local_zone* z = NULL;
if(wr)
lock_rw_wrlock(&r->local_zones->lock);
else
lock_rw_rdlock(&r->local_zones->lock);
z = local_zones_find_le(r->local_zones, qname, qname_len,
dname_count_labels(qname),
LDNS_RR_CLASS_IN, &exact);
if(!z || (only_exact && !exact)) {
lock_rw_unlock(&r->local_zones->lock);
return NULL;
}
if(wr)
lock_rw_wrlock(&z->lock);
else
lock_rw_rdlock(&z->lock);
lock_rw_unlock(&r->local_zones->lock);
if(exact)
return z;
/* No exact match found, lookup wildcard. closest encloser must
* be the shared parent between the qname and the best local
* zone match, append '*' to that and do another lookup. */
ce = dname_get_shared_topdomain(z->name, qname);
if(!ce /* should not happen */ || !*ce /* root */) {
lock_rw_unlock(&z->lock);
return NULL;
}
ce_labs = dname_count_size_labels(ce, &ce_len);
if(ce_len+2 > sizeof(wc)) {
lock_rw_unlock(&z->lock);
return NULL;
}
wc[0] = 1; /* length of wildcard label */
wc[1] = (uint8_t)'*'; /* wildcard label */
memmove(wc+2, ce, ce_len);
lock_rw_unlock(&z->lock);
if(wr)
lock_rw_wrlock(&r->local_zones->lock);
else
lock_rw_rdlock(&r->local_zones->lock);
z = local_zones_find_le(r->local_zones, wc,
ce_len+2, ce_labs+1, qclass, &exact);
if(!z || !exact) {
lock_rw_unlock(&r->local_zones->lock);
return NULL;
}
if(wr)
lock_rw_wrlock(&z->lock);
else
lock_rw_rdlock(&z->lock);
lock_rw_unlock(&r->local_zones->lock);
return z;
}
/**
* Remove RR from RPZ's local-data
* @param z: local-zone for RPZ, holding write lock
* @param policydname: dname of RR to remove
* @param policydnamelen: lenth of policydname
* @param rr_type: RR type of RR to remove
* @param rdata: rdata of RR to remove
* @param rdatalen: length of rdata
* @return: 1 if zone must be removed after RR deletion
*/
static int
rpz_data_delete_rr(struct local_zone* z, uint8_t* policydname,
size_t policydnamelen, uint16_t rr_type, uint8_t* rdata,
size_t rdatalen)
{
struct local_data* ld;
struct packed_rrset_data* d;
size_t index;
ld = local_zone_find_data(z, policydname, policydnamelen,
dname_count_labels(policydname));
if(ld) {
struct local_rrset* prev=NULL, *p=ld->rrsets;
while(p && ntohs(p->rrset->rk.type) != rr_type) {
prev = p;
p = p->next;
}
if(!p)
return 0;
d = (struct packed_rrset_data*)p->rrset->entry.data;
if(packed_rrset_find_rr(d, rdata, rdatalen, &index)) {
if(d->count == 1) {
/* no memory recycling for zone deletions ... */
if(prev) prev->next = p->next;
else ld->rrsets = p->next;
}
if(d->count > 1) {
if(!local_rrset_remove_rr(d, index))
return 0;
}
}
}
if(ld && ld->rrsets)
return 0;
return 1;
}
/**
* Remove RR from RPZ's respip set
* @param raddr: respip node
* @param rr_type: RR type of RR to remove
* @param rdata: rdata of RR to remove
* @param rdatalen: length of rdata
* @return: 1 if zone must be removed after RR deletion
*/
static int
rpz_rrset_delete_rr(struct resp_addr* raddr, uint16_t rr_type, uint8_t* rdata,
size_t rdatalen)
{
size_t index;
struct packed_rrset_data* d;
if(!raddr->data)
return 1;
d = raddr->data->entry.data;
if(ntohs(raddr->data->rk.type) != rr_type) {
return 0;
}
if(packed_rrset_find_rr(d, rdata, rdatalen, &index)) {
if(d->count == 1) {
/* regional alloc'd */
raddr->data->entry.data = NULL;
raddr->data = NULL;
return 1;
}
if(d->count > 1) {
if(!local_rrset_remove_rr(d, index))
return 0;
}
}
return 0;
}
/** Remove RR from RPZ's local-zone */
static void
rpz_remove_qname_trigger(struct rpz* r, uint8_t* dname, size_t dnamelen,
enum rpz_action a, uint16_t rr_type, uint16_t rr_class,
uint8_t* rdatawl, size_t rdatalen)
{
struct local_zone* z;
int delete_zone = 1;
z = rpz_find_zone(r, dname, dnamelen, rr_class,
1 /* only exact */, 1 /* wr lock */);
if(!z) {
verbose(VERB_ALGO, "RPZ: cannot remove RR from IXFR, "
"RPZ domain not found");
return;
}
if(a == RPZ_LOCAL_DATA_ACTION)
delete_zone = rpz_data_delete_rr(z, dname,
dnamelen, rr_type, rdatawl, rdatalen);
else if(a != localzone_type_to_rpz_action(z->type)) {
return;
}
lock_rw_unlock(&z->lock);
if(delete_zone) {
local_zones_del_zone(r->local_zones, z);
}
return;
}
static void
rpz_remove_response_ip_trigger(struct rpz* r, uint8_t* dname, enum rpz_action a,
uint16_t rr_type, uint8_t* rdatawl, size_t rdatalen)
{
struct resp_addr* node;
struct sockaddr_storage addr;
socklen_t addrlen;
int net, af;
int delete_respip = 1;
if(!netblockdnametoaddr(dname, &addr, &addrlen, &net, &af))
return;
lock_rw_wrlock(&r->respip_set->lock);
if(!(node = (struct resp_addr*)addr_tree_find(
&r->respip_set->ip_tree, &addr, addrlen, net))) {
verbose(VERB_ALGO, "RPZ: cannot remove RR from IXFR, "
"RPZ domain not found");
lock_rw_unlock(&r->respip_set->lock);
return;
}
lock_rw_wrlock(&node->lock);
if(a == RPZ_LOCAL_DATA_ACTION) {
/* remove RR, signal whether RR can be removed */
delete_respip = rpz_rrset_delete_rr(node, rr_type, rdatawl,
rdatalen);
}
if(delete_respip) {
/* delete + reset parent pointers */
respip_sockaddr_delete(r->respip_set, node);
} else {
lock_rw_unlock(&node->lock);
}
lock_rw_unlock(&r->respip_set->lock);
}
void
rpz_remove_rr(struct rpz* r, size_t aznamelen, uint8_t* dname, size_t dnamelen,
uint16_t rr_type, uint16_t rr_class, uint8_t* rdatawl, size_t rdatalen)
{
size_t policydnamelen;
enum rpz_trigger t;
enum rpz_action a;
uint8_t* policydname;
if(!(policydname = calloc(1, LDNS_MAX_DOMAINLEN + 1)))
return;
a = rpz_rr_to_action(rr_type, rdatawl, rdatalen);
if(a == RPZ_INVALID_ACTION) {
free(policydname);
return;
}
if(!(policydnamelen = strip_dname_origin(dname, dnamelen, aznamelen,
policydname))) {
free(policydname);
return;
}
t = rpz_dname_to_trigger(policydname);
if(t == RPZ_QNAME_TRIGGER) {
rpz_remove_qname_trigger(r, policydname, policydnamelen, a,
rr_type, rr_class, rdatawl, rdatalen);
} else if(t == RPZ_RESPONSE_IP_TRIGGER) {
rpz_remove_response_ip_trigger(r, policydname, a, rr_type,
rdatawl, rdatalen);
}
free(policydname);
}
/** print log information for an applied RPZ policy. Based on local-zone's
* lz_inform_print().
*/
static void
log_rpz_apply(uint8_t* dname, enum rpz_action a, struct query_info* qinfo,
struct comm_reply* repinfo, char* log_name)
{
char ip[128], txt[512];
char dnamestr[LDNS_MAX_DOMAINLEN+1];
uint16_t port = ntohs(((struct sockaddr_in*)&repinfo->addr)->sin_port);
dname_str(dname, dnamestr);
addr_to_str(&repinfo->addr, repinfo->addrlen, ip, sizeof(ip));
if(log_name)
snprintf(txt, sizeof(txt), "RPZ applied [%s] %s %s %s@%u",
log_name, dnamestr, rpz_action_to_string(a), ip,
(unsigned)port);
else
snprintf(txt, sizeof(txt), "RPZ applied %s %s %s@%u",
dnamestr, rpz_action_to_string(a), ip, (unsigned)port);
log_nametypeclass(0, txt, qinfo->qname, qinfo->qtype, qinfo->qclass);
}
int
rpz_apply_qname_trigger(struct auth_zones* az, struct module_env* env,
struct query_info* qinfo, struct edns_data* edns, sldns_buffer* buf,
struct regional* temp, struct comm_reply* repinfo,
uint8_t* taglist, size_t taglen, struct ub_server_stats* stats)
{
struct rpz* r;
int ret;
enum localzone_type lzt;
struct local_zone* z = NULL;
struct local_data* ld = NULL;
lock_rw_rdlock(&az->rpz_lock);
for(r = az->rpz_first; r; r = r->next) {
if(!r->taglist || taglist_intersect(r->taglist,
r->taglistlen, taglist, taglen)) {
z = rpz_find_zone(r, qinfo->qname, qinfo->qname_len,
qinfo->qclass, 0, 0);
if(z && r->action_override == RPZ_DISABLED_ACTION) {
if(r->log)
log_rpz_apply(z->name,
r->action_override,
qinfo, repinfo, r->log_name);
/* TODO only register stats when stats_extended?
* */
stats->rpz_action[r->action_override]++;
lock_rw_unlock(&z->lock);
z = NULL;
}
if(z)
break;
}
}
lock_rw_unlock(&az->rpz_lock);
if(!z)
return 0;
if(r->action_override == RPZ_NO_OVERRIDE_ACTION)
lzt = z->type;
else
lzt = rpz_action_to_localzone_type(r->action_override);
if(r->action_override == RPZ_CNAME_OVERRIDE_ACTION) {
qinfo->local_alias =
regional_alloc_zero(temp, sizeof(struct local_rrset));
if(!qinfo->local_alias) {
lock_rw_unlock(&z->lock);
return 0; /* out of memory */
}
qinfo->local_alias->rrset =
regional_alloc_init(temp, r->cname_override,
sizeof(*r->cname_override));
if(!qinfo->local_alias->rrset) {
lock_rw_unlock(&z->lock);
return 0; /* out of memory */
}
qinfo->local_alias->rrset->rk.dname = qinfo->qname;
qinfo->local_alias->rrset->rk.dname_len = qinfo->qname_len;
if(r->log)
log_rpz_apply(z->name, RPZ_CNAME_OVERRIDE_ACTION,
qinfo, repinfo, r->log_name);
stats->rpz_action[RPZ_CNAME_OVERRIDE_ACTION]++;
lock_rw_unlock(&z->lock);
return 0;
}
if(lzt == local_zone_redirect && local_data_answer(z, env, qinfo,
edns, repinfo, buf, temp, dname_count_labels(qinfo->qname),
&ld, lzt, -1, NULL, 0, NULL, 0)) {
if(r->log)
log_rpz_apply(z->name,
localzone_type_to_rpz_action(lzt), qinfo,
repinfo, r->log_name);
stats->rpz_action[localzone_type_to_rpz_action(lzt)]++;
lock_rw_unlock(&z->lock);
return !qinfo->local_alias;
}
ret = local_zones_zone_answer(z, env, qinfo, edns, repinfo, buf, temp,
0 /* no local data used */, lzt);
if(r->log)
log_rpz_apply(z->name, localzone_type_to_rpz_action(lzt),
qinfo, repinfo, r->log_name);
stats->rpz_action[localzone_type_to_rpz_action(lzt)]++;
lock_rw_unlock(&z->lock);
return ret;
}

199
services/rpz.h Normal file
View file

@ -0,0 +1,199 @@
/*
* services/rpz.h - rpz service
*
* Copyright (c) 2019, 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 to enable RPZ service.
*/
#ifndef SERVICES_RPZ_H
#define SERVICES_RPZ_H
#include "services/localzone.h"
#include "util/locks.h"
#include "util/log.h"
#include "util/config_file.h"
#include "services/authzone.h"
#include "sldns/sbuffer.h"
#include "daemon/stats.h"
#include "respip/respip.h"
/**
* RPZ triggers, only the QNAME trigger is currently supported in Unbound.
*/
enum rpz_trigger {
RPZ_QNAME_TRIGGER = 0,
/* unsupported triggers */
RPZ_CLIENT_IP_TRIGGER, /* rpz-client-ip */
RPZ_RESPONSE_IP_TRIGGER, /* rpz-ip */
RPZ_NSDNAME_TRIGGER, /* rpz-nsdname */
RPZ_NSIP_TRIGGER, /* rpz-nsip */
};
/**
* RPZ actions.
*/
enum rpz_action {
RPZ_NXDOMAIN_ACTION = 0,/* CNAME . */
RPZ_NODATA_ACTION, /* CNAME *. */
RPZ_PASSTHRU_ACTION, /* CNAME rpz-passthru. */
RPZ_DROP_ACTION, /* CNAME rpz-drop. */
RPZ_TCP_ONLY_ACTION, /* CNAME rpz-tcp-only. */
RPZ_INVALID_ACTION, /* CNAME with (child of) TLD starting with
"rpz-" in target, SOA, NS, DNAME and
DNSSEC-related records. */
RPZ_LOCAL_DATA_ACTION, /* anything else */
/* RPZ override actions */
RPZ_DISABLED_ACTION, /* RPZ action disabled using override */
RPZ_NO_OVERRIDE_ACTION, /* RPZ action no override*/
RPZ_CNAME_OVERRIDE_ACTION, /* RPZ CNAME action override*/
};
/**
* RPZ containing policies. Pointed to from corresponding auth-zone. Part of a
* linked list to keep configuration order. Iterating or changing the linked
* list requires the rpz_lock from struct auth_zones.
*/
struct rpz {
struct local_zones* local_zones;
struct respip_set* respip_set;
uint8_t* taglist;
size_t taglistlen;
enum rpz_action action_override;
struct ub_packed_rrset_key* cname_override;
int log;
char* log_name;
struct rpz* next;
struct rpz* prev;
struct regional* region;
};
/**
* Create policy from RR and add to this RPZ.
* @param r: the rpz to add the policy to.
* @param aznamelen: the length of the auth-zone name
* @param dname: dname of the RR
* @param dnamelen: length of the dname
* @param rr_type: RR type of the RR
* @param rr_class: RR class of the RR
* @param rr_ttl: TTL of the RR
* @param rdatawl: rdata of the RR, prepended with the rdata size
* @param rdatalen: length if the RR, including the prepended rdata size
* @param rr: the complete RR, for logging purposes
* @param rr_len: the length of the complete RR
*/
void rpz_insert_rr(struct rpz* r, size_t aznamelen, uint8_t* dname,
size_t dnamelen, uint16_t rr_type, uint16_t rr_class, uint32_t rr_ttl,
uint8_t* rdatawl, size_t rdatalen, uint8_t* rr, size_t rr_len);
/**
* Delete policy matching RR, used for IXFR.
* @param r: the rpz to add the policy to.
* @param aznamelen: the length of the auth-zone name
* @param dname: dname of the RR
* @param dnamelen: length of the dname
* @param rr_type: RR type of the RR
* @param rr_class: RR class of the RR
* @param rdatawl: rdata of the RR, prepended with the rdata size
* @param rdatalen: length if the RR, including the prepended rdata size
*/
void rpz_remove_rr(struct rpz* r, size_t aznamelen, uint8_t* dname,
size_t dnamelen, uint16_t rr_type, uint16_t rr_class, uint8_t* rdatawl,
size_t rdatalen);
/**
* Walk over the RPZ zones to find and apply a QNAME trigger policy.
* @param az: auth_zones struct, containing first RPZ item and RPZ lock
* @param env: module env
* @param qinfo: qinfo containing qname and qtype
* @param edns: edns data
* @param buf: buffer to write answer to
* @param temp: scratchpad
* @param repinfo: reply info
* @param taglist: taglist to lookup.
* @param taglen: lenth of taglist.
* @param stats: worker stats struct
* @return: 1 if client answer is ready, 0 to continue resolving
*/
int rpz_apply_qname_trigger(struct auth_zones* az, struct module_env* env,
struct query_info* qinfo, struct edns_data* edns, sldns_buffer* buf,
struct regional* temp, struct comm_reply* repinfo,
uint8_t* taglist, size_t taglen, struct ub_server_stats* stats);
/**
* Delete RPZ
* @param r: RPZ struct to delete
*/
void rpz_delete(struct rpz* r);
/**
* Clear local-zones and respip data in RPZ, used after reloading file or
* AXFR/HTTP transfer.
* @param r: RPZ to use
*/
int rpz_clear(struct rpz* r);
/**
* Create RPZ. RPZ must be added to linked list after creation.
* @return: the newly created RPZ
*/
struct rpz* rpz_create(struct config_auth* p);
/**
* String for RPZ action enum
* @param a: RPZ action to get string for
* @return: string for RPZ action
*/
const char* rpz_action_to_string(enum rpz_action a);
enum rpz_action
respip_action_to_rpz_action(enum respip_action a);
/**
* Prepare RPZ after procesing feed content.
* @param r: RPZ to use
*/
void rpz_finish_config(struct rpz* r);
/**
* Classify respip action for RPZ action
* @param a: RPZ action
* @return: the respip action
*/
enum respip_action
rpz_action_to_respip_action(enum rpz_action a);
#endif /* SERVICES_RPZ_H */

View file

@ -165,7 +165,7 @@ int sldns_str2wire_dname_buf_origin(const char* str, uint8_t* buf, size_t* len,
uint8_t* sldns_str2wire_dname(const char* str, size_t* len) uint8_t* sldns_str2wire_dname(const char* str, size_t* len)
{ {
uint8_t dname[LDNS_MAX_DOMAINLEN+1]; uint8_t dname[LDNS_MAX_DOMAINLEN];
*len = sizeof(dname); *len = sizeof(dname);
if(sldns_str2wire_dname_buf(str, dname, len) == 0) { if(sldns_str2wire_dname_buf(str, dname, len) == 0) {
uint8_t* r = (uint8_t*)malloc(*len); uint8_t* r = (uint8_t*)malloc(*len);

View file

@ -469,6 +469,7 @@ check_modules_exist(const char* module_conf)
static void static void
morechecks(struct config_file* cfg) morechecks(struct config_file* cfg)
{ {
struct config_auth* auth;
warn_hosts("stub-host", cfg->stubs); warn_hosts("stub-host", cfg->stubs);
warn_hosts("forward-host", cfg->forwards); warn_hosts("forward-host", cfg->forwards);
interfacechecks(cfg); interfacechecks(cfg);
@ -534,6 +535,12 @@ morechecks(struct config_file* cfg)
cfg->trusted_keys_file_list, cfg->chrootdir, cfg); cfg->trusted_keys_file_list, cfg->chrootdir, cfg);
check_chroot_string("dlv-anchor-file", &cfg->dlv_anchor_file, check_chroot_string("dlv-anchor-file", &cfg->dlv_anchor_file,
cfg->chrootdir, cfg); cfg->chrootdir, cfg);
for(auth = cfg->auths; auth; auth = auth->next) {
char* az = (auth->isrpz) ? "rpz zonefile" :
"auth-zone zonefile";
check_chroot_string(az, &auth->zonefile,
cfg->chrootdir, cfg);
}
#ifdef USE_IPSECMOD #ifdef USE_IPSECMOD
if(cfg->ipsecmod_enabled && strstr(cfg->module_conf, "ipsecmod")) { if(cfg->ipsecmod_enabled && strstr(cfg->module_conf, "ipsecmod")) {
/* only check hook if enabled */ /* only check hook if enabled */
@ -676,8 +683,9 @@ check_hints(struct config_file* cfg)
static void static void
check_auth(struct config_file* cfg) check_auth(struct config_file* cfg)
{ {
int is_rpz = 0;
struct auth_zones* az = auth_zones_create(); struct auth_zones* az = auth_zones_create();
if(!az || !auth_zones_apply_cfg(az, cfg, 0)) { if(!az || !auth_zones_apply_cfg(az, cfg, 0i, &is_rpz)) {
fatal_exit("Could not setup authority zones"); fatal_exit("Could not setup authority zones");
} }
auth_zones_delete(az); auth_zones_delete(az);

362
testdata/rpz_axfr.rpl vendored Normal file
View file

@ -0,0 +1,362 @@
; config options
server:
module-config: "respip validator iterator"
target-fetch-policy: "0 0 0 0 0"
qname-minimisation: no
rpz:
name: "rpz.example.com."
master: 10.20.30.40
zonefile:
TEMPFILE_NAME rpz.example.com
TEMPFILE_CONTENTS rpz.example.com
$ORIGIN rpz.example.com.
a IN CNAME *.
c IN TXT "hello from initial RPZ"
c IN TXT "another hello from initial RPZ"
d IN CNAME .
32.1.123.0.10.rpz-ip CNAME *.
32.3.123.0.10.rpz-ip A 10.66.0.3
32.3.123.0.10.rpz-ip A 10.66.0.4
32.4.123.0.10.rpz-ip CNAME .
TEMPFILE_END
stub-zone:
name: "."
stub-addr: 10.20.30.40
CONFIG_END
SCENARIO_BEGIN Test RPZ QNAME trigger, loaded using AXFR
RANGE_BEGIN 0 100
ADDRESS 10.20.30.40
ENTRY_BEGIN
MATCH opcode qname qtype
ADJUST copy_id
REPLY QR NOERROR AA
SECTION QUESTION
. IN NS
SECTION ANSWER
. IN NS ns.
SECTION ADDITIONAL
ns. IN NS 10.20.30.40
ENTRY_END
ENTRY_BEGIN
MATCH opcode qname qtype
ADJUST copy_id
REPLY QR NOERROR AA
SECTION QUESTION
b. IN TXT
SECTION ANSWER
b. TXT "hello from upstream"
ENTRY_END
ENTRY_BEGIN
MATCH opcode qname qtype
ADJUST copy_id
REPLY QR NOERROR AA
SECTION QUESTION
d. IN TXT
SECTION ANSWER
d. TXT "hello from upstream"
ENTRY_END
ENTRY_BEGIN
MATCH opcode qname qtype
ADJUST copy_id
REPLY QR NOERROR AA
SECTION QUESTION
a.rpz-ip. IN A
SECTION ANSWER
a.rpz-ip. IN A 10.0.123.1
ENTRY_END
ENTRY_BEGIN
MATCH opcode qname qtype
ADJUST copy_id
REPLY QR NOERROR AA
SECTION QUESTION
c.rpz-ip. IN A
SECTION ANSWER
c.rpz-ip. IN A 10.0.123.3
ENTRY_END
ENTRY_BEGIN
MATCH opcode qname qtype
ADJUST copy_id
REPLY QR NOERROR AA
SECTION QUESTION
d.rpz-ip. IN A
SECTION ANSWER
d.rpz-ip. IN A 10.0.123.4
ENTRY_END
ENTRY_BEGIN
MATCH opcode qname qtype
ADJUST copy_id
REPLY QR AA NOERROR
SECTION QUESTION
rpz.example.com. IN SOA
SECTION ANSWER
rpz.example.com. IN SOA ns.rpz.example.com. hostmaster.rpz.example.com. 1 3600 900 86400 3600
ENTRY_END
ENTRY_BEGIN
MATCH opcode qname qtype
ADJUST copy_id
REPLY QR AA NOERROR
SECTION QUESTION
rpz.example.com. IN AXFR
SECTION ANSWER
rpz.example.com. IN SOA ns.rpz.example.com. hostmaster.rpz.example.com. 1 3600 900 86400 3600
b.rpz.example.com. TXT "hello from RPZ"
c.rpz.example.com. TXT "hello from RPZ"
a.rpz.example.com. CNAME .
32.1.123.0.10.rpz-ip.rpz.example.com. CNAME .
32.3.123.0.10.rpz-ip.rpz.example.com. A 10.66.0.5
32.3.123.0.10.rpz-ip.rpz.example.com. A 10.66.0.6
rpz.example.com. IN SOA ns.rpz.example.com. hostmaster.rpz.example.com. 1 3600 900 86400 3600
ENTRY_END
RANGE_END
STEP 1 QUERY
ENTRY_BEGIN
REPLY RD
SECTION QUESTION
b. IN TXT
ENTRY_END
STEP 2 CHECK_ANSWER
ENTRY_BEGIN
MATCH all
REPLY QR RD RA NOERROR
SECTION QUESTION
b. IN TXT
SECTION ANSWER
b. IN TXT "hello from upstream"
ENTRY_END
STEP 3 QUERY
ENTRY_BEGIN
REPLY RD
SECTION QUESTION
a. IN TXT
ENTRY_END
STEP 4 CHECK_ANSWER
ENTRY_BEGIN
MATCH all
REPLY QR RD RA AA NOERROR
SECTION QUESTION
a. IN TXT
SECTION ANSWER
ENTRY_END
STEP 5 QUERY
ENTRY_BEGIN
REPLY RD
SECTION QUESTION
a.rpz-ip. IN A
ENTRY_END
STEP 6 CHECK_ANSWER
ENTRY_BEGIN
MATCH all
REPLY QR RD RA NOERROR
SECTION QUESTION
a.rpz-ip. IN A
SECTION ANSWER
ENTRY_END
STEP 7 QUERY
ENTRY_BEGIN
REPLY RD
SECTION QUESTION
c. IN TXT
ENTRY_END
STEP 8 CHECK_ANSWER
ENTRY_BEGIN
MATCH all
REPLY QR RD RA AA NOERROR
SECTION QUESTION
c. IN TXT
SECTION ANSWER
c. IN TXT "another hello from initial RPZ"
c. IN TXT "hello from initial RPZ"
ENTRY_END
STEP 9 QUERY
ENTRY_BEGIN
REPLY RD
SECTION QUESTION
c.rpz-ip. IN A
ENTRY_END
STEP 10 CHECK_ANSWER
ENTRY_BEGIN
MATCH all
REPLY QR RD RA NOERROR
SECTION QUESTION
c.rpz-ip. IN A
SECTION ANSWER
c.rpz-ip. IN A 10.66.0.4
c.rpz-ip. IN A 10.66.0.3
ENTRY_END
STEP 11 QUERY
ENTRY_BEGIN
REPLY RD
SECTION QUESTION
d. IN TXT
ENTRY_END
STEP 12 CHECK_ANSWER
ENTRY_BEGIN
MATCH all
REPLY QR RD RA AA NXDOMAIN
SECTION QUESTION
d. IN TXT
ENTRY_END
STEP 13 QUERY
ENTRY_BEGIN
REPLY RD
SECTION QUESTION
d.rpz-ip. IN A
ENTRY_END
STEP 14 CHECK_ANSWER
ENTRY_BEGIN
MATCH all
REPLY QR RD RA NXDOMAIN
SECTION QUESTION
d.rpz-ip. IN A
ENTRY_END
STEP 30 TIME_PASSES ELAPSE 10
STEP 40 TRAFFIC
STEP 50 QUERY
ENTRY_BEGIN
REPLY RD
SECTION QUESTION
b. IN TXT
ENTRY_END
STEP 51 CHECK_ANSWER
ENTRY_BEGIN
MATCH all
REPLY QR RD RA AA NOERROR
SECTION QUESTION
b. IN TXT
SECTION ANSWER
b. IN TXT "hello from RPZ"
ENTRY_END
STEP 52 QUERY
ENTRY_BEGIN
REPLY RD
SECTION QUESTION
a. IN TXT
ENTRY_END
STEP 53 CHECK_ANSWER
ENTRY_BEGIN
MATCH all
REPLY QR RD RA AA NXDOMAIN
SECTION QUESTION
a. IN TXT
SECTION ANSWER
ENTRY_END
STEP 54 QUERY
ENTRY_BEGIN
REPLY RD
SECTION QUESTION
a.rpz-ip. IN A
ENTRY_END
STEP 55 CHECK_ANSWER
ENTRY_BEGIN
MATCH all
REPLY QR RD RA NXDOMAIN
SECTION QUESTION
a.rpz-ip. IN A
SECTION ANSWER
ENTRY_END
STEP 56 QUERY
ENTRY_BEGIN
REPLY RD
SECTION QUESTION
c. IN TXT
ENTRY_END
STEP 57 CHECK_ANSWER
ENTRY_BEGIN
MATCH all
REPLY QR RD RA AA NOERROR
SECTION QUESTION
c. IN TXT
SECTION ANSWER
c. IN TXT "hello from RPZ"
ENTRY_END
STEP 58 QUERY
ENTRY_BEGIN
REPLY RD
SECTION QUESTION
c.rpz-ip. IN A
ENTRY_END
STEP 59 CHECK_ANSWER
ENTRY_BEGIN
MATCH all
REPLY QR RD RA NOERROR
SECTION QUESTION
c.rpz-ip. IN A
SECTION ANSWER
c.rpz-ip. IN A 10.66.0.6
c.rpz-ip. IN A 10.66.0.5
ENTRY_END
STEP 60 QUERY
ENTRY_BEGIN
REPLY RD
SECTION QUESTION
d. IN TXT
ENTRY_END
STEP 61 CHECK_ANSWER
ENTRY_BEGIN
MATCH all
REPLY QR RD RA NOERROR
SECTION QUESTION
d. IN TXT
SECTION ANSWER
d. IN TXT "hello from upstream"
ENTRY_END
STEP 62 QUERY
ENTRY_BEGIN
REPLY RD
SECTION QUESTION
d.rpz-ip. IN A
ENTRY_END
STEP 63 CHECK_ANSWER
ENTRY_BEGIN
MATCH all
REPLY QR RD RA NOERROR
SECTION QUESTION
d.rpz-ip. IN A
SECTION ANSWER
d.rpz-ip. IN A 10.0.123.4
ENTRY_END
SCENARIO_END

378
testdata/rpz_ixfr.rpl vendored Normal file
View file

@ -0,0 +1,378 @@
; config options
server:
module-config: "respip validator iterator"
target-fetch-policy: "0 0 0 0 0"
qname-minimisation: no
rpz:
name: "rpz.example.com."
master: 10.20.30.40
zonefile:
TEMPFILE_NAME rpz.example.com
TEMPFILE_CONTENTS rpz.example.com
rpz.example.com. 3600 IN SOA ns.rpz.example.com. hostmaster.rpz.example.com. 1 3600 900 86400 3600
rpz.example.com. 3600 IN NS ns.rpz.example.net.
a.rpz.example.com. IN CNAME *.
c.rpz.example.com. IN TXT "hello from initial RPZ"
c.rpz.example.com. IN TXT "another hello from initial RPZ"
c.rpz.example.com. IN TXT "yet another hello from initial RPZ"
d.rpz.example.com. IN CNAME .
32.1.123.0.10.rpz-ip.rpz.example.com. CNAME *.
32.3.123.0.10.rpz-ip.rpz.example.com. A 10.66.0.3
32.3.123.0.10.rpz-ip.rpz.example.com. A 10.66.0.4
32.4.123.0.10.rpz-ip.rpz.example.com. CNAME .
TEMPFILE_END
stub-zone:
name: "."
stub-addr: 10.20.30.40
CONFIG_END
SCENARIO_BEGIN Test RPZ QNAME trigger, loaded using IXFR
RANGE_BEGIN 0 100
ADDRESS 10.20.30.40
ENTRY_BEGIN
MATCH opcode qname qtype
ADJUST copy_id
REPLY QR NOERROR AA
SECTION QUESTION
. IN NS
SECTION ANSWER
. IN NS ns.
SECTION ADDITIONAL
ns. IN NS 10.20.30.40
ENTRY_END
ENTRY_BEGIN
MATCH opcode qname qtype
ADJUST copy_id
REPLY QR NOERROR AA
SECTION QUESTION
b. IN TXT
SECTION ANSWER
b. TXT "hello from upstream"
ENTRY_END
ENTRY_BEGIN
MATCH opcode qname qtype
ADJUST copy_id
REPLY QR NOERROR AA
SECTION QUESTION
d. IN TXT
SECTION ANSWER
d. TXT "hello from upstream"
ENTRY_END
ENTRY_BEGIN
MATCH opcode qname qtype
ADJUST copy_id
REPLY QR NOERROR AA
SECTION QUESTION
a.rpz-ip. IN A
SECTION ANSWER
a.rpz-ip. IN A 10.0.123.1
ENTRY_END
ENTRY_BEGIN
MATCH opcode qname qtype
ADJUST copy_id
REPLY QR NOERROR AA
SECTION QUESTION
c.rpz-ip. IN A
SECTION ANSWER
c.rpz-ip. IN A 10.0.123.3
ENTRY_END
ENTRY_BEGIN
MATCH opcode qname qtype
ADJUST copy_id
REPLY QR NOERROR AA
SECTION QUESTION
d.rpz-ip. IN A
SECTION ANSWER
d.rpz-ip. IN A 10.0.123.4
ENTRY_END
ENTRY_BEGIN
MATCH opcode qname qtype
ADJUST copy_id
REPLY QR AA NOERROR
SECTION QUESTION
rpz.example.com. IN SOA
SECTION ANSWER
rpz.example.com. IN SOA ns.rpz.example.com. hostmaster.rpz.example.com. 2 3600 900 86400 3600
ENTRY_END
ENTRY_BEGIN
MATCH opcode qname qtype
ADJUST copy_id
REPLY QR AA NOERROR
SECTION QUESTION
rpz.example.com. IN IXFR
SECTION ANSWER
rpz.example.com. IN SOA ns.rpz.example.com. hostmaster.rpz.example.com. 2 3600 900 86400 3600
rpz.example.com. IN SOA ns.rpz.example.com. hostmaster.rpz.example.com. 1 3600 900 86400 3600
a.rpz.example.com. IN CNAME *.
c.rpz.example.com. IN TXT "hello from initial RPZ"
c.rpz.example.com. IN TXT "another hello from initial RPZ"
d.rpz.example.com. IN CNAME .
32.1.123.0.10.rpz-ip.rpz.example.com. CNAME *.
32.3.123.0.10.rpz-ip.rpz.example.com. A 10.66.0.3
32.3.123.0.10.rpz-ip.rpz.example.com. A 10.66.0.4
32.4.123.0.10.rpz-ip.rpz.example.com. CNAME .
rpz.example.com. IN SOA ns.rpz.example.com. hostmaster.rpz.example.com. 2 3600 900 86400 3600
b.rpz.example.com. TXT "hello from RPZ"
c.rpz.example.com. TXT "hello from RPZ"
a.rpz.example.com. CNAME .
32.1.123.0.10.rpz-ip.rpz.example.com. CNAME .
32.3.123.0.10.rpz-ip.rpz.example.com. A 10.66.0.5
32.3.123.0.10.rpz-ip.rpz.example.com. A 10.66.0.6
rpz.example.com. IN SOA ns.rpz.example.com. hostmaster.rpz.example.com. 2 3600 900 86400 3600
ENTRY_END
RANGE_END
STEP 1 QUERY
ENTRY_BEGIN
REPLY RD
SECTION QUESTION
b. IN TXT
ENTRY_END
STEP 2 CHECK_ANSWER
ENTRY_BEGIN
MATCH all
REPLY QR RD RA NOERROR
SECTION QUESTION
b. IN TXT
SECTION ANSWER
b. IN TXT "hello from upstream"
ENTRY_END
STEP 3 QUERY
ENTRY_BEGIN
REPLY RD
SECTION QUESTION
a. IN TXT
ENTRY_END
STEP 4 CHECK_ANSWER
ENTRY_BEGIN
MATCH all
REPLY QR RD RA AA NOERROR
SECTION QUESTION
a. IN TXT
SECTION ANSWER
ENTRY_END
STEP 5 QUERY
ENTRY_BEGIN
REPLY RD
SECTION QUESTION
a.rpz-ip. IN A
ENTRY_END
STEP 6 CHECK_ANSWER
ENTRY_BEGIN
MATCH all
REPLY QR RD RA NOERROR
SECTION QUESTION
a.rpz-ip. IN A
SECTION ANSWER
ENTRY_END
STEP 7 QUERY
ENTRY_BEGIN
REPLY RD
SECTION QUESTION
c. IN TXT
ENTRY_END
STEP 8 CHECK_ANSWER
ENTRY_BEGIN
MATCH all
REPLY QR RD RA AA NOERROR
SECTION QUESTION
c. IN TXT
SECTION ANSWER
c. IN TXT "yet another hello from initial RPZ"
c. IN TXT "another hello from initial RPZ"
c. IN TXT "hello from initial RPZ"
ENTRY_END
STEP 9 QUERY
ENTRY_BEGIN
REPLY RD
SECTION QUESTION
c.rpz-ip. IN A
ENTRY_END
STEP 10 CHECK_ANSWER
ENTRY_BEGIN
MATCH all
REPLY QR RD RA NOERROR
SECTION QUESTION
c.rpz-ip. IN A
SECTION ANSWER
c.rpz-ip. IN A 10.66.0.4
c.rpz-ip. IN A 10.66.0.3
ENTRY_END
STEP 11 QUERY
ENTRY_BEGIN
REPLY RD
SECTION QUESTION
d. IN TXT
ENTRY_END
STEP 12 CHECK_ANSWER
ENTRY_BEGIN
MATCH all
REPLY QR RD RA AA NXDOMAIN
SECTION QUESTION
d. IN TXT
ENTRY_END
STEP 13 QUERY
ENTRY_BEGIN
REPLY RD
SECTION QUESTION
d.rpz-ip. IN A
ENTRY_END
STEP 15 CHECK_ANSWER
ENTRY_BEGIN
MATCH all
REPLY QR RD RA NXDOMAIN
SECTION QUESTION
d.rpz-ip. IN A
ENTRY_END
STEP 16 TIME_PASSES ELAPSE 1
STEP 30 TIME_PASSES ELAPSE 3600
STEP 40 TRAFFIC
STEP 50 QUERY
ENTRY_BEGIN
REPLY RD
SECTION QUESTION
b. IN TXT
ENTRY_END
STEP 51 CHECK_ANSWER
ENTRY_BEGIN
MATCH all
REPLY QR RD RA AA NOERROR
SECTION QUESTION
b. IN TXT
SECTION ANSWER
b. IN TXT "hello from RPZ"
ENTRY_END
STEP 52 QUERY
ENTRY_BEGIN
REPLY RD
SECTION QUESTION
a. IN TXT
ENTRY_END
STEP 53 CHECK_ANSWER
ENTRY_BEGIN
MATCH all
REPLY QR RD RA AA NXDOMAIN
SECTION QUESTION
a. IN TXT
SECTION ANSWER
ENTRY_END
STEP 54 QUERY
ENTRY_BEGIN
REPLY RD
SECTION QUESTION
a.rpz-ip. IN A
ENTRY_END
STEP 55 CHECK_ANSWER
ENTRY_BEGIN
MATCH all
REPLY QR RD RA NXDOMAIN
SECTION QUESTION
a.rpz-ip. IN A
SECTION ANSWER
ENTRY_END
STEP 56 QUERY
ENTRY_BEGIN
REPLY RD
SECTION QUESTION
c. IN TXT
ENTRY_END
STEP 57 CHECK_ANSWER
ENTRY_BEGIN
MATCH all
REPLY QR RD RA AA NOERROR
SECTION QUESTION
c. IN TXT
SECTION ANSWER
c. IN TXT "hello from RPZ"
c. IN TXT "yet another hello from initial RPZ"
ENTRY_END
STEP 58 QUERY
ENTRY_BEGIN
REPLY RD
SECTION QUESTION
c.rpz-ip. IN A
ENTRY_END
STEP 59 CHECK_ANSWER
ENTRY_BEGIN
MATCH all
REPLY QR RD RA NOERROR
SECTION QUESTION
c.rpz-ip. IN A
SECTION ANSWER
c.rpz-ip. IN A 10.66.0.6
c.rpz-ip. IN A 10.66.0.5
ENTRY_END
STEP 60 QUERY
ENTRY_BEGIN
REPLY RD
SECTION QUESTION
d. IN TXT
ENTRY_END
STEP 61 CHECK_ANSWER
ENTRY_BEGIN
MATCH all
REPLY QR RD RA NOERROR
SECTION QUESTION
d. IN TXT
SECTION ANSWER
d. IN TXT "hello from upstream"
ENTRY_END
STEP 62 QUERY
ENTRY_BEGIN
REPLY RD
SECTION QUESTION
d.rpz-ip. IN A
ENTRY_END
STEP 63 CHECK_ANSWER
ENTRY_BEGIN
MATCH all
REPLY QR RD RA NOERROR
SECTION QUESTION
d.rpz-ip. IN A
SECTION ANSWER
d.rpz-ip. IN A 10.0.123.4
ENTRY_END
SCENARIO_END

226
testdata/rpz_qname.rpl vendored Normal file
View file

@ -0,0 +1,226 @@
; config options
server:
module-config: "respip validator iterator"
target-fetch-policy: "0 0 0 0 0"
qname-minimisation: no
rpz:
name: "rpz.example.com."
zonefile:
TEMPFILE_NAME rpz.example.com
TEMPFILE_CONTENTS rpz.example.com
$ORIGIN example.com.
rpz 3600 IN SOA ns1.rpz.example.com. hostmaster.rpz.example.com. (
1379078166 28800 7200 604800 7200 )
3600 IN NS ns1.rpz.example.com.
3600 IN NS ns2.rpz.example.com.
$ORIGIN rpz.example.com.
a CNAME .
a CNAME *. ; duplicate CNAME here on purpose
*.a TXT "wildcard local data"
b.a CNAME *.
c.a CNAME rpz-passthru.
TEMPFILE_END
rpz:
name: "rpz2.example.com."
zonefile:
TEMPFILE_NAME rpz2.example.com
TEMPFILE_CONTENTS rpz2.example.com
$ORIGIN example.com.
rpz 3600 IN SOA ns1.rpz.example.com. hostmaster.rpz.example.com. (
1379078166 28800 7200 604800 7200 )
3600 IN NS ns1.rpz.example.com.
3600 IN NS ns2.rpz.example.com.
$ORIGIN rpz2.example.com.
a TXT "local data 2nd zone"
d TXT "local data 2nd zone"
drop CNAME rpz-drop.
TEMPFILE_END
stub-zone:
name: "a."
stub-addr: 10.20.30.40
CONFIG_END
SCENARIO_BEGIN Test all support RPZ action for QNAME trigger
; c.
RANGE_BEGIN 0 100
ADDRESS 10.20.30.40
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
a. IN NS
SECTION ANSWER
a. IN NS ns.a.
SECTION ADDITIONAL
ns.a IN A 10.20.30.40
ENTRY_END
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
c.a. IN TXT
SECTION ANSWER
c.a. IN TXT "answer from upstream ns"
ENTRY_END
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
x.b.a. IN TXT
SECTION ANSWER
x.b.a. IN TXT "answer from upstream ns"
ENTRY_END
RANGE_END
STEP 10 QUERY
ENTRY_BEGIN
REPLY RD
SECTION QUESTION
a. IN TXT
ENTRY_END
STEP 11 CHECK_ANSWER
ENTRY_BEGIN
MATCH all
REPLY QR RD RA AA NXDOMAIN
SECTION QUESTION
a. IN TXT
SECTION ANSWER
ENTRY_END
STEP 20 QUERY
ENTRY_BEGIN
REPLY RD
SECTION QUESTION
a.a. IN TXT
ENTRY_END
STEP 21 CHECK_ANSWER
ENTRY_BEGIN
MATCH all
REPLY QR RD RA AA NOERROR
SECTION QUESTION
a.a. IN TXT
SECTION ANSWER
a.a. IN TXT "wildcard local data"
ENTRY_END
STEP 30 QUERY
ENTRY_BEGIN
REPLY RD
SECTION QUESTION
b.a. IN TXT
ENTRY_END
STEP 31 CHECK_ANSWER
ENTRY_BEGIN
MATCH all
REPLY QR RD RA AA NOERROR
SECTION QUESTION
b.a. IN TXT
SECTION ANSWER
ENTRY_END
STEP 40 QUERY
ENTRY_BEGIN
REPLY RD
SECTION QUESTION
x.a. IN TXT
ENTRY_END
STEP 41 CHECK_ANSWER
ENTRY_BEGIN
MATCH all
REPLY QR RD RA AA NOERROR
SECTION QUESTION
x.a. IN TXT
SECTION ANSWER
x.a. IN TXT "wildcard local data"
ENTRY_END
STEP 50 QUERY
ENTRY_BEGIN
REPLY RD
SECTION QUESTION
x.a.a. IN TXT
ENTRY_END
STEP 51 CHECK_ANSWER
ENTRY_BEGIN
MATCH all
REPLY QR RD RA AA NOERROR
SECTION QUESTION
x.a.a. IN TXT
SECTION ANSWER
x.a.a. IN TXT "wildcard local data"
ENTRY_END
STEP 60 QUERY
ENTRY_BEGIN
REPLY RD
SECTION QUESTION
c.a. IN TXT
ENTRY_END
STEP 61 CHECK_ANSWER
ENTRY_BEGIN
MATCH all
REPLY QR RD RA NOERROR
SECTION QUESTION
c.a. IN TXT
SECTION ANSWER
c.a. IN TXT "answer from upstream ns"
ENTRY_END
STEP 70 QUERY
ENTRY_BEGIN
REPLY RD
SECTION QUESTION
x.b.a. IN TXT
ENTRY_END
STEP 71 CHECK_ANSWER
ENTRY_BEGIN
MATCH all
REPLY QR RD RA NOERROR
SECTION QUESTION
x.b.a. IN TXT
SECTION ANSWER
x.b.a. IN TXT "answer from upstream ns"
ENTRY_END
STEP 80 QUERY
ENTRY_BEGIN
REPLY RD
SECTION QUESTION
d. IN TXT
ENTRY_END
STEP 81 CHECK_ANSWER
ENTRY_BEGIN
MATCH all
REPLY QR RD RA AA NOERROR
SECTION QUESTION
d. IN TXT
SECTION ANSWER
d. IN TXT "local data 2nd zone"
ENTRY_END
; deny zone
STEP 90 QUERY
ENTRY_BEGIN
SECTION QUESTION
drop. IN TXT
ENTRY_END
; no answer is checked at exit of testbound.
SCENARIO_END

197
testdata/rpz_qname_override.rpl vendored Normal file
View file

@ -0,0 +1,197 @@
; config options
server:
module-config: "respip validator iterator"
target-fetch-policy: "0 0 0 0 0"
qname-minimisation: no
rpz:
name: "rpz.example.com."
rpz-action-override: disabled
zonefile:
TEMPFILE_NAME rpz.example.com
TEMPFILE_CONTENTS rpz.example.com
$ORIGIN rpz.example.com.
a TXT "record zone rpz.example.com"
TEMPFILE_END
rpz:
name: "rpz2.example.com."
zonefile:
TEMPFILE_NAME rpz2.example.com
TEMPFILE_CONTENTS rpz2.example.com
$ORIGIN rpz2.example.com.
a TXT "record zone rpz2.example.com"
TEMPFILE_END
rpz:
name: "rpz3.example.com."
rpz-action-override: nodata
zonefile:
TEMPFILE_NAME rpz3.example.com
TEMPFILE_CONTENTS rpz3.example.com
$ORIGIN rpz3.example.com.
b CNAME .
TEMPFILE_END
rpz:
name: "rpz4.example.com."
rpz-action-override: nxdomain
zonefile:
TEMPFILE_NAME rpz4.example.com
TEMPFILE_CONTENTS rpz4.example.com
$ORIGIN rpz4.example.com.
c CNAME *.
TEMPFILE_END
rpz:
name: "rpz5.example.com."
rpz-action-override: passthru
zonefile:
TEMPFILE_NAME rpz5.example.com
TEMPFILE_CONTENTS rpz5.example.com
$ORIGIN rpz5.example.com.
d TXT "should be override by passthru"
TEMPFILE_END
rpz:
name: "rpz6.example.com."
rpz-action-override: cname
rpz-cname-override: "d."
zonefile:
TEMPFILE_NAME rpz6.example.com
TEMPFILE_CONTENTS rpz6.example.com
$ORIGIN rpz6.example.com.
e TXT "should be override by cname"
TEMPFILE_END
rpz:
name: "rpz7.example.com."
rpz-action-override: drop
zonefile:
TEMPFILE_NAME rpz7.example.com
TEMPFILE_CONTENTS rpz7.example.com
$ORIGIN rpz7.example.com.
f TXT "should be override by drop policy"
TEMPFILE_END
stub-zone:
name: "d."
stub-addr: 10.20.30.40
CONFIG_END
SCENARIO_BEGIN Test RPZ action overrides for QNAME trigger
; d.
RANGE_BEGIN 0 100
ADDRESS 10.20.30.40
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
d. IN TXT
SECTION ANSWER
d. IN TXT "answer from upstream ns"
ENTRY_END
RANGE_END
; check disabled override, should be answered using next policy zone
STEP 10 QUERY
ENTRY_BEGIN
REPLY RD
SECTION QUESTION
a. IN TXT
ENTRY_END
STEP 11 CHECK_ANSWER
ENTRY_BEGIN
MATCH all
REPLY QR RD RA AA NOERROR
SECTION QUESTION
a. IN TXT
SECTION ANSWER
a TXT "record zone rpz2.example.com"
ENTRY_END
; check nodata override, would be NXDOMAIN without override
STEP 20 QUERY
ENTRY_BEGIN
REPLY RD
SECTION QUESTION
b. IN TXT
ENTRY_END
STEP 21 CHECK_ANSWER
ENTRY_BEGIN
MATCH all
REPLY QR RD RA AA NOERROR
SECTION QUESTION
b. IN TXT
SECTION ANSWER
ENTRY_END
; check nxdomain override, would be NODATA without override
STEP 30 QUERY
ENTRY_BEGIN
REPLY RD
SECTION QUESTION
c. IN TXT
ENTRY_END
STEP 31 CHECK_ANSWER
ENTRY_BEGIN
MATCH all
REPLY QR RD RA AA NXDOMAIN
SECTION QUESTION
c. IN TXT
SECTION ANSWER
ENTRY_END
; check passthru override, would be localdata without override
STEP 40 QUERY
ENTRY_BEGIN
REPLY RD
SECTION QUESTION
d. IN TXT
ENTRY_END
STEP 41 CHECK_ANSWER
ENTRY_BEGIN
MATCH all
REPLY QR RD RA NOERROR
SECTION QUESTION
d. IN TXT
SECTION ANSWER
d. IN TXT "answer from upstream ns"
ENTRY_END
; check cname override, would be localdata without override
STEP 50 QUERY
ENTRY_BEGIN
REPLY RD
SECTION QUESTION
e. IN TXT
ENTRY_END
STEP 51 CHECK_ANSWER
ENTRY_BEGIN
MATCH all
REPLY QR RD RA AA NOERROR
SECTION QUESTION
e. IN TXT
SECTION ANSWER
e. IN CNAME d.
d. IN TXT "answer from upstream ns"
ENTRY_END
; check drop override, would be localdata without override
STEP 60 QUERY
ENTRY_BEGIN
REPLY RD
SECTION QUESTION
f. IN TXT
ENTRY_END
; no answer is checked at exit of testbound.
SCENARIO_END

421
testdata/rpz_respip.rpl vendored Normal file
View file

@ -0,0 +1,421 @@
; config options
server:
module-config: "respip validator iterator"
target-fetch-policy: "0 0 0 0 0"
qname-minimisation: no
rpz:
name: "rpz.example.com."
zonefile:
TEMPFILE_NAME rpz.example.com
TEMPFILE_CONTENTS rpz.example.com
$ORIGIN example.com.
rpz 3600 IN SOA ns1.rpz.example.com. hostmaster.rpz.example.com. (
1379078166 28800 7200 604800 7200 )
3600 IN NS ns1.rpz.example.com.
3600 IN NS ns2.rpz.example.com.
$ORIGIN rpz.example.com.
8.0.0.0.10.rpz-ip CNAME *.
16.0.0.10.10.rpz-ip CNAME .
24.0.10.10.10.rpz-ip CNAME rpz-drop.
32.10.10.10.10.rpz-ip CNAME rpz-passthru.
32.zz.db8.2001.rpz-ip CNAME *.
48.zz.aa.db8.2001.rpz-ip CNAME .
64.zz.bb.aa.db8.2001.rpz-ip CNAME rpz-drop.
128.1.zz.cc.bb.aa.db8.2001.rpz-ip CNAME rpz-passthru.
128.123.zz.cc.bb.aa.db8.2001.rpz-ip AAAA 2001:db8::123
TEMPFILE_END
rpz:
name: "rpz2.example.com."
zonefile:
TEMPFILE_NAME rpz2.example.com
TEMPFILE_CONTENTS rpz2.example.com
$ORIGIN example.com.
rpz2 3600 IN SOA ns1.rpz2.example.com. hostmaster.rpz2.example.com. (
1379078166 28800 7200 604800 7200 )
3600 IN NS ns1.rpz2.example.com.
3600 IN NS ns2.rpz2.example.com.
$ORIGIN rpz2.example.com.
32.10.10.10.10.rpz-ip A 203.0.113.123
32.123.2.0.192.rpz-ip A 203.0.113.123
128.1.zz.cc.bb.aa.db8.2001.rpz-ip AAAA 2001:db1::123
TEMPFILE_END
stub-zone:
name: "."
stub-addr: 10.20.30.40
CONFIG_END
SCENARIO_BEGIN Test all supported RPZ action for response IP address trigger
; c.
RANGE_BEGIN 0 100
ADDRESS 10.20.30.40
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
. IN NS
SECTION ANSWER
. IN NS ns.
SECTION ADDITIONAL
ns. IN A 10.20.30.40
ENTRY_END
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
a. IN A
SECTION ANSWER
a. IN A 10.0.0.123
ENTRY_END
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
a. IN AAAA
SECTION ANSWER
a. IN AAAA 2001:db8::123
ENTRY_END
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
b. IN A
SECTION ANSWER
b. IN A 10.1.0.123
ENTRY_END
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
b. IN AAAA
SECTION ANSWER
b. IN AAAA 2001:db8:1::123
ENTRY_END
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
c. IN A
SECTION ANSWER
c. IN A 10.11.0.123
ENTRY_END
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
c. IN AAAA
SECTION ANSWER
c. IN AAAA 2001:db8:ff::123
ENTRY_END
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
d. IN A
SECTION ANSWER
d. IN A 10.10.0.123
ENTRY_END
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
d. IN AAAA
SECTION ANSWER
d. IN AAAA 2001:db8:aa::123
ENTRY_END
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
e. IN A
SECTION ANSWER
e. IN A 10.10.10.123
ENTRY_END
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
e. IN AAAA
SECTION ANSWER
e. IN AAAA 2001:db8:aa:bb::123
ENTRY_END
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
f. IN A
SECTION ANSWER
f. IN A 10.10.10.10
ENTRY_END
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
f. IN AAAA
SECTION ANSWER
f. IN AAAA 2001:db8:aa:bb:cc::1
ENTRY_END
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
g. IN A
SECTION ANSWER
g. IN A 192.0.2.123
ENTRY_END
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
g. IN AAAA
SECTION ANSWER
g. IN AAAA 2001:db8:aa:bb:cc::123
ENTRY_END
RANGE_END
STEP 1 QUERY
ENTRY_BEGIN
REPLY RD
SECTION QUESTION
a. IN A
ENTRY_END
STEP 2 CHECK_ANSWER
ENTRY_BEGIN
MATCH all
REPLY QR RD RA NOERROR
SECTION QUESTION
a. IN A
SECTION ANSWER
ENTRY_END
STEP 3 QUERY
ENTRY_BEGIN
REPLY RD
SECTION QUESTION
a. IN AAAA
ENTRY_END
STEP 4 CHECK_ANSWER
ENTRY_BEGIN
MATCH all
REPLY QR RD RA NOERROR
SECTION QUESTION
a. IN AAAA
SECTION ANSWER
ENTRY_END
STEP 5 QUERY
ENTRY_BEGIN
REPLY RD
SECTION QUESTION
b. IN A
ENTRY_END
STEP 6 CHECK_ANSWER
ENTRY_BEGIN
MATCH all
REPLY QR RD RA NOERROR
SECTION QUESTION
b. IN A
SECTION ANSWER
ENTRY_END
STEP 7 QUERY
ENTRY_BEGIN
REPLY RD
SECTION QUESTION
b. IN AAAA
ENTRY_END
STEP 8 CHECK_ANSWER
ENTRY_BEGIN
MATCH all
REPLY QR RD RA NOERROR
SECTION QUESTION
b. IN AAAA
SECTION ANSWER
ENTRY_END
STEP 9 QUERY
ENTRY_BEGIN
REPLY RD
SECTION QUESTION
c. IN A
ENTRY_END
STEP 10 CHECK_ANSWER
ENTRY_BEGIN
MATCH all
REPLY QR RD RA NOERROR
SECTION QUESTION
c. IN A
SECTION ANSWER
ENTRY_END
STEP 11 QUERY
ENTRY_BEGIN
REPLY RD
SECTION QUESTION
c. IN AAAA
ENTRY_END
STEP 12 CHECK_ANSWER
ENTRY_BEGIN
MATCH all
REPLY QR RD RA NOERROR
SECTION QUESTION
c. IN AAAA
SECTION ANSWER
ENTRY_END
STEP 13 QUERY
ENTRY_BEGIN
REPLY RD
SECTION QUESTION
d. IN A
ENTRY_END
STEP 14 CHECK_ANSWER
ENTRY_BEGIN
MATCH all
REPLY QR RD RA NXDOMAIN
SECTION QUESTION
d. IN A
SECTION ANSWER
ENTRY_END
STEP 15 QUERY
ENTRY_BEGIN
REPLY RD
SECTION QUESTION
d. IN AAAA
ENTRY_END
STEP 16 CHECK_ANSWER
ENTRY_BEGIN
MATCH all
REPLY QR RD RA NXDOMAIN
SECTION QUESTION
d. IN AAAA
SECTION ANSWER
ENTRY_END
STEP 17 QUERY
ENTRY_BEGIN
REPLY RD
SECTION QUESTION
f. IN A
ENTRY_END
STEP 18 CHECK_ANSWER
ENTRY_BEGIN
MATCH all
REPLY QR RD RA NOERROR
SECTION QUESTION
f. IN A
SECTION ANSWER
f. IN A 10.10.10.10
ENTRY_END
STEP 19 QUERY
ENTRY_BEGIN
REPLY RD
SECTION QUESTION
f. IN AAAA
ENTRY_END
STEP 20 CHECK_ANSWER
ENTRY_BEGIN
MATCH all
REPLY QR RD RA NOERROR
SECTION QUESTION
f. IN AAAA
SECTION ANSWER
f. IN AAAA 2001:db8:aa:bb:cc::1
ENTRY_END
STEP 21 QUERY
ENTRY_BEGIN
REPLY RD
SECTION QUESTION
g. IN A
ENTRY_END
STEP 22 CHECK_ANSWER
ENTRY_BEGIN
MATCH all
REPLY QR RD RA NOERROR
SECTION QUESTION
g. IN A
SECTION ANSWER
g. IN A 203.0.113.123
ENTRY_END
STEP 23 QUERY
ENTRY_BEGIN
REPLY RD
SECTION QUESTION
g. IN AAAA
ENTRY_END
STEP 24 CHECK_ANSWER
ENTRY_BEGIN
MATCH all
REPLY QR RD RA NOERROR
SECTION QUESTION
g. IN AAAA
SECTION ANSWER
g. IN AAAA 2001:db8::123
ENTRY_END
; should be dropped
STEP 25 QUERY
ENTRY_BEGIN
REPLY RD
SECTION QUESTION
e. IN A
ENTRY_END
STEP 26 QUERY
ENTRY_BEGIN
REPLY RD
SECTION QUESTION
e. IN AAAA
ENTRY_END
STEP 27 TIME_PASSES ELAPSE 12
SCENARIO_END

265
testdata/rpz_respip_override.rpl vendored Normal file
View file

@ -0,0 +1,265 @@
; config options
server:
module-config: "respip validator iterator"
target-fetch-policy: "0 0 0 0 0"
qname-minimisation: no
rpz:
name: "rpz.example.com."
rpz-action-override: disabled
zonefile:
TEMPFILE_NAME rpz.example.com
TEMPFILE_CONTENTS rpz.example.com
$ORIGIN rpz.example.com.
32.1.113.0.203.rpz-ip A 192.0.2.1
TEMPFILE_END
rpz:
name: "rpz2.example.com."
zonefile:
TEMPFILE_NAME rpz2.example.com
TEMPFILE_CONTENTS rpz2.example.com
$ORIGIN rpz2.example.com.
32.1.113.0.203.rpz-ip A 192.0.2.2
TEMPFILE_END
rpz:
name: "rpz3.example.com."
rpz-action-override: nodata
zonefile:
TEMPFILE_NAME rpz3.example.com
TEMPFILE_CONTENTS rpz3.example.com
$ORIGIN rpz3.example.com.
32.3.113.0.203.rpz-ip CNAME .
TEMPFILE_END
rpz:
name: "rpz4.example.com."
rpz-action-override: nxdomain
zonefile:
TEMPFILE_NAME rpz4.example.com
TEMPFILE_CONTENTS rpz4.example.com
$ORIGIN rpz4.example.com.
32.4.113.0.203.rpz-ip CNAME *.
TEMPFILE_END
rpz:
name: "rpz5.example.com."
rpz-action-override: passthru
zonefile:
TEMPFILE_NAME rpz5.example.com
TEMPFILE_CONTENTS rpz5.example.com
$ORIGIN rpz5.example.com.
32.5.113.0.203.rpz-ip A 192.0.2.5
TEMPFILE_END
rpz:
name: "rpz6.example.com."
rpz-action-override: cname
rpz-cname-override: ns.
zonefile:
TEMPFILE_NAME rpz6.example.com
TEMPFILE_CONTENTS rpz6.example.com
$ORIGIN rpz6.example.com.
32.6.113.0.203.rpz-ip A 192.0.2.6
TEMPFILE_END
rpz:
name: "rpz7.example.com."
rpz-action-override: drop
zonefile:
TEMPFILE_NAME rpz7.example.com
TEMPFILE_CONTENTS rpz7.example.com
$ORIGIN rpz7.example.com.
32.7.113.0.203.rpz-ip A 192.0.2.7
TEMPFILE_END
stub-zone:
name: "."
stub-addr: 10.20.30.40
CONFIG_END
SCENARIO_BEGIN Test all supported RPZ action for response IP address trigger
; c.
RANGE_BEGIN 0 100
ADDRESS 10.20.30.40
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
. IN NS
SECTION ANSWER
. IN NS ns.
SECTION ADDITIONAL
ns. IN A 10.20.30.40
ENTRY_END
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
ns. IN A
SECTION ANSWER
ns. IN A 10.20.30.40
ENTRY_END
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
a. IN A
SECTION ANSWER
a. IN A 203.0.113.1
ENTRY_END
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
b. IN A
SECTION ANSWER
b. IN A 203.0.113.3
ENTRY_END
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
c. IN A
SECTION ANSWER
c. IN A 203.0.113.4
ENTRY_END
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
d. IN A
SECTION ANSWER
d. IN A 203.0.113.5
ENTRY_END
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
e. IN A
SECTION ANSWER
e. IN A 203.0.113.6
ENTRY_END
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
f. IN A
SECTION ANSWER
f. IN A 203.0.113.7
ENTRY_END
RANGE_END
STEP 1 QUERY
ENTRY_BEGIN
REPLY RD
SECTION QUESTION
a. IN A
ENTRY_END
STEP 2 CHECK_ANSWER
ENTRY_BEGIN
MATCH all
REPLY QR RD RA NOERROR
SECTION QUESTION
a. IN A
SECTION ANSWER
a. IN A 192.0.2.2
ENTRY_END
STEP 3 QUERY
ENTRY_BEGIN
REPLY RD
SECTION QUESTION
b. IN A
ENTRY_END
STEP 4 CHECK_ANSWER
ENTRY_BEGIN
MATCH all
REPLY QR RD RA NOERROR
SECTION QUESTION
b. IN A
SECTION ANSWER
ENTRY_END
STEP 5 QUERY
ENTRY_BEGIN
REPLY RD
SECTION QUESTION
c. IN A
ENTRY_END
STEP 6 CHECK_ANSWER
ENTRY_BEGIN
MATCH all
REPLY QR RD RA NXDOMAIN
SECTION QUESTION
c. IN A
SECTION ANSWER
ENTRY_END
STEP 7 QUERY
ENTRY_BEGIN
REPLY RD
SECTION QUESTION
d. IN A
ENTRY_END
STEP 8 CHECK_ANSWER
ENTRY_BEGIN
MATCH all
REPLY QR RD RA NOERROR
SECTION QUESTION
d. IN A
SECTION ANSWER
d. IN A 203.0.113.5
ENTRY_END
STEP 9 QUERY
ENTRY_BEGIN
REPLY RD
SECTION QUESTION
e. IN A
ENTRY_END
STEP 10 CHECK_ANSWER
ENTRY_BEGIN
MATCH all
REPLY QR RD RA NOERROR
SECTION QUESTION
e. IN A
SECTION ANSWER
e. IN CNAME ns.
ns. IN A 10.20.30.40
ENTRY_END
STEP 11 QUERY
ENTRY_BEGIN
REPLY RD
SECTION QUESTION
f. IN A
ENTRY_END
; no answer is checked at exit of testbound.
STEP 12 TIME_PASSES ELAPSE 10
SCENARIO_END

View file

@ -1279,6 +1279,10 @@ config_delauth(struct config_auth* p)
config_delstrlist(p->urls); config_delstrlist(p->urls);
config_delstrlist(p->allow_notify); config_delstrlist(p->allow_notify);
free(p->zonefile); free(p->zonefile);
free(p->rpz_taglist);
free(p->rpz_action_override);
free(p->rpz_cname);
free(p->rpz_log_name);
free(p); free(p);
} }
@ -1942,7 +1946,7 @@ char* config_taglist2str(struct config_file* cfg, uint8_t* taglist,
return strdup(buf); return strdup(buf);
} }
int taglist_intersect(uint8_t* list1, size_t list1len, uint8_t* list2, int taglist_intersect(uint8_t* list1, size_t list1len, const uint8_t* list2,
size_t list2len) size_t list2len)
{ {
size_t i; size_t i;

View file

@ -641,6 +641,21 @@ struct config_auth {
/** fallback to recursion to authorities if zone expired and other /** fallback to recursion to authorities if zone expired and other
* reasons perhaps (like, query bogus) */ * reasons perhaps (like, query bogus) */
int fallback_enabled; int fallback_enabled;
/** this zone is used to create local-zone policies */
int isrpz;
/** rpz tags (or NULL) */
uint8_t* rpz_taglist;
/** length of the taglist (in bytes) */
size_t rpz_taglistlen;
/** Override RPZ action for this zone, regardless of zone content */
char* rpz_action_override;
/** Log when this RPZ policy is applied */
int rpz_log;
/** Display this name in the log when RPZ policy is applied */
char* rpz_log_name;
/** Always reply with this CNAME target if the cname override action is
* used */
char* rpz_cname;
}; };
/** /**
@ -1043,7 +1058,7 @@ char* config_taglist2str(struct config_file* cfg, uint8_t* taglist,
* @param list2len: length in bytes of second list. * @param list2len: length in bytes of second list.
* @return true if there are tags in common, 0 if not. * @return true if there are tags in common, 0 if not.
*/ */
int taglist_intersect(uint8_t* list1, size_t list1len, uint8_t* list2, int taglist_intersect(uint8_t* list1, size_t list1len, const uint8_t* list2,
size_t list2len); size_t list2len);
/** /**

File diff suppressed because it is too large Load diff

View file

@ -317,6 +317,12 @@ forward-no-cache{COLON} { YDVAR(1, VAR_FORWARD_NO_CACHE) }
forward-ssl-upstream{COLON} { YDVAR(1, VAR_FORWARD_SSL_UPSTREAM) } forward-ssl-upstream{COLON} { YDVAR(1, VAR_FORWARD_SSL_UPSTREAM) }
forward-tls-upstream{COLON} { YDVAR(1, VAR_FORWARD_SSL_UPSTREAM) } forward-tls-upstream{COLON} { YDVAR(1, VAR_FORWARD_SSL_UPSTREAM) }
auth-zone{COLON} { YDVAR(0, VAR_AUTH_ZONE) } auth-zone{COLON} { YDVAR(0, VAR_AUTH_ZONE) }
rpz{COLON} { YDVAR(0, VAR_RPZ) }
tags{COLON} { YDVAR(1, VAR_TAGS) }
rpz-action-override{COLON} { YDVAR(1, VAR_RPZ_ACTION_OVERRIDE) }
rpz-cname-override{COLON} { YDVAR(1, VAR_RPZ_CNAME_OVERRIDE) }
rpz-log{COLON} { YDVAR(1, VAR_RPZ_LOG) }
rpz-log-name{COLON} { YDVAR(1, VAR_RPZ_LOG_NAME) }
zonefile{COLON} { YDVAR(1, VAR_ZONEFILE) } zonefile{COLON} { YDVAR(1, VAR_ZONEFILE) }
master{COLON} { YDVAR(1, VAR_MASTER) } master{COLON} { YDVAR(1, VAR_MASTER) }
url{COLON} { YDVAR(1, VAR_URL) } url{COLON} { YDVAR(1, VAR_URL) }

File diff suppressed because it is too large Load diff

View file

@ -1,8 +1,8 @@
/* A Bison parser, made by GNU Bison 3.0.5. */ /* A Bison parser, made by GNU Bison 3.0.4. */
/* Bison interface for Yacc-like parsers in C /* Bison interface for Yacc-like parsers in C
Copyright (C) 1984, 1989-1990, 2000-2015, 2018 Free Software Foundation, Inc. Copyright (C) 1984, 1989-1990, 2000-2015 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
@ -308,10 +308,16 @@ extern int yydebug;
VAR_STREAM_WAIT_SIZE = 518, VAR_STREAM_WAIT_SIZE = 518,
VAR_TLS_CIPHERS = 519, VAR_TLS_CIPHERS = 519,
VAR_TLS_CIPHERSUITES = 520, VAR_TLS_CIPHERSUITES = 520,
VAR_TLS_SESSION_TICKET_KEYS = 521, VAR_IPSET = 521,
VAR_IPSET = 522, VAR_IPSET_NAME_V4 = 522,
VAR_IPSET_NAME_V4 = 523, VAR_IPSET_NAME_V6 = 523,
VAR_IPSET_NAME_V6 = 524 VAR_TLS_SESSION_TICKET_KEYS = 524,
VAR_RPZ = 525,
VAR_TAGS = 526,
VAR_RPZ_ACTION_OVERRIDE = 527,
VAR_RPZ_CNAME_OVERRIDE = 528,
VAR_RPZ_LOG = 529,
VAR_RPZ_LOG_NAME = 530
}; };
#endif #endif
/* Tokens. */ /* Tokens. */
@ -578,21 +584,27 @@ extern int yydebug;
#define VAR_STREAM_WAIT_SIZE 518 #define VAR_STREAM_WAIT_SIZE 518
#define VAR_TLS_CIPHERS 519 #define VAR_TLS_CIPHERS 519
#define VAR_TLS_CIPHERSUITES 520 #define VAR_TLS_CIPHERSUITES 520
#define VAR_TLS_SESSION_TICKET_KEYS 521 #define VAR_IPSET 521
#define VAR_IPSET 522 #define VAR_IPSET_NAME_V4 522
#define VAR_IPSET_NAME_V4 523 #define VAR_IPSET_NAME_V6 523
#define VAR_IPSET_NAME_V6 524 #define VAR_TLS_SESSION_TICKET_KEYS 524
#define VAR_RPZ 525
#define VAR_TAGS 526
#define VAR_RPZ_ACTION_OVERRIDE 527
#define VAR_RPZ_CNAME_OVERRIDE 528
#define VAR_RPZ_LOG 529
#define VAR_RPZ_LOG_NAME 530
/* Value type. */ /* Value type. */
#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
union YYSTYPE union YYSTYPE
{ {
#line 66 "./util/configparser.y" /* yacc.c:1910 */ #line 66 "./util/configparser.y" /* yacc.c:1909 */
char* str; char* str;
#line 596 "util/configparser.h" /* yacc.c:1910 */ #line 608 "util/configparser.h" /* yacc.c:1909 */
}; };
typedef union YYSTYPE YYSTYPE; typedef union YYSTYPE YYSTYPE;

View file

@ -166,8 +166,9 @@ extern struct config_parser_state* cfg_parser;
%token VAR_FORWARD_NO_CACHE VAR_STUB_NO_CACHE VAR_LOG_SERVFAIL VAR_DENY_ANY %token VAR_FORWARD_NO_CACHE VAR_STUB_NO_CACHE VAR_LOG_SERVFAIL VAR_DENY_ANY
%token VAR_UNKNOWN_SERVER_TIME_LIMIT VAR_LOG_TAG_QUERYREPLY %token VAR_UNKNOWN_SERVER_TIME_LIMIT VAR_LOG_TAG_QUERYREPLY
%token VAR_STREAM_WAIT_SIZE VAR_TLS_CIPHERS VAR_TLS_CIPHERSUITES %token VAR_STREAM_WAIT_SIZE VAR_TLS_CIPHERS VAR_TLS_CIPHERSUITES
%token VAR_TLS_SESSION_TICKET_KEYS
%token VAR_IPSET VAR_IPSET_NAME_V4 VAR_IPSET_NAME_V6 %token VAR_IPSET VAR_IPSET_NAME_V4 VAR_IPSET_NAME_V6
%token VAR_TLS_SESSION_TICKET_KEYS VAR_RPZ VAR_TAGS VAR_RPZ_ACTION_OVERRIDE
%token VAR_RPZ_CNAME_OVERRIDE VAR_RPZ_LOG VAR_RPZ_LOG_NAME
%% %%
toplevelvars: /* empty */ | toplevelvars toplevelvar ; toplevelvars: /* empty */ | toplevelvars toplevelvar ;
@ -175,7 +176,8 @@ toplevelvar: serverstart contents_server | stubstart contents_stub |
forwardstart contents_forward | pythonstart contents_py | forwardstart contents_forward | pythonstart contents_py |
rcstart contents_rc | dtstart contents_dt | viewstart contents_view | rcstart contents_rc | dtstart contents_dt | viewstart contents_view |
dnscstart contents_dnsc | cachedbstart contents_cachedb | dnscstart contents_dnsc | cachedbstart contents_cachedb |
ipsetstart contents_ipset | authstart contents_auth ipsetstart contents_ipset | authstart contents_auth |
rpzstart contents_rpz
; ;
/* server: declaration */ /* server: declaration */
@ -335,6 +337,7 @@ authstart: VAR_AUTH_ZONE
s->for_downstream = 1; s->for_downstream = 1;
s->for_upstream = 1; s->for_upstream = 1;
s->fallback_enabled = 0; s->fallback_enabled = 0;
s->isrpz = 0;
} else } else
yyerror("out of memory"); yyerror("out of memory");
} }
@ -345,6 +348,93 @@ content_auth: auth_name | auth_zonefile | auth_master | auth_url |
auth_for_downstream | auth_for_upstream | auth_fallback_enabled | auth_for_downstream | auth_for_upstream | auth_fallback_enabled |
auth_allow_notify auth_allow_notify
; ;
rpz_tag: VAR_TAGS STRING_ARG
{
size_t len;
uint8_t* bitlist;
OUTYY(("P(server_local_zone_tag:%s)\n", $2));
len = 0;
bitlist = config_parse_taglist(cfg_parser->cfg, $2,
&len);
free($2);
if(!bitlist) {
yyerror("could not parse tags, (define-tag them first)");
}
if(bitlist) {
cfg_parser->cfg->auths->rpz_taglist = bitlist;
cfg_parser->cfg->auths->rpz_taglistlen = len;
}
}
;
rpz_action_override: VAR_RPZ_ACTION_OVERRIDE STRING_ARG
{
OUTYY(("P(rpz_action_override:%s)\n", $2));
if(strcmp($2, "nxdomain")!=0 && strcmp($2, "nodata")!=0 &&
strcmp($2, "passthru")!=0 && strcmp($2, "drop")!=0 &&
strcmp($2, "cname")!=0 && strcmp($2, "disabled")!=0) {
yyerror("rpz-action-override action: expected nxdomain, "
"nodata, passthru, drop cname or disabled");
free($2);
cfg_parser->cfg->auths->rpz_action_override = NULL;
}
else {
cfg_parser->cfg->auths->rpz_action_override = $2;
}
}
;
rpz_cname_override: VAR_RPZ_CNAME_OVERRIDE STRING_ARG
{
OUTYY(("P(rpz_cname_override:%s)\n", $2));
free(cfg_parser->cfg->auths->rpz_cname);
cfg_parser->cfg->auths->rpz_cname = $2;
}
;
rpz_log: VAR_RPZ_LOG STRING_ARG
{
OUTYY(("P(rpz_log:%s)\n", $2));
if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
yyerror("expected yes or no.");
else cfg_parser->cfg->auths->rpz_log = (strcmp($2, "yes")==0);
free($2);
}
;
rpz_log_name: VAR_RPZ_LOG_NAME STRING_ARG
{
OUTYY(("P(rpz_log_name:%s)\n", $2));
free(cfg_parser->cfg->auths->rpz_log_name);
cfg_parser->cfg->auths->rpz_log_name = $2;
}
;
rpzstart: VAR_RPZ
{
struct config_auth* s;
OUTYY(("\nP(rpz:)\n"));
s = (struct config_auth*)calloc(1, sizeof(struct config_auth));
if(s) {
s->next = cfg_parser->cfg->auths;
cfg_parser->cfg->auths = s;
/* defaults for RPZ auth zone */
s->for_downstream = 0;
s->for_upstream = 0;
s->fallback_enabled = 0;
s->isrpz = 1;
} else
yyerror("out of memory");
}
;
contents_rpz: contents_rpz content_rpz
| ;
content_rpz: auth_name | auth_zonefile | rpz_tag | auth_master | auth_url |
auth_allow_notify | rpz_action_override | rpz_cname_override |
rpz_log | rpz_log_name
;
server_num_threads: VAR_NUM_THREADS STRING_ARG server_num_threads: VAR_NUM_THREADS STRING_ARG
{ {
OUTYY(("P(server_num_threads:%s)\n", $2)); OUTYY(("P(server_num_threads:%s)\n", $2));

View file

@ -546,6 +546,19 @@ dname_lab_startswith(uint8_t* label, char* prefix, char** endptr)
return 1; return 1;
} }
int
dname_has_label(uint8_t* dname, uint8_t* label)
{
uint8_t lablen = *dname++;
while(lablen) {
if(*label == lablen && memcmp(dname, label+1, lablen) == 0)
return 1;
dname += lablen;
lablen = *dname++;
}
return 0;
}
int int
dname_buffer_write(sldns_buffer* pkt, uint8_t* dname) dname_buffer_write(sldns_buffer* pkt, uint8_t* dname)
{ {
@ -584,7 +597,7 @@ void dname_str(uint8_t* dname, char* str)
return; return;
} }
len += lablen+1; len += lablen+1;
if(len >= LDNS_MAX_DOMAINLEN-1) { if(len >= LDNS_MAX_DOMAINLEN) {
*s++ = '&'; *s++ = '&';
*s = 0; *s = 0;
return; return;

View file

@ -196,6 +196,14 @@ int dname_lab_cmp(uint8_t* d1, int labs1, uint8_t* d2, int labs2, int* mlabs);
*/ */
int dname_lab_startswith(uint8_t* label, char* prefix, char** endptr); int dname_lab_startswith(uint8_t* label, char* prefix, char** endptr);
/**
* Check if dname contains label
* @param dname: dname
* @param label: label to be checked for presence in dname
* @return: 1 if dname has this label, 0 otherwise
*/
int dname_has_label(uint8_t* dname, uint8_t* label);
/** /**
* See if domain name d1 is a strict subdomain of d2. * See if domain name d1 is a strict subdomain of d2.
* That is a subdomain, but not equal. * That is a subdomain, but not equal.

View file

@ -386,3 +386,83 @@ packed_rrset_copy_alloc(struct ub_packed_rrset_key* key,
packed_rrset_ttl_add(dd, now); packed_rrset_ttl_add(dd, now);
return dk; return dk;
} }
int
packed_rrset_find_rr(struct packed_rrset_data* d, uint8_t* rdata, size_t len,
size_t* index)
{
size_t i;
for(i=0; i<d->count; i++) {
if(d->rr_len[i] != len)
continue;
if(memcmp(d->rr_data[i], rdata, len) == 0) {
*index = i;
return 1;
}
}
return 0;
}
struct packed_rrset_data*
packed_rrset_remove_rr(struct packed_rrset_data* old, size_t index,
struct regional* region)
{
struct packed_rrset_data* d;
size_t i;
if(index >= old->count + old->rrsig_count)
return NULL; /* index out of bounds */
if(region)
d = (struct packed_rrset_data*)regional_alloc(region,
packed_rrset_sizeof(old) - ( sizeof(size_t) +
sizeof(uint8_t*) + sizeof(time_t) + old->rr_len[index]));
else
d = (struct packed_rrset_data*)calloc(1,
packed_rrset_sizeof(old) - ( sizeof(size_t) +
sizeof(uint8_t*) + sizeof(time_t) + old->rr_len[index]));
if(!d) {
log_err("malloc failure");
return NULL;
}
d->ttl = old->ttl;
d->count = old->count;
d->rrsig_count = old->rrsig_count;
if(index < d->count) d->count--;
else d->rrsig_count--;
d->trust = old->trust;
d->security = old->security;
/* set rr_len, needed for ptr_fixup */
d->rr_len = (size_t*)((uint8_t*)d +
sizeof(struct packed_rrset_data));
if(index > 0)
memmove(d->rr_len, old->rr_len, (index)*sizeof(size_t));
if(index+1 < old->count+old->rrsig_count)
memmove(&d->rr_len[index], &old->rr_len[index+1],
(old->count+old->rrsig_count - (index+1))*sizeof(size_t));
packed_rrset_ptr_fixup(d);
/* move over ttls */
if(index > 0)
memmove(d->rr_ttl, old->rr_ttl, (index)*sizeof(time_t));
if(index+1 < old->count+old->rrsig_count)
memmove(&d->rr_ttl[index], &old->rr_ttl[index+1],
(old->count+old->rrsig_count - (index+1))*sizeof(time_t));
/* move over rr_data */
for(i=0; i<d->count+d->rrsig_count; i++) {
size_t oldi;
if(i < index) oldi = i;
else oldi = i+1;
memmove(d->rr_data[i], old->rr_data[oldi], d->rr_len[i]);
}
/* recalc ttl (lowest of remaining RR ttls) */
if(d->count + d->rrsig_count > 0)
d->ttl = d->rr_ttl[0];
for(i=0; i<d->count+d->rrsig_count; i++) {
if(d->rr_ttl[i] < d->ttl)
d->ttl = d->rr_ttl[i];
}
return d;
}

View file

@ -446,4 +446,28 @@ struct ub_packed_rrset_key* packed_rrset_copy_alloc(
struct ub_packed_rrset_key* key, struct alloc_cache* alloc, struct ub_packed_rrset_key* key, struct alloc_cache* alloc,
time_t now); time_t now);
/**
* Find RR index in packed rrset
* @param d: packed rrset
* @param rdata: RDATA of RR to find
* @param len: length of rdata
* @param index: pointer to int to store index of found RR
* @return 1 if RR found, 0 otherwise
*/
int
packed_rrset_find_rr(struct packed_rrset_data* d, uint8_t* rdata, size_t len,
size_t* index);
/**
* Remove RR from packed rrset
* @param old: packed rrset containing RR to remove
* @param index: index of RR to remove
* @param region: region to use for allocation of new packet RR. Malloc used if
* NULL
* @return pointer to newly allocated packed rrset
*/
struct packed_rrset_data*
packed_rrset_remove_rr(struct packed_rrset_data* old, size_t index,
struct regional* region);
#endif /* UTIL_DATA_PACKED_RRSET_H */ #endif /* UTIL_DATA_PACKED_RRSET_H */

View file

@ -284,6 +284,92 @@ int netblockstrtoaddr(const char* str, int port, struct sockaddr_storage* addr,
return 1; return 1;
} }
/* RPZ format address dname to network byte order address */
static int ipdnametoaddr(uint8_t* dname, struct sockaddr_storage* addr,
socklen_t* addrlen, int* af)
{
uint8_t* ia;
size_t dnamelabs = dname_count_labels(dname);
uint8_t lablen;
char* e = NULL;
int z = 0;
int i;
*af = AF_INET;
if(dnamelabs > 6 || dname_has_label(dname, (uint8_t*)"\002zz")) {
*af = AF_INET6;
}
lablen = *dname++;
i = (*af == AF_INET) ? 3 : 15;
if(*af == AF_INET6) {
struct sockaddr_in6* sa = (struct sockaddr_in6*)addr;
*addrlen = (socklen_t)sizeof(struct sockaddr_in6);
memset(sa, 0, *addrlen);
sa->sin6_family = AF_INET6;
ia = (uint8_t*)&sa->sin6_addr;
} else { /* ip4 */
struct sockaddr_in* sa = (struct sockaddr_in*)addr;
*addrlen = (socklen_t)sizeof(struct sockaddr_in);
memset(sa, 0, *addrlen);
sa->sin_family = AF_INET;
ia = (uint8_t*)&sa->sin_addr;
}
while(lablen && i >= 0) {
char buff[lablen+1];
uint16_t chunk; /* big enough to not overflow on IPv6 hextet */
if((*af == AF_INET && (lablen > 3 || dnamelabs > 6)) ||
(*af == AF_INET6 && (lablen > 4 || dnamelabs > 10))) {
return 0;
}
if(memcmp(dname, "zz", 2) == 0 && *af == AF_INET6) {
/* add one or more 0 labels */
int zl = 11 - dnamelabs;
if(z || zl < 0)
return 0;
z = 1;
i -= (zl*2);
memset(ia+(i+1), 0, zl*2);
} else {
memcpy(buff, dname, lablen);
buff[lablen] = '\0';
chunk = strtol(buff, &e, (*af == AF_INET) ? 10 : 16);
if(!e || *e != '\0' || (*af == AF_INET && chunk > 255))
return 0;
if(*af == AF_INET) {
ia[i] = (uint8_t)chunk;
i--;
} else {
/* ia in network byte order */
ia[i-1] = (uint8_t)(chunk >> 8);
ia[i] = (uint8_t)(chunk & 0x00FF);
i -= 2;
}
}
dname += lablen;
lablen = *dname++;
}
if(i != -1)
/* input too short */
return 0;
return 1;
}
int netblockdnametoaddr(uint8_t* dname, struct sockaddr_storage* addr,
socklen_t* addrlen, int* net, int* af)
{
char buff[3 /* 3 digit netblock */ + 1];
if(*dname > 3)
/* netblock invalid */
return 0;
memcpy(buff, dname+1, *dname);
buff[*dname] = '\0';
*net = atoi(buff);
dname += *dname;
dname++;
if(!ipdnametoaddr(dname, addr, addrlen, af))
return 0;
return 1;
}
int authextstrtoaddr(char* str, struct sockaddr_storage* addr, int authextstrtoaddr(char* str, struct sockaddr_storage* addr,
socklen_t* addrlen, char** auth_name) socklen_t* addrlen, char** auth_name)
{ {

View file

@ -464,4 +464,15 @@ int tls_session_ticket_key_cb(void *s, unsigned char* key_name,unsigned char* iv
/** Free memory used for TLS session ticket keys */ /** Free memory used for TLS session ticket keys */
void listen_sslctx_delete_ticket_keys(void); void listen_sslctx_delete_ticket_keys(void);
/**
* RPZ format netblock to network byte order address and netblock
* @param dname: the dname containing RPZ format netblock
* @param addr: where to store sockaddr.
* @param addrlen: length of stored sockaddr is returned.
* @param net: where to store netmask
* @param af: where to store address family.
* @return 0 on error.
*/
int netblockdnametoaddr(uint8_t* dname, struct sockaddr_storage* addr,
socklen_t* addrlen, int* net, int* af);
#endif /* NET_HELP_H */ #endif /* NET_HELP_H */

View file

@ -104,11 +104,12 @@ int addr_tree_insert(rbtree_type* tree, struct addr_tree_node* node,
return rbtree_insert(tree, &node->node) != NULL; return rbtree_insert(tree, &node->node) != NULL;
} }
void addr_tree_init_parents(rbtree_type* tree) void addr_tree_init_parents_node(struct addr_tree_node* node)
{ {
struct addr_tree_node* node, *prev = NULL, *p; struct addr_tree_node* prev = NULL, *p;
int m; int m;
RBTREE_FOR(node, struct addr_tree_node*, tree) { for(; (rbnode_type*)node != RBTREE_NULL;
node = (struct addr_tree_node*)rbtree_next((rbnode_type*)node)) {
node->parent = NULL; node->parent = NULL;
if(!prev || prev->addrlen != node->addrlen) { if(!prev || prev->addrlen != node->addrlen) {
prev = node; prev = node;
@ -130,6 +131,12 @@ void addr_tree_init_parents(rbtree_type* tree)
} }
} }
void addr_tree_init_parents(rbtree_type* tree)
{
addr_tree_init_parents_node(
(struct addr_tree_node*)rbtree_first(tree));
}
void name_tree_init_parents(rbtree_type* tree) void name_tree_init_parents(rbtree_type* tree)
{ {
struct name_tree_node* node, *prev = NULL, *p; struct name_tree_node* node, *prev = NULL, *p;

View file

@ -173,6 +173,13 @@ int addr_tree_insert(rbtree_type* tree, struct addr_tree_node* node,
*/ */
void addr_tree_init_parents(rbtree_type* tree); void addr_tree_init_parents(rbtree_type* tree);
/**
* Initialize parent pointers in partial addr tree.
* Reinitialize pointer for part of tree, used after node deletion
* @param node: node to start parent pointer initialization for.
*/
void addr_tree_init_parents_node(struct addr_tree_node* node);
/** /**
* Lookup closest encloser in addr tree. * Lookup closest encloser in addr tree.
* @param tree: addr tree * @param tree: addr tree