mirror of
https://github.com/NLnetLabs/unbound.git
synced 2026-08-17 21:25:50 +02:00
Compare commits
329
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2f99afc6a1 | ||
|
|
885069e1f6 | ||
|
|
077b38e2c5 | ||
|
|
9be04e6fac | ||
|
|
377d5b426a | ||
|
|
f82a128909 | ||
|
|
216759e955 | ||
|
|
9b6caf5a5b | ||
|
|
5c25bbd93f | ||
|
|
d8937492cb | ||
|
|
e91d85edb5 | ||
|
|
5089db7331 | ||
|
|
8e20d628e8 | ||
|
|
d275505df6 | ||
|
|
f7516e6b2b | ||
|
|
898d4c8dd9 | ||
|
|
2e9d09b961 | ||
|
|
8dd6efe5ed | ||
|
|
635df9c806 | ||
|
|
75b8b8c875 | ||
|
|
90f0530234 | ||
|
|
d744827f93 | ||
|
|
fe8b22caa1 | ||
|
|
9a82526b91 | ||
|
|
225a6d9c6e | ||
|
|
87c8dd5434 | ||
|
|
a09c4bbdc2 | ||
|
|
d01651c305 | ||
|
|
00982fc3db | ||
|
|
d8f890a43a | ||
|
|
a58681a718 | ||
|
|
c9d33fb9f7 | ||
|
|
254df71810 | ||
|
|
194dc32059 | ||
|
|
987c1c97e5 | ||
|
|
25c8497ba6 | ||
|
|
5577e55400 | ||
|
|
27472f1270 | ||
|
|
30a14c2716 | ||
|
|
d4a69e4d2a | ||
|
|
000e75581b | ||
|
|
2e5e31e8ac | ||
|
|
ae2653fcc5 | ||
|
|
f7118f29b9 | ||
|
|
57a5e75840 | ||
|
|
8d14e7c0a4 | ||
|
|
e0745813f4 | ||
|
|
0171d06aa2 | ||
|
|
4daf8f5bdb | ||
|
|
8893735a2d | ||
|
|
00ba747be7 | ||
|
|
504ef71975 | ||
|
|
9926fcac4b | ||
|
|
01d8dc2240 | ||
|
|
4fe427ded2 | ||
|
|
b0ca964984 | ||
|
|
e8c4f20f66 | ||
|
|
b0daf867c2 | ||
|
|
8385c462ed | ||
|
|
afd4063f20 | ||
|
|
ed24498f2e | ||
|
|
f2b12c0761 | ||
|
|
df85836b15 | ||
|
|
3f2b6828e5 | ||
|
|
1958d9fbd5 | ||
|
|
0c04b5eaf5 | ||
|
|
8e5a32f4dc | ||
|
|
efe5c8e6be | ||
|
|
1e61604aab | ||
|
|
488eaf09ce | ||
|
|
8b1012613e | ||
|
|
256ab3d935 | ||
|
|
a07337fd6d | ||
|
|
be79ffa371 | ||
|
|
c580e0e33c | ||
|
|
d2f7999b4e | ||
|
|
611e37aa2d | ||
|
|
3f2d186694 | ||
|
|
73f01304f0 | ||
|
|
77bd7d228b | ||
|
|
b97b04a9db | ||
|
|
6e4583a528 | ||
|
|
586b811b87 | ||
|
|
070019c9be | ||
|
|
ce04bcb463 | ||
|
|
cf1bfbba5d | ||
|
|
a4fd088875 | ||
|
|
27023b3f21 | ||
|
|
b2a7933045 | ||
|
|
749d1b9ebc | ||
|
|
87bdb489f9 | ||
|
|
37e9f5591a | ||
|
|
d546e7766d | ||
|
|
62f69f9b40 | ||
|
|
168bc963d3 | ||
|
|
1f148e632f | ||
|
|
c887ae1022 | ||
|
|
375d3e7520 | ||
|
|
3b171545b6 | ||
|
|
aa5efa172d | ||
|
|
a2961e50fb | ||
|
|
adc498d29d | ||
|
|
1ff3e51ee1 | ||
|
|
f9c0f359a7 | ||
|
|
cc538f4f9f | ||
|
|
900cd200a2 | ||
|
|
45e73bcc8e | ||
|
|
26eaf2d1ee | ||
|
|
2f32ef7646 | ||
|
|
b7abbd1d72 | ||
|
|
f364edafd3 | ||
|
|
e3f08cb2a2 | ||
|
|
a92b00ef3c | ||
|
|
3dbdde7fed | ||
|
|
6da37e5ecd | ||
|
|
007123ee2c | ||
|
|
10c085f81d | ||
|
|
1d315e11cf | ||
|
|
c91b657a40 | ||
|
|
60f59271d6 | ||
|
|
40abe08ac8 | ||
|
|
ae1790b8e8 | ||
|
|
aa5fb8b10b | ||
|
|
6de329359c | ||
|
|
2e34a8f643 | ||
|
|
bded93f69b | ||
|
|
38e77d50f2 | ||
|
|
f8e585f308 | ||
|
|
5bda4f9822 | ||
|
|
d2d7b987fa | ||
|
|
7579216922 | ||
|
|
330c6e1cb0 | ||
|
|
41e5a66b73 | ||
|
|
cc5ab744c5 | ||
|
|
0ae750e552 | ||
|
|
cabc120f22 | ||
|
|
c96c2d8a45 | ||
|
|
8aa53f027d | ||
|
|
4bf9d12419 | ||
|
|
f93746b1af | ||
|
|
23dc22b78d | ||
|
|
5e3c30beac | ||
|
|
86f16bef93 | ||
|
|
f2e90b0872 | ||
|
|
1249e0db3f | ||
|
|
15c4dd79f4 | ||
|
|
e324a7819a | ||
|
|
81e9f82a8d | ||
|
|
5d298ed474 | ||
|
|
82e1e3959f | ||
|
|
7181c0fa6a | ||
|
|
49f27c06af | ||
|
|
7247718e12 | ||
|
|
61acc76244 | ||
|
|
2faa4f9ee2 | ||
|
|
2beae211ee | ||
|
|
d3ff7a9333 | ||
|
|
23df700f15 | ||
|
|
755233c720 | ||
|
|
bca54a8b25 | ||
|
|
b5aab36d41 | ||
|
|
d7cfe91cb3 | ||
|
|
a31d45b13e | ||
|
|
23f475bccc | ||
|
|
025fdd0049 | ||
|
|
5bb6dbe21c | ||
|
|
c225ced1a9 | ||
|
|
3a58ad15e8 | ||
|
|
5106ad7a2c | ||
|
|
8c044a616b | ||
|
|
9ccf611954 | ||
|
|
5dfcf122d1 | ||
|
|
7b092127cb | ||
|
|
b26257248d | ||
|
|
3c7d270958 | ||
|
|
c15eae814f | ||
|
|
0e72e06886 | ||
|
|
abff4d1237 | ||
|
|
386f23334b | ||
|
|
a523683d4c | ||
|
|
b25332e1f4 | ||
|
|
a6ec2c6fc7 | ||
|
|
9cb404ba5f | ||
|
|
12251022ec | ||
|
|
00a0cabf7f | ||
|
|
d6ed0e868f | ||
|
|
700ad78f10 | ||
|
|
d65accbb23 | ||
|
|
78767f2014 | ||
|
|
21af42a281 | ||
|
|
0b0ece9db0 | ||
|
|
23edc18cac | ||
|
|
7153c94bd7 | ||
|
|
4df697b4b7 | ||
|
|
7fd32916e8 | ||
|
|
3f837bc440 | ||
|
|
f0769bed93 | ||
|
|
a1bfc07105 | ||
|
|
beba72d6db | ||
|
|
a4a5bfaa2f | ||
|
|
62ea384d19 | ||
|
|
53b1e11eba | ||
|
|
7fae96eb1e | ||
|
|
d386641820 | ||
|
|
7c5e38294a | ||
|
|
1cadc5d677 | ||
|
|
7509bf208e | ||
|
|
ec34bc9af1 | ||
|
|
8d1af17449 | ||
|
|
0db1573d34 | ||
|
|
b3c45a8edb | ||
|
|
1a0bd1a150 | ||
|
|
5a726fb61f | ||
|
|
6792d2d036 | ||
|
|
d32fb26adb | ||
|
|
d4ba7731ad | ||
|
|
b9607297e9 | ||
|
|
9ed59fdf34 | ||
|
|
8bcb44a019 | ||
|
|
6b28c8ace2 | ||
|
|
55088951c0 | ||
|
|
55a0d89f0d | ||
|
|
d532c9913c | ||
|
|
261bf354b7 | ||
|
|
50b6dc4b81 | ||
|
|
ba29a4a078 | ||
|
|
676644d8e8 | ||
|
|
f64a897cbc | ||
|
|
8b209f8f68 | ||
|
|
16b6619dfa | ||
|
|
a8c8fa6bc6 | ||
|
|
6d7e5df98f | ||
|
|
1d5d95c8cb | ||
|
|
8f886fc6dd | ||
|
|
581f975b38 | ||
|
|
d2c8bcf318 | ||
|
|
ef1ed6365c | ||
|
|
82418e2bf7 | ||
|
|
6fefbb4115 | ||
|
|
85bf0bd994 | ||
|
|
913d4537f4 | ||
|
|
4e2bafafef | ||
|
|
bffb7c52d5 | ||
|
|
38c4d3d09d | ||
|
|
2951f21dab | ||
|
|
d97a635084 | ||
|
|
2c9d9fe211 | ||
|
|
583411768d | ||
|
|
a55df65bc9 | ||
|
|
d6de848e29 | ||
|
|
649a98d855 | ||
|
|
127759b160 | ||
|
|
5b29f1b3ac | ||
|
|
755177fb4c | ||
|
|
ee9c42bee5 | ||
|
|
4d06c36342 | ||
|
|
1508d3708c | ||
|
|
ea6266f736 | ||
|
|
406a9d8350 | ||
|
|
2be0263dfa | ||
|
|
deea985a20 | ||
|
|
0d18256828 | ||
|
|
abe18e41bc | ||
|
|
716282cc1a | ||
|
|
f5a59fea5d | ||
|
|
2e70e3a0d3 | ||
|
|
7ff459af13 | ||
|
|
5bee11a6d3 | ||
|
|
0b21483b17 | ||
|
|
7444b3a8bf | ||
|
|
f39e39ed47 | ||
|
|
1989c52ca0 | ||
|
|
d8df0ddef8 | ||
|
|
7f6e3852b8 | ||
|
|
23656b2b0e | ||
|
|
c16a32d2be | ||
|
|
9d28279475 | ||
|
|
913de80cbc | ||
|
|
e4c8085408 | ||
|
|
1b055c6ca7 | ||
|
|
630600e70d | ||
|
|
4809fe1b95 | ||
|
|
2d6715878d | ||
|
|
4691979679 | ||
|
|
4e5af01354 | ||
|
|
b23b39bcfd | ||
|
|
4f974e3465 | ||
|
|
85994fb61c | ||
|
|
ad9784c5e8 | ||
|
|
c239c3f395 | ||
|
|
8d22d3c13d | ||
|
|
6ef9cafc0e | ||
|
|
471ed1befe | ||
|
|
e822adf725 | ||
|
|
d91f09896d | ||
|
|
d41cdb6ce8 | ||
|
|
fbee729c5b | ||
|
|
89ad258515 | ||
|
|
0e5abca6b7 | ||
|
|
9cd2f836bd | ||
|
|
1f9caf5805 | ||
|
|
c515215eea | ||
|
|
100cc496de | ||
|
|
0a06c5bfa2 | ||
|
|
6f4451b761 | ||
|
|
55b5227431 | ||
|
|
2be98b581a | ||
|
|
4e0128f16a | ||
|
|
3d1f9ae9d3 | ||
|
|
5fabe62e70 | ||
|
|
39f6488471 | ||
|
|
170c03f7db | ||
|
|
e5c14bfd16 | ||
|
|
4a0d32ec53 | ||
|
|
9f0d521b88 | ||
|
|
78031b37fc | ||
|
|
e1e629e592 | ||
|
|
554b8b35ae | ||
|
|
874165904f | ||
|
|
1d2d33d01a | ||
|
|
59935375a3 | ||
|
|
e784758a21 | ||
|
|
f7fe1a1093 | ||
|
|
3a287a70cd | ||
|
|
d111aaf64f | ||
|
|
cc617eadc9 | ||
|
|
54e15f5ace | ||
|
|
d1a76b55bc | ||
|
|
a48abc2f8b |
+124
-88
@@ -57,7 +57,7 @@ STRIP=@STRIP@
|
||||
CC=@CC@
|
||||
CPPFLAGS=-I. @CPPFLAGS@
|
||||
PYTHON_CPPFLAGS=-I. @PYTHON_CPPFLAGS@
|
||||
CFLAGS=@CFLAGS@
|
||||
CFLAGS=-DSRCDIR=$(srcdir) @CFLAGS@
|
||||
LDFLAGS=@LDFLAGS@
|
||||
LIBS=@LIBS@
|
||||
LIBOBJS=@LIBOBJS@
|
||||
@@ -83,7 +83,7 @@ LINTFLAGS+=@NETBSD_LINTFLAGS@
|
||||
# compat with OpenBSD
|
||||
LINTFLAGS+="-Dsigset_t=long"
|
||||
# FreeBSD
|
||||
LINTFLAGS+="-D__uint16_t=uint16_t" "-DEVP_PKEY_ASN1_METHOD=int" "-D_RuneLocale=int" "-D__va_list=va_list" "-D__uint32_t=uint32_t"
|
||||
LINTFLAGS+="-D__uint16_t=uint16_t" "-DEVP_PKEY_ASN1_METHOD=int" "-D_RuneLocale=int" "-D__va_list=va_list" "-D__uint32_t=uint32_t" "-D_Alignof(x)=x" "-D__aligned(x)=" "-D__requires_exclusive(x)=" "-D__requires_unlocked(x)=" "-D__locks_exclusive(x)=" "-D__trylocks_exclusive(x)=" "-D__unlocks(x)=" "-D__locks_shared(x)=" "-D__trylocks_shared(x)="
|
||||
|
||||
INSTALL=$(SHELL) $(srcdir)/install-sh
|
||||
|
||||
@@ -112,11 +112,12 @@ iterator/iter_scrub.c iterator/iter_utils.c services/listen_dnsport.c \
|
||||
services/localzone.c services/mesh.c services/modstack.c services/view.c \
|
||||
services/outbound_list.c services/outside_network.c util/alloc.c \
|
||||
util/config_file.c util/configlexer.c util/configparser.c \
|
||||
util/shm_side/shm_main.c services/authzone.c\
|
||||
util/shm_side/shm_main.c services/authzone.c \
|
||||
util/fptr_wlist.c util/locks.c util/log.c util/mini_event.c util/module.c \
|
||||
util/netevent.c util/net_help.c util/random.c util/rbtree.c util/regional.c \
|
||||
util/rtt.c util/storage/dnstree.c util/storage/lookup3.c \
|
||||
util/storage/lruhash.c util/storage/slabhash.c util/timehist.c util/tube.c \
|
||||
util/rtt.c util/edns.c util/storage/dnstree.c util/storage/lookup3.c \
|
||||
util/storage/lruhash.c util/storage/slabhash.c util/tcp_conn_limit.c \
|
||||
util/timehist.c util/tube.c \
|
||||
util/ub_event.c util/ub_event_pluggable.c util/winsock_event.c \
|
||||
validator/autotrust.c validator/val_anchor.c validator/validator.c \
|
||||
validator/val_kcache.c validator/val_kentry.c validator/val_neg.c \
|
||||
@@ -124,18 +125,19 @@ validator/val_nsec3.c validator/val_nsec.c validator/val_secalgo.c \
|
||||
validator/val_sigcrypt.c validator/val_utils.c dns64/dns64.c \
|
||||
edns-subnet/edns-subnet.c edns-subnet/subnetmod.c \
|
||||
edns-subnet/addrtree.c edns-subnet/subnet-whitelist.c \
|
||||
cachedb/cachedb.c respip/respip.c $(CHECKLOCK_SRC) \
|
||||
cachedb/cachedb.c cachedb/redis.c respip/respip.c $(CHECKLOCK_SRC) \
|
||||
$(DNSTAP_SRC) $(DNSCRYPT_SRC) $(IPSECMOD_SRC)
|
||||
COMMON_OBJ_WITHOUT_NETCALL=dns.lo infra.lo rrset.lo dname.lo msgencode.lo \
|
||||
as112.lo msgparse.lo msgreply.lo packed_rrset.lo iterator.lo iter_delegpt.lo \
|
||||
iter_donotq.lo iter_fwd.lo iter_hints.lo iter_priv.lo iter_resptype.lo \
|
||||
iter_scrub.lo iter_utils.lo localzone.lo mesh.lo modstack.lo view.lo \
|
||||
outbound_list.lo alloc.lo config_file.lo configlexer.lo configparser.lo \
|
||||
fptr_wlist.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 \
|
||||
slabhash.lo timehist.lo tube.lo winsock_event.lo autotrust.lo val_anchor.lo \
|
||||
slabhash.lo tcp_conn_limit.lo timehist.lo tube.lo winsock_event.lo \
|
||||
autotrust.lo val_anchor.lo \
|
||||
validator.lo val_kcache.lo val_kentry.lo val_neg.lo val_nsec3.lo val_nsec.lo \
|
||||
val_secalgo.lo val_sigcrypt.lo val_utils.lo dns64.lo cachedb.lo authzone.lo\
|
||||
val_secalgo.lo val_sigcrypt.lo val_utils.lo dns64.lo cachedb.lo redis.lo authzone.lo \
|
||||
$(SUBNET_OBJ) $(PYTHONMOD_OBJ) $(CHECKLOCK_OBJ) $(DNSTAP_OBJ) $(DNSCRYPT_OBJ) \
|
||||
$(IPSECMOD_OBJ) respip.lo
|
||||
COMMON_OBJ_WITHOUT_UB_EVENT=$(COMMON_OBJ_WITHOUT_NETCALL) netevent.lo listen_dnsport.lo \
|
||||
@@ -170,7 +172,8 @@ UNITTEST_OBJ_LINK=$(UNITTEST_OBJ) worker_cb.lo $(COMMON_OBJ) $(SLDNS_OBJ) \
|
||||
$(COMPAT_OBJ)
|
||||
DAEMON_SRC=daemon/acl_list.c daemon/cachedump.c daemon/daemon.c \
|
||||
daemon/remote.c daemon/stats.c daemon/unbound.c daemon/worker.c @WIN_DAEMON_SRC@
|
||||
DAEMON_OBJ=acl_list.lo cachedump.lo daemon.lo shm_main.lo remote.lo stats.lo unbound.lo \
|
||||
DAEMON_OBJ=acl_list.lo cachedump.lo daemon.lo \
|
||||
shm_main.lo remote.lo stats.lo unbound.lo \
|
||||
worker.lo @WIN_DAEMON_OBJ@
|
||||
DAEMON_OBJ_LINK=$(DAEMON_OBJ) $(COMMON_OBJ_ALL_SYMBOLS) $(SLDNS_OBJ) \
|
||||
$(COMPAT_OBJ) @WIN_DAEMON_OBJ_LINK@
|
||||
@@ -190,7 +193,8 @@ UBANCHOR_OBJ=unbound-anchor.lo
|
||||
UBANCHOR_OBJ_LINK=$(UBANCHOR_OBJ) parseutil.lo \
|
||||
$(COMPAT_OBJ_WITHOUT_CTIME) @WIN_UBANCHOR_OBJ_LINK@
|
||||
TESTBOUND_SRC=testcode/testbound.c testcode/testpkts.c \
|
||||
daemon/worker.c daemon/acl_list.c daemon/daemon.c daemon/stats.c \
|
||||
daemon/worker.c daemon/acl_list.c \
|
||||
daemon/daemon.c daemon/stats.c \
|
||||
testcode/replay.c testcode/fake_event.c
|
||||
TESTBOUND_OBJ=testbound.lo replay.lo fake_event.lo
|
||||
TESTBOUND_OBJ_LINK=$(TESTBOUND_OBJ) testpkts.lo worker.lo acl_list.lo \
|
||||
@@ -306,10 +310,11 @@ longcheck: longtest
|
||||
test: unittest$(EXEEXT) testbound$(EXEEXT)
|
||||
./unittest$(EXEEXT)
|
||||
./testbound$(EXEEXT) -s
|
||||
for x in testdata/*.rpl; do echo -n "$$x "; if ./testbound$(EXEEXT) -p $$x >/dev/null 2>&1; then echo OK; else echo failed; exit 1; fi done
|
||||
for x in $(srcdir)/testdata/*.rpl; do echo -n "$$x "; if ./testbound$(EXEEXT) -p $$x >/dev/null 2>&1; then echo OK; else echo failed; exit 1; fi done
|
||||
@echo test OK
|
||||
|
||||
longtest: tests
|
||||
if test ! $(srcdir)/testdata -ef ./testdata; then rm -rf testcode testdata; mkdir testcode testdata; cp -R $(srcdir)/testdata/*.sh $(srcdir)/testdata/*.tdir $(srcdir)/testdata/*.rpl $(srcdir)/testdata/*.crpl testdata; cp $(srcdir)/testcode/*.sh testcode; if test ! -d util; then mkdir util; fi; cp $(srcdir)/util/iana_ports.inc util; fi
|
||||
if test -x "`which bash`"; then bash testcode/do-tests.sh; else sh testcode/do-tests.sh; fi
|
||||
|
||||
lib: libunbound.la unbound.h
|
||||
@@ -327,7 +332,7 @@ unbound-control$(EXEEXT): $(CONTROL_OBJ_LINK) libunbound.la
|
||||
$(LINK) -o $@ $(CONTROL_OBJ_LINK) $(EXTRALINK) $(SSLLIB) $(LIBS)
|
||||
|
||||
unbound-host$(EXEEXT): $(HOST_OBJ_LINK) libunbound.la
|
||||
$(LINK) -o $@ $(HOST_OBJ_LINK) -L. -L.libs -lunbound $(LIBS)
|
||||
$(LINK) -o $@ $(HOST_OBJ_LINK) -L. -L.libs -lunbound $(SSLLIB) $(LIBS)
|
||||
|
||||
unbound-anchor$(EXEEXT): $(UBANCHOR_OBJ_LINK) libunbound.la
|
||||
$(LINK) -o $@ $(UBANCHOR_OBJ_LINK) -L. -L.libs -lunbound -lexpat $(SSLLIB) $(LIBS)
|
||||
@@ -360,7 +365,7 @@ memstats$(EXEEXT): $(MEMSTATS_OBJ_LINK)
|
||||
$(LINK) -o $@ $(MEMSTATS_OBJ_LINK) $(SSLLIB) $(LIBS)
|
||||
|
||||
asynclook$(EXEEXT): $(ASYNCLOOK_OBJ_LINK) libunbound.la
|
||||
$(LINK) -o $@ $(ASYNCLOOK_OBJ_LINK) $(LIBS) -L. -L.libs -lunbound
|
||||
$(LINK) -o $@ $(ASYNCLOOK_OBJ_LINK) -L. -L.libs -lunbound $(SSLLIB) $(LIBS)
|
||||
|
||||
streamtcp$(EXEEXT): $(STREAMTCP_OBJ_LINK)
|
||||
$(LINK) -o $@ $(STREAMTCP_OBJ_LINK) $(SSLLIB) $(LIBS)
|
||||
@@ -587,7 +592,7 @@ iana_update:
|
||||
DEPEND_TMP=depend1073.tmp
|
||||
DEPEND_TMP2=depend1074.tmp
|
||||
DEPEND_TARGET=Makefile
|
||||
DEPEND_TARGET2=Makefile.in
|
||||
DEPEND_TARGET2=$(srcdir)/Makefile.in
|
||||
# actions: generate deplines from gcc,
|
||||
# then, filter out home/xx, /usr/xx and /opt/xx lines (some cc already do this)
|
||||
# then, remove empty " \" lines
|
||||
@@ -595,7 +600,8 @@ DEPEND_TARGET2=Makefile.in
|
||||
# then, remove srcdir from the (generated) parser and lexer.
|
||||
# and mention the .lo
|
||||
depend:
|
||||
(cd $(srcdir) ; $(CC) $(DEPFLAG) $(CPPFLAGS) $(CFLAGS) @PTHREAD_CFLAGS_ONLY@ $(ALL_SRC) $(COMPAT_SRC)) | \
|
||||
(BUILDDIR=$$PWD; cd $(srcdir) ; $(CC) $(DEPFLAG) $(CPPFLAGS) $(CFLAGS) -I$$BUILDDIR @PTHREAD_CFLAGS_ONLY@ $(ALL_SRC) $(COMPAT_SRC)) | \
|
||||
sed -e 's?'$$PWD'/config.h?config.h?g' | \
|
||||
sed -e 's!'$$HOME'[^ ]* !!g' -e 's!'$$HOME'[^ ]*$$!!g' \
|
||||
-e 's!/usr[^ ]* !!g' -e 's!/usr[^ ]*$$!!g' \
|
||||
-e 's!/opt[^ ]* !!g' -e 's!/opt[^ ]*$$!!g' | \
|
||||
@@ -645,7 +651,8 @@ infra.lo infra.o: $(srcdir)/services/cache/infra.c config.h $(srcdir)/sldns/rrde
|
||||
rrset.lo rrset.o: $(srcdir)/services/cache/rrset.c config.h $(srcdir)/services/cache/rrset.h \
|
||||
$(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/testcode/checklocks.h \
|
||||
$(srcdir)/util/storage/slabhash.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/sldns/rrdef.h \
|
||||
$(srcdir)/util/config_file.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/regional.h $(srcdir)/util/alloc.h
|
||||
$(srcdir)/util/config_file.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/regional.h $(srcdir)/util/alloc.h \
|
||||
$(srcdir)/util/net_help.h
|
||||
as112.lo as112.o: $(srcdir)/util/as112.c $(srcdir)/util/as112.h
|
||||
dname.lo dname.o: $(srcdir)/util/data/dname.c config.h $(srcdir)/util/data/dname.h \
|
||||
$(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/testcode/checklocks.h \
|
||||
@@ -762,7 +769,7 @@ mesh.lo mesh.o: $(srcdir)/services/mesh.c config.h $(srcdir)/services/mesh.h $(s
|
||||
$(srcdir)/services/modstack.h $(srcdir)/services/outbound_list.h $(srcdir)/services/cache/dns.h \
|
||||
$(srcdir)/util/net_help.h $(srcdir)/util/regional.h $(srcdir)/util/data/msgencode.h $(srcdir)/util/timehist.h \
|
||||
$(srcdir)/util/fptr_wlist.h $(srcdir)/util/tube.h $(srcdir)/util/alloc.h $(srcdir)/util/config_file.h \
|
||||
$(srcdir)/sldns/sbuffer.h $(srcdir)/sldns/wire2str.h $(srcdir)/services/localzone.h \
|
||||
$(srcdir)/util/edns.h $(srcdir)/sldns/sbuffer.h $(srcdir)/sldns/wire2str.h $(srcdir)/services/localzone.h \
|
||||
$(srcdir)/util/storage/dnstree.h $(srcdir)/services/view.h $(srcdir)/util/data/dname.h $(srcdir)/respip/respip.h
|
||||
modstack.lo modstack.o: $(srcdir)/services/modstack.c config.h $(srcdir)/services/modstack.h \
|
||||
$(srcdir)/util/module.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h \
|
||||
@@ -792,10 +799,11 @@ outside_network.lo outside_network.o: $(srcdir)/services/outside_network.c confi
|
||||
$(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/testcode/checklocks.h \
|
||||
$(srcdir)/services/listen_dnsport.h $(srcdir)/services/cache/infra.h $(srcdir)/util/storage/lruhash.h \
|
||||
$(srcdir)/util/storage/dnstree.h $(srcdir)/util/rtt.h $(srcdir)/util/data/msgreply.h \
|
||||
$(srcdir)/util/data/packed_rrset.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h \
|
||||
$(srcdir)/sldns/rrdef.h $(srcdir)/util/data/msgencode.h $(srcdir)/util/data/dname.h $(srcdir)/util/net_help.h \
|
||||
$(srcdir)/util/random.h $(srcdir)/util/fptr_wlist.h $(srcdir)/util/module.h $(srcdir)/util/tube.h \
|
||||
$(srcdir)/services/mesh.h $(srcdir)/services/modstack.h $(srcdir)/sldns/sbuffer.h $(srcdir)/dnstap/dnstap.h \
|
||||
$(srcdir)/util/data/packed_rrset.h $(srcdir)/iterator/iterator.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)/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 \
|
||||
|
||||
alloc.lo alloc.o: $(srcdir)/util/alloc.c config.h $(srcdir)/util/alloc.h $(srcdir)/util/locks.h $(srcdir)/util/log.h \
|
||||
$(srcdir)/testcode/checklocks.h $(srcdir)/util/regional.h $(srcdir)/util/data/packed_rrset.h \
|
||||
@@ -857,10 +865,11 @@ fptr_wlist.lo fptr_wlist.o: $(srcdir)/util/fptr_wlist.c config.h $(srcdir)/util/
|
||||
$(srcdir)/validator/val_utils.h $(srcdir)/validator/val_anchor.h $(srcdir)/validator/val_nsec3.h \
|
||||
$(srcdir)/validator/val_sigcrypt.h $(srcdir)/validator/val_kentry.h $(srcdir)/validator/val_neg.h \
|
||||
$(srcdir)/validator/autotrust.h $(srcdir)/libunbound/libworker.h $(srcdir)/libunbound/context.h \
|
||||
$(srcdir)/util/alloc.h $(srcdir)/libunbound/unbound.h $(srcdir)/libunbound/worker.h $(srcdir)/sldns/sbuffer.h \
|
||||
$(srcdir)/util/config_file.h $(srcdir)/respip/respip.h $(PYTHONMOD_HEADER) \
|
||||
$(srcdir)/cachedb/cachedb.h $(srcdir)/ipsecmod/ipsecmod.h $(srcdir)/edns-subnet/subnetmod.h \
|
||||
$(srcdir)/util/net_help.h $(srcdir)/edns-subnet/addrtree.h $(srcdir)/edns-subnet/edns-subnet.h
|
||||
$(srcdir)/util/alloc.h $(srcdir)/libunbound/unbound.h $(srcdir)/libunbound/unbound-event.h \
|
||||
$(srcdir)/libunbound/worker.h $(srcdir)/sldns/sbuffer.h $(srcdir)/util/config_file.h $(srcdir)/respip/respip.h \
|
||||
$(PYTHONMOD_HEADER) $(srcdir)/cachedb/cachedb.h $(srcdir)/ipsecmod/ipsecmod.h \
|
||||
$(srcdir)/edns-subnet/subnetmod.h $(srcdir)/util/net_help.h $(srcdir)/edns-subnet/addrtree.h \
|
||||
$(srcdir)/edns-subnet/edns-subnet.h
|
||||
locks.lo locks.o: $(srcdir)/util/locks.c config.h $(srcdir)/util/locks.h $(srcdir)/util/log.h \
|
||||
$(srcdir)/testcode/checklocks.h
|
||||
log.lo log.o: $(srcdir)/util/log.c config.h $(srcdir)/util/log.h $(srcdir)/util/locks.h $(srcdir)/testcode/checklocks.h \
|
||||
@@ -878,11 +887,12 @@ module.lo module.o: $(srcdir)/util/module.c config.h $(srcdir)/util/module.h $(s
|
||||
$(srcdir)/sldns/rrdef.h $(srcdir)/sldns/wire2str.h
|
||||
netevent.lo netevent.o: $(srcdir)/util/netevent.c config.h $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
|
||||
$(srcdir)/dnscrypt/cert.h $(srcdir)/util/locks.h $(srcdir)/util/log.h \
|
||||
$(srcdir)/testcode/checklocks.h $(srcdir)/util/ub_event.h $(srcdir)/util/net_help.h $(srcdir)/util/fptr_wlist.h \
|
||||
$(srcdir)/util/storage/lruhash.h $(srcdir)/util/module.h $(srcdir)/util/data/msgreply.h \
|
||||
$(srcdir)/util/data/packed_rrset.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h \
|
||||
$(srcdir)/sldns/rrdef.h $(srcdir)/util/tube.h $(srcdir)/services/mesh.h $(srcdir)/util/rbtree.h \
|
||||
$(srcdir)/services/modstack.h $(srcdir)/sldns/sbuffer.h $(srcdir)/dnstap/dnstap.h \
|
||||
$(srcdir)/testcode/checklocks.h $(srcdir)/util/ub_event.h $(srcdir)/util/net_help.h \
|
||||
$(srcdir)/util/tcp_conn_limit.h $(srcdir)/util/storage/dnstree.h $(srcdir)/util/rbtree.h \
|
||||
$(srcdir)/util/fptr_wlist.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/module.h \
|
||||
$(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/data/msgparse.h \
|
||||
$(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/tube.h $(srcdir)/services/mesh.h \
|
||||
$(srcdir)/services/modstack.h $(srcdir)/sldns/sbuffer.h $(srcdir)/sldns/str2wire.h $(srcdir)/dnstap/dnstap.h \
|
||||
\
|
||||
|
||||
net_help.lo net_help.o: $(srcdir)/util/net_help.c config.h $(srcdir)/util/net_help.h $(srcdir)/util/log.h \
|
||||
@@ -900,7 +910,15 @@ rbtree.lo rbtree.o: $(srcdir)/util/rbtree.c config.h $(srcdir)/util/log.h $(srcd
|
||||
$(srcdir)/sldns/rrdef.h $(srcdir)/util/tube.h $(srcdir)/services/mesh.h $(srcdir)/util/rbtree.h \
|
||||
$(srcdir)/services/modstack.h
|
||||
regional.lo regional.o: $(srcdir)/util/regional.c config.h $(srcdir)/util/log.h $(srcdir)/util/regional.h
|
||||
rtt.lo rtt.o: $(srcdir)/util/rtt.c config.h $(srcdir)/util/rtt.h
|
||||
rtt.lo rtt.o: $(srcdir)/util/rtt.c config.h $(srcdir)/util/rtt.h $(srcdir)/iterator/iterator.h \
|
||||
$(srcdir)/services/outbound_list.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/storage/lruhash.h \
|
||||
$(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/testcode/checklocks.h $(srcdir)/util/data/packed_rrset.h \
|
||||
$(srcdir)/util/module.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h
|
||||
edns.lo edns.o: $(srcdir)/util/edns.c config.h $(srcdir)/util/config_file.h $(srcdir)/util/netevent.h \
|
||||
$(srcdir)/dnscrypt/dnscrypt.h $(srcdir)/dnscrypt/cert.h \
|
||||
$(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/testcode/checklocks.h $(srcdir)/util/regional.h \
|
||||
$(srcdir)/util/data/msgparse.h $(srcdir)/util/storage/lruhash.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h \
|
||||
$(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h
|
||||
dnstree.lo dnstree.o: $(srcdir)/util/storage/dnstree.c config.h $(srcdir)/util/storage/dnstree.h \
|
||||
$(srcdir)/util/rbtree.h $(srcdir)/util/data/dname.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h \
|
||||
$(srcdir)/util/log.h $(srcdir)/testcode/checklocks.h $(srcdir)/util/net_help.h
|
||||
@@ -914,6 +932,12 @@ lruhash.lo lruhash.o: $(srcdir)/util/storage/lruhash.c config.h $(srcdir)/util/s
|
||||
$(srcdir)/services/modstack.h
|
||||
slabhash.lo slabhash.o: $(srcdir)/util/storage/slabhash.c config.h $(srcdir)/util/storage/slabhash.h \
|
||||
$(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/testcode/checklocks.h
|
||||
tcp_conn_limit.lo tcp_conn_limit.o: $(srcdir)/util/tcp_conn_limit.c config.h $(srcdir)/util/regional.h \
|
||||
$(srcdir)/util/log.h $(srcdir)/util/config_file.h $(srcdir)/util/net_help.h $(srcdir)/util/tcp_conn_limit.h \
|
||||
$(srcdir)/util/storage/dnstree.h $(srcdir)/util/rbtree.h $(srcdir)/util/locks.h $(srcdir)/testcode/checklocks.h \
|
||||
$(srcdir)/services/localzone.h $(srcdir)/util/module.h $(srcdir)/util/storage/lruhash.h \
|
||||
$(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/data/msgparse.h \
|
||||
$(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/services/view.h $(srcdir)/sldns/str2wire.h
|
||||
timehist.lo timehist.o: $(srcdir)/util/timehist.c config.h $(srcdir)/util/timehist.h $(srcdir)/util/log.h
|
||||
tube.lo tube.o: $(srcdir)/util/tube.c config.h $(srcdir)/util/tube.h $(srcdir)/util/log.h $(srcdir)/util/net_help.h \
|
||||
$(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
|
||||
@@ -960,11 +984,11 @@ validator.lo validator.o: $(srcdir)/validator/validator.c config.h $(srcdir)/val
|
||||
$(srcdir)/validator/val_anchor.h $(srcdir)/util/rbtree.h $(srcdir)/validator/val_kcache.h \
|
||||
$(srcdir)/util/storage/slabhash.h $(srcdir)/validator/val_kentry.h $(srcdir)/validator/val_nsec.h \
|
||||
$(srcdir)/validator/val_nsec3.h $(srcdir)/validator/val_neg.h $(srcdir)/validator/val_sigcrypt.h \
|
||||
$(srcdir)/validator/autotrust.h $(srcdir)/services/cache/dns.h $(srcdir)/util/data/dname.h \
|
||||
$(srcdir)/util/net_help.h $(srcdir)/util/regional.h $(srcdir)/util/config_file.h $(srcdir)/util/fptr_wlist.h \
|
||||
$(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
|
||||
$(srcdir)/dnscrypt/cert.h $(srcdir)/util/tube.h $(srcdir)/services/mesh.h $(srcdir)/services/modstack.h \
|
||||
$(srcdir)/sldns/wire2str.h $(srcdir)/sldns/str2wire.h
|
||||
$(srcdir)/validator/autotrust.h $(srcdir)/services/cache/dns.h $(srcdir)/services/cache/rrset.h \
|
||||
$(srcdir)/util/data/dname.h $(srcdir)/util/net_help.h $(srcdir)/util/regional.h $(srcdir)/util/config_file.h \
|
||||
$(srcdir)/util/fptr_wlist.h $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
|
||||
$(srcdir)/dnscrypt/cert.h $(srcdir)/util/tube.h $(srcdir)/services/mesh.h \
|
||||
$(srcdir)/services/modstack.h $(srcdir)/sldns/wire2str.h $(srcdir)/sldns/str2wire.h
|
||||
val_kcache.lo val_kcache.o: $(srcdir)/validator/val_kcache.c config.h $(srcdir)/validator/val_kcache.h \
|
||||
$(srcdir)/util/storage/slabhash.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h \
|
||||
$(srcdir)/testcode/checklocks.h $(srcdir)/validator/val_kentry.h $(srcdir)/util/config_file.h \
|
||||
@@ -1028,7 +1052,8 @@ dns64.lo dns64.o: $(srcdir)/dns64/dns64.c config.h $(srcdir)/dns64/dns64.h $(src
|
||||
$(srcdir)/util/storage/slabhash.h $(srcdir)/util/config_file.h $(srcdir)/util/fptr_wlist.h \
|
||||
$(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
|
||||
$(srcdir)/dnscrypt/cert.h $(srcdir)/util/tube.h $(srcdir)/services/mesh.h $(srcdir)/util/rbtree.h \
|
||||
$(srcdir)/services/modstack.h $(srcdir)/util/net_help.h $(srcdir)/util/regional.h
|
||||
$(srcdir)/services/modstack.h $(srcdir)/util/net_help.h $(srcdir)/util/regional.h \
|
||||
$(srcdir)/util/storage/dnstree.h $(srcdir)/util/data/dname.h $(srcdir)/sldns/str2wire.h
|
||||
edns-subnet.lo edns-subnet.o: $(srcdir)/edns-subnet/edns-subnet.c config.h \
|
||||
$(srcdir)/edns-subnet/edns-subnet.h $(srcdir)/util/net_help.h $(srcdir)/util/log.h
|
||||
subnetmod.lo subnetmod.o: $(srcdir)/edns-subnet/subnetmod.c config.h $(srcdir)/edns-subnet/subnetmod.h \
|
||||
@@ -1054,11 +1079,16 @@ subnet-whitelist.lo subnet-whitelist.o: $(srcdir)/edns-subnet/subnet-whitelist.c
|
||||
cachedb.lo cachedb.o: $(srcdir)/cachedb/cachedb.c config.h $(srcdir)/cachedb/cachedb.h $(srcdir)/util/module.h \
|
||||
$(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/testcode/checklocks.h \
|
||||
$(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/data/msgparse.h \
|
||||
$(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/regional.h $(srcdir)/util/net_help.h \
|
||||
$(srcdir)/util/config_file.h $(srcdir)/util/data/msgencode.h $(srcdir)/services/cache/dns.h \
|
||||
$(srcdir)/validator/val_neg.h $(srcdir)/util/rbtree.h $(srcdir)/validator/val_secalgo.h \
|
||||
$(srcdir)/iterator/iter_utils.h $(srcdir)/iterator/iter_resptype.h $(srcdir)/sldns/parseutil.h \
|
||||
$(srcdir)/sldns/wire2str.h $(srcdir)/sldns/sbuffer.h
|
||||
$(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/cachedb/redis.h $(srcdir)/util/regional.h \
|
||||
$(srcdir)/util/net_help.h $(srcdir)/util/config_file.h $(srcdir)/util/data/msgencode.h \
|
||||
$(srcdir)/services/cache/dns.h $(srcdir)/validator/val_neg.h $(srcdir)/util/rbtree.h \
|
||||
$(srcdir)/validator/val_secalgo.h $(srcdir)/iterator/iter_utils.h $(srcdir)/iterator/iter_resptype.h \
|
||||
$(srcdir)/sldns/parseutil.h $(srcdir)/sldns/wire2str.h $(srcdir)/sldns/sbuffer.h
|
||||
redis.lo redis.o: $(srcdir)/cachedb/redis.c config.h $(srcdir)/cachedb/redis.h $(srcdir)/cachedb/cachedb.h \
|
||||
$(srcdir)/util/module.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h \
|
||||
$(srcdir)/testcode/checklocks.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h \
|
||||
$(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/alloc.h \
|
||||
$(srcdir)/util/config_file.h $(srcdir)/sldns/sbuffer.h
|
||||
respip.lo respip.o: $(srcdir)/respip/respip.c config.h $(srcdir)/services/localzone.h $(srcdir)/util/rbtree.h \
|
||||
$(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/testcode/checklocks.h $(srcdir)/util/storage/dnstree.h \
|
||||
$(srcdir)/util/module.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/data/msgreply.h \
|
||||
@@ -1104,12 +1134,13 @@ unitmain.lo unitmain.o: $(srcdir)/testcode/unitmain.c config.h \
|
||||
$(srcdir)/sldns/rrdef.h $(srcdir)/sldns/keyraw.h \
|
||||
$(srcdir)/util/log.h $(srcdir)/testcode/unitmain.h $(srcdir)/util/alloc.h $(srcdir)/util/locks.h \
|
||||
$(srcdir)/testcode/checklocks.h $(srcdir)/util/net_help.h $(srcdir)/util/config_file.h $(srcdir)/util/rtt.h \
|
||||
$(srcdir)/util/timehist.h $(srcdir)/libunbound/unbound.h $(srcdir)/services/cache/infra.h \
|
||||
$(srcdir)/util/storage/lruhash.h $(srcdir)/util/storage/dnstree.h $(srcdir)/util/rbtree.h \
|
||||
$(srcdir)/util/timehist.h $(srcdir)/iterator/iterator.h $(srcdir)/services/outbound_list.h \
|
||||
$(srcdir)/util/data/msgreply.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/data/packed_rrset.h \
|
||||
$(srcdir)/util/module.h $(srcdir)/util/data/msgparse.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)/dnscrypt/cert.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h \
|
||||
$(srcdir)/util/random.h $(srcdir)/respip/respip.h $(srcdir)/util/module.h $(srcdir)/util/data/msgparse.h \
|
||||
$(srcdir)/sldns/pkthdr.h $(srcdir)/services/localzone.h $(srcdir)/services/view.h
|
||||
$(srcdir)/dnscrypt/cert.h $(srcdir)/util/random.h $(srcdir)/respip/respip.h $(srcdir)/services/localzone.h \
|
||||
$(srcdir)/services/view.h
|
||||
unitmsgparse.lo unitmsgparse.o: $(srcdir)/testcode/unitmsgparse.c config.h $(srcdir)/util/log.h \
|
||||
$(srcdir)/testcode/unitmain.h $(srcdir)/util/data/msgparse.h $(srcdir)/util/storage/lruhash.h \
|
||||
$(srcdir)/util/locks.h $(srcdir)/testcode/checklocks.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h \
|
||||
@@ -1187,10 +1218,10 @@ daemon.lo daemon.o: $(srcdir)/daemon/daemon.c config.h \
|
||||
$(srcdir)/daemon/remote.h \
|
||||
$(srcdir)/daemon/acl_list.h $(srcdir)/util/storage/dnstree.h $(srcdir)/util/rbtree.h $(srcdir)/services/view.h \
|
||||
$(srcdir)/util/config_file.h $(srcdir)/util/shm_side/shm_main.h $(srcdir)/util/storage/lookup3.h \
|
||||
$(srcdir)/util/storage/slabhash.h $(srcdir)/services/listen_dnsport.h $(srcdir)/services/cache/rrset.h \
|
||||
$(srcdir)/services/cache/infra.h $(srcdir)/util/rtt.h $(srcdir)/services/localzone.h \
|
||||
$(srcdir)/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
|
||||
$(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 \
|
||||
@@ -1204,12 +1235,12 @@ remote.lo remote.o: $(srcdir)/daemon/remote.c config.h \
|
||||
$(srcdir)/util/net_help.h $(srcdir)/services/listen_dnsport.h $(srcdir)/services/cache/rrset.h \
|
||||
$(srcdir)/util/storage/slabhash.h $(srcdir)/services/cache/infra.h $(srcdir)/util/storage/dnstree.h \
|
||||
$(srcdir)/util/rbtree.h $(srcdir)/util/rtt.h $(srcdir)/services/mesh.h $(srcdir)/services/localzone.h \
|
||||
$(srcdir)/services/view.h $(srcdir)/util/fptr_wlist.h $(srcdir)/util/tube.h $(srcdir)/util/data/dname.h \
|
||||
$(srcdir)/validator/validator.h $(srcdir)/validator/val_utils.h $(srcdir)/validator/val_kcache.h \
|
||||
$(srcdir)/validator/val_kentry.h $(srcdir)/validator/val_anchor.h $(srcdir)/iterator/iterator.h \
|
||||
$(srcdir)/services/outbound_list.h $(srcdir)/iterator/iter_fwd.h $(srcdir)/iterator/iter_hints.h \
|
||||
$(srcdir)/iterator/iter_delegpt.h $(srcdir)/services/outside_network.h $(srcdir)/sldns/str2wire.h \
|
||||
$(srcdir)/sldns/parseutil.h $(srcdir)/sldns/wire2str.h
|
||||
$(srcdir)/services/view.h $(srcdir)/services/authzone.h $(srcdir)/util/fptr_wlist.h $(srcdir)/util/tube.h \
|
||||
$(srcdir)/util/data/dname.h $(srcdir)/validator/validator.h $(srcdir)/validator/val_utils.h \
|
||||
$(srcdir)/validator/val_kcache.h $(srcdir)/validator/val_kentry.h $(srcdir)/validator/val_anchor.h \
|
||||
$(srcdir)/iterator/iterator.h $(srcdir)/services/outbound_list.h $(srcdir)/iterator/iter_fwd.h \
|
||||
$(srcdir)/iterator/iter_hints.h $(srcdir)/iterator/iter_delegpt.h $(srcdir)/services/outside_network.h \
|
||||
$(srcdir)/sldns/str2wire.h $(srcdir)/sldns/parseutil.h $(srcdir)/sldns/wire2str.h
|
||||
stats.lo stats.o: $(srcdir)/daemon/stats.c config.h $(srcdir)/daemon/stats.h $(srcdir)/util/timehist.h \
|
||||
$(srcdir)/libunbound/unbound.h $(srcdir)/daemon/worker.h $(srcdir)/libunbound/worker.h $(srcdir)/sldns/sbuffer.h \
|
||||
$(srcdir)/util/data/packed_rrset.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h \
|
||||
@@ -1222,7 +1253,8 @@ 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)/iterator/iterator.h $(srcdir)/services/outbound_list.h $(srcdir)/services/cache/rrset.h \
|
||||
$(srcdir)/util/storage/slabhash.h $(srcdir)/services/cache/infra.h $(srcdir)/util/storage/dnstree.h \
|
||||
$(srcdir)/util/rtt.h $(srcdir)/validator/val_kcache.h
|
||||
$(srcdir)/util/rtt.h $(srcdir)/services/authzone.h $(srcdir)/validator/val_kcache.h \
|
||||
$(srcdir)/validator/val_neg.h
|
||||
unbound.lo unbound.o: $(srcdir)/daemon/unbound.c config.h $(srcdir)/util/log.h $(srcdir)/daemon/daemon.h \
|
||||
$(srcdir)/util/locks.h $(srcdir)/testcode/checklocks.h $(srcdir)/util/alloc.h $(srcdir)/services/modstack.h \
|
||||
$(srcdir)/daemon/remote.h \
|
||||
@@ -1248,10 +1280,10 @@ worker.lo worker.o: $(srcdir)/daemon/worker.c config.h $(srcdir)/util/log.h $(sr
|
||||
$(srcdir)/services/outbound_list.h $(srcdir)/services/cache/rrset.h $(srcdir)/services/cache/infra.h \
|
||||
$(srcdir)/util/rtt.h $(srcdir)/services/cache/dns.h $(srcdir)/services/authzone.h $(srcdir)/services/mesh.h \
|
||||
$(srcdir)/services/localzone.h $(srcdir)/util/data/msgencode.h $(srcdir)/util/data/dname.h \
|
||||
$(srcdir)/util/fptr_wlist.h $(srcdir)/util/tube.h $(srcdir)/iterator/iter_fwd.h $(srcdir)/iterator/iter_hints.h \
|
||||
$(srcdir)/validator/autotrust.h $(srcdir)/validator/val_anchor.h $(srcdir)/respip/respip.h \
|
||||
$(srcdir)/libunbound/context.h $(srcdir)/libunbound/libworker.h $(srcdir)/sldns/wire2str.h \
|
||||
$(srcdir)/util/shm_side/shm_main.h
|
||||
$(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)/respip/respip.h $(srcdir)/libunbound/context.h $(srcdir)/libunbound/unbound-event.h \
|
||||
$(srcdir)/libunbound/libworker.h $(srcdir)/sldns/wire2str.h $(srcdir)/util/shm_side/shm_main.h
|
||||
testbound.lo testbound.o: $(srcdir)/testcode/testbound.c config.h $(srcdir)/testcode/testpkts.h \
|
||||
$(srcdir)/testcode/replay.h $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
|
||||
$(srcdir)/dnscrypt/cert.h $(srcdir)/util/locks.h $(srcdir)/util/log.h \
|
||||
@@ -1282,10 +1314,10 @@ worker.lo worker.o: $(srcdir)/daemon/worker.c config.h $(srcdir)/util/log.h $(sr
|
||||
$(srcdir)/services/outbound_list.h $(srcdir)/services/cache/rrset.h $(srcdir)/services/cache/infra.h \
|
||||
$(srcdir)/util/rtt.h $(srcdir)/services/cache/dns.h $(srcdir)/services/authzone.h $(srcdir)/services/mesh.h \
|
||||
$(srcdir)/services/localzone.h $(srcdir)/util/data/msgencode.h $(srcdir)/util/data/dname.h \
|
||||
$(srcdir)/util/fptr_wlist.h $(srcdir)/util/tube.h $(srcdir)/iterator/iter_fwd.h $(srcdir)/iterator/iter_hints.h \
|
||||
$(srcdir)/validator/autotrust.h $(srcdir)/validator/val_anchor.h $(srcdir)/respip/respip.h \
|
||||
$(srcdir)/libunbound/context.h $(srcdir)/libunbound/libworker.h $(srcdir)/sldns/wire2str.h \
|
||||
$(srcdir)/util/shm_side/shm_main.h
|
||||
$(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)/respip/respip.h $(srcdir)/libunbound/context.h $(srcdir)/libunbound/unbound-event.h \
|
||||
$(srcdir)/libunbound/libworker.h $(srcdir)/sldns/wire2str.h $(srcdir)/util/shm_side/shm_main.h
|
||||
acl_list.lo acl_list.o: $(srcdir)/daemon/acl_list.c config.h $(srcdir)/daemon/acl_list.h \
|
||||
$(srcdir)/util/storage/dnstree.h $(srcdir)/util/rbtree.h $(srcdir)/services/view.h $(srcdir)/util/locks.h \
|
||||
$(srcdir)/util/log.h $(srcdir)/testcode/checklocks.h $(srcdir)/util/regional.h $(srcdir)/util/config_file.h \
|
||||
@@ -1303,10 +1335,10 @@ daemon.lo daemon.o: $(srcdir)/daemon/daemon.c config.h \
|
||||
$(srcdir)/daemon/remote.h \
|
||||
$(srcdir)/daemon/acl_list.h $(srcdir)/util/storage/dnstree.h $(srcdir)/util/rbtree.h $(srcdir)/services/view.h \
|
||||
$(srcdir)/util/config_file.h $(srcdir)/util/shm_side/shm_main.h $(srcdir)/util/storage/lookup3.h \
|
||||
$(srcdir)/util/storage/slabhash.h $(srcdir)/services/listen_dnsport.h $(srcdir)/services/cache/rrset.h \
|
||||
$(srcdir)/services/cache/infra.h $(srcdir)/util/rtt.h $(srcdir)/services/localzone.h \
|
||||
$(srcdir)/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
|
||||
$(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
|
||||
stats.lo stats.o: $(srcdir)/daemon/stats.c config.h $(srcdir)/daemon/stats.h $(srcdir)/util/timehist.h \
|
||||
$(srcdir)/libunbound/unbound.h $(srcdir)/daemon/worker.h $(srcdir)/libunbound/worker.h $(srcdir)/sldns/sbuffer.h \
|
||||
$(srcdir)/util/data/packed_rrset.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h \
|
||||
@@ -1319,7 +1351,8 @@ 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)/iterator/iterator.h $(srcdir)/services/outbound_list.h $(srcdir)/services/cache/rrset.h \
|
||||
$(srcdir)/util/storage/slabhash.h $(srcdir)/services/cache/infra.h $(srcdir)/util/storage/dnstree.h \
|
||||
$(srcdir)/util/rtt.h $(srcdir)/validator/val_kcache.h
|
||||
$(srcdir)/util/rtt.h $(srcdir)/services/authzone.h $(srcdir)/validator/val_kcache.h \
|
||||
$(srcdir)/validator/val_neg.h
|
||||
replay.lo replay.o: $(srcdir)/testcode/replay.c config.h $(srcdir)/util/log.h $(srcdir)/util/net_help.h \
|
||||
$(srcdir)/util/config_file.h $(srcdir)/testcode/replay.h $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
|
||||
$(srcdir)/dnscrypt/cert.h $(srcdir)/util/locks.h \
|
||||
@@ -1367,22 +1400,22 @@ unbound-checkconf.lo unbound-checkconf.o: $(srcdir)/smallapp/unbound-checkconf.c
|
||||
$(PYTHONMOD_HEADER) $(srcdir)/edns-subnet/subnet-whitelist.h
|
||||
worker_cb.lo worker_cb.o: $(srcdir)/smallapp/worker_cb.c config.h $(srcdir)/libunbound/context.h \
|
||||
$(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/testcode/checklocks.h $(srcdir)/util/alloc.h $(srcdir)/util/rbtree.h \
|
||||
$(srcdir)/services/modstack.h $(srcdir)/libunbound/unbound.h $(srcdir)/util/data/packed_rrset.h \
|
||||
$(srcdir)/util/storage/lruhash.h $(srcdir)/libunbound/worker.h $(srcdir)/sldns/sbuffer.h \
|
||||
$(srcdir)/util/fptr_wlist.h $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
|
||||
$(srcdir)/services/modstack.h $(srcdir)/libunbound/unbound.h $(srcdir)/libunbound/unbound-event.h \
|
||||
$(srcdir)/util/data/packed_rrset.h $(srcdir)/util/storage/lruhash.h $(srcdir)/libunbound/worker.h \
|
||||
$(srcdir)/sldns/sbuffer.h $(srcdir)/util/fptr_wlist.h $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
|
||||
$(srcdir)/dnscrypt/cert.h $(srcdir)/util/module.h \
|
||||
$(srcdir)/util/data/msgreply.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h \
|
||||
$(srcdir)/util/tube.h $(srcdir)/services/mesh.h
|
||||
context.lo context.o: $(srcdir)/libunbound/context.c config.h $(srcdir)/libunbound/context.h \
|
||||
$(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/testcode/checklocks.h $(srcdir)/util/alloc.h $(srcdir)/util/rbtree.h \
|
||||
$(srcdir)/services/modstack.h $(srcdir)/libunbound/unbound.h $(srcdir)/util/data/packed_rrset.h \
|
||||
$(srcdir)/util/storage/lruhash.h $(srcdir)/util/module.h $(srcdir)/util/data/msgreply.h \
|
||||
$(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/config_file.h \
|
||||
$(srcdir)/util/net_help.h $(srcdir)/services/localzone.h $(srcdir)/util/storage/dnstree.h \
|
||||
$(srcdir)/services/view.h $(srcdir)/services/cache/rrset.h $(srcdir)/util/storage/slabhash.h \
|
||||
$(srcdir)/services/cache/infra.h $(srcdir)/util/rtt.h $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
|
||||
$(srcdir)/dnscrypt/cert.h $(srcdir)/services/authzone.h \
|
||||
$(srcdir)/services/mesh.h $(srcdir)/sldns/sbuffer.h
|
||||
$(srcdir)/services/modstack.h $(srcdir)/libunbound/unbound.h $(srcdir)/libunbound/unbound-event.h \
|
||||
$(srcdir)/util/data/packed_rrset.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/module.h \
|
||||
$(srcdir)/util/data/msgreply.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h \
|
||||
$(srcdir)/util/config_file.h $(srcdir)/util/net_help.h $(srcdir)/services/localzone.h \
|
||||
$(srcdir)/util/storage/dnstree.h $(srcdir)/services/view.h $(srcdir)/services/cache/rrset.h \
|
||||
$(srcdir)/util/storage/slabhash.h $(srcdir)/services/cache/infra.h $(srcdir)/util/rtt.h \
|
||||
$(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
|
||||
$(srcdir)/dnscrypt/cert.h $(srcdir)/services/authzone.h $(srcdir)/services/mesh.h $(srcdir)/sldns/sbuffer.h
|
||||
libunbound.lo libunbound.o: $(srcdir)/libunbound/libunbound.c $(srcdir)/libunbound/unbound.h \
|
||||
$(srcdir)/libunbound/unbound-event.h config.h $(srcdir)/libunbound/context.h $(srcdir)/util/locks.h \
|
||||
$(srcdir)/util/log.h $(srcdir)/testcode/checklocks.h $(srcdir)/util/alloc.h $(srcdir)/util/rbtree.h \
|
||||
@@ -1399,7 +1432,7 @@ libworker.lo libworker.o: $(srcdir)/libunbound/libworker.c config.h \
|
||||
$(srcdir)/libunbound/libworker.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/storage/lruhash.h \
|
||||
$(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/testcode/checklocks.h $(srcdir)/libunbound/context.h \
|
||||
$(srcdir)/util/alloc.h $(srcdir)/util/rbtree.h $(srcdir)/services/modstack.h $(srcdir)/libunbound/unbound.h \
|
||||
$(srcdir)/libunbound/worker.h $(srcdir)/sldns/sbuffer.h $(srcdir)/libunbound/unbound-event.h \
|
||||
$(srcdir)/libunbound/unbound-event.h $(srcdir)/libunbound/worker.h $(srcdir)/sldns/sbuffer.h \
|
||||
$(srcdir)/services/outside_network.h $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
|
||||
$(srcdir)/dnscrypt/cert.h \
|
||||
$(srcdir)/services/mesh.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h \
|
||||
@@ -1411,11 +1444,14 @@ libworker.lo libworker.o: $(srcdir)/libunbound/libworker.c config.h \
|
||||
$(srcdir)/util/data/dname.h $(srcdir)/util/data/msgencode.h $(srcdir)/iterator/iter_fwd.h \
|
||||
$(srcdir)/iterator/iter_hints.h $(srcdir)/sldns/str2wire.h
|
||||
unbound-host.lo unbound-host.o: $(srcdir)/smallapp/unbound-host.c config.h $(srcdir)/libunbound/unbound.h \
|
||||
$(srcdir)/sldns/rrdef.h $(srcdir)/sldns/wire2str.h
|
||||
$(srcdir)/sldns/rrdef.h $(srcdir)/sldns/wire2str.h \
|
||||
|
||||
asynclook.lo asynclook.o: $(srcdir)/testcode/asynclook.c config.h $(srcdir)/libunbound/unbound.h \
|
||||
$(srcdir)/libunbound/context.h $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/testcode/checklocks.h \
|
||||
$(srcdir)/util/alloc.h $(srcdir)/util/rbtree.h $(srcdir)/services/modstack.h $(srcdir)/util/data/packed_rrset.h \
|
||||
$(srcdir)/util/storage/lruhash.h $(srcdir)/sldns/rrdef.h
|
||||
$(srcdir)/util/alloc.h $(srcdir)/util/rbtree.h $(srcdir)/services/modstack.h \
|
||||
$(srcdir)/libunbound/unbound-event.h $(srcdir)/util/data/packed_rrset.h \
|
||||
$(srcdir)/util/storage/lruhash.h $(srcdir)/sldns/rrdef.h \
|
||||
|
||||
streamtcp.lo streamtcp.o: $(srcdir)/testcode/streamtcp.c config.h $(srcdir)/util/locks.h $(srcdir)/util/log.h \
|
||||
$(srcdir)/testcode/checklocks.h $(srcdir)/util/net_help.h $(srcdir)/util/data/msgencode.h \
|
||||
$(srcdir)/util/data/msgparse.h $(srcdir)/util/storage/lruhash.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h \
|
||||
@@ -1455,7 +1491,7 @@ win_svc.lo win_svc.o: $(srcdir)/winrc/win_svc.c config.h $(srcdir)/winrc/win_svc
|
||||
$(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/daemon/stats.h \
|
||||
$(srcdir)/util/timehist.h $(srcdir)/libunbound/unbound.h $(srcdir)/util/module.h $(srcdir)/dnstap/dnstap.h \
|
||||
$(srcdir)/daemon/remote.h \
|
||||
$(srcdir)/util/config_file.h $(srcdir)/util/ub_event.h
|
||||
$(srcdir)/util/config_file.h $(srcdir)/util/ub_event.h $(srcdir)/util/net_help.h
|
||||
w_inst.lo w_inst.o: $(srcdir)/winrc/w_inst.c config.h $(srcdir)/winrc/w_inst.h $(srcdir)/winrc/win_svc.h
|
||||
unbound-service-install.lo unbound-service-install.o: $(srcdir)/winrc/unbound-service-install.c config.h \
|
||||
$(srcdir)/winrc/w_inst.h
|
||||
|
||||
+22
-2
@@ -43,6 +43,7 @@
|
||||
#include "config.h"
|
||||
#ifdef USE_CACHEDB
|
||||
#include "cachedb/cachedb.h"
|
||||
#include "cachedb/redis.h"
|
||||
#include "util/regional.h"
|
||||
#include "util/net_help.h"
|
||||
#include "util/config_file.h"
|
||||
@@ -56,7 +57,20 @@
|
||||
#include "sldns/wire2str.h"
|
||||
#include "sldns/sbuffer.h"
|
||||
|
||||
#define CACHEDB_HASHSIZE 256 /* bit hash */
|
||||
/* header file for htobe64 */
|
||||
#ifdef HAVE_ENDIAN_H
|
||||
# include <endian.h>
|
||||
#endif
|
||||
#ifdef HAVE_SYS_ENDIAN_H
|
||||
# include <sys/endian.h>
|
||||
#endif
|
||||
#ifdef HAVE_LIBKERN_OSBYTEORDER_H
|
||||
/* In practice this is specific to MacOS X. We assume it doesn't have
|
||||
* htobe64/be64toh but has alternatives with a different name. */
|
||||
# include <libkern/OSByteOrder.h>
|
||||
# define htobe64(x) OSSwapHostToBigInt64(x)
|
||||
# define be64toh(x) OSSwapBigToHostInt64(x)
|
||||
#endif
|
||||
|
||||
/** the unit test testframe for cachedb, its module state contains
|
||||
* a cache for a couple queries (in memory). */
|
||||
@@ -176,6 +190,10 @@ static struct cachedb_backend testframe_backend = { "testframe",
|
||||
static struct cachedb_backend*
|
||||
cachedb_find_backend(const char* str)
|
||||
{
|
||||
#ifdef USE_REDIS
|
||||
if(strcmp(str, redis_backend.name) == 0)
|
||||
return &redis_backend;
|
||||
#endif
|
||||
if(strcmp(str, testframe_backend.name) == 0)
|
||||
return &testframe_backend;
|
||||
/* TODO add more backends here */
|
||||
@@ -428,6 +446,7 @@ adjust_msg_ttl(struct dns_msg* msg, time_t adjust)
|
||||
msg->rep->ttl -= adjust;
|
||||
else msg->rep->ttl = 0;
|
||||
msg->rep->prefetch_ttl = PREFETCH_TTL_CALC(msg->rep->ttl);
|
||||
msg->rep->serve_expired_ttl = msg->rep->ttl + SERVE_EXPIRED_TTL;
|
||||
|
||||
for(i=0; i<msg->rep->rrset_count; i++) {
|
||||
packed_rrset_ttl_subtract((struct packed_rrset_data*)msg->
|
||||
@@ -571,7 +590,8 @@ cachedb_intcache_lookup(struct module_qstate* qstate)
|
||||
qstate->region, qstate->env->scratch,
|
||||
1 /* no partial messages with only a CNAME */
|
||||
);
|
||||
if(!msg && qstate->env->neg_cache) {
|
||||
if(!msg && qstate->env->neg_cache &&
|
||||
iter_qname_indicates_dnssec(qstate->env, &qstate->qinfo)) {
|
||||
/* lookup in negative cache; may result in
|
||||
* NOERROR/NODATA or NXDOMAIN answers that need validation */
|
||||
msg = val_neg_getmsg(qstate->env->neg_cache, &qstate->qinfo,
|
||||
|
||||
@@ -87,6 +87,8 @@ struct cachedb_backend {
|
||||
uint8_t*, size_t);
|
||||
};
|
||||
|
||||
#define CACHEDB_HASHSIZE 256 /* bit hash */
|
||||
|
||||
/** Init the cachedb module */
|
||||
int cachedb_init(struct module_env* env, int id);
|
||||
/** Deinit the cachedb module */
|
||||
|
||||
+283
@@ -0,0 +1,283 @@
|
||||
/*
|
||||
* cachedb/redis.c - cachedb redis module
|
||||
*
|
||||
* Copyright (c) 2018, NLnet Labs. All rights reserved.
|
||||
*
|
||||
* This software is open source.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* Neither the name of the NLNET LABS nor the names of its contributors may
|
||||
* be used to endorse or promote products derived from this software without
|
||||
* specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
|
||||
* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* \file
|
||||
*
|
||||
* This file contains a module that uses the redis database to cache
|
||||
* dns responses.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#ifdef USE_CACHEDB
|
||||
#include "cachedb/redis.h"
|
||||
#include "cachedb/cachedb.h"
|
||||
#include "util/alloc.h"
|
||||
#include "util/config_file.h"
|
||||
#include "sldns/sbuffer.h"
|
||||
|
||||
#ifdef USE_REDIS
|
||||
#include "hiredis/hiredis.h"
|
||||
|
||||
struct redis_moddata {
|
||||
redisContext** ctxs; /* thread-specific redis contexts */
|
||||
int numctxs; /* number of ctx entries */
|
||||
const char* server_host; /* server's IP address or host name */
|
||||
int server_port; /* server's TCP port */
|
||||
struct timeval timeout; /* timeout for connection setup and commands */
|
||||
};
|
||||
|
||||
static redisContext*
|
||||
redis_connect(const struct redis_moddata* moddata)
|
||||
{
|
||||
redisContext* ctx;
|
||||
|
||||
ctx = redisConnectWithTimeout(moddata->server_host,
|
||||
moddata->server_port, moddata->timeout);
|
||||
if(!ctx || ctx->err) {
|
||||
const char *errstr = "out of memory";
|
||||
if(ctx)
|
||||
errstr = ctx->errstr;
|
||||
log_err("failed to connect to redis server: %s", errstr);
|
||||
goto fail;
|
||||
}
|
||||
if(redisSetTimeout(ctx, moddata->timeout) != REDIS_OK) {
|
||||
log_err("failed to set redis timeout");
|
||||
goto fail;
|
||||
}
|
||||
return ctx;
|
||||
|
||||
fail:
|
||||
if(ctx)
|
||||
redisFree(ctx);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int
|
||||
redis_init(struct module_env* env, struct cachedb_env* cachedb_env)
|
||||
{
|
||||
int i;
|
||||
struct redis_moddata* moddata = NULL;
|
||||
|
||||
verbose(VERB_ALGO, "redis_init");
|
||||
|
||||
moddata = calloc(1, sizeof(struct redis_moddata));
|
||||
if(!moddata) {
|
||||
log_err("out of memory");
|
||||
return 0;
|
||||
}
|
||||
moddata->numctxs = env->cfg->num_threads;
|
||||
moddata->ctxs = calloc(env->cfg->num_threads, sizeof(redisContext*));
|
||||
if(!moddata->ctxs) {
|
||||
log_err("out of memory");
|
||||
free(moddata);
|
||||
return 0;
|
||||
}
|
||||
/* note: server_host is a shallow reference to configured string.
|
||||
* we don't have to free it in this module. */
|
||||
moddata->server_host = env->cfg->redis_server_host;
|
||||
moddata->server_port = env->cfg->redis_server_port;
|
||||
moddata->timeout.tv_sec = env->cfg->redis_timeout / 1000;
|
||||
moddata->timeout.tv_usec = (env->cfg->redis_timeout % 1000) * 1000;
|
||||
for(i = 0; i < moddata->numctxs; i++)
|
||||
moddata->ctxs[i] = redis_connect(moddata);
|
||||
cachedb_env->backend_data = moddata;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void
|
||||
redis_deinit(struct module_env* env, struct cachedb_env* cachedb_env)
|
||||
{
|
||||
struct redis_moddata* moddata = (struct redis_moddata*)
|
||||
cachedb_env->backend_data;
|
||||
(void)env;
|
||||
|
||||
verbose(VERB_ALGO, "redis_deinit");
|
||||
|
||||
if(!moddata)
|
||||
return;
|
||||
if(moddata->ctxs) {
|
||||
int i;
|
||||
for(i = 0; i < moddata->numctxs; i++) {
|
||||
if(moddata->ctxs[i])
|
||||
redisFree(moddata->ctxs[i]);
|
||||
}
|
||||
free(moddata->ctxs);
|
||||
}
|
||||
free(moddata);
|
||||
}
|
||||
|
||||
/*
|
||||
* Send a redis command and get a reply. Unified so that it can be used for
|
||||
* both SET and GET. If 'data' is non-NULL the command is supposed to be
|
||||
* SET and GET otherwise, but the implementation of this function is agnostic
|
||||
* about the semantics (except for logging): 'command', 'data', and 'data_len'
|
||||
* are opaquely passed to redisCommand().
|
||||
* This function first checks whether a connection with a redis server has
|
||||
* been established; if not it tries to set up a new one.
|
||||
* It returns redisReply returned from redisCommand() or NULL if some low
|
||||
* level error happens. The caller is responsible to check the return value,
|
||||
* if it's non-NULL, it has to free it with freeReplyObject().
|
||||
*/
|
||||
static redisReply*
|
||||
redis_command(struct module_env* env, struct cachedb_env* cachedb_env,
|
||||
const char* command, const uint8_t* data, size_t data_len)
|
||||
{
|
||||
redisContext* ctx;
|
||||
redisReply* rep;
|
||||
struct redis_moddata* d = (struct redis_moddata*)
|
||||
cachedb_env->backend_data;
|
||||
|
||||
/* We assume env->alloc->thread_num is a unique ID for each thread
|
||||
* in [0, num-of-threads). We could treat it as an error condition
|
||||
* if the assumption didn't hold, but it seems to be a fundamental
|
||||
* assumption throughout the unbound architecture, so we simply assert
|
||||
* it. */
|
||||
log_assert(env->alloc->thread_num < d->numctxs);
|
||||
ctx = d->ctxs[env->alloc->thread_num];
|
||||
|
||||
/* If we've not established a connection to the server or we've closed
|
||||
* it on a failure, try to re-establish a new one. Failures will be
|
||||
* logged in redis_connect(). */
|
||||
if(!ctx) {
|
||||
ctx = redis_connect(d);
|
||||
d->ctxs[env->alloc->thread_num] = ctx;
|
||||
}
|
||||
if(!ctx)
|
||||
return NULL;
|
||||
|
||||
/* Send the command and get a reply, synchronously. */
|
||||
rep = (redisReply*)redisCommand(ctx, command, data, data_len);
|
||||
if(!rep) {
|
||||
/* Once an error as a NULL-reply is returned the context cannot
|
||||
* be reused and we'll need to set up a new connection. */
|
||||
log_err("redis_command: failed to receive a reply, "
|
||||
"closing connection: %s", ctx->errstr);
|
||||
redisFree(ctx);
|
||||
d->ctxs[env->alloc->thread_num] = NULL;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Check error in reply to unify logging in that case.
|
||||
* The caller may perform context-dependent checks and logging. */
|
||||
if(rep->type == REDIS_REPLY_ERROR)
|
||||
log_err("redis: %s resulted in an error: %s",
|
||||
data ? "set" : "get", rep->str);
|
||||
|
||||
return rep;
|
||||
}
|
||||
|
||||
static int
|
||||
redis_lookup(struct module_env* env, struct cachedb_env* cachedb_env,
|
||||
char* key, struct sldns_buffer* result_buffer)
|
||||
{
|
||||
redisReply* rep;
|
||||
char cmdbuf[4+(CACHEDB_HASHSIZE/8)*2+1]; /* "GET " + key */
|
||||
int n;
|
||||
int ret = 0;
|
||||
|
||||
verbose(VERB_ALGO, "redis_lookup of %s", key);
|
||||
|
||||
n = snprintf(cmdbuf, sizeof(cmdbuf), "GET %s", key);
|
||||
if(n < 0 || n >= (int)sizeof(cmdbuf)) {
|
||||
log_err("redis_lookup: unexpected failure to build command");
|
||||
return 0;
|
||||
}
|
||||
|
||||
rep = redis_command(env, cachedb_env, cmdbuf, NULL, 0);
|
||||
if(!rep)
|
||||
return 0;
|
||||
switch (rep->type) {
|
||||
case REDIS_REPLY_NIL:
|
||||
verbose(VERB_ALGO, "redis_lookup: no data cached");
|
||||
break;
|
||||
case REDIS_REPLY_STRING:
|
||||
verbose(VERB_ALGO, "redis_lookup found %d bytes",
|
||||
(int)rep->len);
|
||||
if((size_t)rep->len > sldns_buffer_capacity(result_buffer)) {
|
||||
log_err("redis_lookup: replied data too long: %lu",
|
||||
(size_t)rep->len);
|
||||
break;
|
||||
}
|
||||
sldns_buffer_clear(result_buffer);
|
||||
sldns_buffer_write(result_buffer, rep->str, rep->len);
|
||||
sldns_buffer_flip(result_buffer);
|
||||
ret = 1;
|
||||
break;
|
||||
case REDIS_REPLY_ERROR:
|
||||
break; /* already logged */
|
||||
default:
|
||||
log_err("redis_lookup: unexpected type of reply for (%d)",
|
||||
rep->type);
|
||||
break;
|
||||
}
|
||||
freeReplyObject(rep);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void
|
||||
redis_store(struct module_env* env, struct cachedb_env* cachedb_env,
|
||||
char* key, uint8_t* data, size_t data_len)
|
||||
{
|
||||
redisReply* rep;
|
||||
char cmdbuf[4+(CACHEDB_HASHSIZE/8)*2+3+1]; /* "SET " + key + " %b" */
|
||||
int n;
|
||||
|
||||
verbose(VERB_ALGO, "redis_store %s (%d bytes)", key, (int)data_len);
|
||||
|
||||
/* build command to set to a binary safe string */
|
||||
n = snprintf(cmdbuf, sizeof(cmdbuf), "SET %s %%b", key);
|
||||
if(n < 0 || n >= (int)sizeof(cmdbuf)) {
|
||||
log_err("redis_store: unexpected failure to build command");
|
||||
return;
|
||||
}
|
||||
|
||||
rep = redis_command(env, cachedb_env, cmdbuf, data, data_len);
|
||||
if(rep) {
|
||||
verbose(VERB_ALGO, "redis_store set completed");
|
||||
if(rep->type != REDIS_REPLY_STATUS &&
|
||||
rep->type != REDIS_REPLY_ERROR) {
|
||||
log_err("redis_store: unexpected type of reply (%d)",
|
||||
rep->type);
|
||||
}
|
||||
freeReplyObject(rep);
|
||||
}
|
||||
}
|
||||
|
||||
struct cachedb_backend redis_backend = { "redis",
|
||||
redis_init, redis_deinit, redis_lookup, redis_store
|
||||
};
|
||||
#endif /* USE_REDIS */
|
||||
#endif /* USE_CACHEDB */
|
||||
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* cachedb/redis.h - cachedb redis module
|
||||
*
|
||||
* Copyright (c) 2018, NLnet Labs. All rights reserved.
|
||||
*
|
||||
* This software is open source.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* Neither the name of the NLNET LABS nor the names of its contributors may
|
||||
* be used to endorse or promote products derived from this software without
|
||||
* specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
|
||||
* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* \file
|
||||
*
|
||||
* This file contains a module that uses the redis database to cache
|
||||
* dns responses.
|
||||
*/
|
||||
|
||||
/** the redis backend definition, contains callable functions
|
||||
* and name string */
|
||||
extern struct cachedb_backend redis_backend;
|
||||
+71
-2
@@ -71,6 +71,72 @@ static struct {
|
||||
|
||||
static inline void _rs_rekey(u_char *dat, size_t datlen);
|
||||
|
||||
/*
|
||||
* Basic sanity checking; wish we could do better.
|
||||
*/
|
||||
static int
|
||||
fallback_gotdata(char *buf, size_t len)
|
||||
{
|
||||
char any_set = 0;
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < len; ++i)
|
||||
any_set |= buf[i];
|
||||
if (any_set == 0)
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* fallback for getentropy in case libc returns failure */
|
||||
static int
|
||||
fallback_getentropy_urandom(void *buf, size_t len)
|
||||
{
|
||||
size_t i;
|
||||
int fd, flags;
|
||||
int save_errno = errno;
|
||||
|
||||
start:
|
||||
|
||||
flags = O_RDONLY;
|
||||
#ifdef O_NOFOLLOW
|
||||
flags |= O_NOFOLLOW;
|
||||
#endif
|
||||
#ifdef O_CLOEXEC
|
||||
flags |= O_CLOEXEC;
|
||||
#endif
|
||||
fd = open("/dev/urandom", flags, 0);
|
||||
if (fd == -1) {
|
||||
if (errno == EINTR)
|
||||
goto start;
|
||||
goto nodevrandom;
|
||||
}
|
||||
#ifndef O_CLOEXEC
|
||||
# ifdef HAVE_FCNTL
|
||||
fcntl(fd, F_SETFD, fcntl(fd, F_GETFD) | FD_CLOEXEC);
|
||||
# endif
|
||||
#endif
|
||||
for (i = 0; i < len; ) {
|
||||
size_t wanted = len - i;
|
||||
ssize_t ret = read(fd, (char*)buf + i, wanted);
|
||||
|
||||
if (ret == -1) {
|
||||
if (errno == EAGAIN || errno == EINTR)
|
||||
continue;
|
||||
close(fd);
|
||||
goto nodevrandom;
|
||||
}
|
||||
i += ret;
|
||||
}
|
||||
close(fd);
|
||||
if (fallback_gotdata(buf, len) == 0) {
|
||||
errno = save_errno;
|
||||
return 0; /* satisfied */
|
||||
}
|
||||
nodevrandom:
|
||||
errno = EIO;
|
||||
return -1;
|
||||
}
|
||||
|
||||
static inline void
|
||||
_rs_init(u_char *buf, size_t n)
|
||||
{
|
||||
@@ -114,11 +180,14 @@ _rs_stir(void)
|
||||
u_char rnd[KEYSZ + IVSZ];
|
||||
|
||||
if (getentropy(rnd, sizeof rnd) == -1) {
|
||||
if(errno != ENOSYS ||
|
||||
fallback_getentropy_urandom(rnd, sizeof rnd) == -1) {
|
||||
#ifdef SIGKILL
|
||||
raise(SIGKILL);
|
||||
raise(SIGKILL);
|
||||
#else
|
||||
exit(9); /* windows */
|
||||
exit(9); /* windows */
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
if (!rs)
|
||||
|
||||
+45
-1
@@ -1,5 +1,11 @@
|
||||
/* config.h.in. Generated from configure.ac by autoheader. */
|
||||
|
||||
/* apply the noreturn attribute to a function that exits the program */
|
||||
#undef ATTR_NORETURN
|
||||
|
||||
/* apply the weak attribute to a symbol */
|
||||
#undef ATTR_WEAK
|
||||
|
||||
/* Directory to chroot to */
|
||||
#undef CHROOT_DIR
|
||||
|
||||
@@ -30,6 +36,9 @@
|
||||
internal symbols */
|
||||
#undef EXPORT_ALL_SYMBOLS
|
||||
|
||||
/* Define to 1 if you have the `accept4' function. */
|
||||
#undef HAVE_ACCEPT4
|
||||
|
||||
/* Define to 1 if you have the `arc4random' function. */
|
||||
#undef HAVE_ARC4RANDOM
|
||||
|
||||
@@ -42,6 +51,9 @@
|
||||
/* Whether the C compiler accepts the "format" attribute */
|
||||
#undef HAVE_ATTR_FORMAT
|
||||
|
||||
/* Whether the C compiler accepts the "noreturn" attribute */
|
||||
#undef HAVE_ATTR_NORETURN
|
||||
|
||||
/* Whether the C compiler accepts the "unused" attribute */
|
||||
#undef HAVE_ATTR_UNUSED
|
||||
|
||||
@@ -83,6 +95,10 @@
|
||||
don't. */
|
||||
#undef HAVE_DECL_NID_ED25519
|
||||
|
||||
/* Define to 1 if you have the declaration of `NID_ED448', and to 0 if you
|
||||
don't. */
|
||||
#undef HAVE_DECL_NID_ED448
|
||||
|
||||
/* Define to 1 if you have the declaration of `NID_secp384r1', and to 0 if you
|
||||
don't. */
|
||||
#undef HAVE_DECL_NID_SECP384R1
|
||||
@@ -95,6 +111,10 @@
|
||||
don't. */
|
||||
#undef HAVE_DECL_REALLOCARRAY
|
||||
|
||||
/* Define to 1 if you have the declaration of `redisConnect', and to 0 if you
|
||||
don't. */
|
||||
#undef HAVE_DECL_REDISCONNECT
|
||||
|
||||
/* Define to 1 if you have the declaration of `sk_SSL_COMP_pop_free', and to 0
|
||||
if you don't. */
|
||||
#undef HAVE_DECL_SK_SSL_COMP_POP_FREE
|
||||
@@ -188,6 +208,9 @@
|
||||
/* Define to 1 if you have the <expat.h> header file. */
|
||||
#undef HAVE_EXPAT_H
|
||||
|
||||
/* Define to 1 if you have the `explicit_bzero' function. */
|
||||
#undef HAVE_EXPLICIT_BZERO
|
||||
|
||||
/* Define to 1 if you have the `fcntl' function. */
|
||||
#undef HAVE_FCNTL
|
||||
|
||||
@@ -233,6 +256,9 @@
|
||||
/* Define to 1 if you have the <grp.h> header file. */
|
||||
#undef HAVE_GRP_H
|
||||
|
||||
/* Define to 1 if you have the <hiredis/hiredis.h> header file. */
|
||||
#undef HAVE_HIREDIS_HIREDIS_H
|
||||
|
||||
/* If you have HMAC_Update */
|
||||
#undef HAVE_HMAC_UPDATE
|
||||
|
||||
@@ -263,6 +289,9 @@
|
||||
/* Define to 1 if you have the `kill' function. */
|
||||
#undef HAVE_KILL
|
||||
|
||||
/* Define to 1 if you have the <libkern/OSByteOrder.h> header file. */
|
||||
#undef HAVE_LIBKERN_OSBYTEORDER_H
|
||||
|
||||
/* Define if we have LibreSSL */
|
||||
#undef HAVE_LIBRESSL
|
||||
|
||||
@@ -479,6 +508,9 @@
|
||||
/* Define to 1 if systemd should be used */
|
||||
#undef HAVE_SYSTEMD
|
||||
|
||||
/* Define to 1 if you have the <sys/endian.h> header file. */
|
||||
#undef HAVE_SYS_ENDIAN_H
|
||||
|
||||
/* Define to 1 if you have the <sys/ipc.h> header file. */
|
||||
#undef HAVE_SYS_IPC_H
|
||||
|
||||
@@ -703,6 +735,9 @@
|
||||
/* Define this to enable ED25519 support. */
|
||||
#undef USE_ED25519
|
||||
|
||||
/* Define this to enable ED448 support. */
|
||||
#undef USE_ED448
|
||||
|
||||
/* Define this to enable GOST support. */
|
||||
#undef USE_GOST
|
||||
|
||||
@@ -718,6 +753,9 @@
|
||||
/* Define this to enable client TCP Fast Open. */
|
||||
#undef USE_OSX_MSG_FASTOPEN
|
||||
|
||||
/* Define this to use hiredis client. */
|
||||
#undef USE_REDIS
|
||||
|
||||
/* Define this to enable SHA1 support. */
|
||||
#undef USE_SHA1
|
||||
|
||||
@@ -1118,6 +1156,11 @@ char *strsep(char **stringp, const char *delim);
|
||||
int isblank(int c);
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_EXPLICIT_BZERO
|
||||
#define explicit_bzero unbound_explicit_bzero
|
||||
void explicit_bzero(void* buf, size_t len);
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_INET_NTOP) && !HAVE_DECL_INET_NTOP
|
||||
const char *inet_ntop(int af, const void *src, char *dst, size_t size);
|
||||
#endif
|
||||
@@ -1150,7 +1193,6 @@ void *reallocarray(void *ptr, size_t nmemb, size_t size);
|
||||
# endif
|
||||
#endif /* HAVE_LIBRESSL */
|
||||
#ifndef HAVE_ARC4RANDOM
|
||||
void explicit_bzero(void* buf, size_t len);
|
||||
int getentropy(void* buf, size_t len);
|
||||
uint32_t arc4random(void);
|
||||
void arc4random_buf(void* buf, size_t n);
|
||||
@@ -1222,6 +1264,8 @@ void *unbound_stat_realloc_log(void *ptr, size_t size, const char* file,
|
||||
|
||||
/** default port for DNS traffic. */
|
||||
#define UNBOUND_DNS_PORT 53
|
||||
/** default port for DNS over TLS traffic. */
|
||||
#define UNBOUND_DNS_OVER_TLS_PORT 853
|
||||
/** default port for unbound control traffic, registered port with IANA,
|
||||
ub-dns-control 8953/tcp unbound dns nameserver control */
|
||||
#define UNBOUND_CONTROL_PORT 8953
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#! /bin/sh
|
||||
# Guess values for system-dependent variables and create Makefiles.
|
||||
# Generated by GNU Autoconf 2.69 for unbound 1.7.0.
|
||||
# Generated by GNU Autoconf 2.69 for unbound 1.8.1.
|
||||
#
|
||||
# Report bugs to <unbound-bugs@nlnetlabs.nl>.
|
||||
#
|
||||
@@ -590,8 +590,8 @@ MAKEFLAGS=
|
||||
# Identity of this package.
|
||||
PACKAGE_NAME='unbound'
|
||||
PACKAGE_TARNAME='unbound'
|
||||
PACKAGE_VERSION='1.7.0'
|
||||
PACKAGE_STRING='unbound 1.7.0'
|
||||
PACKAGE_VERSION='1.8.1'
|
||||
PACKAGE_STRING='unbound 1.8.1'
|
||||
PACKAGE_BUGREPORT='unbound-bugs@nlnetlabs.nl'
|
||||
PACKAGE_URL=''
|
||||
|
||||
@@ -670,9 +670,6 @@ SYSTEMD_DAEMON_LIBS
|
||||
SYSTEMD_DAEMON_CFLAGS
|
||||
SYSTEMD_LIBS
|
||||
SYSTEMD_CFLAGS
|
||||
PKG_CONFIG_LIBDIR
|
||||
PKG_CONFIG_PATH
|
||||
PKG_CONFIG
|
||||
staticexe
|
||||
PC_LIBEVENT_DEPENDENCY
|
||||
UNBOUND_EVENT_UNINSTALL
|
||||
@@ -697,6 +694,9 @@ swig
|
||||
SWIG_LIB
|
||||
SWIG
|
||||
PC_PY_DEPENDENCY
|
||||
PKG_CONFIG_LIBDIR
|
||||
PKG_CONFIG_PATH
|
||||
PKG_CONFIG
|
||||
PY_MAJOR_VERSION
|
||||
PYTHON_SITE_PKG
|
||||
PYTHON_LDFLAGS
|
||||
@@ -859,11 +859,13 @@ enable_gost
|
||||
enable_ecdsa
|
||||
enable_dsa
|
||||
enable_ed25519
|
||||
enable_ed448
|
||||
enable_event_api
|
||||
enable_tfo_client
|
||||
enable_tfo_server
|
||||
with_libevent
|
||||
with_libexpat
|
||||
with_libhiredis
|
||||
enable_static_exe
|
||||
enable_systemd
|
||||
enable_lock_checks
|
||||
@@ -1438,7 +1440,7 @@ if test "$ac_init_help" = "long"; then
|
||||
# Omit some internal or obsolete options to make the list less imposing.
|
||||
# This message is too long to be a string in the A/UX 3.1 sh.
|
||||
cat <<_ACEOF
|
||||
\`configure' configures unbound 1.7.0 to adapt to many kinds of systems.
|
||||
\`configure' configures unbound 1.8.1 to adapt to many kinds of systems.
|
||||
|
||||
Usage: $0 [OPTION]... [VAR=VALUE]...
|
||||
|
||||
@@ -1503,7 +1505,7 @@ fi
|
||||
|
||||
if test -n "$ac_init_help"; then
|
||||
case $ac_init_help in
|
||||
short | recursive ) echo "Configuration of unbound 1.7.0:";;
|
||||
short | recursive ) echo "Configuration of unbound 1.8.1:";;
|
||||
esac
|
||||
cat <<\_ACEOF
|
||||
|
||||
@@ -1544,6 +1546,7 @@ Optional Features:
|
||||
--disable-ecdsa Disable ECDSA support
|
||||
--disable-dsa Disable DSA support
|
||||
--disable-ed25519 Disable ED25519 support
|
||||
--disable-ed448 Disable ED448 support
|
||||
--enable-event-api Enable (experimental) pluggable event base
|
||||
libunbound API installed to unbound-event.h
|
||||
--enable-tfo-client Enable TCP Fast Open for client mode
|
||||
@@ -1610,6 +1613,7 @@ Optional Packages:
|
||||
an explicit path). Slower, but allows use of large
|
||||
outgoing port ranges.
|
||||
--with-libexpat=path specify explicit path for libexpat.
|
||||
--with-libhiredis=path specify explicit path for libhiredis.
|
||||
--with-dnstap-socket-path=pathname
|
||||
set default dnstap socket path
|
||||
--with-protobuf-c=path Path where protobuf-c is installed, for dnstap
|
||||
@@ -1718,7 +1722,7 @@ fi
|
||||
test -n "$ac_init_help" && exit $ac_status
|
||||
if $ac_init_version; then
|
||||
cat <<\_ACEOF
|
||||
unbound configure 1.7.0
|
||||
unbound configure 1.8.1
|
||||
generated by GNU Autoconf 2.69
|
||||
|
||||
Copyright (C) 2012 Free Software Foundation, Inc.
|
||||
@@ -2427,7 +2431,7 @@ cat >config.log <<_ACEOF
|
||||
This file contains any messages produced by compilers while
|
||||
running configure, to aid debugging if configure makes a mistake.
|
||||
|
||||
It was created by unbound $as_me 1.7.0, which was
|
||||
It was created by unbound $as_me 1.8.1, which was
|
||||
generated by GNU Autoconf 2.69. Invocation command line was
|
||||
|
||||
$ $0 $@
|
||||
@@ -2777,14 +2781,14 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu
|
||||
|
||||
UNBOUND_VERSION_MAJOR=1
|
||||
|
||||
UNBOUND_VERSION_MINOR=7
|
||||
UNBOUND_VERSION_MINOR=8
|
||||
|
||||
UNBOUND_VERSION_MICRO=0
|
||||
UNBOUND_VERSION_MICRO=1
|
||||
|
||||
|
||||
LIBUNBOUND_CURRENT=7
|
||||
LIBUNBOUND_REVISION=8
|
||||
LIBUNBOUND_AGE=5
|
||||
LIBUNBOUND_CURRENT=8
|
||||
LIBUNBOUND_REVISION=1
|
||||
LIBUNBOUND_AGE=0
|
||||
# 1.0.0 had 0:12:0
|
||||
# 1.0.1 had 0:13:0
|
||||
# 1.0.2 had 0:14:0
|
||||
@@ -2843,6 +2847,11 @@ LIBUNBOUND_AGE=5
|
||||
# 1.6.7 had 7:6:5
|
||||
# 1.6.8 had 7:7:5
|
||||
# 1.7.0 had 7:8:5
|
||||
# 1.7.1 had 7:9:5
|
||||
# 1.7.2 had 7:10:5
|
||||
# 1.7.3 had 7:11:5
|
||||
# 1.8.0 had 8:0:0 # changes the event callback function signature
|
||||
# 1.8.1 had 8:1:0
|
||||
|
||||
# Current -- the number of the binary API that we're implementing
|
||||
# Revision -- which iteration of the implementation of the binary
|
||||
@@ -6257,6 +6266,54 @@ if test $ac_cv_c_weak_attribute = yes; then
|
||||
|
||||
$as_echo "#define HAVE_ATTR_WEAK 1" >>confdefs.h
|
||||
|
||||
|
||||
$as_echo "#define ATTR_WEAK __attribute__((weak))" >>confdefs.h
|
||||
|
||||
fi
|
||||
|
||||
|
||||
|
||||
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler (${CC-cc}) accepts the \"noreturn\" attribute" >&5
|
||||
$as_echo_n "checking whether the C compiler (${CC-cc}) accepts the \"noreturn\" attribute... " >&6; }
|
||||
if ${ac_cv_c_noreturn_attribute+:} false; then :
|
||||
$as_echo_n "(cached) " >&6
|
||||
else
|
||||
ac_cv_c_noreturn_attribute=no
|
||||
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||
/* end confdefs.h. */
|
||||
#include <stdio.h>
|
||||
__attribute__((noreturn)) void f(int x) { printf("%d", x); }
|
||||
|
||||
int
|
||||
main ()
|
||||
{
|
||||
|
||||
f(1);
|
||||
|
||||
;
|
||||
return 0;
|
||||
}
|
||||
_ACEOF
|
||||
if ac_fn_c_try_compile "$LINENO"; then :
|
||||
ac_cv_c_noreturn_attribute="yes"
|
||||
else
|
||||
ac_cv_c_noreturn_attribute="no"
|
||||
fi
|
||||
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
|
||||
|
||||
fi
|
||||
|
||||
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_noreturn_attribute" >&5
|
||||
$as_echo "$ac_cv_c_noreturn_attribute" >&6; }
|
||||
if test $ac_cv_c_noreturn_attribute = yes; then
|
||||
|
||||
$as_echo "#define HAVE_ATTR_NORETURN 1" >>confdefs.h
|
||||
|
||||
|
||||
$as_echo "#define ATTR_NORETURN __attribute__((__noreturn__))" >>confdefs.h
|
||||
|
||||
fi
|
||||
|
||||
|
||||
@@ -6266,6 +6323,8 @@ fi
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
for ac_prog in flex lex
|
||||
do
|
||||
# Extract the first word of "$ac_prog", so it can be a program name with args.
|
||||
@@ -6425,6 +6484,7 @@ fi
|
||||
rm -f conftest.l $LEX_OUTPUT_ROOT.c
|
||||
|
||||
fi
|
||||
if test "$LEX" != "" -a "$LEX" != ":"; then
|
||||
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for yylex_destroy" >&5
|
||||
$as_echo_n "checking for yylex_destroy... " >&6; }
|
||||
@@ -6435,8 +6495,27 @@ $as_echo "#define LEX_HAS_YYLEX_DESTROY 1" >>confdefs.h
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
|
||||
$as_echo "yes" >&6; }
|
||||
else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
|
||||
$as_echo "no" >&6; }; fi
|
||||
$as_echo "no" >&6; };
|
||||
LEX=":"
|
||||
fi
|
||||
|
||||
fi
|
||||
if test "$LEX" != "" -a "$LEX" != ":"; then
|
||||
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for lex %option" >&5
|
||||
$as_echo_n "checking for lex %option... " >&6; }
|
||||
if cat <<EOF | $LEX -t 2>&1 | grep yy_delete_buffer >/dev/null 2>&1; then
|
||||
%option nounput
|
||||
%%
|
||||
EOF
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
|
||||
$as_echo "yes" >&6; }
|
||||
else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
|
||||
$as_echo "no" >&6; };
|
||||
LEX=":"
|
||||
fi
|
||||
|
||||
fi
|
||||
for ac_prog in 'bison -y' byacc
|
||||
do
|
||||
# Extract the first word of "$ac_prog", so it can be a program name with args.
|
||||
@@ -14477,7 +14556,7 @@ CC=$lt_save_CC
|
||||
|
||||
|
||||
# Checks for header files.
|
||||
for ac_header in stdarg.h stdbool.h netinet/in.h netinet/tcp.h sys/param.h sys/socket.h sys/un.h sys/uio.h sys/resource.h arpa/inet.h syslog.h netdb.h sys/wait.h pwd.h glob.h grp.h login_cap.h winsock2.h ws2tcpip.h endian.h sys/ipc.h sys/shm.h
|
||||
for ac_header in stdarg.h stdbool.h netinet/in.h netinet/tcp.h sys/param.h sys/socket.h sys/un.h sys/uio.h sys/resource.h arpa/inet.h syslog.h netdb.h sys/wait.h pwd.h glob.h grp.h login_cap.h winsock2.h ws2tcpip.h endian.h sys/endian.h libkern/OSByteOrder.h sys/ipc.h sys/shm.h
|
||||
do :
|
||||
as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
|
||||
ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default
|
||||
@@ -16922,7 +17001,136 @@ $as_echo "#define HAVE_PYTHON 1" >>confdefs.h
|
||||
CPPFLAGS="$PYTHON_CPPFLAGS"
|
||||
fi
|
||||
ub_have_python=yes
|
||||
PC_PY_DEPENDENCY="python"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then
|
||||
if test -n "$ac_tool_prefix"; then
|
||||
# Extract the first word of "${ac_tool_prefix}pkg-config", so it can be a program name with args.
|
||||
set dummy ${ac_tool_prefix}pkg-config; ac_word=$2
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
|
||||
$as_echo_n "checking for $ac_word... " >&6; }
|
||||
if ${ac_cv_path_PKG_CONFIG+:} false; then :
|
||||
$as_echo_n "(cached) " >&6
|
||||
else
|
||||
case $PKG_CONFIG in
|
||||
[\\/]* | ?:[\\/]*)
|
||||
ac_cv_path_PKG_CONFIG="$PKG_CONFIG" # Let the user override the test with a path.
|
||||
;;
|
||||
*)
|
||||
as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
|
||||
for as_dir in $PATH
|
||||
do
|
||||
IFS=$as_save_IFS
|
||||
test -z "$as_dir" && as_dir=.
|
||||
for ac_exec_ext in '' $ac_executable_extensions; do
|
||||
if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
|
||||
ac_cv_path_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext"
|
||||
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
|
||||
break 2
|
||||
fi
|
||||
done
|
||||
done
|
||||
IFS=$as_save_IFS
|
||||
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
PKG_CONFIG=$ac_cv_path_PKG_CONFIG
|
||||
if test -n "$PKG_CONFIG"; then
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $PKG_CONFIG" >&5
|
||||
$as_echo "$PKG_CONFIG" >&6; }
|
||||
else
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
|
||||
$as_echo "no" >&6; }
|
||||
fi
|
||||
|
||||
|
||||
fi
|
||||
if test -z "$ac_cv_path_PKG_CONFIG"; then
|
||||
ac_pt_PKG_CONFIG=$PKG_CONFIG
|
||||
# Extract the first word of "pkg-config", so it can be a program name with args.
|
||||
set dummy pkg-config; ac_word=$2
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
|
||||
$as_echo_n "checking for $ac_word... " >&6; }
|
||||
if ${ac_cv_path_ac_pt_PKG_CONFIG+:} false; then :
|
||||
$as_echo_n "(cached) " >&6
|
||||
else
|
||||
case $ac_pt_PKG_CONFIG in
|
||||
[\\/]* | ?:[\\/]*)
|
||||
ac_cv_path_ac_pt_PKG_CONFIG="$ac_pt_PKG_CONFIG" # Let the user override the test with a path.
|
||||
;;
|
||||
*)
|
||||
as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
|
||||
for as_dir in $PATH
|
||||
do
|
||||
IFS=$as_save_IFS
|
||||
test -z "$as_dir" && as_dir=.
|
||||
for ac_exec_ext in '' $ac_executable_extensions; do
|
||||
if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
|
||||
ac_cv_path_ac_pt_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext"
|
||||
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
|
||||
break 2
|
||||
fi
|
||||
done
|
||||
done
|
||||
IFS=$as_save_IFS
|
||||
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
ac_pt_PKG_CONFIG=$ac_cv_path_ac_pt_PKG_CONFIG
|
||||
if test -n "$ac_pt_PKG_CONFIG"; then
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_pt_PKG_CONFIG" >&5
|
||||
$as_echo "$ac_pt_PKG_CONFIG" >&6; }
|
||||
else
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
|
||||
$as_echo "no" >&6; }
|
||||
fi
|
||||
|
||||
if test "x$ac_pt_PKG_CONFIG" = x; then
|
||||
PKG_CONFIG=""
|
||||
else
|
||||
case $cross_compiling:$ac_tool_warned in
|
||||
yes:)
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
|
||||
$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
|
||||
ac_tool_warned=yes ;;
|
||||
esac
|
||||
PKG_CONFIG=$ac_pt_PKG_CONFIG
|
||||
fi
|
||||
else
|
||||
PKG_CONFIG="$ac_cv_path_PKG_CONFIG"
|
||||
fi
|
||||
|
||||
fi
|
||||
if test -n "$PKG_CONFIG"; then
|
||||
_pkg_min_version=0.9.0
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking pkg-config is at least version $_pkg_min_version" >&5
|
||||
$as_echo_n "checking pkg-config is at least version $_pkg_min_version... " >&6; }
|
||||
if $PKG_CONFIG --atleast-pkgconfig-version $_pkg_min_version; then
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
|
||||
$as_echo "yes" >&6; }
|
||||
else
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
|
||||
$as_echo "no" >&6; }
|
||||
PKG_CONFIG=""
|
||||
fi
|
||||
fi
|
||||
if test -n "$PKG_CONFIG" && \
|
||||
{ { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"\"python\${PY_MAJOR_VERSION}\"\""; } >&5
|
||||
($PKG_CONFIG --exists --print-errors ""python${PY_MAJOR_VERSION}"") 2>&5
|
||||
ac_status=$?
|
||||
$as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
|
||||
test $ac_status = 0; }; then
|
||||
PC_PY_DEPENDENCY="python${PY_MAJOR_VERSION}"
|
||||
else
|
||||
PC_PY_DEPENDENCY="python"
|
||||
fi
|
||||
|
||||
|
||||
# Check for SWIG
|
||||
@@ -18314,6 +18522,50 @@ _ACEOF
|
||||
;;
|
||||
esac
|
||||
|
||||
# Check whether --enable-ed448 was given.
|
||||
if test "${enable_ed448+set}" = set; then :
|
||||
enableval=$enable_ed448;
|
||||
fi
|
||||
|
||||
use_ed448="no"
|
||||
case "$enable_ed448" in
|
||||
no)
|
||||
;;
|
||||
*)
|
||||
if test $USE_NSS = "no" -a $USE_NETTLE = "no"; then
|
||||
ac_fn_c_check_decl "$LINENO" "NID_ED448" "ac_cv_have_decl_NID_ED448" "$ac_includes_default
|
||||
#include <openssl/evp.h>
|
||||
|
||||
"
|
||||
if test "x$ac_cv_have_decl_NID_ED448" = xyes; then :
|
||||
ac_have_decl=1
|
||||
else
|
||||
ac_have_decl=0
|
||||
fi
|
||||
|
||||
cat >>confdefs.h <<_ACEOF
|
||||
#define HAVE_DECL_NID_ED448 $ac_have_decl
|
||||
_ACEOF
|
||||
if test $ac_have_decl = 1; then :
|
||||
|
||||
use_ed448="yes"
|
||||
|
||||
else
|
||||
if test "x$enable_ed448" = "xyes"; then as_fn_error $? "OpenSSL does not support ED448 and you used --enable-ed448." "$LINENO" 5
|
||||
fi
|
||||
fi
|
||||
|
||||
fi
|
||||
if test $use_ed448 = "yes"; then
|
||||
|
||||
cat >>confdefs.h <<_ACEOF
|
||||
#define USE_ED448 1
|
||||
_ACEOF
|
||||
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
|
||||
# Check whether --enable-event-api was given.
|
||||
if test "${enable_event_api+set}" = set; then :
|
||||
enableval=$enable_event_api;
|
||||
@@ -18810,6 +19062,70 @@ cat >>confdefs.h <<_ACEOF
|
||||
_ACEOF
|
||||
|
||||
|
||||
# hiredis (redis C client for cachedb)
|
||||
|
||||
# Check whether --with-libhiredis was given.
|
||||
if test "${with_libhiredis+set}" = set; then :
|
||||
withval=$with_libhiredis;
|
||||
else
|
||||
withval="no"
|
||||
fi
|
||||
|
||||
found_libhiredis="no"
|
||||
if test x_$withval = x_yes -o x_$withval != x_no; then
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for libhiredis" >&5
|
||||
$as_echo_n "checking for libhiredis... " >&6; }
|
||||
if test x_$withval = x_ -o x_$withval = x_yes; then
|
||||
withval="/usr/local /opt/local /usr/lib /usr/pkg /usr/sfw /usr"
|
||||
fi
|
||||
for dir in $withval ; do
|
||||
if test -f "$dir/include/hiredis/hiredis.h"; then
|
||||
found_libhiredis="yes"
|
||||
if test "$dir" != "/usr"; then
|
||||
CPPFLAGS="$CPPFLAGS -I$dir/include"
|
||||
LDFLAGS="$LDFLAGS -L$dir/lib"
|
||||
fi
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: found in $dir" >&5
|
||||
$as_echo "found in $dir" >&6; }
|
||||
|
||||
$as_echo "#define USE_REDIS 1" >>confdefs.h
|
||||
|
||||
LIBS="$LIBS -lhiredis"
|
||||
break;
|
||||
fi
|
||||
done
|
||||
if test x_$found_libhiredis != x_yes; then
|
||||
as_fn_error $? "Could not find libhiredis, hiredis.h" "$LINENO" 5
|
||||
fi
|
||||
for ac_header in hiredis/hiredis.h
|
||||
do :
|
||||
ac_fn_c_check_header_compile "$LINENO" "hiredis/hiredis.h" "ac_cv_header_hiredis_hiredis_h" "$ac_includes_default
|
||||
"
|
||||
if test "x$ac_cv_header_hiredis_hiredis_h" = xyes; then :
|
||||
cat >>confdefs.h <<_ACEOF
|
||||
#define HAVE_HIREDIS_HIREDIS_H 1
|
||||
_ACEOF
|
||||
|
||||
fi
|
||||
|
||||
done
|
||||
|
||||
ac_fn_c_check_decl "$LINENO" "redisConnect" "ac_cv_have_decl_redisConnect" "$ac_includes_default
|
||||
#include <hiredis/hiredis.h>
|
||||
|
||||
"
|
||||
if test "x$ac_cv_have_decl_redisConnect" = xyes; then :
|
||||
ac_have_decl=1
|
||||
else
|
||||
ac_have_decl=0
|
||||
fi
|
||||
|
||||
cat >>confdefs.h <<_ACEOF
|
||||
#define HAVE_DECL_REDISCONNECT $ac_have_decl
|
||||
_ACEOF
|
||||
|
||||
fi
|
||||
|
||||
# set static linking if requested
|
||||
|
||||
staticexe=""
|
||||
@@ -18844,126 +19160,6 @@ else
|
||||
fi
|
||||
|
||||
have_systemd=no
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then
|
||||
if test -n "$ac_tool_prefix"; then
|
||||
# Extract the first word of "${ac_tool_prefix}pkg-config", so it can be a program name with args.
|
||||
set dummy ${ac_tool_prefix}pkg-config; ac_word=$2
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
|
||||
$as_echo_n "checking for $ac_word... " >&6; }
|
||||
if ${ac_cv_path_PKG_CONFIG+:} false; then :
|
||||
$as_echo_n "(cached) " >&6
|
||||
else
|
||||
case $PKG_CONFIG in
|
||||
[\\/]* | ?:[\\/]*)
|
||||
ac_cv_path_PKG_CONFIG="$PKG_CONFIG" # Let the user override the test with a path.
|
||||
;;
|
||||
*)
|
||||
as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
|
||||
for as_dir in $PATH
|
||||
do
|
||||
IFS=$as_save_IFS
|
||||
test -z "$as_dir" && as_dir=.
|
||||
for ac_exec_ext in '' $ac_executable_extensions; do
|
||||
if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
|
||||
ac_cv_path_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext"
|
||||
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
|
||||
break 2
|
||||
fi
|
||||
done
|
||||
done
|
||||
IFS=$as_save_IFS
|
||||
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
PKG_CONFIG=$ac_cv_path_PKG_CONFIG
|
||||
if test -n "$PKG_CONFIG"; then
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $PKG_CONFIG" >&5
|
||||
$as_echo "$PKG_CONFIG" >&6; }
|
||||
else
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
|
||||
$as_echo "no" >&6; }
|
||||
fi
|
||||
|
||||
|
||||
fi
|
||||
if test -z "$ac_cv_path_PKG_CONFIG"; then
|
||||
ac_pt_PKG_CONFIG=$PKG_CONFIG
|
||||
# Extract the first word of "pkg-config", so it can be a program name with args.
|
||||
set dummy pkg-config; ac_word=$2
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
|
||||
$as_echo_n "checking for $ac_word... " >&6; }
|
||||
if ${ac_cv_path_ac_pt_PKG_CONFIG+:} false; then :
|
||||
$as_echo_n "(cached) " >&6
|
||||
else
|
||||
case $ac_pt_PKG_CONFIG in
|
||||
[\\/]* | ?:[\\/]*)
|
||||
ac_cv_path_ac_pt_PKG_CONFIG="$ac_pt_PKG_CONFIG" # Let the user override the test with a path.
|
||||
;;
|
||||
*)
|
||||
as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
|
||||
for as_dir in $PATH
|
||||
do
|
||||
IFS=$as_save_IFS
|
||||
test -z "$as_dir" && as_dir=.
|
||||
for ac_exec_ext in '' $ac_executable_extensions; do
|
||||
if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
|
||||
ac_cv_path_ac_pt_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext"
|
||||
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
|
||||
break 2
|
||||
fi
|
||||
done
|
||||
done
|
||||
IFS=$as_save_IFS
|
||||
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
ac_pt_PKG_CONFIG=$ac_cv_path_ac_pt_PKG_CONFIG
|
||||
if test -n "$ac_pt_PKG_CONFIG"; then
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_pt_PKG_CONFIG" >&5
|
||||
$as_echo "$ac_pt_PKG_CONFIG" >&6; }
|
||||
else
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
|
||||
$as_echo "no" >&6; }
|
||||
fi
|
||||
|
||||
if test "x$ac_pt_PKG_CONFIG" = x; then
|
||||
PKG_CONFIG=""
|
||||
else
|
||||
case $cross_compiling:$ac_tool_warned in
|
||||
yes:)
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
|
||||
$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
|
||||
ac_tool_warned=yes ;;
|
||||
esac
|
||||
PKG_CONFIG=$ac_pt_PKG_CONFIG
|
||||
fi
|
||||
else
|
||||
PKG_CONFIG="$ac_cv_path_PKG_CONFIG"
|
||||
fi
|
||||
|
||||
fi
|
||||
if test -n "$PKG_CONFIG"; then
|
||||
_pkg_min_version=0.9.0
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking pkg-config is at least version $_pkg_min_version" >&5
|
||||
$as_echo_n "checking pkg-config is at least version $_pkg_min_version... " >&6; }
|
||||
if $PKG_CONFIG --atleast-pkgconfig-version $_pkg_min_version; then
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
|
||||
$as_echo "yes" >&6; }
|
||||
else
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
|
||||
$as_echo "no" >&6; }
|
||||
PKG_CONFIG=""
|
||||
fi
|
||||
fi
|
||||
if test "x$enable_systemd" != xno; then :
|
||||
|
||||
|
||||
@@ -19354,7 +19550,7 @@ else
|
||||
WINDRES="$ac_cv_prog_WINDRES"
|
||||
fi
|
||||
|
||||
LIBS="$LIBS -liphlpapi"
|
||||
LIBS="$LIBS -liphlpapi -lcrypt32"
|
||||
WINAPPS="unbound-service-install.exe unbound-service-remove.exe anchor-update.exe"
|
||||
|
||||
WIN_DAEMON_SRC="winrc/win_svc.c winrc/w_inst.c"
|
||||
@@ -19588,7 +19784,7 @@ if test "$ac_res" != no; then :
|
||||
|
||||
fi
|
||||
|
||||
for ac_func in tzset sigprocmask fcntl getpwnam endpwent getrlimit setrlimit setsid chroot kill chown sleep usleep random srandom recvmsg sendmsg writev socketpair glob initgroups strftime localtime_r setusercontext _beginthreadex endservent endprotoent fsync shmget
|
||||
for ac_func in tzset sigprocmask fcntl getpwnam endpwent getrlimit setrlimit setsid chroot kill chown sleep usleep random srandom recvmsg sendmsg writev socketpair glob initgroups strftime localtime_r setusercontext _beginthreadex endservent endprotoent fsync shmget accept4
|
||||
do :
|
||||
as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
|
||||
ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
|
||||
@@ -19648,7 +19844,7 @@ done
|
||||
|
||||
|
||||
# check if setreuid en setregid fail, on MacOSX10.4(darwin8).
|
||||
if echo $build_os | grep darwin8 > /dev/null; then
|
||||
if echo $target_os | grep darwin8 > /dev/null; then
|
||||
|
||||
$as_echo "#define DARWIN_BROKEN_SETREUID 1" >>confdefs.h
|
||||
|
||||
@@ -19886,6 +20082,20 @@ esac
|
||||
fi
|
||||
|
||||
|
||||
ac_fn_c_check_func "$LINENO" "explicit_bzero" "ac_cv_func_explicit_bzero"
|
||||
if test "x$ac_cv_func_explicit_bzero" = xyes; then :
|
||||
$as_echo "#define HAVE_EXPLICIT_BZERO 1" >>confdefs.h
|
||||
|
||||
else
|
||||
case " $LIBOBJS " in
|
||||
*" explicit_bzero.$ac_objext "* ) ;;
|
||||
*) LIBOBJS="$LIBOBJS explicit_bzero.$ac_objext"
|
||||
;;
|
||||
esac
|
||||
|
||||
fi
|
||||
|
||||
|
||||
LIBOBJ_WITHOUT_CTIMEARC4="$LIBOBJS"
|
||||
|
||||
ac_fn_c_check_func "$LINENO" "reallocarray" "ac_cv_func_reallocarray"
|
||||
@@ -19932,12 +20142,6 @@ fi
|
||||
|
||||
|
||||
if test "$ac_cv_func_arc4random" = "no"; then
|
||||
case " $LIBOBJS " in
|
||||
*" explicit_bzero.$ac_objext "* ) ;;
|
||||
*) LIBOBJS="$LIBOBJS explicit_bzero.$ac_objext"
|
||||
;;
|
||||
esac
|
||||
|
||||
case " $LIBOBJS " in
|
||||
*" arc4_lock.$ac_objext "* ) ;;
|
||||
*) LIBOBJS="$LIBOBJS arc4_lock.$ac_objext"
|
||||
@@ -20741,6 +20945,8 @@ if test "${enable_cachedb+set}" = set; then :
|
||||
enableval=$enable_cachedb;
|
||||
fi
|
||||
|
||||
# turn on cachedb when hiredis support is enabled.
|
||||
if test "$found_libhiredis" = "yes"; then enable_cachedb="yes"; fi
|
||||
case "$enable_cachedb" in
|
||||
yes)
|
||||
|
||||
@@ -20928,7 +21134,7 @@ _ACEOF
|
||||
|
||||
|
||||
|
||||
version=1.7.0
|
||||
version=1.8.1
|
||||
|
||||
date=`date +'%b %e, %Y'`
|
||||
|
||||
@@ -21447,7 +21653,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
|
||||
# report actual input values of CONFIG_FILES etc. instead of their
|
||||
# values after options handling.
|
||||
ac_log="
|
||||
This file was extended by unbound $as_me 1.7.0, which was
|
||||
This file was extended by unbound $as_me 1.8.1, which was
|
||||
generated by GNU Autoconf 2.69. Invocation command line was
|
||||
|
||||
CONFIG_FILES = $CONFIG_FILES
|
||||
@@ -21513,7 +21719,7 @@ _ACEOF
|
||||
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
|
||||
ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
|
||||
ac_cs_version="\\
|
||||
unbound config.status 1.7.0
|
||||
unbound config.status 1.8.1
|
||||
configured by $0, generated by GNU Autoconf 2.69,
|
||||
with options \\"\$ac_cs_config\\"
|
||||
|
||||
|
||||
+126
-13
@@ -10,16 +10,16 @@ sinclude(dnscrypt/dnscrypt.m4)
|
||||
|
||||
# must be numbers. ac_defun because of later processing
|
||||
m4_define([VERSION_MAJOR],[1])
|
||||
m4_define([VERSION_MINOR],[7])
|
||||
m4_define([VERSION_MICRO],[0])
|
||||
m4_define([VERSION_MINOR],[8])
|
||||
m4_define([VERSION_MICRO],[1])
|
||||
AC_INIT(unbound, m4_defn([VERSION_MAJOR]).m4_defn([VERSION_MINOR]).m4_defn([VERSION_MICRO]), unbound-bugs@nlnetlabs.nl, unbound)
|
||||
AC_SUBST(UNBOUND_VERSION_MAJOR, [VERSION_MAJOR])
|
||||
AC_SUBST(UNBOUND_VERSION_MINOR, [VERSION_MINOR])
|
||||
AC_SUBST(UNBOUND_VERSION_MICRO, [VERSION_MICRO])
|
||||
|
||||
LIBUNBOUND_CURRENT=7
|
||||
LIBUNBOUND_REVISION=8
|
||||
LIBUNBOUND_AGE=5
|
||||
LIBUNBOUND_CURRENT=8
|
||||
LIBUNBOUND_REVISION=1
|
||||
LIBUNBOUND_AGE=0
|
||||
# 1.0.0 had 0:12:0
|
||||
# 1.0.1 had 0:13:0
|
||||
# 1.0.2 had 0:14:0
|
||||
@@ -78,6 +78,11 @@ LIBUNBOUND_AGE=5
|
||||
# 1.6.7 had 7:6:5
|
||||
# 1.6.8 had 7:7:5
|
||||
# 1.7.0 had 7:8:5
|
||||
# 1.7.1 had 7:9:5
|
||||
# 1.7.2 had 7:10:5
|
||||
# 1.7.3 had 7:11:5
|
||||
# 1.8.0 had 8:0:0 # changes the event callback function signature
|
||||
# 1.8.1 had 8:1:0
|
||||
|
||||
# Current -- the number of the binary API that we're implementing
|
||||
# Revision -- which iteration of the implementation of the binary
|
||||
@@ -306,11 +311,36 @@ __attribute__((weak)) void f(int x) { printf("%d", x); }
|
||||
AC_MSG_RESULT($ac_cv_c_weak_attribute)
|
||||
if test $ac_cv_c_weak_attribute = yes; then
|
||||
AC_DEFINE(HAVE_ATTR_WEAK, 1, [Whether the C compiler accepts the "weak" attribute])
|
||||
AC_DEFINE(ATTR_WEAK, [__attribute__((weak))], [apply the weak attribute to a symbol])
|
||||
fi
|
||||
])dnl End of CHECK_WEAK_ATTRIBUTE
|
||||
|
||||
CHECK_WEAK_ATTRIBUTE
|
||||
|
||||
AC_DEFUN([CHECK_NORETURN_ATTRIBUTE],
|
||||
[AC_REQUIRE([AC_PROG_CC])
|
||||
AC_MSG_CHECKING(whether the C compiler (${CC-cc}) accepts the "noreturn" attribute)
|
||||
AC_CACHE_VAL(ac_cv_c_noreturn_attribute,
|
||||
[ac_cv_c_noreturn_attribute=no
|
||||
AC_TRY_COMPILE(
|
||||
[ #include <stdio.h>
|
||||
__attribute__((noreturn)) void f(int x) { printf("%d", x); }
|
||||
], [
|
||||
f(1);
|
||||
],
|
||||
[ac_cv_c_noreturn_attribute="yes"],
|
||||
[ac_cv_c_noreturn_attribute="no"])
|
||||
])
|
||||
|
||||
AC_MSG_RESULT($ac_cv_c_noreturn_attribute)
|
||||
if test $ac_cv_c_noreturn_attribute = yes; then
|
||||
AC_DEFINE(HAVE_ATTR_NORETURN, 1, [Whether the C compiler accepts the "noreturn" attribute])
|
||||
AC_DEFINE(ATTR_NORETURN, [__attribute__((__noreturn__))], [apply the noreturn attribute to a function that exits the program])
|
||||
fi
|
||||
])dnl End of CHECK_NORETURN_ATTRIBUTE
|
||||
|
||||
CHECK_NORETURN_ATTRIBUTE
|
||||
|
||||
if test "$srcdir" != "."; then
|
||||
CPPFLAGS="$CPPFLAGS -I$srcdir"
|
||||
fi
|
||||
@@ -320,18 +350,37 @@ AC_DEFUN([ACX_YYLEX_DESTROY], [
|
||||
if echo %% | $LEX -t 2>&1 | grep yylex_destroy >/dev/null 2>&1; then
|
||||
AC_DEFINE(LEX_HAS_YYLEX_DESTROY, 1, [if lex has yylex_destroy])
|
||||
AC_MSG_RESULT(yes)
|
||||
else AC_MSG_RESULT(no); fi
|
||||
else AC_MSG_RESULT(no);
|
||||
LEX=":"
|
||||
fi
|
||||
])
|
||||
|
||||
AC_DEFUN([ACX_YYLEX_OPTION], [
|
||||
AC_MSG_CHECKING([for lex %option])
|
||||
if cat <<EOF | $LEX -t 2>&1 | grep yy_delete_buffer >/dev/null 2>&1; then
|
||||
%option nounput
|
||||
%%
|
||||
EOF
|
||||
AC_MSG_RESULT(yes)
|
||||
else AC_MSG_RESULT(no);
|
||||
LEX=":"
|
||||
fi
|
||||
])
|
||||
|
||||
AC_PROG_LEX
|
||||
if test "$LEX" != "" -a "$LEX" != ":"; then
|
||||
ACX_YYLEX_DESTROY
|
||||
fi
|
||||
if test "$LEX" != "" -a "$LEX" != ":"; then
|
||||
ACX_YYLEX_OPTION
|
||||
fi
|
||||
AC_PROG_YACC
|
||||
AC_CHECK_PROG(doxygen, doxygen, doxygen)
|
||||
AC_CHECK_TOOL(STRIP, strip)
|
||||
ACX_LIBTOOL_C_ONLY
|
||||
|
||||
# Checks for header files.
|
||||
AC_CHECK_HEADERS([stdarg.h stdbool.h netinet/in.h netinet/tcp.h sys/param.h sys/socket.h sys/un.h sys/uio.h sys/resource.h arpa/inet.h syslog.h netdb.h sys/wait.h pwd.h glob.h grp.h login_cap.h winsock2.h ws2tcpip.h endian.h sys/ipc.h sys/shm.h],,, [AC_INCLUDES_DEFAULT])
|
||||
AC_CHECK_HEADERS([stdarg.h stdbool.h netinet/in.h netinet/tcp.h sys/param.h sys/socket.h sys/un.h sys/uio.h sys/resource.h arpa/inet.h syslog.h netdb.h sys/wait.h pwd.h glob.h grp.h login_cap.h winsock2.h ws2tcpip.h endian.h sys/endian.h libkern/OSByteOrder.h sys/ipc.h sys/shm.h],,, [AC_INCLUDES_DEFAULT])
|
||||
|
||||
# check for types.
|
||||
# Using own tests for int64* because autoconf builtin only give 32bit.
|
||||
@@ -582,7 +631,10 @@ if test x_$ub_test_python != x_no; then
|
||||
CPPFLAGS="$PYTHON_CPPFLAGS"
|
||||
fi
|
||||
ub_have_python=yes
|
||||
PC_PY_DEPENDENCY="python"
|
||||
PKG_PROG_PKG_CONFIG
|
||||
PKG_CHECK_EXISTS(["python${PY_MAJOR_VERSION}"],
|
||||
[PC_PY_DEPENDENCY="python${PY_MAJOR_VERSION}"],
|
||||
[PC_PY_DEPENDENCY="python"])
|
||||
AC_SUBST(PC_PY_DEPENDENCY)
|
||||
|
||||
# Check for SWIG
|
||||
@@ -992,6 +1044,26 @@ case "$enable_ed25519" in
|
||||
;;
|
||||
esac
|
||||
|
||||
AC_ARG_ENABLE(ed448, AC_HELP_STRING([--disable-ed448], [Disable ED448 support]))
|
||||
use_ed448="no"
|
||||
case "$enable_ed448" in
|
||||
no)
|
||||
;;
|
||||
*)
|
||||
if test $USE_NSS = "no" -a $USE_NETTLE = "no"; then
|
||||
AC_CHECK_DECLS([NID_ED448], [
|
||||
use_ed448="yes"
|
||||
], [ if test "x$enable_ed448" = "xyes"; then AC_MSG_ERROR([OpenSSL does not support ED448 and you used --enable-ed448.])
|
||||
fi ], [AC_INCLUDES_DEFAULT
|
||||
#include <openssl/evp.h>
|
||||
])
|
||||
fi
|
||||
if test $use_ed448 = "yes"; then
|
||||
AC_DEFINE_UNQUOTED([USE_ED448], [1], [Define this to enable ED448 support.])
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
|
||||
AC_ARG_ENABLE(event-api, AC_HELP_STRING([--enable-event-api], [Enable (experimental) pluggable event base libunbound API installed to unbound-event.h]))
|
||||
case "$enable_event_api" in
|
||||
yes)
|
||||
@@ -1150,6 +1222,39 @@ AC_CHECK_DECLS([XML_StopParser], [], [], [AC_INCLUDES_DEFAULT
|
||||
#include <expat.h>
|
||||
])
|
||||
|
||||
# hiredis (redis C client for cachedb)
|
||||
AC_ARG_WITH(libhiredis, AC_HELP_STRING([--with-libhiredis=path],
|
||||
[specify explicit path for libhiredis.]),
|
||||
[ ],[ withval="no" ])
|
||||
found_libhiredis="no"
|
||||
if test x_$withval = x_yes -o x_$withval != x_no; then
|
||||
AC_MSG_CHECKING(for libhiredis)
|
||||
if test x_$withval = x_ -o x_$withval = x_yes; then
|
||||
withval="/usr/local /opt/local /usr/lib /usr/pkg /usr/sfw /usr"
|
||||
fi
|
||||
for dir in $withval ; do
|
||||
if test -f "$dir/include/hiredis/hiredis.h"; then
|
||||
found_libhiredis="yes"
|
||||
dnl assume /usr is in default path.
|
||||
if test "$dir" != "/usr"; then
|
||||
CPPFLAGS="$CPPFLAGS -I$dir/include"
|
||||
LDFLAGS="$LDFLAGS -L$dir/lib"
|
||||
fi
|
||||
AC_MSG_RESULT(found in $dir)
|
||||
AC_DEFINE([USE_REDIS], [1], [Define this to use hiredis client.])
|
||||
LIBS="$LIBS -lhiredis"
|
||||
break;
|
||||
fi
|
||||
done
|
||||
if test x_$found_libhiredis != x_yes; then
|
||||
AC_ERROR([Could not find libhiredis, hiredis.h])
|
||||
fi
|
||||
AC_CHECK_HEADERS([hiredis/hiredis.h],,, [AC_INCLUDES_DEFAULT])
|
||||
AC_CHECK_DECLS([redisConnect], [], [], [AC_INCLUDES_DEFAULT
|
||||
#include <hiredis/hiredis.h>
|
||||
])
|
||||
fi
|
||||
|
||||
# set static linking if requested
|
||||
AC_SUBST(staticexe)
|
||||
staticexe=""
|
||||
@@ -1191,7 +1296,7 @@ if test "$USE_WINSOCK" = 1; then
|
||||
#include <windows.h>
|
||||
])
|
||||
AC_CHECK_TOOL(WINDRES, windres)
|
||||
LIBS="$LIBS -liphlpapi"
|
||||
LIBS="$LIBS -liphlpapi -lcrypt32"
|
||||
WINAPPS="unbound-service-install.exe unbound-service-remove.exe anchor-update.exe"
|
||||
AC_SUBST(WINAPPS)
|
||||
WIN_DAEMON_SRC="winrc/win_svc.c winrc/w_inst.c"
|
||||
@@ -1264,12 +1369,12 @@ AC_INCLUDES_DEFAULT
|
||||
#endif
|
||||
])
|
||||
AC_SEARCH_LIBS([setusercontext], [util])
|
||||
AC_CHECK_FUNCS([tzset sigprocmask fcntl getpwnam endpwent getrlimit setrlimit setsid chroot kill chown sleep usleep random srandom recvmsg sendmsg writev socketpair glob initgroups strftime localtime_r setusercontext _beginthreadex endservent endprotoent fsync shmget])
|
||||
AC_CHECK_FUNCS([tzset sigprocmask fcntl getpwnam endpwent getrlimit setrlimit setsid chroot kill chown sleep usleep random srandom recvmsg sendmsg writev socketpair glob initgroups strftime localtime_r setusercontext _beginthreadex endservent endprotoent fsync shmget accept4])
|
||||
AC_CHECK_FUNCS([setresuid],,[AC_CHECK_FUNCS([setreuid])])
|
||||
AC_CHECK_FUNCS([setresgid],,[AC_CHECK_FUNCS([setregid])])
|
||||
|
||||
# check if setreuid en setregid fail, on MacOSX10.4(darwin8).
|
||||
if echo $build_os | grep darwin8 > /dev/null; then
|
||||
if echo $target_os | grep darwin8 > /dev/null; then
|
||||
AC_DEFINE(DARWIN_BROKEN_SETREUID, 1, [Define this if on macOSX10.4-darwin8 and setreuid and setregid do not work])
|
||||
fi
|
||||
AC_CHECK_DECLS([inet_pton,inet_ntop], [], [], [
|
||||
@@ -1317,6 +1422,7 @@ AC_REPLACE_FUNCS(strlcpy)
|
||||
AC_REPLACE_FUNCS(memmove)
|
||||
AC_REPLACE_FUNCS(gmtime_r)
|
||||
AC_REPLACE_FUNCS(isblank)
|
||||
AC_REPLACE_FUNCS(explicit_bzero)
|
||||
dnl without CTIME, ARC4-functions and without reallocarray.
|
||||
LIBOBJ_WITHOUT_CTIMEARC4="$LIBOBJS"
|
||||
AC_SUBST(LIBOBJ_WITHOUT_CTIMEARC4)
|
||||
@@ -1325,7 +1431,6 @@ if test "$USE_NSS" = "no"; then
|
||||
AC_REPLACE_FUNCS(arc4random)
|
||||
AC_REPLACE_FUNCS(arc4random_uniform)
|
||||
if test "$ac_cv_func_arc4random" = "no"; then
|
||||
AC_LIBOBJ(explicit_bzero)
|
||||
AC_LIBOBJ(arc4_lock)
|
||||
AC_CHECK_FUNCS([getentropy],,[
|
||||
if test "$USE_WINSOCK" = 1; then
|
||||
@@ -1434,6 +1539,8 @@ dnsc_DNSCRYPT([
|
||||
|
||||
# check for cachedb if requested
|
||||
AC_ARG_ENABLE(cachedb, AC_HELP_STRING([--enable-cachedb], [enable cachedb module that can use external cache storage]))
|
||||
# turn on cachedb when hiredis support is enabled.
|
||||
if test "$found_libhiredis" = "yes"; then enable_cachedb="yes"; fi
|
||||
case "$enable_cachedb" in
|
||||
yes)
|
||||
AC_DEFINE([USE_CACHEDB], [1], [Define to 1 to use cachedb support])
|
||||
@@ -1648,6 +1755,11 @@ char *strsep(char **stringp, const char *delim);
|
||||
int isblank(int c);
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_EXPLICIT_BZERO
|
||||
#define explicit_bzero unbound_explicit_bzero
|
||||
void explicit_bzero(void* buf, size_t len);
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_INET_NTOP) && !HAVE_DECL_INET_NTOP
|
||||
const char *inet_ntop(int af, const void *src, char *dst, size_t size);
|
||||
#endif
|
||||
@@ -1680,7 +1792,6 @@ void *reallocarray(void *ptr, size_t nmemb, size_t size);
|
||||
# endif
|
||||
#endif /* HAVE_LIBRESSL */
|
||||
#ifndef HAVE_ARC4RANDOM
|
||||
void explicit_bzero(void* buf, size_t len);
|
||||
int getentropy(void* buf, size_t len);
|
||||
uint32_t arc4random(void);
|
||||
void arc4random_buf(void* buf, size_t n);
|
||||
@@ -1752,6 +1863,8 @@ void *unbound_stat_realloc_log(void *ptr, size_t size, const char* file,
|
||||
|
||||
/** default port for DNS traffic. */
|
||||
#define UNBOUND_DNS_PORT 53
|
||||
/** default port for DNS over TLS traffic. */
|
||||
#define UNBOUND_DNS_OVER_TLS_PORT 853
|
||||
/** default port for unbound control traffic, registered port with IANA,
|
||||
ub-dns-control 8953/tcp unbound dns nameserver control */
|
||||
#define UNBOUND_CONTROL_PORT 8953
|
||||
|
||||
@@ -35,3 +35,6 @@ distribution but may be helpful.
|
||||
instead of SERVFAIL. Contributed by SIDN.
|
||||
* fastrpz.patch: fastrpz support from Farsight Security.
|
||||
* libunbound.so.conf: ltrace.conf file, see ltrace.conf(5), for libunbound.
|
||||
* unbound-querycachedb.py: utility to show data stored in cachedb backend
|
||||
for a particular query name and type. It requires dnspython and (for
|
||||
redis backend) redis Python modules.
|
||||
|
||||
@@ -21,7 +21,7 @@ Index: unbound-1.7.0~rc1/Makefile.in
|
||||
@@ -125,7 +127,7 @@ validator/val_sigcrypt.c validator/val_u
|
||||
edns-subnet/edns-subnet.c edns-subnet/subnetmod.c \
|
||||
edns-subnet/addrtree.c edns-subnet/subnet-whitelist.c \
|
||||
cachedb/cachedb.c respip/respip.c $(CHECKLOCK_SRC) \
|
||||
cachedb/cachedb.c cachedb/redis.c respip/respip.c $(CHECKLOCK_SRC) \
|
||||
-$(DNSTAP_SRC) $(DNSCRYPT_SRC) $(IPSECMOD_SRC)
|
||||
+$(DNSTAP_SRC) $(FASTRPZ_SRC) $(DNSCRYPT_SRC) $(IPSECMOD_SRC)
|
||||
COMMON_OBJ_WITHOUT_NETCALL=dns.lo infra.lo rrset.lo dname.lo msgencode.lo \
|
||||
@@ -274,10 +274,10 @@ Index: unbound-1.7.0~rc1/doc/unbound.conf.5.in
|
||||
===================================================================
|
||||
--- unbound-1.7.0~rc1.orig/doc/unbound.conf.5.in
|
||||
+++ unbound-1.7.0~rc1/doc/unbound.conf.5.in
|
||||
@@ -1581,6 +1581,81 @@ It must be /96 or shorter. The default
|
||||
.B dns64\-synthall: \fI<yes or no>\fR
|
||||
Debug option, default no. If enabled, synthesize all AAAA records
|
||||
despite the presence of actual AAAA records.
|
||||
@@ -1705,6 +1705,81 @@ It must be /96 or shorter. The default
|
||||
used by dns64 processing instead. Can be entered multiple times, list a
|
||||
new domain for which it applies, one per line. Applies also to names
|
||||
underneath the name given.
|
||||
+.SS "Response Policy Zone Rewriting"
|
||||
+.LP
|
||||
+Response policy zone rewriting is controlled with the
|
||||
@@ -3269,7 +3269,7 @@ Index: unbound-1.7.0~rc1/util/configparser.y
|
||||
+
|
||||
+ OUTYY(("P(rpz_zone:%s)\n", $2));
|
||||
+ old_cstr = cfg_parser->cfg->rpz_cstr;
|
||||
+ asprintf(&new_cstr, "%s\nzone %s", old_cstr?old_cstr:"", $2);
|
||||
+ (void)asprintf(&new_cstr, "%s\nzone %s", old_cstr?old_cstr:"", $2);
|
||||
+ if(!new_cstr)
|
||||
+ yyerror("out of memory");
|
||||
+ free(old_cstr);
|
||||
@@ -3282,7 +3282,7 @@ Index: unbound-1.7.0~rc1/util/configparser.y
|
||||
+
|
||||
+ OUTYY(("P(rpz_option:%s)\n", $2));
|
||||
+ old_cstr = cfg_parser->cfg->rpz_cstr;
|
||||
+ asprintf(&new_cstr, "%s\n%s", old_cstr ? old_cstr : "", $2);
|
||||
+ (void)asprintf(&new_cstr, "%s\n%s", old_cstr ? old_cstr : "", $2);
|
||||
+ if(!new_cstr)
|
||||
+ yyerror("out of memory");
|
||||
+ free(old_cstr);
|
||||
|
||||
@@ -7,7 +7,8 @@ Name: unbound
|
||||
Description: Library with validating, recursive, and caching DNS resolver
|
||||
URL: http://www.unbound.net
|
||||
Version: @PACKAGE_VERSION@
|
||||
Requires: libcrypto libssl @PC_LIBEVENT_DEPENDENCY@ @PC_PY_DEPENDENCY@
|
||||
Libs: -L${libdir} -lunbound
|
||||
Requires: libcrypto libssl @PC_LIBEVENT_DEPENDENCY@
|
||||
Requires.private: @PC_PY_DEPENDENCY@
|
||||
Libs: -L${libdir} -lunbound -lssl -lcrypto
|
||||
Libs.private: @SSLLIB@ @LIBS@
|
||||
Cflags: -I${includedir}
|
||||
|
||||
@@ -0,0 +1,77 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
import hashlib
|
||||
import sys
|
||||
import struct
|
||||
import socket
|
||||
import time
|
||||
from optparse import OptionParser
|
||||
|
||||
import dns.message
|
||||
import dns.name
|
||||
import dns.rdataclass
|
||||
import dns.rdatatype
|
||||
|
||||
def _calc_hashkey(qname, secret, qtype):
|
||||
qclass = 'IN' # CLASS is fixed for simplicity
|
||||
hobj = hashlib.sha256()
|
||||
hobj.update(dns.name.from_text(qname).to_wire())
|
||||
hobj.update(struct.pack('HH',
|
||||
socket.htons(dns.rdatatype.from_text(qtype)),
|
||||
socket.htons(dns.rdataclass.from_text(qclass))))
|
||||
hobj.update(secret)
|
||||
return hobj.hexdigest().upper()
|
||||
|
||||
def _redis_get(options, key):
|
||||
import redis
|
||||
return redis.Redis(options.address, int(options.port)).get(key)
|
||||
|
||||
def _dump_value(options, qname, key, value):
|
||||
print(';; query=%s/IN/%s' % (qname, options.qtype))
|
||||
print(';; key=%s' % key)
|
||||
if value is None:
|
||||
print(';; no value')
|
||||
return
|
||||
if len(value) < 16:
|
||||
print(';; broken value, short length: %d' % len(value))
|
||||
return
|
||||
now = int(time.time())
|
||||
timestamp = struct.unpack('!Q', value[-16:-8])[0]
|
||||
expire = struct.unpack('!Q', value[-8:])[0]
|
||||
print(';; Now=%d, TimeStamp=%d, Expire=%d, TTL=%d' %
|
||||
(now, timestamp, expire, max(expire - now, 0)))
|
||||
print(dns.message.from_wire(value[:-16]))
|
||||
|
||||
def main():
|
||||
parser = OptionParser(usage='usage: %prog [options] query_name')
|
||||
parser.add_option("-a", "--address", dest="address", action="store",
|
||||
default='127.0.0.1', help="backend-server address",
|
||||
metavar='ADDRESS')
|
||||
parser.add_option("-b", "--backend", dest="backend", action="store",
|
||||
default='redis', help="backend name",
|
||||
metavar='BACKEND')
|
||||
parser.add_option("-p", "--port", dest="port", action="store",
|
||||
default='6379', help="backend-server port",
|
||||
metavar='PORT')
|
||||
parser.add_option("-s", "--secret", dest="secret", action="store",
|
||||
default='default', help="secret seed", metavar='SECRET')
|
||||
parser.add_option("-t", "--qtype", dest="qtype", action="store",
|
||||
default='A', help="query RR type", metavar='QTYPE')
|
||||
|
||||
(options, args) = parser.parse_args()
|
||||
if len(args) < 1:
|
||||
parser.error('qname is missing')
|
||||
if options.backend == 'redis':
|
||||
get_func = _redis_get
|
||||
else:
|
||||
raise Exception('unknown backend name: %s\n' % options.backend)
|
||||
key = _calc_hashkey(args[0], options.secret, options.qtype)
|
||||
value = get_func(options, key)
|
||||
_dump_value(options, args[0], key, value)
|
||||
|
||||
if __name__ == '__main__':
|
||||
try:
|
||||
main()
|
||||
except Exception as e:
|
||||
sys.stderr.write('%s\n' % e)
|
||||
exit(1)
|
||||
@@ -1,6 +1,9 @@
|
||||
[Unit]
|
||||
Description=Validating, recursive, and caching DNS resolver
|
||||
Documentation=man:unbound(8)
|
||||
After=network.target
|
||||
Before=network-online.target nss-lookup.target
|
||||
Wants=nss-lookup.target
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
@@ -10,7 +13,7 @@ ExecReload=/bin/kill -HUP $MAINPID
|
||||
ExecStart=@UNBOUND_SBIN_DIR@/unbound
|
||||
NotifyAccess=main
|
||||
Type=notify
|
||||
CapabilityBoundingSet=CAP_IPC_LOCK CAP_NET_BIND_SERVICE CAP_SETGID CAP_SETUID CAP_SYS_CHROOT
|
||||
CapabilityBoundingSet=CAP_IPC_LOCK CAP_NET_BIND_SERVICE CAP_SETGID CAP_SETUID CAP_SYS_CHROOT CAP_SYS_RESOURCE
|
||||
MemoryDenyWriteExecute=true
|
||||
NoNewPrivileges=true
|
||||
PrivateDevices=true
|
||||
@@ -21,7 +24,7 @@ ProtectKernelModules=true
|
||||
ProtectKernelTunables=true
|
||||
ProtectSystem=strict
|
||||
ReadWritePaths=@UNBOUND_SYSCONF_DIR@ @UNBOUND_LOCALSTATE_DIR@ /run @UNBOUND_RUN_DIR@
|
||||
RestrictAddressFamilies=AF_INET AF_UNIX
|
||||
RestrictAddressFamilies=AF_INET AF_INET6 AF_UNIX
|
||||
RestrictRealtime=true
|
||||
SystemCallArchitectures=native
|
||||
SystemCallFilter=~@clock @cpu-emulation @debug @keyring @module mount @obsolete @resources
|
||||
|
||||
@@ -111,6 +111,8 @@ acl_list_str_cfg(struct acl_list* acl, const char* str, const char* s2,
|
||||
control = acl_refuse_non_local;
|
||||
else if(strcmp(s2, "allow_snoop") == 0)
|
||||
control = acl_allow_snoop;
|
||||
else if(strcmp(s2, "allow_setrd") == 0)
|
||||
control = acl_allow_setrd;
|
||||
else {
|
||||
log_err("access control type %s unknown", str);
|
||||
return 0;
|
||||
|
||||
+3
-1
@@ -63,7 +63,9 @@ enum acl_access {
|
||||
/** allow full access for recursion (+RD) queries */
|
||||
acl_allow,
|
||||
/** allow full access for all queries, recursion and cache snooping */
|
||||
acl_allow_snoop
|
||||
acl_allow_snoop,
|
||||
/** allow full access for recursion queries and set RD flag regardless of request */
|
||||
acl_allow_setrd
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
+22
-21
@@ -62,7 +62,7 @@
|
||||
|
||||
/** dump one rrset zonefile line */
|
||||
static int
|
||||
dump_rrset_line(SSL* ssl, struct ub_packed_rrset_key* k, time_t now, size_t i)
|
||||
dump_rrset_line(RES* ssl, struct ub_packed_rrset_key* k, time_t now, size_t i)
|
||||
{
|
||||
char s[65535];
|
||||
if(!packed_rr_to_string(k, i, now, s, sizeof(s))) {
|
||||
@@ -73,7 +73,7 @@ dump_rrset_line(SSL* ssl, struct ub_packed_rrset_key* k, time_t now, size_t i)
|
||||
|
||||
/** dump rrset key and data info */
|
||||
static int
|
||||
dump_rrset(SSL* ssl, struct ub_packed_rrset_key* k,
|
||||
dump_rrset(RES* ssl, struct ub_packed_rrset_key* k,
|
||||
struct packed_rrset_data* d, time_t now)
|
||||
{
|
||||
size_t i;
|
||||
@@ -99,7 +99,7 @@ dump_rrset(SSL* ssl, struct ub_packed_rrset_key* k,
|
||||
|
||||
/** dump lruhash rrset cache */
|
||||
static int
|
||||
dump_rrset_lruhash(SSL* ssl, struct lruhash* h, time_t now)
|
||||
dump_rrset_lruhash(RES* ssl, struct lruhash* h, time_t now)
|
||||
{
|
||||
struct lruhash_entry* e;
|
||||
/* lruhash already locked by caller */
|
||||
@@ -118,7 +118,7 @@ dump_rrset_lruhash(SSL* ssl, struct lruhash* h, time_t now)
|
||||
|
||||
/** dump rrset cache */
|
||||
static int
|
||||
dump_rrset_cache(SSL* ssl, struct worker* worker)
|
||||
dump_rrset_cache(RES* ssl, struct worker* worker)
|
||||
{
|
||||
struct rrset_cache* r = worker->env.rrset_cache;
|
||||
size_t slab;
|
||||
@@ -137,7 +137,7 @@ dump_rrset_cache(SSL* ssl, struct worker* worker)
|
||||
|
||||
/** dump message to rrset reference */
|
||||
static int
|
||||
dump_msg_ref(SSL* ssl, struct ub_packed_rrset_key* k)
|
||||
dump_msg_ref(RES* ssl, struct ub_packed_rrset_key* k)
|
||||
{
|
||||
char* nm, *tp, *cl;
|
||||
nm = sldns_wire2str_dname(k->rk.dname, k->rk.dname_len);
|
||||
@@ -164,7 +164,7 @@ dump_msg_ref(SSL* ssl, struct ub_packed_rrset_key* k)
|
||||
|
||||
/** dump message entry */
|
||||
static int
|
||||
dump_msg(SSL* ssl, struct query_info* k, struct reply_info* d,
|
||||
dump_msg(RES* ssl, struct query_info* k, struct reply_info* d,
|
||||
time_t now)
|
||||
{
|
||||
size_t i;
|
||||
@@ -246,7 +246,7 @@ copy_msg(struct regional* region, struct lruhash_entry* e,
|
||||
|
||||
/** dump lruhash msg cache */
|
||||
static int
|
||||
dump_msg_lruhash(SSL* ssl, struct worker* worker, struct lruhash* h)
|
||||
dump_msg_lruhash(RES* ssl, struct worker* worker, struct lruhash* h)
|
||||
{
|
||||
struct lruhash_entry* e;
|
||||
struct query_info* k;
|
||||
@@ -274,7 +274,7 @@ dump_msg_lruhash(SSL* ssl, struct worker* worker, struct lruhash* h)
|
||||
|
||||
/** dump msg cache */
|
||||
static int
|
||||
dump_msg_cache(SSL* ssl, struct worker* worker)
|
||||
dump_msg_cache(RES* ssl, struct worker* worker)
|
||||
{
|
||||
struct slabhash* sh = worker->env.msg_cache;
|
||||
size_t slab;
|
||||
@@ -291,7 +291,7 @@ dump_msg_cache(SSL* ssl, struct worker* worker)
|
||||
}
|
||||
|
||||
int
|
||||
dump_cache(SSL* ssl, struct worker* worker)
|
||||
dump_cache(RES* ssl, struct worker* worker)
|
||||
{
|
||||
if(!dump_rrset_cache(ssl, worker))
|
||||
return 0;
|
||||
@@ -302,7 +302,7 @@ dump_cache(SSL* ssl, struct worker* worker)
|
||||
|
||||
/** read a line from ssl into buffer */
|
||||
static int
|
||||
ssl_read_buf(SSL* ssl, sldns_buffer* buf)
|
||||
ssl_read_buf(RES* ssl, sldns_buffer* buf)
|
||||
{
|
||||
return ssl_read_line(ssl, (char*)sldns_buffer_begin(buf),
|
||||
sldns_buffer_capacity(buf));
|
||||
@@ -310,7 +310,7 @@ ssl_read_buf(SSL* ssl, sldns_buffer* buf)
|
||||
|
||||
/** check fixed text on line */
|
||||
static int
|
||||
read_fixed(SSL* ssl, sldns_buffer* buf, const char* str)
|
||||
read_fixed(RES* ssl, sldns_buffer* buf, const char* str)
|
||||
{
|
||||
if(!ssl_read_buf(ssl, buf)) return 0;
|
||||
return (strcmp((char*)sldns_buffer_begin(buf), str) == 0);
|
||||
@@ -318,7 +318,7 @@ read_fixed(SSL* ssl, sldns_buffer* buf, const char* str)
|
||||
|
||||
/** load an RR into rrset */
|
||||
static int
|
||||
load_rr(SSL* ssl, sldns_buffer* buf, struct regional* region,
|
||||
load_rr(RES* ssl, sldns_buffer* buf, struct regional* region,
|
||||
struct ub_packed_rrset_key* rk, struct packed_rrset_data* d,
|
||||
unsigned int i, int is_rrsig, int* go_on, time_t now)
|
||||
{
|
||||
@@ -435,7 +435,7 @@ move_into_cache(struct ub_packed_rrset_key* k,
|
||||
|
||||
/** load an rrset entry */
|
||||
static int
|
||||
load_rrset(SSL* ssl, sldns_buffer* buf, struct worker* worker)
|
||||
load_rrset(RES* ssl, sldns_buffer* buf, struct worker* worker)
|
||||
{
|
||||
char* s = (char*)sldns_buffer_begin(buf);
|
||||
struct regional* region = worker->scratchpad;
|
||||
@@ -519,7 +519,7 @@ load_rrset(SSL* ssl, sldns_buffer* buf, struct worker* worker)
|
||||
|
||||
/** load rrset cache */
|
||||
static int
|
||||
load_rrset_cache(SSL* ssl, struct worker* worker)
|
||||
load_rrset_cache(RES* ssl, struct worker* worker)
|
||||
{
|
||||
sldns_buffer* buf = worker->env.scratch_buffer;
|
||||
if(!read_fixed(ssl, buf, "START_RRSET_CACHE")) return 0;
|
||||
@@ -575,7 +575,7 @@ load_qinfo(char* str, struct query_info* qinfo, struct regional* region)
|
||||
|
||||
/** load a msg rrset reference */
|
||||
static int
|
||||
load_ref(SSL* ssl, sldns_buffer* buf, struct worker* worker,
|
||||
load_ref(RES* ssl, sldns_buffer* buf, struct worker* worker,
|
||||
struct regional *region, struct ub_packed_rrset_key** rrset,
|
||||
int* go_on)
|
||||
{
|
||||
@@ -620,7 +620,7 @@ load_ref(SSL* ssl, sldns_buffer* buf, struct worker* worker,
|
||||
|
||||
/** load a msg entry */
|
||||
static int
|
||||
load_msg(SSL* ssl, sldns_buffer* buf, struct worker* worker)
|
||||
load_msg(RES* ssl, sldns_buffer* buf, struct worker* worker)
|
||||
{
|
||||
struct regional* region = worker->scratchpad;
|
||||
struct query_info qinf;
|
||||
@@ -653,6 +653,7 @@ load_msg(SSL* ssl, sldns_buffer* buf, struct worker* worker)
|
||||
rep.qdcount = (uint16_t)qdcount;
|
||||
rep.ttl = (time_t)ttl;
|
||||
rep.prefetch_ttl = PREFETCH_TTL_CALC(rep.ttl);
|
||||
rep.serve_expired_ttl = rep.ttl + SERVE_EXPIRED_TTL;
|
||||
rep.security = (enum sec_status)security;
|
||||
if(an > RR_COUNT_MAX || ns > RR_COUNT_MAX || ar > RR_COUNT_MAX) {
|
||||
log_warn("error too many rrsets");
|
||||
@@ -685,7 +686,7 @@ load_msg(SSL* ssl, sldns_buffer* buf, struct worker* worker)
|
||||
|
||||
/** load msg cache */
|
||||
static int
|
||||
load_msg_cache(SSL* ssl, struct worker* worker)
|
||||
load_msg_cache(RES* ssl, struct worker* worker)
|
||||
{
|
||||
sldns_buffer* buf = worker->env.scratch_buffer;
|
||||
if(!read_fixed(ssl, buf, "START_MSG_CACHE")) return 0;
|
||||
@@ -698,7 +699,7 @@ load_msg_cache(SSL* ssl, struct worker* worker)
|
||||
}
|
||||
|
||||
int
|
||||
load_cache(SSL* ssl, struct worker* worker)
|
||||
load_cache(RES* ssl, struct worker* worker)
|
||||
{
|
||||
if(!load_rrset_cache(ssl, worker))
|
||||
return 0;
|
||||
@@ -709,7 +710,7 @@ load_cache(SSL* ssl, struct worker* worker)
|
||||
|
||||
/** print details on a delegation point */
|
||||
static void
|
||||
print_dp_details(SSL* ssl, struct worker* worker, struct delegpt* dp)
|
||||
print_dp_details(RES* ssl, struct worker* worker, struct delegpt* dp)
|
||||
{
|
||||
char buf[257];
|
||||
struct delegpt_addr* a;
|
||||
@@ -785,7 +786,7 @@ print_dp_details(SSL* ssl, struct worker* worker, struct delegpt* dp)
|
||||
|
||||
/** print main dp info */
|
||||
static void
|
||||
print_dp_main(SSL* ssl, struct delegpt* dp, struct dns_msg* msg)
|
||||
print_dp_main(RES* ssl, struct delegpt* dp, struct dns_msg* msg)
|
||||
{
|
||||
size_t i, n_ns, n_miss, n_addr, n_res, n_avail;
|
||||
|
||||
@@ -813,7 +814,7 @@ print_dp_main(SSL* ssl, struct delegpt* dp, struct dns_msg* msg)
|
||||
return;
|
||||
}
|
||||
|
||||
int print_deleg_lookup(SSL* ssl, struct worker* worker, uint8_t* nm,
|
||||
int print_deleg_lookup(RES* ssl, struct worker* worker, uint8_t* nm,
|
||||
size_t nmlen, int ATTR_UNUSED(nmlabs))
|
||||
{
|
||||
/* deep links into the iterator module */
|
||||
|
||||
+4
-3
@@ -72,6 +72,7 @@
|
||||
#ifndef DAEMON_DUMPCACHE_H
|
||||
#define DAEMON_DUMPCACHE_H
|
||||
struct worker;
|
||||
#include "daemon/remote.h"
|
||||
|
||||
/**
|
||||
* Dump cache(s) to text
|
||||
@@ -80,7 +81,7 @@ struct worker;
|
||||
* ptrs to the caches.
|
||||
* @return false on ssl print error.
|
||||
*/
|
||||
int dump_cache(SSL* ssl, struct worker* worker);
|
||||
int dump_cache(RES* ssl, struct worker* worker);
|
||||
|
||||
/**
|
||||
* Load cache(s) from text
|
||||
@@ -89,7 +90,7 @@ int dump_cache(SSL* ssl, struct worker* worker);
|
||||
* ptrs to the caches.
|
||||
* @return false on ssl error.
|
||||
*/
|
||||
int load_cache(SSL* ssl, struct worker* worker);
|
||||
int load_cache(RES* ssl, struct worker* worker);
|
||||
|
||||
/**
|
||||
* Print the delegation used to lookup for this name.
|
||||
@@ -101,7 +102,7 @@ int load_cache(SSL* ssl, struct worker* worker);
|
||||
* @param nmlabs: labels in name.
|
||||
* @return false on ssl error.
|
||||
*/
|
||||
int print_deleg_lookup(SSL* ssl, struct worker* worker, uint8_t* nm,
|
||||
int print_deleg_lookup(RES* ssl, struct worker* worker, uint8_t* nm,
|
||||
size_t nmlen, int nmlabs);
|
||||
|
||||
#endif /* DAEMON_DUMPCACHE_H */
|
||||
|
||||
+23
-16
@@ -76,6 +76,7 @@
|
||||
#include "util/shm_side/shm_main.h"
|
||||
#include "util/storage/lookup3.h"
|
||||
#include "util/storage/slabhash.h"
|
||||
#include "util/tcp_conn_limit.h"
|
||||
#include "services/listen_dnsport.h"
|
||||
#include "services/cache/rrset.h"
|
||||
#include "services/cache/infra.h"
|
||||
@@ -104,10 +105,8 @@ static int sig_record_reload = 0;
|
||||
/** cleaner ssl memory freeup */
|
||||
static void* comp_meth = NULL;
|
||||
#endif
|
||||
#ifdef LEX_HAS_YYLEX_DESTROY
|
||||
/** remove buffers for parsing and init */
|
||||
int ub_c_lex_destroy(void);
|
||||
#endif
|
||||
|
||||
/** used when no other sighandling happens, so we don't die
|
||||
* when multiple signals in quick succession are sent to us.
|
||||
@@ -182,15 +181,8 @@ static void
|
||||
signal_handling_playback(struct worker* wrk)
|
||||
{
|
||||
#ifdef SIGHUP
|
||||
if(sig_record_reload) {
|
||||
# ifdef HAVE_SYSTEMD
|
||||
sd_notify(0, "RELOADING=1");
|
||||
# endif
|
||||
if(sig_record_reload)
|
||||
worker_sighandler(SIGHUP, wrk);
|
||||
# ifdef HAVE_SYSTEMD
|
||||
sd_notify(0, "READY=1");
|
||||
# endif
|
||||
}
|
||||
#endif
|
||||
if(sig_record_quit)
|
||||
worker_sighandler(SIGTERM, wrk);
|
||||
@@ -279,11 +271,20 @@ daemon_init(void)
|
||||
free(daemon);
|
||||
return NULL;
|
||||
}
|
||||
daemon->tcl = tcl_list_create();
|
||||
if(!daemon->tcl) {
|
||||
acl_list_delete(daemon->acl);
|
||||
edns_known_options_delete(daemon->env);
|
||||
free(daemon->env);
|
||||
free(daemon);
|
||||
return NULL;
|
||||
}
|
||||
if(gettimeofday(&daemon->time_boot, NULL) < 0)
|
||||
log_err("gettimeofday: %s", strerror(errno));
|
||||
daemon->time_last_stat = daemon->time_boot;
|
||||
if((daemon->env->auth_zones = auth_zones_create()) == 0) {
|
||||
acl_list_delete(daemon->acl);
|
||||
tcl_list_delete(daemon->tcl);
|
||||
edns_known_options_delete(daemon->env);
|
||||
free(daemon->env);
|
||||
free(daemon);
|
||||
@@ -584,6 +585,8 @@ daemon_fork(struct daemon* daemon)
|
||||
|
||||
if(!acl_list_apply_cfg(daemon->acl, daemon->cfg, daemon->views))
|
||||
fatal_exit("Could not setup access control list");
|
||||
if(!tcl_list_apply_cfg(daemon->tcl, daemon->cfg))
|
||||
fatal_exit("Could not setup TCP connection limits");
|
||||
if(daemon->cfg->dnscrypt) {
|
||||
#ifdef USE_DNSCRYPT
|
||||
daemon->dnscenv = dnsc_create();
|
||||
@@ -662,7 +665,10 @@ daemon_fork(struct daemon* daemon)
|
||||
log_info("start of service (%s).", PACKAGE_STRING);
|
||||
worker_work(daemon->workers[0]);
|
||||
#ifdef HAVE_SYSTEMD
|
||||
sd_notify(0, "STOPPING=1");
|
||||
if (daemon->workers[0]->need_to_exit)
|
||||
sd_notify(0, "STOPPING=1");
|
||||
else
|
||||
sd_notify(0, "RELOADING=1");
|
||||
#endif
|
||||
log_info("service stopped (%s).", PACKAGE_STRING);
|
||||
|
||||
@@ -704,11 +710,14 @@ daemon_cleanup(struct daemon* daemon)
|
||||
free(daemon->workers);
|
||||
daemon->workers = NULL;
|
||||
daemon->num = 0;
|
||||
alloc_clear_special(&daemon->superalloc);
|
||||
#ifdef USE_DNSTAP
|
||||
dt_delete(daemon->dtenv);
|
||||
daemon->dtenv = NULL;
|
||||
#endif
|
||||
#ifdef USE_DNSCRYPT
|
||||
dnsc_delete(daemon->dnscenv);
|
||||
daemon->dnscenv = NULL;
|
||||
#endif
|
||||
daemon->cfg = NULL;
|
||||
}
|
||||
@@ -735,6 +744,7 @@ daemon_delete(struct daemon* daemon)
|
||||
ub_randfree(daemon->rand);
|
||||
alloc_clear(&daemon->superalloc);
|
||||
acl_list_delete(daemon->acl);
|
||||
tcl_list_delete(daemon->tcl);
|
||||
free(daemon->chroot);
|
||||
free(daemon->pidfile);
|
||||
free(daemon->env);
|
||||
@@ -743,10 +753,8 @@ daemon_delete(struct daemon* daemon)
|
||||
SSL_CTX_free((SSL_CTX*)daemon->connect_sslctx);
|
||||
#endif
|
||||
free(daemon);
|
||||
#ifdef LEX_HAS_YYLEX_DESTROY
|
||||
/* lex cleanup */
|
||||
ub_c_lex_destroy();
|
||||
#endif
|
||||
/* libcrypto cleanup */
|
||||
#ifdef HAVE_SSL
|
||||
# if defined(USE_GOST) && defined(HAVE_LDNS_KEY_EVP_UNLOAD_GOST)
|
||||
@@ -797,9 +805,8 @@ void daemon_apply_cfg(struct daemon* daemon, struct config_file* cfg)
|
||||
{
|
||||
daemon->cfg = cfg;
|
||||
config_apply(cfg);
|
||||
if(!daemon->env->msg_cache ||
|
||||
cfg->msg_cache_size != slabhash_get_size(daemon->env->msg_cache) ||
|
||||
cfg->msg_cache_slabs != daemon->env->msg_cache->size) {
|
||||
if(!slabhash_is_size(daemon->env->msg_cache, cfg->msg_cache_size,
|
||||
cfg->msg_cache_slabs)) {
|
||||
slabhash_delete(daemon->env->msg_cache);
|
||||
daemon->env->msg_cache = slabhash_create(cfg->msg_cache_slabs,
|
||||
HASH_DEFAULT_STARTARRAY, cfg->msg_cache_size,
|
||||
|
||||
@@ -113,6 +113,8 @@ struct daemon {
|
||||
struct module_stack mods;
|
||||
/** access control, which client IPs are allowed to connect */
|
||||
struct acl_list* acl;
|
||||
/** TCP connection limit, limit connections from client IPs */
|
||||
struct tcl_list* tcl;
|
||||
/** local authority zones */
|
||||
struct local_zones* local_zones;
|
||||
/** last time of statistics printout */
|
||||
|
||||
+388
-264
File diff suppressed because it is too large
Load Diff
+21
-6
@@ -73,6 +73,8 @@ struct rc_state {
|
||||
/** the ssl state */
|
||||
SSL* ssl;
|
||||
#endif
|
||||
/** file descriptor */
|
||||
int fd;
|
||||
/** the rc this is part of */
|
||||
struct daemon_remote* rc;
|
||||
};
|
||||
@@ -103,6 +105,19 @@ struct daemon_remote {
|
||||
#endif
|
||||
};
|
||||
|
||||
/**
|
||||
* Connection to print to, either SSL or plain over fd
|
||||
*/
|
||||
struct remote_stream {
|
||||
#ifdef HAVE_SSL
|
||||
/** SSL structure, nonNULL if using SSL */
|
||||
SSL* ssl;
|
||||
#endif
|
||||
/** file descriptor for plain transfer */
|
||||
int fd;
|
||||
};
|
||||
typedef struct remote_stream RES;
|
||||
|
||||
/**
|
||||
* Create new remote control state for the daemon.
|
||||
* @param cfg: config file with key file settings.
|
||||
@@ -166,26 +181,26 @@ void daemon_remote_exec(struct worker* worker);
|
||||
* @param text: the text.
|
||||
* @return false on connection failure.
|
||||
*/
|
||||
int ssl_print_text(SSL* ssl, const char* text);
|
||||
int ssl_print_text(RES* ssl, const char* text);
|
||||
|
||||
/**
|
||||
* printf style printing to the ssl connection
|
||||
* @param ssl: the SSL connection to print to. Blocking.
|
||||
* @param ssl: the RES connection to print to. Blocking.
|
||||
* @param format: printf style format string.
|
||||
* @return success or false on a network failure.
|
||||
*/
|
||||
int ssl_printf(SSL* ssl, const char* format, ...)
|
||||
int ssl_printf(RES* ssl, const char* format, ...)
|
||||
ATTR_FORMAT(printf, 2, 3);
|
||||
|
||||
/**
|
||||
* Read until \n is encountered
|
||||
* If SSL signals EOF, the string up to then is returned (without \n).
|
||||
* @param ssl: the SSL connection to read from. blocking.
|
||||
* If stream signals EOF, the string up to then is returned (without \n).
|
||||
* @param ssl: the RES connection to read from. blocking.
|
||||
* @param buf: buffer to read to.
|
||||
* @param max: size of buffer.
|
||||
* @return false on connection failure.
|
||||
*/
|
||||
int ssl_read_line(SSL* ssl, char* buf, size_t max);
|
||||
int ssl_read_line(RES* ssl, char* buf, size_t max);
|
||||
#endif /* HAVE_SSL */
|
||||
|
||||
#endif /* DAEMON_REMOTE_H */
|
||||
|
||||
+87
-1
@@ -60,7 +60,12 @@
|
||||
#include "sldns/sbuffer.h"
|
||||
#include "services/cache/rrset.h"
|
||||
#include "services/cache/infra.h"
|
||||
#include "services/authzone.h"
|
||||
#include "validator/val_kcache.h"
|
||||
#include "validator/val_neg.h"
|
||||
#ifdef CLIENT_SUBNET
|
||||
#include "edns-subnet/subnetmod.h"
|
||||
#endif
|
||||
|
||||
/** add timers and the values do not overflow or become negative */
|
||||
static void
|
||||
@@ -122,6 +127,57 @@ void server_stats_log(struct ub_server_stats* stats, struct worker* worker,
|
||||
(unsigned)worker->env.mesh->stats_jostled);
|
||||
}
|
||||
|
||||
|
||||
#ifdef CLIENT_SUBNET
|
||||
/** Set the EDNS Subnet stats. */
|
||||
static void
|
||||
set_subnet_stats(struct worker* worker, struct ub_server_stats* svr,
|
||||
int reset)
|
||||
{
|
||||
int m = modstack_find(&worker->env.mesh->mods, "subnet");
|
||||
struct subnet_env* sne;
|
||||
if(m == -1)
|
||||
return;
|
||||
sne = (struct subnet_env*)worker->env.modinfo[m];
|
||||
if(reset && !worker->env.cfg->stat_cumulative) {
|
||||
lock_rw_wrlock(&sne->biglock);
|
||||
} else {
|
||||
lock_rw_rdlock(&sne->biglock);
|
||||
}
|
||||
svr->num_query_subnet = (long long)(sne->num_msg_nocache + sne->num_msg_cache);
|
||||
svr->num_query_subnet_cache = (long long)sne->num_msg_cache;
|
||||
if(reset && !worker->env.cfg->stat_cumulative) {
|
||||
sne->num_msg_cache = 0;
|
||||
sne->num_msg_nocache = 0;
|
||||
}
|
||||
lock_rw_unlock(&sne->biglock);
|
||||
}
|
||||
#endif /* CLIENT_SUBNET */
|
||||
|
||||
/** Set the neg cache stats. */
|
||||
static void
|
||||
set_neg_cache_stats(struct worker* worker, struct ub_server_stats* svr,
|
||||
int reset)
|
||||
{
|
||||
int m = modstack_find(&worker->env.mesh->mods, "validator");
|
||||
struct val_env* ve;
|
||||
struct val_neg_cache* neg;
|
||||
if(m == -1)
|
||||
return;
|
||||
ve = (struct val_env*)worker->env.modinfo[m];
|
||||
if(!ve->neg_cache)
|
||||
return;
|
||||
neg = ve->neg_cache;
|
||||
lock_basic_lock(&neg->lock);
|
||||
svr->num_neg_cache_noerror = (long long)neg->num_neg_cache_noerror;
|
||||
svr->num_neg_cache_nxdomain = (long long)neg->num_neg_cache_nxdomain;
|
||||
if(reset && !worker->env.cfg->stat_cumulative) {
|
||||
neg->num_neg_cache_noerror = 0;
|
||||
neg->num_neg_cache_nxdomain = 0;
|
||||
}
|
||||
lock_basic_unlock(&neg->lock);
|
||||
}
|
||||
|
||||
/** get rrsets bogus number from validator */
|
||||
static size_t
|
||||
get_rrset_bogus(struct worker* worker, int reset)
|
||||
@@ -256,6 +312,32 @@ server_stats_compile(struct worker* worker, struct ub_stats_info* s, int reset)
|
||||
s->svr.nonce_cache_count = 0;
|
||||
s->svr.num_query_dnscrypt_replay = 0;
|
||||
#endif /* USE_DNSCRYPT */
|
||||
if(worker->env.auth_zones) {
|
||||
if(reset && !worker->env.cfg->stat_cumulative) {
|
||||
lock_rw_wrlock(&worker->env.auth_zones->lock);
|
||||
} else {
|
||||
lock_rw_rdlock(&worker->env.auth_zones->lock);
|
||||
}
|
||||
s->svr.num_query_authzone_up = (long long)worker->env.
|
||||
auth_zones->num_query_up;
|
||||
s->svr.num_query_authzone_down = (long long)worker->env.
|
||||
auth_zones->num_query_down;
|
||||
if(reset && !worker->env.cfg->stat_cumulative) {
|
||||
worker->env.auth_zones->num_query_up = 0;
|
||||
worker->env.auth_zones->num_query_down = 0;
|
||||
}
|
||||
lock_rw_unlock(&worker->env.auth_zones->lock);
|
||||
}
|
||||
|
||||
/* Set neg cache usage numbers */
|
||||
set_neg_cache_stats(worker, &s->svr, reset);
|
||||
#ifdef CLIENT_SUBNET
|
||||
/* EDNS Subnet usage numbers */
|
||||
set_subnet_stats(worker, &s->svr, reset);
|
||||
#else
|
||||
s->svr.num_query_subnet = 0;
|
||||
s->svr.num_query_subnet_cache = 0;
|
||||
#endif
|
||||
|
||||
/* get tcp accept usage */
|
||||
s->svr.tcp_accept_usage = 0;
|
||||
@@ -329,6 +411,7 @@ void server_stats_add(struct ub_stats_info* total, struct ub_stats_info* a)
|
||||
total->svr.qclass_big += a->svr.qclass_big;
|
||||
total->svr.qtcp += a->svr.qtcp;
|
||||
total->svr.qtcp_outgoing += a->svr.qtcp_outgoing;
|
||||
total->svr.qtls += a->svr.qtls;
|
||||
total->svr.qipv6 += a->svr.qipv6;
|
||||
total->svr.qbit_QR += a->svr.qbit_QR;
|
||||
total->svr.qbit_AA += a->svr.qbit_AA;
|
||||
@@ -383,8 +466,11 @@ void server_stats_insquery(struct ub_server_stats* stats, struct comm_point* c,
|
||||
stats->qclass[qclass]++;
|
||||
else stats->qclass_big++;
|
||||
stats->qopcode[ LDNS_OPCODE_WIRE(sldns_buffer_begin(c->buffer)) ]++;
|
||||
if(c->type != comm_udp)
|
||||
if(c->type != comm_udp) {
|
||||
stats->qtcp++;
|
||||
if(c->ssl != NULL)
|
||||
stats->qtls++;
|
||||
}
|
||||
if(repinfo && addr_is_ip6(&repinfo->addr, repinfo->addrlen))
|
||||
stats->qipv6++;
|
||||
if( (flags&BIT_QR) )
|
||||
|
||||
+7
-4
@@ -101,6 +101,7 @@ static void usage(void)
|
||||
printf("-c file config file to read instead of %s\n", CONFIGFILE);
|
||||
printf(" file format is described in unbound.conf(5).\n");
|
||||
printf("-d do not fork into the background.\n");
|
||||
printf("-p do not create a pidfile.\n");
|
||||
printf("-v verbose (more times to increase verbosity)\n");
|
||||
#ifdef UB_ON_WINDOWS
|
||||
printf("-w opt windows option: \n");
|
||||
@@ -431,7 +432,7 @@ perform_setup(struct daemon* daemon, struct config_file* cfg, int debug_mode,
|
||||
fatal_exit("could not set up listen SSL_CTX");
|
||||
}
|
||||
if(!(daemon->connect_sslctx = connect_sslctx_create(NULL, NULL,
|
||||
cfg->tls_cert_bundle)))
|
||||
cfg->tls_cert_bundle, cfg->tls_win_cert)))
|
||||
fatal_exit("could not set up connect SSL_CTX");
|
||||
#endif
|
||||
|
||||
@@ -626,8 +627,10 @@ run_daemon(const char* cfgfile, int cmdline_verbose, int debug_mode, const char*
|
||||
fatal_exit("Could not alloc config defaults");
|
||||
if(!config_read(cfg, cfgfile, daemon->chroot)) {
|
||||
if(errno != ENOENT)
|
||||
fatal_exit("Could not read config file: %s",
|
||||
cfgfile);
|
||||
fatal_exit("Could not read config file: %s."
|
||||
" Maybe try unbound -dd, it stays on "
|
||||
"the commandline to see more errors, "
|
||||
"or unbound-checkconf", cfgfile);
|
||||
log_warn("Continuing with default config settings");
|
||||
}
|
||||
apply_settings(daemon, cfg, cmdline_verbose, debug_mode, log_default_identity);
|
||||
@@ -727,7 +730,7 @@ main(int argc, char* argv[])
|
||||
}
|
||||
}
|
||||
argc -= optind;
|
||||
argv += optind;
|
||||
/* argv += optind; not using further arguments */
|
||||
|
||||
if(winopt) {
|
||||
#ifdef UB_ON_WINDOWS
|
||||
|
||||
+192
-71
@@ -66,6 +66,7 @@
|
||||
#include "util/data/dname.h"
|
||||
#include "util/fptr_wlist.h"
|
||||
#include "util/tube.h"
|
||||
#include "util/edns.h"
|
||||
#include "iterator/iter_fwd.h"
|
||||
#include "iterator/iter_hints.h"
|
||||
#include "validator/autotrust.h"
|
||||
@@ -342,7 +343,8 @@ worker_check_request(sldns_buffer* pkt, struct worker* worker)
|
||||
verbose(VERB_QUERY, "request bad, has TC bit on");
|
||||
return worker_err_ratelimit(worker, LDNS_RCODE_FORMERR);
|
||||
}
|
||||
if(LDNS_OPCODE_WIRE(sldns_buffer_begin(pkt)) != LDNS_PACKET_QUERY) {
|
||||
if(LDNS_OPCODE_WIRE(sldns_buffer_begin(pkt)) != LDNS_PACKET_QUERY &&
|
||||
LDNS_OPCODE_WIRE(sldns_buffer_begin(pkt)) != LDNS_PACKET_NOTIFY) {
|
||||
verbose(VERB_QUERY, "request unknown opcode %d",
|
||||
LDNS_OPCODE_WIRE(sldns_buffer_begin(pkt)));
|
||||
return worker_err_ratelimit(worker, LDNS_RCODE_NOTIMPL);
|
||||
@@ -352,7 +354,9 @@ worker_check_request(sldns_buffer* pkt, struct worker* worker)
|
||||
LDNS_QDCOUNT(sldns_buffer_begin(pkt)));
|
||||
return worker_err_ratelimit(worker, LDNS_RCODE_FORMERR);
|
||||
}
|
||||
if(LDNS_ANCOUNT(sldns_buffer_begin(pkt)) != 0) {
|
||||
if(LDNS_ANCOUNT(sldns_buffer_begin(pkt)) != 0 &&
|
||||
(LDNS_ANCOUNT(sldns_buffer_begin(pkt)) != 1 ||
|
||||
LDNS_OPCODE_WIRE(sldns_buffer_begin(pkt)) != LDNS_PACKET_NOTIFY)) {
|
||||
verbose(VERB_QUERY, "request wrong nr an=%d",
|
||||
LDNS_ANCOUNT(sldns_buffer_begin(pkt)));
|
||||
return worker_err_ratelimit(worker, LDNS_RCODE_FORMERR);
|
||||
@@ -474,6 +478,7 @@ answer_norec_from_cache(struct worker* worker, struct query_info* qinfo,
|
||||
* Then check if it needs validation, if so, this routine fails,
|
||||
* so that iterator can prime and validator can verify rrsets.
|
||||
*/
|
||||
struct edns_data edns_bak;
|
||||
uint16_t udpsize = edns->udp_size;
|
||||
int secure = 0;
|
||||
time_t timenow = *worker->env.now;
|
||||
@@ -499,13 +504,14 @@ answer_norec_from_cache(struct worker* worker, struct query_info* qinfo,
|
||||
* let validator do that */
|
||||
return 0;
|
||||
case sec_status_bogus:
|
||||
case sec_status_secure_sentinel_fail:
|
||||
/* some rrsets are bogus, reply servfail */
|
||||
edns->edns_version = EDNS_ADVERTISED_VERSION;
|
||||
edns->udp_size = EDNS_ADVERTISED_SIZE;
|
||||
edns->ext_rcode = 0;
|
||||
edns->bits &= EDNS_DO;
|
||||
if(!inplace_cb_reply_servfail_call(&worker->env, qinfo, NULL,
|
||||
msg->rep, LDNS_RCODE_SERVFAIL, edns, worker->scratchpad))
|
||||
msg->rep, LDNS_RCODE_SERVFAIL, edns, repinfo, worker->scratchpad))
|
||||
return 0;
|
||||
error_encode(repinfo->c->buffer, LDNS_RCODE_SERVFAIL,
|
||||
&msg->qinfo, id, flags, edns);
|
||||
@@ -530,19 +536,22 @@ answer_norec_from_cache(struct worker* worker, struct query_info* qinfo,
|
||||
}
|
||||
}
|
||||
/* return this delegation from the cache */
|
||||
edns_bak = *edns;
|
||||
edns->edns_version = EDNS_ADVERTISED_VERSION;
|
||||
edns->udp_size = EDNS_ADVERTISED_SIZE;
|
||||
edns->ext_rcode = 0;
|
||||
edns->bits &= EDNS_DO;
|
||||
if(!inplace_cb_reply_cache_call(&worker->env, qinfo, NULL, msg->rep,
|
||||
(int)(flags&LDNS_RCODE_MASK), edns, worker->scratchpad))
|
||||
(int)(flags&LDNS_RCODE_MASK), edns, repinfo, worker->scratchpad))
|
||||
return 0;
|
||||
msg->rep->flags |= BIT_QR|BIT_RA;
|
||||
if(!reply_info_answer_encode(&msg->qinfo, msg->rep, id, flags,
|
||||
if(!apply_edns_options(edns, &edns_bak, worker->env.cfg,
|
||||
repinfo->c, worker->scratchpad) ||
|
||||
!reply_info_answer_encode(&msg->qinfo, msg->rep, id, flags,
|
||||
repinfo->c->buffer, 0, 1, worker->scratchpad,
|
||||
udpsize, edns, (int)(edns->bits & EDNS_DO), secure)) {
|
||||
if(!inplace_cb_reply_servfail_call(&worker->env, qinfo, NULL, NULL,
|
||||
LDNS_RCODE_SERVFAIL, edns, worker->scratchpad))
|
||||
LDNS_RCODE_SERVFAIL, edns, repinfo, worker->scratchpad))
|
||||
edns->opt_list = NULL;
|
||||
error_encode(repinfo->c->buffer, LDNS_RCODE_SERVFAIL,
|
||||
&msg->qinfo, id, flags, edns);
|
||||
@@ -610,6 +619,7 @@ answer_from_cache(struct worker* worker, struct query_info* qinfo,
|
||||
struct reply_info* rep, uint16_t id, uint16_t flags,
|
||||
struct comm_reply* repinfo, struct edns_data* edns)
|
||||
{
|
||||
struct edns_data edns_bak;
|
||||
time_t timenow = *worker->env.now;
|
||||
uint16_t udpsize = edns->udp_size;
|
||||
struct reply_info* encode_rep = rep;
|
||||
@@ -619,7 +629,9 @@ answer_from_cache(struct worker* worker, struct query_info* qinfo,
|
||||
&& worker->env.need_to_validate;
|
||||
*partial_repp = NULL; /* avoid accidental further pass */
|
||||
if(worker->env.cfg->serve_expired) {
|
||||
/* always lock rrsets, rep->ttl is ignored */
|
||||
if(worker->env.cfg->serve_expired_ttl &&
|
||||
rep->serve_expired_ttl < timenow)
|
||||
return 0;
|
||||
if(!rrset_array_lock(rep->ref, rep->rrset_count, 0))
|
||||
return 0;
|
||||
/* below, rrsets with ttl before timenow become TTL 0 in
|
||||
@@ -655,14 +667,15 @@ answer_from_cache(struct worker* worker, struct query_info* qinfo,
|
||||
}
|
||||
}
|
||||
/* check security status of the cached answer */
|
||||
if( rep->security == sec_status_bogus && must_validate) {
|
||||
if(must_validate && (rep->security == sec_status_bogus ||
|
||||
rep->security == sec_status_secure_sentinel_fail)) {
|
||||
/* BAD cached */
|
||||
edns->edns_version = EDNS_ADVERTISED_VERSION;
|
||||
edns->udp_size = EDNS_ADVERTISED_SIZE;
|
||||
edns->ext_rcode = 0;
|
||||
edns->bits &= EDNS_DO;
|
||||
if(!inplace_cb_reply_servfail_call(&worker->env, qinfo, NULL, rep,
|
||||
LDNS_RCODE_SERVFAIL, edns, worker->scratchpad))
|
||||
LDNS_RCODE_SERVFAIL, edns, repinfo, worker->scratchpad))
|
||||
goto bail_out;
|
||||
error_encode(repinfo->c->buffer, LDNS_RCODE_SERVFAIL,
|
||||
qinfo, id, flags, edns);
|
||||
@@ -690,12 +703,13 @@ answer_from_cache(struct worker* worker, struct query_info* qinfo,
|
||||
}
|
||||
} else secure = 0;
|
||||
|
||||
edns_bak = *edns;
|
||||
edns->edns_version = EDNS_ADVERTISED_VERSION;
|
||||
edns->udp_size = EDNS_ADVERTISED_SIZE;
|
||||
edns->ext_rcode = 0;
|
||||
edns->bits &= EDNS_DO;
|
||||
if(!inplace_cb_reply_cache_call(&worker->env, qinfo, NULL, rep,
|
||||
(int)(flags&LDNS_RCODE_MASK), edns, worker->scratchpad))
|
||||
(int)(flags&LDNS_RCODE_MASK), edns, repinfo, worker->scratchpad))
|
||||
goto bail_out;
|
||||
*alias_rrset = NULL; /* avoid confusion if caller set it to non-NULL */
|
||||
if(worker->daemon->use_response_ip && !partial_rep &&
|
||||
@@ -723,11 +737,13 @@ answer_from_cache(struct worker* worker, struct query_info* qinfo,
|
||||
if(!*partial_repp)
|
||||
goto bail_out;
|
||||
}
|
||||
} else if(!reply_info_answer_encode(qinfo, encode_rep, id, flags,
|
||||
} else if(!apply_edns_options(edns, &edns_bak, worker->env.cfg,
|
||||
repinfo->c, worker->scratchpad) ||
|
||||
!reply_info_answer_encode(qinfo, encode_rep, id, flags,
|
||||
repinfo->c->buffer, timenow, 1, worker->scratchpad,
|
||||
udpsize, edns, (int)(edns->bits & EDNS_DO), secure)) {
|
||||
if(!inplace_cb_reply_servfail_call(&worker->env, qinfo, NULL, NULL,
|
||||
LDNS_RCODE_SERVFAIL, edns, worker->scratchpad))
|
||||
LDNS_RCODE_SERVFAIL, edns, repinfo, worker->scratchpad))
|
||||
edns->opt_list = NULL;
|
||||
error_encode(repinfo->c->buffer, LDNS_RCODE_SERVFAIL,
|
||||
qinfo, id, flags, edns);
|
||||
@@ -774,10 +790,11 @@ reply_and_prefetch(struct worker* worker, struct query_info* qinfo,
|
||||
* @param num: number of strings in array.
|
||||
* @param edns: edns reply information.
|
||||
* @param worker: worker with scratch region.
|
||||
* @param repinfo: reply information for a communication point.
|
||||
*/
|
||||
static void
|
||||
chaos_replystr(sldns_buffer* pkt, char** str, int num, struct edns_data* edns,
|
||||
struct worker* worker)
|
||||
struct worker* worker, struct comm_reply* repinfo)
|
||||
{
|
||||
int i;
|
||||
unsigned int rd = LDNS_RD_WIRE(sldns_buffer_begin(pkt));
|
||||
@@ -810,7 +827,7 @@ chaos_replystr(sldns_buffer* pkt, char** str, int num, struct edns_data* edns,
|
||||
edns->udp_size = EDNS_ADVERTISED_SIZE;
|
||||
edns->bits &= EDNS_DO;
|
||||
if(!inplace_cb_reply_local_call(&worker->env, NULL, NULL, NULL,
|
||||
LDNS_RCODE_NOERROR, edns, worker->scratchpad))
|
||||
LDNS_RCODE_NOERROR, edns, repinfo, worker->scratchpad))
|
||||
edns->opt_list = NULL;
|
||||
if(sldns_buffer_capacity(pkt) >=
|
||||
sldns_buffer_limit(pkt)+calc_edns_field_size(edns))
|
||||
@@ -820,9 +837,9 @@ chaos_replystr(sldns_buffer* pkt, char** str, int num, struct edns_data* edns,
|
||||
/** Reply with one string */
|
||||
static void
|
||||
chaos_replyonestr(sldns_buffer* pkt, const char* str, struct edns_data* edns,
|
||||
struct worker* worker)
|
||||
struct worker* worker, struct comm_reply* repinfo)
|
||||
{
|
||||
chaos_replystr(pkt, (char**)&str, 1, edns, worker);
|
||||
chaos_replystr(pkt, (char**)&str, 1, edns, worker, repinfo);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -830,9 +847,11 @@ chaos_replyonestr(sldns_buffer* pkt, const char* str, struct edns_data* edns,
|
||||
* @param pkt: buffer
|
||||
* @param edns: edns reply information.
|
||||
* @param w: worker with scratch region.
|
||||
* @param repinfo: reply information for a communication point.
|
||||
*/
|
||||
static void
|
||||
chaos_trustanchor(sldns_buffer* pkt, struct edns_data* edns, struct worker* w)
|
||||
chaos_trustanchor(sldns_buffer* pkt, struct edns_data* edns, struct worker* w,
|
||||
struct comm_reply* repinfo)
|
||||
{
|
||||
#define TA_RESPONSE_MAX_TXT 16 /* max number of TXT records */
|
||||
#define TA_RESPONSE_MAX_TAGS 32 /* max number of tags printed per zone */
|
||||
@@ -843,7 +862,7 @@ chaos_trustanchor(sldns_buffer* pkt, struct edns_data* edns, struct worker* w)
|
||||
|
||||
if(!w->env.need_to_validate) {
|
||||
/* no validator module, reply no trustanchors */
|
||||
chaos_replystr(pkt, NULL, 0, edns, w);
|
||||
chaos_replystr(pkt, NULL, 0, edns, w, repinfo);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -877,7 +896,7 @@ chaos_trustanchor(sldns_buffer* pkt, struct edns_data* edns, struct worker* w)
|
||||
}
|
||||
lock_basic_unlock(&w->env.anchors->lock);
|
||||
|
||||
chaos_replystr(pkt, str_array, num, edns, w);
|
||||
chaos_replystr(pkt, str_array, num, edns, w, repinfo);
|
||||
regional_free_all(w->scratchpad);
|
||||
}
|
||||
|
||||
@@ -886,12 +905,13 @@ chaos_trustanchor(sldns_buffer* pkt, struct edns_data* edns, struct worker* w)
|
||||
* @param w: worker
|
||||
* @param qinfo: query info. Pointer into packet buffer.
|
||||
* @param edns: edns info from query.
|
||||
* @param repinfo: reply information for a communication point.
|
||||
* @param pkt: packet buffer.
|
||||
* @return: true if a reply is to be sent.
|
||||
*/
|
||||
static int
|
||||
answer_chaos(struct worker* w, struct query_info* qinfo,
|
||||
struct edns_data* edns, sldns_buffer* pkt)
|
||||
answer_chaos(struct worker* w, struct query_info* qinfo,
|
||||
struct edns_data* edns, struct comm_reply* repinfo, sldns_buffer* pkt)
|
||||
{
|
||||
struct config_file* cfg = w->env.cfg;
|
||||
if(qinfo->qtype != LDNS_RR_TYPE_ANY && qinfo->qtype != LDNS_RR_TYPE_TXT)
|
||||
@@ -907,13 +927,13 @@ answer_chaos(struct worker* w, struct query_info* qinfo,
|
||||
char buf[MAXHOSTNAMELEN+1];
|
||||
if (gethostname(buf, MAXHOSTNAMELEN) == 0) {
|
||||
buf[MAXHOSTNAMELEN] = 0;
|
||||
chaos_replyonestr(pkt, buf, edns, w);
|
||||
chaos_replyonestr(pkt, buf, edns, w, repinfo);
|
||||
} else {
|
||||
log_err("gethostname: %s", strerror(errno));
|
||||
chaos_replyonestr(pkt, "no hostname", edns, w);
|
||||
chaos_replyonestr(pkt, "no hostname", edns, w, repinfo);
|
||||
}
|
||||
}
|
||||
else chaos_replyonestr(pkt, cfg->identity, edns, w);
|
||||
else chaos_replyonestr(pkt, cfg->identity, edns, w, repinfo);
|
||||
return 1;
|
||||
}
|
||||
if(query_dname_compare(qinfo->qname,
|
||||
@@ -924,8 +944,8 @@ answer_chaos(struct worker* w, struct query_info* qinfo,
|
||||
if(cfg->hide_version)
|
||||
return 0;
|
||||
if(cfg->version==NULL || cfg->version[0]==0)
|
||||
chaos_replyonestr(pkt, PACKAGE_STRING, edns, w);
|
||||
else chaos_replyonestr(pkt, cfg->version, edns, w);
|
||||
chaos_replyonestr(pkt, PACKAGE_STRING, edns, w, repinfo);
|
||||
else chaos_replyonestr(pkt, cfg->version, edns, w, repinfo);
|
||||
return 1;
|
||||
}
|
||||
if(query_dname_compare(qinfo->qname,
|
||||
@@ -933,13 +953,73 @@ answer_chaos(struct worker* w, struct query_info* qinfo,
|
||||
{
|
||||
if(cfg->hide_trustanchor)
|
||||
return 0;
|
||||
chaos_trustanchor(pkt, edns, w);
|
||||
chaos_trustanchor(pkt, edns, w, repinfo);
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Answer notify queries. These are notifies for authoritative zones,
|
||||
* the reply is an ack that the notify has been received. We need to check
|
||||
* access permission here.
|
||||
* @param w: worker
|
||||
* @param qinfo: query info. Pointer into packet buffer.
|
||||
* @param edns: edns info from query.
|
||||
* @param repinfo: reply info with source address.
|
||||
* @param pkt: packet buffer.
|
||||
*/
|
||||
static void
|
||||
answer_notify(struct worker* w, struct query_info* qinfo,
|
||||
struct edns_data* edns, sldns_buffer* pkt, struct comm_reply* repinfo)
|
||||
{
|
||||
int refused = 0;
|
||||
int rcode = LDNS_RCODE_NOERROR;
|
||||
uint32_t serial = 0;
|
||||
int has_serial;
|
||||
if(!w->env.auth_zones) return;
|
||||
has_serial = auth_zone_parse_notify_serial(pkt, &serial);
|
||||
if(auth_zones_notify(w->env.auth_zones, &w->env, qinfo->qname,
|
||||
qinfo->qname_len, qinfo->qclass, &repinfo->addr,
|
||||
repinfo->addrlen, has_serial, serial, &refused)) {
|
||||
rcode = LDNS_RCODE_NOERROR;
|
||||
} else {
|
||||
if(refused)
|
||||
rcode = LDNS_RCODE_REFUSED;
|
||||
else rcode = LDNS_RCODE_SERVFAIL;
|
||||
}
|
||||
|
||||
if(verbosity >= VERB_DETAIL) {
|
||||
char buf[380];
|
||||
char zname[255+1];
|
||||
char sr[25];
|
||||
dname_str(qinfo->qname, zname);
|
||||
sr[0]=0;
|
||||
if(has_serial)
|
||||
snprintf(sr, sizeof(sr), "serial %u ",
|
||||
(unsigned)serial);
|
||||
if(rcode == LDNS_RCODE_REFUSED)
|
||||
snprintf(buf, sizeof(buf),
|
||||
"refused NOTIFY %sfor %s from", sr, zname);
|
||||
else if(rcode == LDNS_RCODE_SERVFAIL)
|
||||
snprintf(buf, sizeof(buf),
|
||||
"servfail for NOTIFY %sfor %s from", sr, zname);
|
||||
else snprintf(buf, sizeof(buf),
|
||||
"received NOTIFY %sfor %s from", sr, zname);
|
||||
log_addr(VERB_DETAIL, buf, &repinfo->addr, repinfo->addrlen);
|
||||
}
|
||||
edns->edns_version = EDNS_ADVERTISED_VERSION;
|
||||
edns->udp_size = EDNS_ADVERTISED_SIZE;
|
||||
edns->ext_rcode = 0;
|
||||
edns->bits &= EDNS_DO;
|
||||
edns->opt_list = NULL;
|
||||
error_encode(pkt, rcode, qinfo,
|
||||
*(uint16_t*)(void *)sldns_buffer_begin(pkt),
|
||||
sldns_buffer_read_u16_at(pkt, 2), edns);
|
||||
LDNS_OPCODE_SET(sldns_buffer_begin(pkt), LDNS_PACKET_NOTIFY);
|
||||
}
|
||||
|
||||
static int
|
||||
deny_refuse(struct comm_point* c, enum acl_access acl,
|
||||
enum acl_access deny, enum acl_access refuse,
|
||||
@@ -1100,7 +1180,7 @@ worker_handle_request(struct comm_point* c, void* arg, int error,
|
||||
char addrbuf[128];
|
||||
addr_to_str(&repinfo->addr, repinfo->addrlen,
|
||||
addrbuf, sizeof(addrbuf));
|
||||
verbose(VERB_OPS, "ip_ratelimit allowed through for ip address %s ",
|
||||
verbose(VERB_QUERY, "ip_ratelimit allowed through for ip address %s because of slip in ip_ratelimit_factor",
|
||||
addrbuf);
|
||||
} else {
|
||||
worker->stats.num_queries_ip_ratelimited++;
|
||||
@@ -1181,29 +1261,52 @@ worker_handle_request(struct comm_point* c, void* arg, int error,
|
||||
server_stats_insrcode(&worker->stats, c->buffer);
|
||||
goto send_reply;
|
||||
}
|
||||
if(edns.edns_present && edns.edns_version != 0) {
|
||||
edns.ext_rcode = (uint8_t)(EDNS_RCODE_BADVERS>>4);
|
||||
edns.edns_version = EDNS_ADVERTISED_VERSION;
|
||||
edns.udp_size = EDNS_ADVERTISED_SIZE;
|
||||
edns.bits &= EDNS_DO;
|
||||
edns.opt_list = NULL;
|
||||
verbose(VERB_ALGO, "query with bad edns version.");
|
||||
log_addr(VERB_CLIENT,"from",&repinfo->addr, repinfo->addrlen);
|
||||
error_encode(c->buffer, EDNS_RCODE_BADVERS&0xf, &qinfo,
|
||||
*(uint16_t*)(void *)sldns_buffer_begin(c->buffer),
|
||||
sldns_buffer_read_u16_at(c->buffer, 2), NULL);
|
||||
if(sldns_buffer_capacity(c->buffer) >=
|
||||
sldns_buffer_limit(c->buffer)+calc_edns_field_size(&edns))
|
||||
attach_edns_record(c->buffer, &edns);
|
||||
regional_free_all(worker->scratchpad);
|
||||
goto send_reply;
|
||||
}
|
||||
if(edns.edns_present && edns.udp_size < NORMAL_UDP_SIZE &&
|
||||
worker->daemon->cfg->harden_short_bufsize) {
|
||||
verbose(VERB_QUERY, "worker request: EDNS bufsize %d ignored",
|
||||
(int)edns.udp_size);
|
||||
log_addr(VERB_CLIENT,"from",&repinfo->addr, repinfo->addrlen);
|
||||
edns.udp_size = NORMAL_UDP_SIZE;
|
||||
if(edns.edns_present) {
|
||||
struct edns_option* edns_opt;
|
||||
if(edns.edns_version != 0) {
|
||||
edns.ext_rcode = (uint8_t)(EDNS_RCODE_BADVERS>>4);
|
||||
edns.edns_version = EDNS_ADVERTISED_VERSION;
|
||||
edns.udp_size = EDNS_ADVERTISED_SIZE;
|
||||
edns.bits &= EDNS_DO;
|
||||
edns.opt_list = NULL;
|
||||
verbose(VERB_ALGO, "query with bad edns version.");
|
||||
log_addr(VERB_CLIENT,"from",&repinfo->addr, repinfo->addrlen);
|
||||
error_encode(c->buffer, EDNS_RCODE_BADVERS&0xf, &qinfo,
|
||||
*(uint16_t*)(void *)sldns_buffer_begin(c->buffer),
|
||||
sldns_buffer_read_u16_at(c->buffer, 2), NULL);
|
||||
if(sldns_buffer_capacity(c->buffer) >=
|
||||
sldns_buffer_limit(c->buffer)+calc_edns_field_size(&edns))
|
||||
attach_edns_record(c->buffer, &edns);
|
||||
regional_free_all(worker->scratchpad);
|
||||
goto send_reply;
|
||||
}
|
||||
if(edns.udp_size < NORMAL_UDP_SIZE &&
|
||||
worker->daemon->cfg->harden_short_bufsize) {
|
||||
verbose(VERB_QUERY, "worker request: EDNS bufsize %d ignored",
|
||||
(int)edns.udp_size);
|
||||
log_addr(VERB_CLIENT,"from",&repinfo->addr, repinfo->addrlen);
|
||||
edns.udp_size = NORMAL_UDP_SIZE;
|
||||
}
|
||||
if(c->type != comm_udp) {
|
||||
edns_opt = edns_opt_list_find(edns.opt_list, LDNS_EDNS_KEEPALIVE);
|
||||
if(edns_opt && edns_opt->opt_len > 0) {
|
||||
edns.ext_rcode = 0;
|
||||
edns.edns_version = EDNS_ADVERTISED_VERSION;
|
||||
edns.udp_size = EDNS_ADVERTISED_SIZE;
|
||||
edns.bits &= EDNS_DO;
|
||||
edns.opt_list = NULL;
|
||||
verbose(VERB_ALGO, "query with bad edns keepalive.");
|
||||
log_addr(VERB_CLIENT,"from",&repinfo->addr, repinfo->addrlen);
|
||||
error_encode(c->buffer, LDNS_RCODE_FORMERR, &qinfo,
|
||||
*(uint16_t*)(void *)sldns_buffer_begin(c->buffer),
|
||||
sldns_buffer_read_u16_at(c->buffer, 2), NULL);
|
||||
if(sldns_buffer_capacity(c->buffer) >=
|
||||
sldns_buffer_limit(c->buffer)+calc_edns_field_size(&edns))
|
||||
attach_edns_record(c->buffer, &edns);
|
||||
regional_free_all(worker->scratchpad);
|
||||
goto send_reply;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(edns.udp_size > worker->daemon->cfg->max_udp_size &&
|
||||
c->type == comm_udp) {
|
||||
@@ -1233,11 +1336,17 @@ worker_handle_request(struct comm_point* c, void* arg, int error,
|
||||
if(c->type != comm_udp)
|
||||
edns.udp_size = 65535; /* max size for TCP replies */
|
||||
if(qinfo.qclass == LDNS_RR_CLASS_CH && answer_chaos(worker, &qinfo,
|
||||
&edns, c->buffer)) {
|
||||
&edns, repinfo, c->buffer)) {
|
||||
server_stats_insrcode(&worker->stats, c->buffer);
|
||||
regional_free_all(worker->scratchpad);
|
||||
goto send_reply;
|
||||
}
|
||||
if(LDNS_OPCODE_WIRE(sldns_buffer_begin(c->buffer)) ==
|
||||
LDNS_PACKET_NOTIFY) {
|
||||
answer_notify(worker, &qinfo, &edns, c->buffer, repinfo);
|
||||
regional_free_all(worker->scratchpad);
|
||||
goto send_reply;
|
||||
}
|
||||
if(local_zones_answer(worker->daemon->local_zones, &worker->env, &qinfo,
|
||||
&edns, c->buffer, worker->scratchpad, repinfo, acladdr->taglist,
|
||||
acladdr->taglen, acladdr->tag_actions,
|
||||
@@ -1254,7 +1363,7 @@ worker_handle_request(struct comm_point* c, void* arg, int error,
|
||||
}
|
||||
if(worker->env.auth_zones &&
|
||||
auth_zones_answer(worker->env.auth_zones, &worker->env,
|
||||
&qinfo, &edns, c->buffer, worker->scratchpad)) {
|
||||
&qinfo, &edns, repinfo, c->buffer, worker->scratchpad)) {
|
||||
regional_free_all(worker->scratchpad);
|
||||
if(sldns_buffer_limit(c->buffer) == 0) {
|
||||
comm_point_drop_reply(repinfo);
|
||||
@@ -1279,6 +1388,13 @@ worker_handle_request(struct comm_point* c, void* arg, int error,
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* If this request does not have the recursion bit set, verify
|
||||
* ACLs allow the recursion bit to be treated as set. */
|
||||
if(!(LDNS_RD_WIRE(sldns_buffer_begin(c->buffer))) &&
|
||||
acl == acl_allow_setrd ) {
|
||||
LDNS_RD_SET(sldns_buffer_begin(c->buffer));
|
||||
}
|
||||
|
||||
/* If this request does not have the recursion bit set, verify
|
||||
* ACLs allow the snooping. */
|
||||
if(!(LDNS_RD_WIRE(sldns_buffer_begin(c->buffer))) &&
|
||||
@@ -1555,14 +1671,14 @@ worker_create(struct daemon* daemon, int id, int* ports, int n)
|
||||
(((unsigned int)worker->thread_num)<<17);
|
||||
/* shift thread_num so it does not match out pid bits */
|
||||
if(!(worker->rndstate = ub_initstate(seed, daemon->rand))) {
|
||||
seed = 0;
|
||||
explicit_bzero(&seed, sizeof(seed));
|
||||
log_err("could not init random numbers.");
|
||||
tube_delete(worker->cmd);
|
||||
free(worker->ports);
|
||||
free(worker);
|
||||
return NULL;
|
||||
}
|
||||
seed = 0;
|
||||
explicit_bzero(&seed, sizeof(seed));
|
||||
#ifdef USE_DNSTAP
|
||||
if(daemon->cfg->dnstap) {
|
||||
log_assert(daemon->dtenv != NULL);
|
||||
@@ -1630,9 +1746,13 @@ worker_init(struct worker* worker, struct config_file *cfg,
|
||||
worker->comsig = NULL;
|
||||
}
|
||||
worker->front = listen_create(worker->base, ports,
|
||||
cfg->msg_buffer_size, (int)cfg->incoming_num_tcp,
|
||||
worker->daemon->listen_sslctx, dtenv, worker_handle_request,
|
||||
worker);
|
||||
cfg->msg_buffer_size, (int)cfg->incoming_num_tcp,
|
||||
cfg->do_tcp_keepalive
|
||||
? cfg->tcp_keepalive_timeout
|
||||
: cfg->tcp_idle_timeout,
|
||||
worker->daemon->tcl,
|
||||
worker->daemon->listen_sslctx,
|
||||
dtenv, worker_handle_request, worker);
|
||||
if(!worker->front) {
|
||||
log_err("could not create listening sockets");
|
||||
worker_delete(worker);
|
||||
@@ -1806,7 +1926,7 @@ struct outbound_entry*
|
||||
worker_send_query(struct query_info* qinfo, uint16_t flags, int dnssec,
|
||||
int want_dnssec, int nocaps, struct sockaddr_storage* addr,
|
||||
socklen_t addrlen, uint8_t* zone, size_t zonelen, int ssl_upstream,
|
||||
struct module_qstate* q)
|
||||
char* tls_auth_name, struct module_qstate* q)
|
||||
{
|
||||
struct worker* worker = q->env->worker;
|
||||
struct outbound_entry* e = (struct outbound_entry*)regional_alloc(
|
||||
@@ -1816,7 +1936,7 @@ worker_send_query(struct query_info* qinfo, uint16_t flags, int dnssec,
|
||||
e->qstate = q;
|
||||
e->qsent = outnet_serviced_query(worker->back, qinfo, flags, dnssec,
|
||||
want_dnssec, nocaps, q->env->cfg->tcp_upstream,
|
||||
ssl_upstream, addr, addrlen, zone, zonelen, q,
|
||||
ssl_upstream, tls_auth_name, addr, addrlen, zone, zonelen, q,
|
||||
worker_handle_service_reply, e, worker->back->udp_buff, q->env);
|
||||
if(!e->qsent) {
|
||||
return NULL;
|
||||
@@ -1863,7 +1983,8 @@ struct outbound_entry* libworker_send_query(
|
||||
int ATTR_UNUSED(want_dnssec), int ATTR_UNUSED(nocaps),
|
||||
struct sockaddr_storage* ATTR_UNUSED(addr), socklen_t ATTR_UNUSED(addrlen),
|
||||
uint8_t* ATTR_UNUSED(zone), size_t ATTR_UNUSED(zonelen),
|
||||
int ATTR_UNUSED(ssl_upstream), struct module_qstate* ATTR_UNUSED(q))
|
||||
int ATTR_UNUSED(ssl_upstream), char* ATTR_UNUSED(tls_auth_name),
|
||||
struct module_qstate* ATTR_UNUSED(q))
|
||||
{
|
||||
log_assert(0);
|
||||
return 0;
|
||||
@@ -1893,22 +2014,22 @@ void libworker_handle_control_cmd(struct tube* ATTR_UNUSED(tube),
|
||||
}
|
||||
|
||||
void libworker_fg_done_cb(void* ATTR_UNUSED(arg), int ATTR_UNUSED(rcode),
|
||||
sldns_buffer* ATTR_UNUSED(buf), enum sec_status ATTR_UNUSED(s),
|
||||
char* ATTR_UNUSED(why_bogus))
|
||||
sldns_buffer* ATTR_UNUSED(buf), enum sec_status ATTR_UNUSED(s),
|
||||
char* ATTR_UNUSED(why_bogus), int ATTR_UNUSED(was_ratelimited))
|
||||
{
|
||||
log_assert(0);
|
||||
}
|
||||
|
||||
void libworker_bg_done_cb(void* ATTR_UNUSED(arg), int ATTR_UNUSED(rcode),
|
||||
sldns_buffer* ATTR_UNUSED(buf), enum sec_status ATTR_UNUSED(s),
|
||||
char* ATTR_UNUSED(why_bogus))
|
||||
sldns_buffer* ATTR_UNUSED(buf), enum sec_status ATTR_UNUSED(s),
|
||||
char* ATTR_UNUSED(why_bogus), int ATTR_UNUSED(was_ratelimited))
|
||||
{
|
||||
log_assert(0);
|
||||
}
|
||||
|
||||
void libworker_event_done_cb(void* ATTR_UNUSED(arg), int ATTR_UNUSED(rcode),
|
||||
sldns_buffer* ATTR_UNUSED(buf), enum sec_status ATTR_UNUSED(s),
|
||||
char* ATTR_UNUSED(why_bogus))
|
||||
sldns_buffer* ATTR_UNUSED(buf), enum sec_status ATTR_UNUSED(s),
|
||||
char* ATTR_UNUSED(why_bogus), int ATTR_UNUSED(was_ratelimited))
|
||||
{
|
||||
log_assert(0);
|
||||
}
|
||||
@@ -1921,13 +2042,13 @@ int context_query_cmp(const void* ATTR_UNUSED(a), const void* ATTR_UNUSED(b))
|
||||
|
||||
int order_lock_cmp(const void* ATTR_UNUSED(e1), const void* ATTR_UNUSED(e2))
|
||||
{
|
||||
log_assert(0);
|
||||
return 0;
|
||||
log_assert(0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int codeline_cmp(const void* ATTR_UNUSED(a), const void* ATTR_UNUSED(b))
|
||||
{
|
||||
log_assert(0);
|
||||
return 0;
|
||||
log_assert(0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
+121
-10
@@ -48,6 +48,9 @@
|
||||
#include "util/fptr_wlist.h"
|
||||
#include "util/net_help.h"
|
||||
#include "util/regional.h"
|
||||
#include "util/storage/dnstree.h"
|
||||
#include "util/data/dname.h"
|
||||
#include "sldns/str2wire.h"
|
||||
|
||||
/******************************************************************************
|
||||
* *
|
||||
@@ -111,6 +114,11 @@ struct dns64_env {
|
||||
* This is the CIDR length of the prefix. It needs to be between 0 and 96.
|
||||
*/
|
||||
int prefix_net;
|
||||
|
||||
/**
|
||||
* Tree of names for which AAAA is ignored. always synthesize from A.
|
||||
*/
|
||||
rbtree_type ignore_aaaa;
|
||||
};
|
||||
|
||||
|
||||
@@ -284,6 +292,40 @@ synthesize_aaaa(const uint8_t prefix_addr[16], int prefix_net,
|
||||
* *
|
||||
******************************************************************************/
|
||||
|
||||
/**
|
||||
* insert ignore_aaaa element into the tree
|
||||
* @param dns64_env: module env.
|
||||
* @param str: string with domain name.
|
||||
* @return false on failure.
|
||||
*/
|
||||
static int
|
||||
dns64_insert_ignore_aaaa(struct dns64_env* dns64_env, char* str)
|
||||
{
|
||||
/* parse and insert element */
|
||||
struct name_tree_node* node;
|
||||
node = (struct name_tree_node*)calloc(1, sizeof(*node));
|
||||
if(!node) {
|
||||
log_err("out of memory");
|
||||
return 0;
|
||||
}
|
||||
node->name = sldns_str2wire_dname(str, &node->len);
|
||||
if(!node->name) {
|
||||
free(node);
|
||||
log_err("cannot parse dns64-ignore-aaaa: %s", str);
|
||||
return 0;
|
||||
}
|
||||
node->labs = dname_count_labels(node->name);
|
||||
node->dclass = LDNS_RR_CLASS_IN;
|
||||
if(!name_tree_insert(&dns64_env->ignore_aaaa, node,
|
||||
node->name, node->len, node->labs, node->dclass)) {
|
||||
/* ignore duplicate element */
|
||||
free(node->name);
|
||||
free(node);
|
||||
return 1;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* This function applies the configuration found in the parsed configuration
|
||||
* file \a cfg to this instance of the dns64 module. Currently only the DNS64
|
||||
@@ -295,6 +337,7 @@ synthesize_aaaa(const uint8_t prefix_addr[16], int prefix_net,
|
||||
static int
|
||||
dns64_apply_cfg(struct dns64_env* dns64_env, struct config_file* cfg)
|
||||
{
|
||||
struct config_strlist* s;
|
||||
verbose(VERB_ALGO, "dns64-prefix: %s", cfg->dns64_prefix);
|
||||
if (!netblockstrtoaddr(cfg->dns64_prefix ? cfg->dns64_prefix :
|
||||
DEFAULT_DNS64_PREFIX, 0, &dns64_env->prefix_addr,
|
||||
@@ -311,6 +354,11 @@ dns64_apply_cfg(struct dns64_env* dns64_env, struct config_file* cfg)
|
||||
cfg->dns64_prefix);
|
||||
return 0;
|
||||
}
|
||||
for(s = cfg->dns64_ignore_aaaa; s; s = s->next) {
|
||||
if(!dns64_insert_ignore_aaaa(dns64_env, s->str))
|
||||
return 0;
|
||||
}
|
||||
name_tree_init_parents(&dns64_env->ignore_aaaa);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -329,7 +377,8 @@ dns64_init(struct module_env* env, int id)
|
||||
log_err("malloc failure");
|
||||
return 0;
|
||||
}
|
||||
env->modinfo[id] = (void*)dns64_env;
|
||||
env->modinfo[id] = (void*)dns64_env;
|
||||
name_tree_init(&dns64_env->ignore_aaaa);
|
||||
if (!dns64_apply_cfg(dns64_env, env->cfg)) {
|
||||
log_err("dns64: could not apply configuration settings.");
|
||||
return 0;
|
||||
@@ -337,6 +386,16 @@ dns64_init(struct module_env* env, int id)
|
||||
return 1;
|
||||
}
|
||||
|
||||
/** free ignore AAAA elements */
|
||||
static void
|
||||
free_ignore_aaaa_node(rbnode_type* node, void* ATTR_UNUSED(arg))
|
||||
{
|
||||
struct name_tree_node* n = (struct name_tree_node*)node;
|
||||
if(!n) return;
|
||||
free(n->name);
|
||||
free(n);
|
||||
}
|
||||
|
||||
/**
|
||||
* Deinitializes this instance of the dns64 module.
|
||||
*
|
||||
@@ -346,8 +405,14 @@ dns64_init(struct module_env* env, int id)
|
||||
void
|
||||
dns64_deinit(struct module_env* env, int id)
|
||||
{
|
||||
struct dns64_env* dns64_env;
|
||||
if (!env)
|
||||
return;
|
||||
dns64_env = (struct dns64_env*)env->modinfo[id];
|
||||
if(dns64_env) {
|
||||
traverse_postorder(&dns64_env->ignore_aaaa, free_ignore_aaaa_node,
|
||||
NULL);
|
||||
}
|
||||
free(env->modinfo[id]);
|
||||
env->modinfo[id] = NULL;
|
||||
}
|
||||
@@ -440,6 +505,25 @@ generate_type_A_query(struct module_qstate* qstate, int id)
|
||||
return module_wait_subquery;
|
||||
}
|
||||
|
||||
/**
|
||||
* See if query name is in the always synth config.
|
||||
* The ignore-aaaa list has names for which the AAAA for the domain is
|
||||
* ignored and the A is always used to create the answer.
|
||||
* @param qstate: query state.
|
||||
* @param id: module id.
|
||||
* @return true if the name is covered by ignore-aaaa.
|
||||
*/
|
||||
static int
|
||||
dns64_always_synth_for_qname(struct module_qstate* qstate, int id)
|
||||
{
|
||||
struct dns64_env* dns64_env = (struct dns64_env*)qstate->env->modinfo[id];
|
||||
int labs = dname_count_labels(qstate->qinfo.qname);
|
||||
struct name_tree_node* node = name_tree_lookup(&dns64_env->ignore_aaaa,
|
||||
qstate->qinfo.qname, qstate->qinfo.qname_len, labs,
|
||||
qstate->qinfo.qclass);
|
||||
return (node != NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles the "pass" event for a query. This event is received when a new query
|
||||
* is received by this module. The query may have been generated internally by
|
||||
@@ -468,6 +552,14 @@ handle_event_pass(struct module_qstate* qstate, int id)
|
||||
&& qstate->qinfo.qtype == LDNS_RR_TYPE_AAAA)
|
||||
return generate_type_A_query(qstate, id);
|
||||
|
||||
if(dns64_always_synth_for_qname(qstate, id) &&
|
||||
(uintptr_t)qstate->minfo[id] == DNS64_NEW_QUERY
|
||||
&& !(qstate->query_flags & BIT_CD)
|
||||
&& qstate->qinfo.qtype == LDNS_RR_TYPE_AAAA) {
|
||||
verbose(VERB_ALGO, "dns64: ignore-aaaa and synthesize anyway");
|
||||
return generate_type_A_query(qstate, id);
|
||||
}
|
||||
|
||||
/* We are finished when our sub-query is finished. */
|
||||
if ((uintptr_t)qstate->minfo[id] == DNS64_SUBQUERY_FINISHED)
|
||||
return module_finished;
|
||||
@@ -501,17 +593,29 @@ handle_event_moddone(struct module_qstate* qstate, int id)
|
||||
* synthesize in (sec 5.1.2 of RFC6147).
|
||||
* - A successful AAAA query with an answer.
|
||||
*/
|
||||
if ( (enum dns64_qstate)qstate->minfo[id] == DNS64_INTERNAL_QUERY
|
||||
|| qstate->qinfo.qtype != LDNS_RR_TYPE_AAAA
|
||||
|| (qstate->query_flags & BIT_CD)
|
||||
|| (qstate->return_msg &&
|
||||
if((enum dns64_qstate)qstate->minfo[id] != DNS64_INTERNAL_QUERY
|
||||
&& qstate->qinfo.qtype == LDNS_RR_TYPE_AAAA
|
||||
&& !(qstate->query_flags & BIT_CD)
|
||||
&& !(qstate->return_msg &&
|
||||
qstate->return_msg->rep &&
|
||||
reply_find_answer_rrset(&qstate->qinfo,
|
||||
qstate->return_msg->rep)))
|
||||
return module_finished;
|
||||
/* not internal, type AAAA, not CD, and no answer RRset,
|
||||
* So, this is a AAAA noerror/nodata answer */
|
||||
return generate_type_A_query(qstate, id);
|
||||
|
||||
/* So, this is a AAAA noerror/nodata answer */
|
||||
return generate_type_A_query(qstate, id);
|
||||
if((enum dns64_qstate)qstate->minfo[id] != DNS64_INTERNAL_QUERY
|
||||
&& qstate->qinfo.qtype == LDNS_RR_TYPE_AAAA
|
||||
&& !(qstate->query_flags & BIT_CD)
|
||||
&& dns64_always_synth_for_qname(qstate, id)) {
|
||||
/* if it is not internal, AAAA, not CD and listed domain,
|
||||
* generate from A record and ignore AAAA */
|
||||
verbose(VERB_ALGO, "dns64: ignore-aaaa and synthesize anyway");
|
||||
return generate_type_A_query(qstate, id);
|
||||
}
|
||||
|
||||
/* do nothing */
|
||||
return module_finished;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -677,8 +781,9 @@ dns64_adjust_a(int id, struct module_qstate* super, struct module_qstate* qstate
|
||||
* Build the actual reply.
|
||||
*/
|
||||
cp = construct_reply_info_base(super->region, rep->flags, rep->qdcount,
|
||||
rep->ttl, rep->prefetch_ttl, rep->an_numrrsets, rep->ns_numrrsets,
|
||||
rep->ar_numrrsets, rep->rrset_count, rep->security);
|
||||
rep->ttl, rep->prefetch_ttl, rep->serve_expired_ttl,
|
||||
rep->an_numrrsets, rep->ns_numrrsets, rep->ar_numrrsets,
|
||||
rep->rrset_count, rep->security);
|
||||
if(!cp)
|
||||
return;
|
||||
|
||||
@@ -705,6 +810,12 @@ dns64_adjust_a(int id, struct module_qstate* super, struct module_qstate* qstate
|
||||
rrset_cache_remove(super->env->rrset_cache, dk->rk.dname,
|
||||
dk->rk.dname_len, LDNS_RR_TYPE_AAAA,
|
||||
LDNS_RR_CLASS_IN, 0);
|
||||
/* Delete negative AAAA in msg cache for CNAMEs,
|
||||
* stored by the iterator module */
|
||||
if(i != 0) /* if not the first RR */
|
||||
msg_cache_remove(super->env, dk->rk.dname,
|
||||
dk->rk.dname_len, LDNS_RR_TYPE_AAAA,
|
||||
LDNS_RR_CLASS_IN, 0);
|
||||
} else {
|
||||
dk->entry.hash = fk->entry.hash;
|
||||
dk->rk.dname = (uint8_t*)regional_alloc_init(super->region,
|
||||
|
||||
+574
-2
@@ -1,6 +1,578 @@
|
||||
1 October 2018: Wouter
|
||||
- tag for release 1.8.1rc1.
|
||||
|
||||
27 September 2018: Wouter
|
||||
- Fix #4188: IPv6 forwarders without ipv6 result in SERVFAIL, fixes
|
||||
qname minimisation with a forwarder when connectivity has issues
|
||||
from rejecting responses.
|
||||
|
||||
25 September 2018: Wouter
|
||||
- Perform TLS SNI indication of the host that is being contacted
|
||||
for DNS over TLS service. It sets the configured tls auth name.
|
||||
This is useful for hosts that apart from the DNS over TLS services
|
||||
also provide other (web) services.
|
||||
- Fix #4149: Add SSL cleanup for tcp timeout.
|
||||
|
||||
17 September 2018: Wouter
|
||||
- Fix compile on Mac for unbound, provide explicit_bzero when libc
|
||||
does not have it.
|
||||
- Fix unbound for openssl in FIPS mode, it uses the digests with
|
||||
the EVP call contexts.
|
||||
- Fix that with harden-below-nxdomain and qname minisation enabled
|
||||
some iterator states for nonresponsive domains can get into a
|
||||
state where they waited for an empty list.
|
||||
- Stop UDP to TCP failover after timeouts that causes the ping count
|
||||
to be reset by the TCP time measurement (that exists for TLS),
|
||||
because that causes the UDP part to not be measured as timeout.
|
||||
- Fix #4156: Fix systemd service manager state change notification.
|
||||
|
||||
13 September 2018: Wouter
|
||||
- Fix seed for random backup code to use explicit zero when wiped.
|
||||
- exit log routine is annotated as noreturn function.
|
||||
- free memory leaks in config strlist and str2list insert functions.
|
||||
- do not move unused argv variable after getopt.
|
||||
- Remove unused if clause in testcode.
|
||||
- in testcode, free async ids, initialise array, and check for null
|
||||
pointer during test of the test. And use exit for return to note
|
||||
irregular program stop.
|
||||
- Free memory leak in config strlist append.
|
||||
- make sure nsec3 comparison salt is initialized.
|
||||
- unit test has clang analysis.
|
||||
- remove unused variable assignment from iterator scrub routine.
|
||||
- check for null in delegation point during iterator refetch
|
||||
in forward zone.
|
||||
- neater pointer cast in libunbound context quit routine.
|
||||
- initialize statistics totals for printout.
|
||||
- in authzone check that node exists before adding rrset.
|
||||
- in unbound-anchor, use readwrite memory BIO.
|
||||
- assertion in autotrust that packed rrset is formed correctly.
|
||||
- Fix memory leak when message parse fails partway through copy.
|
||||
- remove unused udpsize assignment in message encode.
|
||||
- nicer bio free code in unbound-anchor.
|
||||
- annotate exit functions with noreturn in unbound-control.
|
||||
|
||||
11 September 2018: Wouter
|
||||
- Fixed unused return value warnings in contrib/fastrpz.patch for
|
||||
asprintf.
|
||||
- Fix to squelch respip warning in unit test, it is printed at
|
||||
higher verbosity settings.
|
||||
- Fix spelling errors.
|
||||
- Fix initialisation in remote.c
|
||||
|
||||
10 September 2018: Wouter
|
||||
- 1.8.1 in svn trunk. (changes from 4,5,.. sep apply).
|
||||
- iana port update.
|
||||
|
||||
5 September 2018: Wouter
|
||||
- Fix spelling error in header, from getdns commit by Andreas Gelmini.
|
||||
|
||||
4 September 2018: Ralph
|
||||
- More explicitly mention the type of ratelimit when applying
|
||||
ip-ratelimit.
|
||||
|
||||
4 September 2018: Wouter
|
||||
- Tag for 1.8.0rc1 release, became 1.8.0 release on 10 Sep 2018.
|
||||
|
||||
31 August 2018: Wouter
|
||||
- Disable minimal-responses in subnet unit tests.
|
||||
|
||||
30 August 2018: Wouter
|
||||
- Fix that a local-zone with a local-zone-type that is transparent
|
||||
in a view with view-first, makes queries check for answers from the
|
||||
local-zones defined outside of views.
|
||||
|
||||
28 August 2018: Ralph
|
||||
- Disable minimal-responses in ipsecmod unit tests.
|
||||
- Added serve-expired-ttl and serve-expired-ttl-reset options.
|
||||
|
||||
27 August 2018: Wouter
|
||||
- Set defaults to yes for a number of options to increase speed and
|
||||
resilience of the server. The so-reuseport, harden-below-nxdomain,
|
||||
and minimal-responses options are enabled by default. They used
|
||||
to be disabled by default, waiting to make sure they worked. They
|
||||
are enabled by default now, and can be disabled explicitly by
|
||||
setting them to "no" in the unbound.conf config file. The reuseport
|
||||
and minimal options increases speed of the server, and should be
|
||||
otherwise harmless. The harden-below-nxdomain option works well
|
||||
together with the recently default enabled qname minimisation, this
|
||||
causes more fetches to use information from the cache.
|
||||
- next release is called 1.8.0.
|
||||
- Fix lintflags for lint on FreeBSD.
|
||||
|
||||
22 August 2018: George
|
||||
- #4140: Expose repinfo (comm_reply) to the inplace_callbacks. This
|
||||
gives access to reply information for the client's communication
|
||||
point when the callback is called before the mesh state (modules).
|
||||
Changes to C and Python's inplace_callback signatures were also
|
||||
necessary.
|
||||
|
||||
21 August 2018: Wouter
|
||||
- log-local-actions: yes option for unbound.conf that logs all the
|
||||
local zone actions, a patch from Saksham Manchanda (Secure64).
|
||||
- #4146: num.query.subnet and num.query.subnet_cache counters.
|
||||
- Fix only misc failure from log-servfail when val-log-level is not
|
||||
enabled.
|
||||
|
||||
17 August 2018: Ralph
|
||||
- Fix classification for QTYPE=CNAME queries when QNAME minimisation is
|
||||
enabled.
|
||||
|
||||
17 August 2018: Wouter
|
||||
- Set libunbound to increase current, because the libunbound change
|
||||
to the event callback function signature. That needs programs,
|
||||
that use it, to recompile against the new header definition.
|
||||
- print servfail info to log as error.
|
||||
- added more servfail printout statements, to the iterator.
|
||||
- log-servfail: yes prints log lines that say why queries are
|
||||
returning SERVFAIL to clients.
|
||||
|
||||
16 August 2018: Wouter
|
||||
- Fix warning on compile without threads.
|
||||
- Fix contrib/fastrpz.patch.
|
||||
|
||||
15 August 2018: Wouter
|
||||
- Fix segfault in auth-zone read and reorder of RRSIGs.
|
||||
|
||||
14 August 2018: Wouter
|
||||
- Fix that printout of error for cycle targets is a verbosity 4
|
||||
printout and does not wrongly print it is a memory error.
|
||||
- Upgraded crosscompile script to include libunbound DLL in the
|
||||
zipfile.
|
||||
|
||||
10 August 2018: Wouter
|
||||
- Fix #4144: dns64 module caches wrong (negative) information.
|
||||
|
||||
9 August 2018: Wouter
|
||||
- unbound-checkconf checks if modules exist and prints if they are
|
||||
not compiled in the name of the wrong module.
|
||||
- document --enable-subnet in doc/README.
|
||||
- Patch for stub-no-cache and forward-no-cache options that disable
|
||||
caching for the contents of that stub or forward, for when you
|
||||
want immediate changes visible, from Bjoern A. Zeeb.
|
||||
|
||||
7 August 2018: Ralph
|
||||
- Make capsforid fallback QNAME minimisation aware.
|
||||
|
||||
7 August 2018: Wouter
|
||||
- Fix #4142: unbound.service.in: improvements and fixes.
|
||||
Add unit dependency ordering (based on systemd-resolved).
|
||||
Add 'CAP_SYS_RESOURCE' to 'CapabilityBoundingSet' (fixes warnings
|
||||
about missing privileges during startup). Add 'AF_INET6' to
|
||||
'RestrictAddressFamilies' (without it IPV6 can't work). From
|
||||
Guido Shanahan.
|
||||
- Patch to implement tcp-connection-limit from Jim Hague (Sinodun).
|
||||
This limits the number of simultaneous TCP client connections
|
||||
from a nominated netblock.
|
||||
- make depend, yacc, lex, doc, headers. And log the limit exceeded
|
||||
message only on high verbosity, so as to not spam the logs when
|
||||
it is busy.
|
||||
|
||||
6 August 2018: Wouter
|
||||
- Fix for #4136: Fix to unconditionally call destroy in daemon.c.
|
||||
|
||||
3 August 2018: George
|
||||
- Expose if a query (or a subquery) was ratelimited (not src IP
|
||||
ratelimiting) to libunbound under 'ub_result.was_ratelimited'.
|
||||
This also introduces a change to 'ub_event_callback_type' in
|
||||
libunbound/unbound-event.h.
|
||||
- Tidy pylib tests.
|
||||
|
||||
3 August 2018: Wouter
|
||||
- Revert previous change for #4136: because it introduces build
|
||||
problems.
|
||||
- New fix for #4136: This one ignores lex without without
|
||||
yylex_destroy.
|
||||
|
||||
1 August 2018: Wouter
|
||||
- Fix to remove systemd sockaddr function check, that is not
|
||||
always present. Make socket activation more lenient. But not
|
||||
different when socket activation is not used.
|
||||
- iana port list update.
|
||||
|
||||
31 July 2018: Wouter
|
||||
- Patches from Jim Hague (Sinodun) for EDNS KeepAlive.
|
||||
- Sort out test runs when the build directory isn't the project
|
||||
root directory.
|
||||
- Add config tcp-idle-timeout (default 30s). This applies to
|
||||
client connections only; the timeout on TCP connections upstream
|
||||
is unaffected.
|
||||
- Error if EDNS Keepalive received over UDP.
|
||||
- Add edns-tcp-keepalive and edns-tcp-keepalive timeout options
|
||||
and implement option in client responses.
|
||||
- Correct and expand manual page entries for keepalive and idle timeout.
|
||||
- Implement progressive backoff of TCP idle/keepalive timeout.
|
||||
- Fix 'make depend' to work when build dir is not project root.
|
||||
- Add delay parameter to streamtcp, -d secs.
|
||||
To be used when testing idle timeout.
|
||||
- From Wouter: make depend, the dependencies in the patches did not
|
||||
apply cleanly. Also remade yacc and lex.
|
||||
- Fix mesh.c incompatible pointer pass.
|
||||
- Please doxygen so it passes.
|
||||
- Fix #4139: Fix unbound-host leaks memory on ANY.
|
||||
|
||||
30 July 2018: Wouter
|
||||
- Fix #4136: insufficiency from mismatch of FLEX capability between
|
||||
released tarball and build host.
|
||||
|
||||
27 July 2018: Wouter
|
||||
- Fix man page, say that chroot is enabled by default.
|
||||
|
||||
26 July 2018: Wouter
|
||||
- Fix #4135: 64-bit Windows Installer Creates Entries Under The
|
||||
Wrong Registry Key, reported by Brian White.
|
||||
|
||||
23 July 2018: Wouter
|
||||
- Fix use-systemd readiness signalling, only when use-systemd is yes
|
||||
and not in signal handler.
|
||||
|
||||
20 July 2018: Wouter
|
||||
- Fix #4130: print text describing -dd and unbound-checkconf on
|
||||
config file read error at startup, the errors may have been moved
|
||||
away by the startup process.
|
||||
- Fix #4131: for solaris, error YY_CURRENT_BUFFER undeclared.
|
||||
|
||||
19 July 2018: Wouter
|
||||
- Fix #4129 unbound-control error message with wrong cert permissions
|
||||
is too cryptic.
|
||||
|
||||
17 July 2018: Wouter
|
||||
- Fix #4127 unbound -h does not list -p help.
|
||||
- Print error if SSL name verification configured but not available
|
||||
in the ssl library.
|
||||
- Fix that ratelimit and ip-ratelimit are applied after reload of
|
||||
changed config file.
|
||||
- Resize ratelimit and ip-ratelimit caches if changed on reload.
|
||||
|
||||
16 July 2018: Wouter
|
||||
- Fix qname minimisation NXDOMAIN validation lookup failures causing
|
||||
error_supers assertion fails.
|
||||
- Squelch can't bind socket errors with Permission denied unless
|
||||
verbosity is 4 or higher, for UDP outgoing sockets.
|
||||
|
||||
12 July 2018: Wouter
|
||||
- Fix to improve systemd socket activation code file descriptor
|
||||
assignment.
|
||||
- Fix for 4126 that the #define for UNKNOWN_SERVER_NICENESS can be more
|
||||
easily changed to adjust default rtt assumptions.
|
||||
|
||||
10 July 2018: Wouter
|
||||
- Note in documentation that the cert name match code needs
|
||||
OpenSSL 1.1.0 or later to be enabled.
|
||||
|
||||
6 July 2018: Wouter
|
||||
- Fix documentation ambiguity for tls-win-cert in tls-upstream and
|
||||
forward-tls-upstream docs.
|
||||
- iana port update.
|
||||
- Note RFC8162 support. SMIMEA record type can be read in by the
|
||||
zone record parser.
|
||||
- Fix round robin for failed addresses with prefer-ip6: yes
|
||||
|
||||
4 July 2018: Wouter
|
||||
- Fix #4112: Fix that unbound-anchor -f /etc/resolv.conf will not pass
|
||||
if DNSSEC is not enabled. New option -R allows fallback from
|
||||
resolv.conf to direct queries.
|
||||
|
||||
3 July 2018: Wouter
|
||||
- Better documentation for unblock-lan-zones and insecure-lan-zones
|
||||
config statements.
|
||||
- Fix permission denied printed for auth zone probe random port nrs.
|
||||
|
||||
2 July 2018: Wouter
|
||||
- Fix checking for libhiredis printout in configure output.
|
||||
- Fix typo on man page in ip-address description.
|
||||
- Update libunbound/python/examples/dnssec_test.py example code to
|
||||
also set the 20326 trust anchor for the root in the example code.
|
||||
|
||||
29 June 2018: Wouter
|
||||
- dns64-ignore-aaaa: config option to list domain names for which the
|
||||
existing AAAA is ignored and dns64 processing is used on the A
|
||||
record.
|
||||
|
||||
28 June 2018: Wouter
|
||||
- num.queries.tls counter for queries over TLS.
|
||||
- log port number with err_addr logs.
|
||||
|
||||
27 June 2018: Wouter
|
||||
- #4109: Fix that package config depends on python unconditionally.
|
||||
- Patch, do not export python from pkg-config, from Petr Menšík.
|
||||
|
||||
26 June 2018: Wouter
|
||||
- Partial fix for permission denied on IPv6 address on FreeBSD.
|
||||
- Fix that auth-zone master reply with current SOA serial does not
|
||||
stop scan of masters for an updated zone.
|
||||
- Fix that auth-zone does not start the wait timer without checking
|
||||
if the wait timer has already been started.
|
||||
|
||||
21 June 2018: Wouter
|
||||
- #4108: systemd reload hang fix.
|
||||
- Fix usage printout for unbound-host, hostname has to be last
|
||||
argument on BSDs and Windows.
|
||||
|
||||
19 June 2018: Wouter
|
||||
- Fix for unbound-control on Windows and set TCP socket parameters
|
||||
more closely.
|
||||
This fix is part of 1.7.3.
|
||||
- Windows example service.conf edited with more windows specific
|
||||
configuration.
|
||||
- Fix windows unbound-control no cert bad file descriptor error.
|
||||
This fix is part of 1.7.3.
|
||||
|
||||
18 June 2018: Wouter
|
||||
- Fix that control-use-cert: no works for 127.0.0.1 to disable certs.
|
||||
This fix is part of 1.7.3rc2.
|
||||
- Fix unbound-checkconf for control-use-cert.
|
||||
This fix is part of 1.7.3.
|
||||
|
||||
15 June 2018: Wouter
|
||||
- tag for 1.7.3rc1.
|
||||
- trunk has 1.7.4.
|
||||
- unbound-control auth_zone_reload _zone_ option rereads the zonefile.
|
||||
- unbound-control auth_zone_transfer _zone_ option starts the probe
|
||||
sequence for a master to transfer the zone from and transfers when
|
||||
a new zone version is available.
|
||||
|
||||
14 June 2018: Wouter
|
||||
- #4103: Fix that auth-zone does not insist on SOA record first in
|
||||
file for url downloads.
|
||||
- Fix that first control-interface determines if TLS is used. Warn
|
||||
when IP address interfaces are used without TLS.
|
||||
- Fix nettle compile.
|
||||
|
||||
12 June 2018: Ralph
|
||||
- Don't count CNAME response types received during qname minimisation as
|
||||
query restart.
|
||||
|
||||
12 June 2018: Wouter
|
||||
- #4102 for NSD, but for Unbound. Named unix pipes do not use
|
||||
certificate and key files, access can be restricted with file and
|
||||
directory permissions. The option control-use-cert is no longer
|
||||
used, and ignored if found in unbound.conf.
|
||||
- Rename tls-additional-ports to tls-additional-port, because every
|
||||
line adds one port.
|
||||
- Fix buffer size warning in unit test.
|
||||
- remade dependencies in the Makefile.
|
||||
|
||||
6 June 2018: Wouter
|
||||
- Patch to fix openwrt for mac os build darwin detection in configure.
|
||||
|
||||
5 June 2018: Wouter
|
||||
- Fix crash if ratelimit taken into use with unbound-control
|
||||
instead of with unbound.conf.
|
||||
|
||||
4 June 2018: Wouter
|
||||
- Fix deadlock caused by incoming notify for auth-zone.
|
||||
- tag for 1.7.2rc1, became 1.7.2 release on 11 June 2018,
|
||||
trunk is 1.7.3 in development from this point.
|
||||
- #4100: Fix stub reprime when it becomes useless.
|
||||
|
||||
1 June 2018: Wouter
|
||||
- Rename additional-tls-port to tls-additional-ports.
|
||||
The older name is accepted for backwards compatibility.
|
||||
|
||||
30 May 2018: Wouter
|
||||
- Patch from Syzdek: Add ability to ignore RD bit and treat all
|
||||
requests as if the RD bit is set.
|
||||
|
||||
29 May 2018: Wouter
|
||||
- in compat/arc4random call getentropy_urandom when getentropy fails
|
||||
with ENOSYS.
|
||||
- Fix that fallback for windows port.
|
||||
|
||||
28 May 2018: Wouter
|
||||
- Fix windows tcp and tls spin on events.
|
||||
- Add routine from getdns to add windows cert store to the SSL_CTX.
|
||||
- tls-win-cert option that adds the system certificate store for
|
||||
authenticating DNS-over-TLS connections. It can be used instead
|
||||
of the tls-cert-bundle option, or with it to add certificates.
|
||||
|
||||
25 May 2018: Wouter
|
||||
- For TCP and TLS connections that don't establish, perform address
|
||||
update in infra cache, so future selections can exclude them.
|
||||
- Fix that tcp sticky events are removed for closed fd on windows.
|
||||
- Fix close events for tcp only.
|
||||
|
||||
24 May 2018: Wouter
|
||||
- Fix that libunbound can do DNS-over-TLS, when configured.
|
||||
- Fix that windows unbound service can use DNS-over-TLS.
|
||||
- unbound-host initializes ssl (for potential DNS-over-TLS usage
|
||||
inside libunbound), when ssl upstream or a cert-bundle is configured.
|
||||
|
||||
23 May 2018: Wouter
|
||||
- Use accept4 to speed up incoming TCP (and TLS) connections,
|
||||
available on Linux, FreeBSD and OpenBSD.
|
||||
|
||||
17 May 2018: Ralph
|
||||
- Qname minimisation default changed to yes.
|
||||
|
||||
15 May 2018: Wouter
|
||||
- Fix low-rtt-pct to low-rtt-permil, as it is parts in one thousand.
|
||||
|
||||
11 May 2018: Wouter
|
||||
- Fix contrib/libunbound.pc for libssl libcrypto references,
|
||||
from https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=226914
|
||||
|
||||
7 May 2018: Wouter
|
||||
- Fix windows to not have sticky TLS events for TCP.
|
||||
- Fix read of DNS over TLS length and data in one read call.
|
||||
- Fix mesh state assertion failure due to callback removal.
|
||||
|
||||
3 May 2018: Wouter
|
||||
- Fix that configure --with-libhiredis also turns on cachedb.
|
||||
- Fix gcc 8 buffer warning in testcode.
|
||||
- Fix function type cast warning in libunbound context callback type.
|
||||
|
||||
2 May 2018: Wouter
|
||||
- Fix fail to reject dead peers in forward-zone, with ssl-upstream.
|
||||
|
||||
1 May 2018: Wouter
|
||||
- Fix that unbound-control reload frees the rrset keys and returns
|
||||
the memory pages to the system.
|
||||
|
||||
30 April 2018: Wouter
|
||||
- Fix spelling error in man page and note defaults as no instead of
|
||||
off.
|
||||
|
||||
26 April 2018: Wouter
|
||||
- Fix for crash in daemon_cleanup with dnstap during reload,
|
||||
from Saksham Manchanda.
|
||||
- Also that for dnscrypt.
|
||||
- tag for 1.7.1rc1 release. Became 1.7.1 release on 3 May, trunk
|
||||
is from here 1.7.2 in development.
|
||||
|
||||
25 April 2018: Ralph
|
||||
- Fix memory leak when caching wildcard records for aggressive NSEC use
|
||||
|
||||
24 April 2018: Wouter
|
||||
- Fix contrib/fastrpz.patch for this release.
|
||||
- Fix auth https for libev.
|
||||
|
||||
24 April 2018: Ralph
|
||||
- Added root-key-sentinel support
|
||||
|
||||
23 April 2018: Wouter
|
||||
- makedist uses bz2 for expat code, instead of tar.gz.
|
||||
- Fix #4092: libunbound: use-caps-for-id lacks colon in
|
||||
config_set_option.
|
||||
- auth zone http download stores exact copy of downloaded file,
|
||||
including comments in the file.
|
||||
- Fix sldns parse failure for CDS alternate delete syntax empty hex.
|
||||
- Attempt for auth zone fix; add of callback in mesh gets from
|
||||
callback does not skip callback of result.
|
||||
- Fix cname classification with qname minimisation enabled.
|
||||
- list_auth_zones unbound-control command.
|
||||
|
||||
20 April 2018: Wouter
|
||||
- man page documentation for dns-over-tls forward-addr '#' notation.
|
||||
- removed free from failed parse case.
|
||||
- Fix #4091: Fix that reload of auth-zone does not merge the zonefile
|
||||
with the previous contents.
|
||||
- Delete auth zone when removed from config.
|
||||
|
||||
19 April 2018: Wouter
|
||||
- Can set tls authentication with forward-addr: IP#tls.auth.name
|
||||
And put the public cert bundle in tls-cert-bundle: "ca-bundle.pem".
|
||||
such as forward-addr: 9.9.9.9@853#dns.quad9.net or
|
||||
1.1.1.1@853#cloudflare-dns.com
|
||||
- Fix #658: unbound using TLS in a forwarding configuration does not
|
||||
verify the server's certificate (RFC 8310 support).
|
||||
- For addr with #authname and no @port notation, the default is 853.
|
||||
|
||||
18 April 2018: Wouter
|
||||
- Fix auth-zone retry timer to be on schedule with retry timeout,
|
||||
with backoff. Also time a refresh at the zone expiry.
|
||||
|
||||
17 April 2018: Wouter
|
||||
- auth zone notify work.
|
||||
- allow-notify: config statement for auth-zones.
|
||||
- unit test for allow-notify
|
||||
|
||||
16 April 2018: Wouter
|
||||
- Fix auth zone target lookup iterator.
|
||||
- auth zone notify with prefix
|
||||
- auth zone notify work.
|
||||
|
||||
13 April 2018: Wouter
|
||||
- Fix for max include depth for authzones.
|
||||
- Fix memory free on fail for $INCLUDE in authzone.
|
||||
- Fix that an internal error to look up the wrong rr type for
|
||||
auth zone gets stopped, before trying to send there.
|
||||
- auth zone notify work.
|
||||
|
||||
10 April 2018: Ralph
|
||||
- num.query.aggressive.NOERROR and num.query.aggressive.NXDOMAIN
|
||||
statistics counters.
|
||||
|
||||
10 April 2018: Wouter
|
||||
- documentation for low-rtt and low-rtt-pct.
|
||||
- auth zone notify work.
|
||||
|
||||
9 April 2018: Wouter
|
||||
- Fix that flush_zone sets prefetch ttl expired, so that with
|
||||
serve-expired enabled it'll start prefetching those entries.
|
||||
- num.query.authzone.up and num.query.authzone.down statistics counters.
|
||||
- Fix downstream auth zone, only fallback when auth zone fails to
|
||||
answer and fallback is enabled.
|
||||
- Accept both option names with and without colon for get_option
|
||||
and set_option.
|
||||
- low-rtt and low-rtt-pct in unbound.conf enable the server selection
|
||||
of fast servers for some percentage of the time.
|
||||
|
||||
5 April 2018: Wouter
|
||||
- Combine write of tcp length and tcp query for dns over tls.
|
||||
- nitpick fixes in example.conf.
|
||||
- Fix above stub queries for type NS and useless delegation point.
|
||||
- Fix unbound-control over pipe with openssl 1.1.1, the TLSv1.3
|
||||
tls_choose_sigalg routine does not allow the ciphers for the pipe,
|
||||
so use TLSv1.2.
|
||||
- ED448 support.
|
||||
|
||||
3 April 2018: Wouter
|
||||
- Fix #4043: make test fails due to v6 presentation issue in macOS.
|
||||
- Fix unable to resolve after new WLAN connection, due to auth-zone
|
||||
failing with a forwarder set. Now, auth-zone is only used for
|
||||
answers (not referrals) when a forwarder is set.
|
||||
|
||||
29 March 2018: Ralph
|
||||
- Check "result" in dup_all(), by Florian Obser.
|
||||
|
||||
23 March 2018: Ralph
|
||||
- Fix unbound-control get_option aggressive-nsec
|
||||
|
||||
21 March 2018: Ralph
|
||||
- Do not use cached NSEC records to generate negative answers for
|
||||
domains under DNSSEC Negative Trust Anchors.
|
||||
|
||||
19 March 2018: Wouter
|
||||
- iana port update.
|
||||
|
||||
16 March 2018: Wouter
|
||||
- corrected a minor typo in the changelog.
|
||||
- move htobe64/be64toh portability code to cachedb.c.
|
||||
|
||||
15 March 2018: Wouter
|
||||
- Add --with-libhiredis, unbound support for a new cachedb backend
|
||||
that uses a Redis server as the storage. This implementation
|
||||
depends on the hiredis client library (https://redislabs.com/lp/hiredis/).
|
||||
And unbound should be built with both --enable-cachedb and
|
||||
--with-libhiredis[=PATH] (where $PATH/include/hiredis/hiredis.h
|
||||
should exist). Patch from Jinmei Tatuya (Infoblox).
|
||||
- Fix #3817: core dump happens in libunbound delete, when queued
|
||||
servfail hits deleted message queue.
|
||||
- Create additional tls service interfaces by opening them on other
|
||||
portnumbers and listing the portnumbers as additional-tls-port: nr.
|
||||
|
||||
13 March 2018: Wouter
|
||||
- Fix typo in documentation.
|
||||
- Fix #3736: Fix 0 TTL domains stuck on SERVFAIL unless manually
|
||||
flushed with serve-expired on.
|
||||
|
||||
12 March 2018: Wouter
|
||||
- Added documentation for aggressive-nsec: yes.
|
||||
- tag 1.7.0rc3.
|
||||
- tag 1.7.0rc3. That became the 1.7.0 release on 15 Mar, trunk
|
||||
now has 1.7.1 in development.
|
||||
- Fix #3727: Protocol name is TLS, options have been renamed but
|
||||
documentation is not consistent.
|
||||
- Check IXFR start serial.
|
||||
|
||||
9 March 2018: Wouter
|
||||
- Fix #3598: Fix swig build issue on rhel6 based system.
|
||||
@@ -1356,7 +1928,7 @@
|
||||
compatibility with cisco dns guard. This lowers false positives.
|
||||
|
||||
18 April 2016: Wouter
|
||||
- Fix some malformed reponses to edns queries get fallback to nonedns.
|
||||
- Fix some malformed responses to edns queries get fallback to nonedns.
|
||||
|
||||
15 April 2016: Wouter
|
||||
- cachedb module event handling design.
|
||||
|
||||
@@ -76,6 +76,8 @@ The DNSTAP code has BSD license in dnstap/dnstap.c.
|
||||
Disable support for RSASHA256 and RSASHA512 crypto.
|
||||
* --disable-gost
|
||||
Disable support for GOST crypto, RFC 5933.
|
||||
* --enable-subnet
|
||||
Enable EDNS client subnet processing.
|
||||
|
||||
* 'make test' runs a series of self checks.
|
||||
|
||||
|
||||
+78
-16
@@ -103,7 +103,7 @@ server:
|
||||
# so-sndbuf: 0
|
||||
|
||||
# use SO_REUSEPORT to distribute queries over threads.
|
||||
# so-reuseport: no
|
||||
# so-reuseport: yes
|
||||
|
||||
# use IP_TRANSPARENT so the interface: addresses can be non-local
|
||||
# and you can config non-existing IPs that are going to work later on
|
||||
@@ -199,7 +199,7 @@ server:
|
||||
# upstream connections use TCP only (and no UDP), "yes" or "no"
|
||||
# useful for tunneling scenarios, default no.
|
||||
# tcp-upstream: no
|
||||
|
||||
|
||||
# upstream connections also use UDP (even if do-udp is no).
|
||||
# useful if if you want UDP upstream, but don't provide UDP downstream.
|
||||
# udp-upstream-without-downstream: no
|
||||
@@ -212,6 +212,15 @@ server:
|
||||
# Default is 0, system default MSS.
|
||||
# outgoing-tcp-mss: 0
|
||||
|
||||
# Idle TCP timeout, connection closed in milliseconds
|
||||
# tcp-idle-timeout: 30000
|
||||
|
||||
# Enable EDNS TCP keepalive option.
|
||||
# edns-tcp-keepalive: no
|
||||
|
||||
# Timeout for EDNS TCP keepalive, in msec.
|
||||
# edns-tcp-keepalive-timeout: 120000
|
||||
|
||||
# Use systemd socket activation for UDP, TCP, and control sockets.
|
||||
# use-systemd: no
|
||||
|
||||
@@ -223,7 +232,8 @@ server:
|
||||
# to this server. Specify classless netblocks with /size and action.
|
||||
# By default everything is refused, except for localhost.
|
||||
# Choose deny (drop message), refuse (polite error reply),
|
||||
# allow (recursive ok), allow_snoop (recursive and nonrecursive ok)
|
||||
# allow (recursive ok), allow_setrd (recursive ok, rd bit is forced on),
|
||||
# allow_snoop (recursive and nonrecursive ok)
|
||||
# deny_non_local (drop queries unless can be answered from local-data)
|
||||
# refuse_non_local (like deny_non_local but polite error reply).
|
||||
# access-control: 0.0.0.0/0 refuse
|
||||
@@ -308,6 +318,13 @@ server:
|
||||
# timetoresolve, fromcache and responsesize.
|
||||
# log-replies: no
|
||||
|
||||
# log the local-zone actions, like local-zone type inform is enabled
|
||||
# also for the other local zone types.
|
||||
# log-local-actions: no
|
||||
|
||||
# print log lines that say why queries return SERVFAIL to clients.
|
||||
# log-servfail: no
|
||||
|
||||
# the pid file. Can be an absolute path outside of chroot/work dir.
|
||||
# pidfile: "@UNBOUND_PIDFILE@"
|
||||
|
||||
@@ -320,7 +337,7 @@ server:
|
||||
|
||||
# enable to not answer version.server and version.bind queries.
|
||||
# hide-version: no
|
||||
|
||||
|
||||
# enable to not answer trustanchor.unbound queries.
|
||||
# hide-trustanchor: no
|
||||
|
||||
@@ -356,7 +373,7 @@ server:
|
||||
# harden-dnssec-stripped: yes
|
||||
|
||||
# Harden against queries that fall under dnssec-signed nxdomain names.
|
||||
# harden-below-nxdomain: no
|
||||
# harden-below-nxdomain: yes
|
||||
|
||||
# Harden the referral path by performing additional queries for
|
||||
# infrastructure data. Validates the replies (if possible).
|
||||
@@ -372,7 +389,7 @@ server:
|
||||
# Sent minimum amount of information to upstream servers to enhance
|
||||
# privacy. Only sent minimum required labels of the QNAME and set QTYPE
|
||||
# to A when possible.
|
||||
# qname-minimisation: no
|
||||
# qname-minimisation: yes
|
||||
|
||||
# QNAME minimisation in strict mode. Do not fall-back to sending full
|
||||
# QNAME to potentially broken nameservers. A lot of domains will not be
|
||||
@@ -437,7 +454,7 @@ server:
|
||||
|
||||
# if yes, Unbound doesn't insert authority/additional sections
|
||||
# into response messages when those sections are not required.
|
||||
# minimal-responses: no
|
||||
# minimal-responses: yes
|
||||
|
||||
# true to disable DNSSEC lameness check in iterator.
|
||||
# disable-dnssec-lame-check: no
|
||||
@@ -458,6 +475,9 @@ server:
|
||||
|
||||
# trust anchor signaling sends a RFC8145 key tag query after priming.
|
||||
# trust-anchor-signaling: yes
|
||||
|
||||
# Root key trust anchor sentinel (draft-ietf-dnsop-kskroll-sentinel)
|
||||
# root-key-sentinel: yes
|
||||
|
||||
# File with DLV trusted keys. Same format as trust-anchor-file.
|
||||
# There can be only one DLV configured, it is trusted from root down.
|
||||
@@ -523,6 +543,16 @@ server:
|
||||
# Serve expired responses from cache, with TTL 0 in the response,
|
||||
# and then attempt to fetch the data afresh.
|
||||
# serve-expired: no
|
||||
#
|
||||
# Limit serving of expired responses to configured seconds after
|
||||
# expiration. 0 disables the limit.
|
||||
# serve-expired-ttl: 0
|
||||
#
|
||||
# Set the TTL of expired records to the serve-expired-ttl value after a
|
||||
# failed attempt to retrieve the record from upstream. This makes sure
|
||||
# that the expired records will be served as long as there are queries
|
||||
# for it.
|
||||
# serve-expired-ttl-reset: no
|
||||
|
||||
# Have the validator log failed validations for your diagnosis.
|
||||
# 0: off. 1: A line per failed user query. 2: With reason and bad IP.
|
||||
@@ -630,7 +660,7 @@ server:
|
||||
# o inform acts like transparent, but logs client IP address
|
||||
# o inform_deny drops queries and logs client IP address
|
||||
# o always_transparent, always_refuse, always_nxdomain, resolve in
|
||||
# that way but ignore local data for that name.
|
||||
# that way but ignore local data for that name
|
||||
# o noview breaks out of that view towards global local-zones.
|
||||
#
|
||||
# defaults are localhost address, reverse for 127.0.0.1 and ::1
|
||||
@@ -664,24 +694,33 @@ server:
|
||||
# add a netblock specific override to a localzone, with zone type
|
||||
# local-zone-override: "example.com" 192.0.2.0/24 refuse
|
||||
|
||||
# service clients over SSL (on the TCP sockets), with plain DNS inside
|
||||
# the SSL stream. Give the certificate to use and private key.
|
||||
# service clients over TLS (on the TCP sockets), with plain DNS inside
|
||||
# the TLS stream. Give the certificate to use and private key.
|
||||
# default is "" (disabled). requires restart to take effect.
|
||||
# tls-service-key: "path/to/privatekeyfile.key"
|
||||
# tls-service-pem: "path/to/publiccertfile.pem"
|
||||
# tls-port: 853
|
||||
|
||||
# request upstream over SSL (with plain DNS inside the SSL stream).
|
||||
# request upstream over TLS (with plain DNS inside the TLS stream).
|
||||
# Default is no. Can be turned on and off with unbound-control.
|
||||
# tls-upstream: no
|
||||
|
||||
# Certificates used to authenticate connections made upstream.
|
||||
# tls-cert-bundle: ""
|
||||
|
||||
# Add system certs to the cert bundle, from the Windows Cert Store
|
||||
# tls-win-cert: no
|
||||
|
||||
# Also serve tls on these port numbers (eg. 443, ...), by listing
|
||||
# tls-additional-port: portno for each of the port numbers.
|
||||
|
||||
# DNS64 prefix. Must be specified when DNS64 is use.
|
||||
# Enable dns64 in module-config. Used to synthesize IPv6 from IPv4.
|
||||
# dns64-prefix: 64:ff9b::0/96
|
||||
|
||||
# DNS64 ignore AAAA records for these domains and use A instead.
|
||||
# dns64-ignore-aaaa: "example.com"
|
||||
|
||||
# ratelimit for uncached, new queries, this limits recursion effort.
|
||||
# ratelimiting is experimental, and may help against randomqueryflood.
|
||||
# if 0(default) it is disabled, otherwise state qps allowed per zone.
|
||||
@@ -715,6 +754,15 @@ server:
|
||||
# 0 blocks when ip is ratelimited, otherwise let 1/xth traffic through
|
||||
# ip-ratelimit-factor: 10
|
||||
|
||||
# Limit the number of connections simultaneous from a netblock
|
||||
# tcp-connection-limit: 192.0.2.0/24 12
|
||||
|
||||
# what is considered a low rtt (ping time for upstream server), in msec
|
||||
# low-rtt: 45
|
||||
# select low rtt this many times out of 1000. 0 means the fast server
|
||||
# select is disabled. prefetches are not sped up.
|
||||
# low-rtt-permil: 0
|
||||
|
||||
# Specific options for ipsecmod. unbound needs to be configured with
|
||||
# --enable-ipsecmod for these to take effect.
|
||||
#
|
||||
@@ -758,18 +806,20 @@ remote-control:
|
||||
# set up the keys and certificates with unbound-control-setup.
|
||||
# control-enable: no
|
||||
|
||||
# Set to no and use an absolute path as control-interface to use
|
||||
# a unix local named pipe for unbound-control.
|
||||
# control-use-cert: yes
|
||||
|
||||
# what interfaces are listened to for remote control.
|
||||
# give 0.0.0.0 and ::0 to listen to all interfaces.
|
||||
# set to an absolute path to use a unix local name pipe, certificates
|
||||
# are not used for that, so key and cert files need not be present.
|
||||
# control-interface: 127.0.0.1
|
||||
# control-interface: ::1
|
||||
|
||||
# port number for remote control operations.
|
||||
# control-port: 8953
|
||||
|
||||
# for localhost, you can disable use of TLS by setting this to "no"
|
||||
# For local sockets this option is ignored, and TLS is not used.
|
||||
# control-use-cert: "yes"
|
||||
|
||||
# unbound server key file.
|
||||
# server-key-file: "@UNBOUND_RUN_DIR@/unbound_server.key"
|
||||
|
||||
@@ -796,6 +846,7 @@ remote-control:
|
||||
# stub-prime: no
|
||||
# stub-first: no
|
||||
# stub-tls-upstream: no
|
||||
# stub-no-cache: no
|
||||
# stub-zone:
|
||||
# name: "example.org"
|
||||
# stub-host: ns.example.com.
|
||||
@@ -812,6 +863,7 @@ remote-control:
|
||||
# forward-addr: 192.0.2.73@5355 # forward to port 5355.
|
||||
# forward-first: no
|
||||
# forward-tls-upstream: no
|
||||
# forward-no-cache: no
|
||||
# forward-zone:
|
||||
# name: "example.org"
|
||||
# forward-host: fwd.example.com
|
||||
@@ -823,6 +875,8 @@ remote-control:
|
||||
# has a copy of the root for local usage. The second serves example.org
|
||||
# authoritatively. zonefile: reads from file (and writes to it if you also
|
||||
# download it), master: fetches with AXFR and IXFR, or url to zonefile.
|
||||
# With allow-notify: you can give additional (apart from masters) sources of
|
||||
# notifies.
|
||||
# auth-zone:
|
||||
# name: "."
|
||||
# for-downstream: no
|
||||
@@ -851,7 +905,7 @@ remote-control:
|
||||
# name: "viewname"
|
||||
# local-zone: "example.com" redirect
|
||||
# local-data: "example.com A 192.0.2.3"
|
||||
# local-data-ptr: "192.0.2.3 www.example.com"
|
||||
# local-data-ptr: "192.0.2.3 www.example.com"
|
||||
# view-first: no
|
||||
# view:
|
||||
# name: "anotherview"
|
||||
@@ -886,3 +940,11 @@ remote-control:
|
||||
# backend: "testframe"
|
||||
# # secret seed string to calculate hashed keys
|
||||
# secret-seed: "default"
|
||||
#
|
||||
# # For "redis" backend:
|
||||
# # redis server's IP address or host name
|
||||
# redis-server-host: 127.0.0.1
|
||||
# # redis server's TCP port
|
||||
# redis-server-port: 6379
|
||||
# # timeout (in ms) for communication with the redis server
|
||||
# redis-timeout: 100
|
||||
|
||||
@@ -109,6 +109,11 @@ It does so, because the tool when used for bootstrapping the recursive
|
||||
resolver, cannot use that recursive resolver itself because it is bootstrapping
|
||||
that server.
|
||||
.TP
|
||||
.B \-R
|
||||
Allow fallback from \-f resolv.conf file to direct root servers query.
|
||||
It allows you to prefer local resolvers, but fallback automatically
|
||||
to direct root query if they do not respond or do not support DNSSEC.
|
||||
.TP
|
||||
.B \-v
|
||||
More verbose. Once prints informational messages, multiple times may enable
|
||||
large debug amounts (such as full certificates or byte\-dumps of downloaded
|
||||
|
||||
@@ -144,6 +144,9 @@ Remove the name, type information from the cache.
|
||||
Remove all information at or below the name from the cache.
|
||||
The rrsets and key entries are removed so that new lookups will be performed.
|
||||
This needs to walk and inspect the entire cache, and is a slow operation.
|
||||
The entries are set to expired in the implementation of this command (so,
|
||||
with serve\-expired enabled, it'll serve that information but schedule a
|
||||
prefetch for new information).
|
||||
.TP
|
||||
.B flush_bogus
|
||||
Remove all bogus data from the cache.
|
||||
@@ -286,6 +289,22 @@ estimated qps and qps limit from config. With +a it prints all ips, not
|
||||
just the ratelimited ips, with their estimated qps. The ratelimited
|
||||
ips are dropped before checking the cache.
|
||||
.TP
|
||||
.B list_auth_zones
|
||||
List the auth zones that are configured. Printed one per line with a
|
||||
status, indicating if the zone is expired and current serial number.
|
||||
.TP
|
||||
.B auth_zone_reload \fIzone\fR
|
||||
Reload the auth zone from zonefile. The zonefile is read in overwriting
|
||||
the current contents of the zone in memory. This changes the auth zone
|
||||
contents itself, not the cache contents. Such cache contents exists if
|
||||
you set unbound to validate with for-upstream yes and that can be cleared
|
||||
with \fBflush_zone\fR \fIzone\fR.
|
||||
.TP
|
||||
.B auth_zone_transfer \fIzone\fR
|
||||
Transfer the auth zone from master. The auth zone probe sequence is started,
|
||||
where the masters are probed to see if they have an updated zone (with the SOA
|
||||
serial check). And then the zone is transferred for a newer zone version.
|
||||
.TP
|
||||
.B view_list_local_zones \fIview\fR
|
||||
\fIlist_local_zones\fR for given view.
|
||||
.TP
|
||||
@@ -508,6 +527,10 @@ Number of queries that were made using TCP towards the unbound server.
|
||||
Number of queries that the unbound server made using TCP outgoing towards
|
||||
other servers.
|
||||
.TP
|
||||
.I num.query.tls
|
||||
Number of queries that were made using TLS towards the unbound server.
|
||||
These are also counted in num.query.tcp, because TLS uses TCP.
|
||||
.TP
|
||||
.I num.query.ipv6
|
||||
Number of queries that were made using IPv6 towards the unbound server.
|
||||
.TP
|
||||
@@ -598,6 +621,34 @@ dnscrypt queries replay. The client nonce must be unique for each client public
|
||||
key/server secret key pair. This cache should be able to host QPS * `replay
|
||||
window` interval keys to prevent replay of a query during `replay window`
|
||||
seconds.
|
||||
.TP
|
||||
.I num.query.authzone.up
|
||||
The number of queries answered from auth\-zone data, upstream queries.
|
||||
These queries would otherwise have been sent (with fallback enabled) to
|
||||
the internet, but are now answered from the auth zone.
|
||||
.TP
|
||||
.I num.query.authzone.down
|
||||
The number of queries for downstream answered from auth\-zone data.
|
||||
These queries are from downstream clients, and have had an answer from
|
||||
the data in the auth zone.
|
||||
.TP
|
||||
.I num.query.aggressive.NOERROR
|
||||
The number of queries answered using cached NSEC records with NODATA RCODE.
|
||||
These queries would otherwise have been sent to the internet, but are now
|
||||
answered using cached data.
|
||||
.TP
|
||||
.I num.query.aggressive.NXDOMAIN
|
||||
The number of queries answered using cached NSEC records with NXDOMAIN RCODE.
|
||||
These queries would otherwise have been sent to the internet, but are now
|
||||
answered using cached data.
|
||||
.TP
|
||||
.I num.query.subnet
|
||||
Number of queries that got an answer that contained EDNS client subnet data.
|
||||
.TP
|
||||
.I num.query.subnet_cache
|
||||
Number of queries answered from the edns client subnet cache. These are
|
||||
counted as cachemiss by the main counters, but hit the client subnet
|
||||
specific cache, after getting processed by the edns client subnet module.
|
||||
.SH "FILES"
|
||||
.TP
|
||||
.I @ub_conf_file@
|
||||
|
||||
@@ -12,20 +12,20 @@
|
||||
\- unbound DNS lookup utility
|
||||
.SH "SYNOPSIS"
|
||||
.B unbound\-host
|
||||
.RB [ \-C
|
||||
.IR configfile ]
|
||||
.RB [ \-vdhr46D ]
|
||||
.RB [ \-c
|
||||
.IR class ]
|
||||
.RB [ \-t
|
||||
.IR type ]
|
||||
.I hostname
|
||||
.RB [ \-y
|
||||
.IR key ]
|
||||
.RB [ \-f
|
||||
.IR keyfile ]
|
||||
.RB [ \-F
|
||||
.IR namedkeyfile ]
|
||||
.RB [ \-C
|
||||
.IR configfile ]
|
||||
.I hostname
|
||||
.SH "DESCRIPTION"
|
||||
.B Unbound\-host
|
||||
uses the unbound validating resolver to query for the hostname and display
|
||||
@@ -86,6 +86,8 @@ are read.
|
||||
.B \-C \fIconfigfile
|
||||
Uses the specified unbound.conf to prime
|
||||
.IR libunbound (3).
|
||||
Pass it as first argument if you want to override some options from the
|
||||
config file with further arguments on the commandline.
|
||||
.TP
|
||||
.B \-r
|
||||
Read /etc/resolv.conf, and use the forward DNS servers from there (those could
|
||||
|
||||
+224
-34
@@ -121,7 +121,7 @@ interface and port number), if not specified the default port (from
|
||||
\fBport\fR) is used.
|
||||
.TP
|
||||
.B ip\-address: \fI<ip address[@port]>
|
||||
Same as interface: (for easy of compatibility with nsd.conf).
|
||||
Same as interface: (for ease of compatibility with nsd.conf).
|
||||
.TP
|
||||
.B interface\-automatic: \fI<yes or no>
|
||||
Detect source interface on UDP queries and copy them to replies. This
|
||||
@@ -278,9 +278,9 @@ to so\-rcvbuf.
|
||||
.B so\-reuseport: \fI<yes or no>
|
||||
If yes, then open dedicated listening sockets for incoming queries for each
|
||||
thread and try to set the SO_REUSEPORT socket option on each socket. May
|
||||
distribute incoming queries to threads more evenly. Default is no. On Linux
|
||||
it is supported in kernels >= 3.9. On other systems, FreeBSD, OSX it may
|
||||
also work. You can enable it (on any platform and kernel),
|
||||
distribute incoming queries to threads more evenly. Default is yes.
|
||||
On Linux it is supported in kernels >= 3.9. On other systems, FreeBSD, OSX
|
||||
it may also work. You can enable it (on any platform and kernel),
|
||||
it then attempts to open the port and passes the option if it was available
|
||||
at compile time, if that works it is used, if it fails, it continues
|
||||
silently (unless verbosity 3) without the option.
|
||||
@@ -288,7 +288,7 @@ silently (unless verbosity 3) without the option.
|
||||
.B ip\-transparent: \fI<yes or no>
|
||||
If yes, then use IP_TRANSPARENT socket option on sockets where unbound
|
||||
is listening for incoming traffic. Default no. Allows you to bind to
|
||||
non\-local interfaces. For example for non\-existant IP addresses that
|
||||
non\-local interfaces. For example for non\-existent IP addresses that
|
||||
are going to exist later on, with host failover configuration. This is
|
||||
a lot like interface\-automatic, but that one services all interfaces
|
||||
and with this option you can select which (future) interfaces unbound
|
||||
@@ -389,6 +389,37 @@ Note that not all platform supports socket option to set MSS (TCP_MAXSEG).
|
||||
Default is system default MSS determined by interface MTU and
|
||||
negotiation between Unbound and other servers.
|
||||
.TP
|
||||
.B tcp-idle-timeout: \fI<msec>\fR
|
||||
The period Unbound will wait for a query on a TCP connection.
|
||||
If this timeout expires Unbound closes the connection.
|
||||
This option defaults to 30000 milliseconds.
|
||||
When the number of free incoming TCP buffers falls below 50% of the
|
||||
total number configured, the option value used is progressively
|
||||
reduced, first to 1% of the configured value, then to 0.2% of the
|
||||
configured value if the number of free buffers falls below 35% of the
|
||||
total number configured, and finally to 0 if the number of free buffers
|
||||
falls below 20% of the total number configured. A minimum timeout of
|
||||
200 milliseconds is observed regardless of the option value used.
|
||||
.TP
|
||||
.B edns-tcp-keepalive: \fI<yes or no>\fR
|
||||
Enable or disable EDNS TCP Keepalive. Default is no.
|
||||
.TP
|
||||
.B edns-tcp-keepalive-timeout: \fI<msec>\fR
|
||||
The period Unbound will wait for a query on a TCP connection when
|
||||
EDNS TCP Keepalive is active. If this timeout expires Unbound closes
|
||||
the connection. If the client supports the EDNS TCP Keepalive option,
|
||||
Unbound sends the timeout value to the client to encourage it to
|
||||
close the connection before the server times out.
|
||||
This option defaults to 120000 milliseconds.
|
||||
When the number of free incoming TCP buffers falls below 50% of
|
||||
the total number configured, the advertised timeout is progressively
|
||||
reduced to 1% of the configured value, then to 0.2% of the configured
|
||||
value if the number of free buffers falls below 35% of the total number
|
||||
configured, and finally to 0 if the number of free buffers falls below
|
||||
20% of the total number configured.
|
||||
A minimum actual timeout of 200 milliseconds is observed regardless of the
|
||||
advertised timeout.
|
||||
.TP
|
||||
.B tcp\-upstream: \fI<yes or no>
|
||||
Enable or disable whether the upstream queries use TCP only for transport.
|
||||
Default is no. Useful in tunneling scenarios.
|
||||
@@ -399,17 +430,19 @@ change anything. Useful for TLS service providers, that want no udp downstream
|
||||
but use udp to fetch data upstream.
|
||||
.TP
|
||||
.B tls\-upstream: \fI<yes or no>
|
||||
Enabled or disable whether the upstream queries use SSL only for transport.
|
||||
Default is no. Useful in tunneling scenarios. The SSL contains plain DNS in
|
||||
Enabled or disable whether the upstream queries use TLS only for transport.
|
||||
Default is no. Useful in tunneling scenarios. The TLS contains plain DNS in
|
||||
TCP wireformat. The other server must support this (see
|
||||
\fBtls\-service\-key\fR).
|
||||
If you enable this, also configure a tls\-cert\-bundle or use tls\-win\-cert to
|
||||
load CA certs, otherwise the connections cannot be authenticated.
|
||||
.TP
|
||||
.B ssl\-upstream: \fI<yes or no>
|
||||
Alternate syntax for \fBtls\-upstream\fR. If both are present in the config
|
||||
file the last is used.
|
||||
.TP
|
||||
.B tls\-service\-key: \fI<file>
|
||||
If enabled, the server provider SSL service on its TCP sockets. The clients
|
||||
If enabled, the server provider TLS service on its TCP sockets. The clients
|
||||
have to use tls\-upstream: yes. The file is the private key for the TLS
|
||||
session. The public certificate is in the tls\-service\-pem file. Default
|
||||
is "", turned off. Requires a restart (a reload is not enough) if changed,
|
||||
@@ -429,8 +462,8 @@ turned off.
|
||||
Alternate syntax for \fBtls\-service\-pem\fR.
|
||||
.TP
|
||||
.B tls\-port: \fI<number>
|
||||
The port number on which to provide TCP SSL service, default 853, only
|
||||
interfaces configured with that port number as @number get the SSL service.
|
||||
The port number on which to provide TCP TLS service, default 853, only
|
||||
interfaces configured with that port number as @number get the TLS service.
|
||||
.TP
|
||||
.B ssl\-port: \fI<number>
|
||||
Alternate syntax for \fBtls\-port\fR.
|
||||
@@ -444,6 +477,17 @@ urls, and also DNS over TLS connections.
|
||||
.B ssl\-cert\-bundle: \fI<file>
|
||||
Alternate syntax for \fBtls\-cert\-bundle\fR.
|
||||
.TP
|
||||
.B tls\-win\-cert: \fI<yes or no>
|
||||
Add the system certificates to the cert bundle certificates for authentication.
|
||||
If no cert bundle, it uses only these certificates. Default is no.
|
||||
On windows this option uses the certificates from the cert store. Use
|
||||
the tls\-cert\-bundle option on other systems.
|
||||
.TP
|
||||
.B tls\-additional\-port: \fI<portnr>
|
||||
List portnumbers as tls\-additional\-port, and when interfaces are defined,
|
||||
eg. with the @port suffix, as this port number, they provide dns over TLS
|
||||
service. Can list multiple, each on a new statement.
|
||||
.TP
|
||||
.B use\-systemd: \fI<yes or no>
|
||||
Enable or disable systemd socket activation.
|
||||
Default is no.
|
||||
@@ -453,10 +497,16 @@ Enable or disable whether the unbound server forks into the background as
|
||||
a daemon. Set the value to \fIno\fR when unbound runs as systemd service.
|
||||
Default is yes.
|
||||
.TP
|
||||
.B tcp\-connection\-limit: \fI<IP netblock> <limit>
|
||||
Allow up to \fIlimit\fR simultaneous TCP connections from the given netblock.
|
||||
When at the limit, further connections are accepted but closed immediately.
|
||||
This option is experimental at this time.
|
||||
.TP
|
||||
.B access\-control: \fI<IP netblock> <action>
|
||||
The netblock is given as an IP4 or IP6 address with /size appended for a
|
||||
classless network block. The action can be \fIdeny\fR, \fIrefuse\fR,
|
||||
\fIallow\fR, \fIallow_snoop\fR, \fIdeny_non_local\fR or \fIrefuse_non_local\fR.
|
||||
\fIallow\fR, \fIallow_setrd\fR, \fIallow_snoop\fR, \fIdeny_non_local\fR or
|
||||
\fIrefuse_non_local\fR.
|
||||
The most specific netblock match is used, if none match \fIdeny\fR is used.
|
||||
.IP
|
||||
The action \fIdeny\fR stops queries from hosts from that netblock.
|
||||
@@ -475,6 +525,15 @@ in the reply. This supports normal operations where nonrecursive queries
|
||||
are made for the authoritative data. For nonrecursive queries any replies
|
||||
from the dynamic cache are refused.
|
||||
.IP
|
||||
The \fIallow_setrd\fR action ignores the recursion desired (RD) bit and
|
||||
treats all requests as if the recursion desired bit is set. Note that this
|
||||
behavior violates RFC 1034 which states that a name server should never perform
|
||||
recursive service unless asked via the RD bit since this interferes with
|
||||
trouble shooting of name servers and their databases. This prohibited behavior
|
||||
may be useful if another DNS server must forward requests for specific
|
||||
zones to a resolver DNS server, but only supports stub domains and
|
||||
sends queries to the resolver DNS server with the RD bit cleared.
|
||||
.IP
|
||||
The action \fIallow_snoop\fR gives nonrecursive access too. This give
|
||||
both recursive and non recursive access. The name \fIallow_snoop\fR refers
|
||||
to cache snooping, a technique to use nonrecursive queries to examine
|
||||
@@ -534,8 +593,9 @@ to chroot and dropping permissions. This allows the pidfile to be
|
||||
Additionally, unbound may need to access /dev/random (for entropy)
|
||||
from inside the chroot.
|
||||
.IP
|
||||
If given a chroot is done to the given directory. The default is
|
||||
"@UNBOUND_CHROOT_DIR@". If you give "" no chroot is performed.
|
||||
If given a chroot is done to the given directory. By default chroot is
|
||||
enabled and the default is "@UNBOUND_CHROOT_DIR@". If you give "" no
|
||||
chroot is performed.
|
||||
.TP
|
||||
.B username: \fI<name>
|
||||
If given, after binding the port the user privileges are dropped. Default is
|
||||
@@ -595,6 +655,16 @@ Default is no. Note that it takes time to print these
|
||||
lines which makes the server (significantly) slower. Odd (nonprintable)
|
||||
characters in names are printed as '?'.
|
||||
.TP
|
||||
.B log\-local\-actions: \fI<yes or no>
|
||||
Print log lines to inform about local zone actions. These lines are like the
|
||||
local\-zone type inform prints out, but they are also printed for the other
|
||||
types of local zones.
|
||||
.TP
|
||||
.B log\-servfail: \fI<yes or no>
|
||||
Print log lines that say why queries return SERVFAIL to clients.
|
||||
This is separate from the verbosity debug logs, much smaller, and printed
|
||||
at the error level, not the info level of debug info from verbosity.
|
||||
.TP
|
||||
.B pidfile: \fI<filename>
|
||||
The process id is written to the file. Default is "@UNBOUND_PIDFILE@".
|
||||
So,
|
||||
@@ -677,7 +747,7 @@ noerror for empty nonterminals, hence this is possible. Very old software
|
||||
might return nxdomain for empty nonterminals (that usually happen for reverse
|
||||
IP address lookups), and thus may be incompatible with this. To try to avoid
|
||||
this only DNSSEC-secure nxdomains are used, because the old software does not
|
||||
have DNSSEC. Default is off.
|
||||
have DNSSEC. Default is on.
|
||||
The nxdomain must be secure, this means nsec3 with optout is insufficient.
|
||||
.TP
|
||||
.B harden\-referral\-path: \fI<yes or no>
|
||||
@@ -686,7 +756,7 @@ infrastructure data. Validates the replies if trust anchors are configured
|
||||
and the zones are signed. This enforces DNSSEC validation on nameserver
|
||||
NS sets and the nameserver addresses that are encountered on the referral
|
||||
path to the answer.
|
||||
Default off, because it burdens the authority servers, and it is
|
||||
Default no, because it burdens the authority servers, and it is
|
||||
not RFC standard, and could lead to performance problems because of the
|
||||
extra query load that is generated. Experimental option.
|
||||
If you enable it consider adding more numbers after the target\-fetch\-policy
|
||||
@@ -717,7 +787,7 @@ Send minimum amount of information to upstream servers to enhance privacy.
|
||||
Only sent minimum required labels of the QNAME and set QTYPE to A when
|
||||
possible. Best effort approach; full QNAME and original QTYPE will be sent when
|
||||
upstream replies with a RCODE other than NOERROR, except when receiving
|
||||
NXDOMAIN from a DNSSEC signed zone. Default is off.
|
||||
NXDOMAIN from a DNSSEC signed zone. Default is yes.
|
||||
.TP
|
||||
.B qname\-minimisation\-strict: \fI<yes or no>
|
||||
QNAME minimisation in strict mode. Do not fall-back to sending full QNAME to
|
||||
@@ -728,8 +798,8 @@ This option only has effect when qname-minimisation is enabled. Default is off.
|
||||
.B aggressive\-nsec: \fI<yes or no>
|
||||
Aggressive NSEC uses the DNSSEC NSEC chain to synthesize NXDOMAIN
|
||||
and other denials, using information from previous NXDOMAINs answers.
|
||||
Default is off. It helps to reduce the query rate towards targets that get
|
||||
a very high nonexistant name lookup rate.
|
||||
Default is no. It helps to reduce the query rate towards targets that get
|
||||
a very high nonexistent name lookup rate.
|
||||
.TP
|
||||
.B private\-address: \fI<IP address or subnet>
|
||||
Give IPv4 of IPv6 addresses or classless subnets. These are addresses
|
||||
@@ -791,9 +861,11 @@ from the query ID, for speed and thread safety). Default is no.
|
||||
If yes, Unbound doesn't insert authority/additional sections into response
|
||||
messages when those sections are not required. This reduces response
|
||||
size significantly, and may avoid TCP fallback for some responses.
|
||||
This may cause a slight speedup. The default is no, because the DNS
|
||||
This may cause a slight speedup. The default is yes, even though the DNS
|
||||
protocol RFCs mandate these sections, and the additional content could
|
||||
be of use and save roundtrips for clients.
|
||||
be of use and save roundtrips for clients. Because they are not used,
|
||||
and the saved roundtrips are easier saved with prefetch, whilst this is
|
||||
faster.
|
||||
.TP
|
||||
.B disable-dnssec-lame-check: \fI<yes or no>
|
||||
If true, disables the DNSSEC lameness check in the iterator. This check
|
||||
@@ -844,6 +916,9 @@ expanded on start and on reload.
|
||||
.B trust\-anchor\-signaling: \fI<yes or no>
|
||||
Send RFC8145 key tag query after trust anchor priming. Default is on.
|
||||
.TP
|
||||
.B root\-key\-sentinel: \fI<yes or no>
|
||||
Root key trust anchor sentinel. Default is on.
|
||||
.TP
|
||||
.B dlv\-anchor\-file: \fI<filename>
|
||||
This option was used during early days DNSSEC deployment when no parent-side
|
||||
DS record registrations were easily available. Nowadays, it is best to have
|
||||
@@ -938,6 +1013,17 @@ If enabled, unbound attempts to serve old responses from cache with a
|
||||
TTL of 0 in the response without waiting for the actual resolution to finish.
|
||||
The actual resolution answer ends up in the cache later on. Default is "no".
|
||||
.TP
|
||||
.B serve\-expired\-ttl: \fI<seconds>
|
||||
Limit serving of expired responses to configured seconds after expiration. 0
|
||||
disables the limit. This option only applies when \fBserve\-expired\fR is
|
||||
enabled. The default is 0.
|
||||
.TP
|
||||
.B serve\-expired\-ttl\-reset: \fI<yes or no>
|
||||
Set the TTL of expired records to the \fBserve\-expired\-ttl\fR value after a
|
||||
failed attempt to retrieve the record from upstream. This makes sure that the
|
||||
expired records will be served as long as there are queries for it. Default is
|
||||
"no".
|
||||
.TP
|
||||
.B val\-nsec3\-keysize\-iterations: \fI<"list of values">
|
||||
List of keysize and iteration count values, separated by spaces, surrounded
|
||||
by quotes. Default is "1024 150 2048 500 4096 2500". This determines the
|
||||
@@ -986,7 +1072,7 @@ Number of bytes size of the aggressive negative cache. Default is 1 megabyte.
|
||||
A plain number is in bytes, append 'k', 'm' or 'g' for kilobytes, megabytes
|
||||
or gigabytes (1024*1024 bytes in a megabyte).
|
||||
.TP
|
||||
.B unblock\-lan\-zones: \fI<yesno>
|
||||
.B unblock\-lan\-zones: \fI<yes or no>
|
||||
Default is disabled. If enabled, then for private address space,
|
||||
the reverse lookups are no longer filtered. This allows unbound when
|
||||
running as dns service on a host where it provides service for that host,
|
||||
@@ -997,7 +1083,7 @@ as a (DHCP-) DNS network resolver for a group of machines, where such
|
||||
lookups should be filtered (RFC compliance), this also stops potential
|
||||
data leakage about the local network to the upstream DNS servers.
|
||||
.TP
|
||||
.B insecure\-lan\-zones: \fI<yesno>
|
||||
.B insecure\-lan\-zones: \fI<yes or no>
|
||||
Default is disabled. If enabled, then reverse lookups in private
|
||||
address space are not validated. This is usually required whenever
|
||||
\fIunblock\-lan\-zones\fR is used.
|
||||
@@ -1304,13 +1390,30 @@ to complete. Default is 10, allowing 1/10 traffic to flow normally.
|
||||
This can make ordinary queries complete (if repeatedly queried for),
|
||||
and enter the cache, whilst also mitigating the traffic flow by the
|
||||
factor given.
|
||||
.TP 5
|
||||
.B low\-rtt: \fI<msec time>
|
||||
Set the time in millisecond that is considere a low ping time for fast
|
||||
server selection with the low\-rtt\-permil option, that turns this on or off.
|
||||
The default is 45 msec, a number from IPv6 quick response documents.
|
||||
.TP 5
|
||||
.B low\-rtt\-permil: \fI<number>
|
||||
Specify how many times out of 1000 to pick the fast server from the low
|
||||
rtt band. 0 turns the feature off. A value of 900 would pick the fast
|
||||
server when such fast servers are available 90 percent of the time, and
|
||||
the remaining time perform normal exploration of random servers.
|
||||
When prefetch is enabled (or serve\-expired), such prefetches are not
|
||||
sped up, because there is no one waiting for it, and it presents a good
|
||||
moment to perform server exploration. The low\-rtt option can be used
|
||||
to specify which servers are picked for fast server selection, servers
|
||||
with a ping roundtrip time below that value are considered.
|
||||
The default for low\-rtt\-permil is 0.
|
||||
.SS "Remote Control Options"
|
||||
In the
|
||||
.B remote\-control:
|
||||
clause are the declarations for the remote control facility. If this is
|
||||
enabled, the \fIunbound\-control\fR(8) utility can be used to send
|
||||
commands to the running unbound server. The server uses these clauses
|
||||
to setup SSLv3 / TLSv1 security for the connection. The
|
||||
to setup TLSv1 security for the connection. The
|
||||
\fIunbound\-control\fR(8) utility also reads the \fBremote\-control\fR
|
||||
section for options. To setup the correct self\-signed certificates use the
|
||||
\fIunbound\-control\-setup\fR(8) utility.
|
||||
@@ -1326,6 +1429,14 @@ By default localhost (127.0.0.1 and ::1) is listened to.
|
||||
Use 0.0.0.0 and ::0 to listen to all interfaces.
|
||||
If you change this and permissions have been dropped, you must restart
|
||||
the server for the change to take effect.
|
||||
.IP
|
||||
If you set it to an absolute path, a local socket is used. The local socket
|
||||
does not use the certificates and keys, so those files need not be present.
|
||||
To restrict access, unbound sets permissions on the file to the user and
|
||||
group that is configured, the access bits are set to allow the group members
|
||||
to access the control socket file. Put users that need to access the socket
|
||||
in the that group. To restrict access further, create a directory to put
|
||||
the control socket in and restrict access to that directory.
|
||||
.TP 5
|
||||
.B control\-port: \fI<port number>
|
||||
The port number to listen on for IPv4 or IPv6 control interfaces,
|
||||
@@ -1334,11 +1445,9 @@ If you change this and permissions have been dropped, you must restart
|
||||
the server for the change to take effect.
|
||||
.TP 5
|
||||
.B control\-use\-cert: \fI<yes or no>
|
||||
Whether to require certificate authentication of control connections.
|
||||
The default is "yes".
|
||||
This should not be changed unless there are other mechanisms in place
|
||||
to prevent untrusted users from accessing the remote control
|
||||
interface.
|
||||
For localhost control-interface you can disable the use of TLS by setting
|
||||
this option to "no", default is "yes". For local sockets, TLS is disabled
|
||||
and the value of this option is ignored.
|
||||
.TP 5
|
||||
.B server\-key\-file: \fI<private key file>
|
||||
Path to the server private key, by default unbound_server.key.
|
||||
@@ -1404,7 +1513,7 @@ IP address of stub zone nameserver. Can be IP 4 or IP 6.
|
||||
To use a nondefault port for DNS communication append '@' with the port number.
|
||||
.TP
|
||||
.B stub\-prime: \fI<yes or no>
|
||||
This option is by default off. If enabled it performs NS set priming,
|
||||
This option is by default no. If enabled it performs NS set priming,
|
||||
which is similar to root hints, where it starts using the list of nameservers
|
||||
currently published by the zone. Thus, if the hint list is slightly outdated,
|
||||
the resolver picks up a correct list online.
|
||||
@@ -1416,11 +1525,15 @@ the servers are unreachable, instead it is tried without this clause.
|
||||
The default is no.
|
||||
.TP
|
||||
.B stub\-tls\-upstream: \fI<yes or no>
|
||||
Enabled or disable whether the queries to this stub use SSL for transport.
|
||||
Enabled or disable whether the queries to this stub use TLS for transport.
|
||||
Default is no.
|
||||
.TP
|
||||
.B stub\-ssl\-upstream: \fI<yes or no>
|
||||
Alternate syntax for \fBstub\-tls\-upstream\fR.
|
||||
.TP
|
||||
.B stub\-no\-cache: \fI<yes or no>
|
||||
Default is no. If enabled, data inside the stub is not cached. This is
|
||||
useful when you want immediate changes to be visible.
|
||||
.SS "Forward Zone Options"
|
||||
.LP
|
||||
There may be multiple
|
||||
@@ -1448,6 +1561,14 @@ Name of server to forward to. Is itself resolved before it is used.
|
||||
.B forward\-addr: \fI<IP address>
|
||||
IP address of server to forward to. Can be IP 4 or IP 6.
|
||||
To use a nondefault port for DNS communication append '@' with the port number.
|
||||
If tls is enabled, then you can append a '#' and a name, then it'll check
|
||||
the tls authentication certificates with that name. If you combine
|
||||
the '@' and '#', the '@' comes first.
|
||||
.IP
|
||||
At high verbosity it logs the TLS certificate, with TLS enabled.
|
||||
If you leave out the '#' and auth name from the forward\-addr, any
|
||||
name is accepted. The cert must also match a CA from the tls\-cert\-bundle.
|
||||
The cert name match code needs OpenSSL 1.1.0 or later to be enabled.
|
||||
.TP
|
||||
.B forward\-first: \fI<yes or no>
|
||||
If enabled, a query is attempted without the forward clause if it fails.
|
||||
@@ -1456,11 +1577,17 @@ the servers are unreachable, instead it is tried without this clause.
|
||||
The default is no.
|
||||
.TP
|
||||
.B forward\-tls\-upstream: \fI<yes or no>
|
||||
Enabled or disable whether the queries to this forwarder use SSL for transport.
|
||||
Enabled or disable whether the queries to this forwarder use TLS for transport.
|
||||
Default is no.
|
||||
If you enable this, also configure a tls\-cert\-bundle or use tls\-win\-cert to
|
||||
load CA certs, otherwise the connections cannot be authenticated.
|
||||
.TP
|
||||
.B forward\-ssl\-upstream: \fI<yes or no>
|
||||
Alternate syntax for \fBforward\-tls\-upstream\fR.
|
||||
.TP
|
||||
.B forward\-no\-cache: \fI<yes or no>
|
||||
Default is no. If enabled, data inside the forward is not cached. This is
|
||||
useful when you want immediate changes to be visible.
|
||||
.SS "Authority Zone Options"
|
||||
.LP
|
||||
Authority zones are configured with \fBauth\-zone:\fR, and each one must
|
||||
@@ -1496,6 +1623,14 @@ If none of the urls work, the masters are tried with IXFR and AXFR.
|
||||
For https, the \fBtls\-cert\-bundle\fR and the hostname from the url are used
|
||||
to authenticate the connection.
|
||||
.TP
|
||||
.B allow\-notify: \fI<IP address or host name or netblockIP/prefix>
|
||||
With allow\-notify you can specify additional sources of notifies.
|
||||
When notified, the server attempts to first probe and then zone transfer.
|
||||
If the notify is from a master, it first attempts that master. Otherwise
|
||||
other masters are attempted. If there are no masters, but only urls, the
|
||||
file is downloaded when notified. The masters from master: statements are
|
||||
allowed notify by default.
|
||||
.TP
|
||||
.B fallback\-enabled: \fI<yes or no>
|
||||
Default no. If enabled, unbound falls back to querying the internet as
|
||||
a resolver for this zone when lookups fail. For example for DNSSEC
|
||||
@@ -1587,6 +1722,12 @@ It must be /96 or shorter. The default prefix is 64:ff9b::/96.
|
||||
.B dns64\-synthall: \fI<yes or no>\fR
|
||||
Debug option, default no. If enabled, synthesize all AAAA records
|
||||
despite the presence of actual AAAA records.
|
||||
.TP
|
||||
.B dns64\-ignore\-aaaa: \fI<name>\fR
|
||||
List domain for which the AAAA records are ignored and the A record is
|
||||
used by dns64 processing instead. Can be entered multiple times, list a
|
||||
new domain for which it applies, one per line. Applies also to names
|
||||
underneath the name given.
|
||||
.SS "DNSCrypt Options"
|
||||
.LP
|
||||
The
|
||||
@@ -1781,15 +1922,42 @@ If it finds a valid answer in the backend, Unbound uses it to respond
|
||||
to the query without performing iterative DNS resolution.
|
||||
If Unbound cannot even find an answer in the backend, it resolves the
|
||||
query as usual, and stores the answer in the backend.
|
||||
.P
|
||||
If Unbound was built with
|
||||
\fB\-\-with\-libhiredis\fR
|
||||
on a system that has installed the hiredis C client library of Redis,
|
||||
then the "redis" backend can be used.
|
||||
This backend communicates with the specified Redis server over a TCP
|
||||
connection to store and retrieve cache data.
|
||||
It can be used as a persistent and/or shared cache backend.
|
||||
It should be noted that Unbound never removes data stored in the Redis server,
|
||||
even if some data have expired in terms of DNS TTL or the Redis server has
|
||||
cached too much data;
|
||||
if necessary the Redis server must be configured to limit the cache size,
|
||||
preferably with some kind of least-recently-used eviction policy.
|
||||
This backend uses synchronous communication with the Redis server
|
||||
based on the assumption that the communication is stable and sufficiently
|
||||
fast.
|
||||
The thread waiting for a response from the Redis server cannot handle
|
||||
other DNS queries.
|
||||
Although the backend has the ability to reconnect to the server when
|
||||
the connection is closed unexpectedly and there is a configurable timeout
|
||||
in case the server is overly slow or hangs up, these cases are assumed
|
||||
to be very rare.
|
||||
If connection close or timeout happens too often, Unbound will be
|
||||
effectively unusable with this backend.
|
||||
It's the administrator's responsibility to make the assumption hold.
|
||||
.P
|
||||
The
|
||||
.B cachedb:
|
||||
clause gives custom settings of the cache DB module.
|
||||
.TP
|
||||
.B backend: \fI<backend name>\fR
|
||||
Specify the backend database name.
|
||||
Currently, only the in-memory "testframe" backend is supported.
|
||||
As the name suggests this backend is not of any practical use.
|
||||
This option defaults to "testframe".
|
||||
The default database is the in-memory backend named "testframe", which,
|
||||
as the name suggests, is not of any practical use.
|
||||
Depending on the build-time configuration, "redis" backend may also be
|
||||
used as described above.
|
||||
.TP
|
||||
.B secret-seed: \fI<"secret string">\fR
|
||||
Specify a seed to calculate a hash value from query information.
|
||||
@@ -1799,6 +1967,28 @@ operationally.
|
||||
If the backend database is shared by multiple Unbound instances,
|
||||
all instances must use the same secret seed.
|
||||
This option defaults to "default".
|
||||
.P
|
||||
The following
|
||||
.B cachedb
|
||||
otions are specific to the redis backend.
|
||||
.TP
|
||||
.B redis-server-host: \fI<server address or name>\fR
|
||||
The IP (either v6 or v4) address or domain name of the Redis server.
|
||||
In general an IP address should be specified as otherwise Unbound will have to
|
||||
resolve the name of the server every time it establishes a connection
|
||||
to the server.
|
||||
This option defaults to "127.0.0.1".
|
||||
.TP
|
||||
.B redis-server-port: \fI<port number>\fR
|
||||
The TCP port number of the Redis server.
|
||||
This option defaults to 6379.
|
||||
.TP
|
||||
.B redis-timeout: \fI<msec>\fR
|
||||
The period until when Unbound waits for a response from the Redis sever.
|
||||
If this timeout expires Unbound closes the connection, treats it as
|
||||
if the Redis server does not have the requested data, and will try to
|
||||
re-establish a new connection later.
|
||||
This option defaults to 100 milliseconds.
|
||||
.SH "MEMORY CONTROL EXAMPLE"
|
||||
In the example config settings below memory usage is reduced. Some service
|
||||
levels are lower, notable very large data and a high TCP load are no longer
|
||||
|
||||
+10
-2
@@ -464,7 +464,12 @@ eval_response(struct module_qstate *qstate, int id, struct subnet_qstate *sq)
|
||||
|
||||
memset(c_out, 0, sizeof(*c_out));
|
||||
|
||||
if (!qstate->return_msg) return module_error;
|
||||
if (!qstate->return_msg) {
|
||||
/* already an answer and its not a message, but retain
|
||||
* the actual rcode, instead of module_error, so send
|
||||
* module_finished */
|
||||
return module_finished;
|
||||
}
|
||||
|
||||
/* We have not asked for subnet data */
|
||||
if (!sq->subnet_sent) {
|
||||
@@ -511,6 +516,7 @@ eval_response(struct module_qstate *qstate, int id, struct subnet_qstate *sq)
|
||||
|
||||
lock_rw_wrlock(&sne->biglock);
|
||||
update_cache(qstate, id);
|
||||
sne->num_msg_nocache++;
|
||||
lock_rw_unlock(&sne->biglock);
|
||||
|
||||
if (sq->subnet_downstream) {
|
||||
@@ -693,6 +699,7 @@ subnetmod_operate(struct module_qstate *qstate, enum module_ev event,
|
||||
|
||||
lock_rw_wrlock(&sne->biglock);
|
||||
if (lookup_and_reply(qstate, id, sq)) {
|
||||
sne->num_msg_cache++;
|
||||
lock_rw_unlock(&sne->biglock);
|
||||
verbose(VERB_QUERY, "subnet: answered from cache");
|
||||
qstate->ext_state[id] = module_finished;
|
||||
@@ -741,7 +748,8 @@ subnetmod_operate(struct module_qstate *qstate, enum module_ev event,
|
||||
/* Query handed back by next module, we have a 'final' answer */
|
||||
if(sq && event == module_event_moddone) {
|
||||
qstate->ext_state[id] = eval_response(qstate, id, sq);
|
||||
if(qstate->ext_state[id] == module_finished) {
|
||||
if(qstate->ext_state[id] == module_finished &&
|
||||
qstate->return_msg) {
|
||||
ecs_opt_list_append(&sq->ecs_client_out,
|
||||
&qstate->edns_opts_front_out, qstate);
|
||||
}
|
||||
|
||||
@@ -61,6 +61,10 @@ struct subnet_env {
|
||||
/** allocation service */
|
||||
struct alloc_cache alloc;
|
||||
lock_rw_type biglock;
|
||||
/** number of messages from cache */
|
||||
size_t num_msg_cache;
|
||||
/** number of messages not from cache */
|
||||
size_t num_msg_nocache;
|
||||
};
|
||||
|
||||
struct subnet_msg_cache_data {
|
||||
|
||||
@@ -341,6 +341,8 @@ ipsecmod_handle_query(struct module_qstate* qstate,
|
||||
qstate->env->cfg->ipsecmod_max_ttl;
|
||||
qstate->return_msg->rep->prefetch_ttl = PREFETCH_TTL_CALC(
|
||||
qstate->return_msg->rep->ttl);
|
||||
qstate->return_msg->rep->serve_expired_ttl = qstate->return_msg->rep->ttl +
|
||||
qstate->env->cfg->serve_expired_ttl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+28
-6
@@ -84,7 +84,7 @@ struct delegpt* delegpt_copy(struct delegpt* dp, struct regional* region)
|
||||
}
|
||||
for(a = dp->target_list; a; a = a->next_target) {
|
||||
if(!delegpt_add_addr(copy, region, &a->addr, a->addrlen,
|
||||
a->bogus, a->lame))
|
||||
a->bogus, a->lame, a->tls_auth_name))
|
||||
return NULL;
|
||||
}
|
||||
return copy;
|
||||
@@ -176,13 +176,13 @@ delegpt_add_target(struct delegpt* dp, struct regional* region,
|
||||
if(ns->got4 && ns->got6)
|
||||
ns->resolved = 1;
|
||||
}
|
||||
return delegpt_add_addr(dp, region, addr, addrlen, bogus, lame);
|
||||
return delegpt_add_addr(dp, region, addr, addrlen, bogus, lame, NULL);
|
||||
}
|
||||
|
||||
int
|
||||
delegpt_add_addr(struct delegpt* dp, struct regional* region,
|
||||
struct sockaddr_storage* addr, socklen_t addrlen, uint8_t bogus,
|
||||
uint8_t lame)
|
||||
uint8_t lame, char* tls_auth_name)
|
||||
{
|
||||
struct delegpt_addr* a;
|
||||
log_assert(!dp->dp_type_mlc);
|
||||
@@ -210,6 +210,13 @@ delegpt_add_addr(struct delegpt* dp, struct regional* region,
|
||||
a->bogus = bogus;
|
||||
a->lame = lame;
|
||||
a->dnsseclame = 0;
|
||||
if(tls_auth_name) {
|
||||
a->tls_auth_name = regional_strdup(region, tls_auth_name);
|
||||
if(!a->tls_auth_name)
|
||||
return 0;
|
||||
} else {
|
||||
a->tls_auth_name = NULL;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -276,11 +283,16 @@ void delegpt_log(enum verbosity_value v, struct delegpt* dp)
|
||||
(ns->done_pside6?" PSIDE_AAAA":""));
|
||||
}
|
||||
for(a = dp->target_list; a; a = a->next_target) {
|
||||
char s[128];
|
||||
const char* str = " ";
|
||||
if(a->bogus && a->lame) str = " BOGUS ADDR_LAME ";
|
||||
else if(a->bogus) str = " BOGUS ";
|
||||
else if(a->lame) str = " ADDR_LAME ";
|
||||
log_addr(VERB_ALGO, str, &a->addr, a->addrlen);
|
||||
if(a->tls_auth_name)
|
||||
snprintf(s, sizeof(s), "%s[%s]", str,
|
||||
a->tls_auth_name);
|
||||
else snprintf(s, sizeof(s), "%s", str);
|
||||
log_addr(VERB_ALGO, s, &a->addr, a->addrlen);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -539,6 +551,7 @@ void delegpt_free_mlc(struct delegpt* dp)
|
||||
a = dp->target_list;
|
||||
while(a) {
|
||||
na = a->next_target;
|
||||
free(a->tls_auth_name);
|
||||
free(a);
|
||||
a = na;
|
||||
}
|
||||
@@ -585,7 +598,7 @@ int delegpt_add_ns_mlc(struct delegpt* dp, uint8_t* name, uint8_t lame)
|
||||
}
|
||||
|
||||
int delegpt_add_addr_mlc(struct delegpt* dp, struct sockaddr_storage* addr,
|
||||
socklen_t addrlen, uint8_t bogus, uint8_t lame)
|
||||
socklen_t addrlen, uint8_t bogus, uint8_t lame, char* tls_auth_name)
|
||||
{
|
||||
struct delegpt_addr* a;
|
||||
log_assert(dp->dp_type_mlc);
|
||||
@@ -612,6 +625,15 @@ int delegpt_add_addr_mlc(struct delegpt* dp, struct sockaddr_storage* addr,
|
||||
a->bogus = bogus;
|
||||
a->lame = lame;
|
||||
a->dnsseclame = 0;
|
||||
if(tls_auth_name) {
|
||||
a->tls_auth_name = strdup(tls_auth_name);
|
||||
if(!a->tls_auth_name) {
|
||||
free(a);
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
a->tls_auth_name = NULL;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -632,7 +654,7 @@ int delegpt_add_target_mlc(struct delegpt* dp, uint8_t* name, size_t namelen,
|
||||
if(ns->got4 && ns->got6)
|
||||
ns->resolved = 1;
|
||||
}
|
||||
return delegpt_add_addr_mlc(dp, addr, addrlen, bogus, lame);
|
||||
return delegpt_add_addr_mlc(dp, addr, addrlen, bogus, lame, NULL);
|
||||
}
|
||||
|
||||
size_t delegpt_get_mem(struct delegpt* dp)
|
||||
|
||||
@@ -85,6 +85,8 @@ struct delegpt {
|
||||
uint8_t ssl_upstream;
|
||||
/** delegpt from authoritative zone that is locally hosted */
|
||||
uint8_t auth_dp;
|
||||
/*** no cache */
|
||||
int no_cache;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -151,6 +153,8 @@ struct delegpt_addr {
|
||||
* option is useful to mark the address dnsseclame.
|
||||
* This value is not copied in addr-copy and dp-copy. */
|
||||
uint8_t dnsseclame;
|
||||
/** the TLS authentication name, (if not NULL) to use. */
|
||||
char* tls_auth_name;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -259,11 +263,12 @@ int delegpt_add_rrset(struct delegpt* dp, struct regional* regional,
|
||||
* @param addrlen: the length of addr.
|
||||
* @param bogus: if address is bogus.
|
||||
* @param lame: if address is lame.
|
||||
* @param tls_auth_name: TLS authentication name (or NULL).
|
||||
* @return false on error.
|
||||
*/
|
||||
int delegpt_add_addr(struct delegpt* dp, struct regional* regional,
|
||||
struct sockaddr_storage* addr, socklen_t addrlen,
|
||||
uint8_t bogus, uint8_t lame);
|
||||
uint8_t bogus, uint8_t lame, char* tls_auth_name);
|
||||
|
||||
/**
|
||||
* Find NS record in name list of delegation point.
|
||||
@@ -394,10 +399,11 @@ int delegpt_add_ns_mlc(struct delegpt* dp, uint8_t* name, uint8_t lame);
|
||||
* @param addrlen: the length of addr.
|
||||
* @param bogus: if address is bogus.
|
||||
* @param lame: if address is lame.
|
||||
* @param tls_auth_name: TLS authentication name (or NULL).
|
||||
* @return false on error.
|
||||
*/
|
||||
int delegpt_add_addr_mlc(struct delegpt* dp, struct sockaddr_storage* addr,
|
||||
socklen_t addrlen, uint8_t bogus, uint8_t lame);
|
||||
socklen_t addrlen, uint8_t bogus, uint8_t lame, char* tls_auth_name);
|
||||
|
||||
/**
|
||||
* Add target address to the delegation point.
|
||||
|
||||
+11
-2
@@ -231,14 +231,21 @@ read_fwds_addr(struct config_stub* s, struct delegpt* dp)
|
||||
struct config_strlist* p;
|
||||
struct sockaddr_storage addr;
|
||||
socklen_t addrlen;
|
||||
char* tls_auth_name;
|
||||
for(p = s->addrs; p; p = p->next) {
|
||||
log_assert(p->str);
|
||||
if(!extstrtoaddr(p->str, &addr, &addrlen)) {
|
||||
if(!authextstrtoaddr(p->str, &addr, &addrlen, &tls_auth_name)) {
|
||||
log_err("cannot parse forward %s ip address: '%s'",
|
||||
s->name, p->str);
|
||||
return 0;
|
||||
}
|
||||
if(!delegpt_add_addr_mlc(dp, &addr, addrlen, 0, 0)) {
|
||||
#ifndef HAVE_SSL_SET1_HOST
|
||||
if(tls_auth_name)
|
||||
log_err("no name verification functionality in "
|
||||
"ssl library, ignored name for %s", p->str);
|
||||
#endif
|
||||
if(!delegpt_add_addr_mlc(dp, &addr, addrlen, 0, 0,
|
||||
tls_auth_name)) {
|
||||
log_err("out of memory");
|
||||
return 0;
|
||||
}
|
||||
@@ -265,6 +272,8 @@ read_forwards(struct iter_forwards* fwd, struct config_file* cfg)
|
||||
* last resort will ask for parent-side NS record and thus
|
||||
* fallback to the internet name servers on a failure */
|
||||
dp->has_parent_side_NS = (uint8_t)!s->isfirst;
|
||||
/* Do not cache if set. */
|
||||
dp->no_cache = s->no_cache;
|
||||
/* use SSL for queries to this forwarder */
|
||||
dp->ssl_upstream = (uint8_t)s->ssl_upstream;
|
||||
verbose(VERB_QUERY, "Forward zone server list:");
|
||||
|
||||
+11
-2
@@ -244,14 +244,21 @@ read_stubs_addr(struct config_stub* s, struct delegpt* dp)
|
||||
struct config_strlist* p;
|
||||
struct sockaddr_storage addr;
|
||||
socklen_t addrlen;
|
||||
char* auth_name;
|
||||
for(p = s->addrs; p; p = p->next) {
|
||||
log_assert(p->str);
|
||||
if(!extstrtoaddr(p->str, &addr, &addrlen)) {
|
||||
if(!authextstrtoaddr(p->str, &addr, &addrlen, &auth_name)) {
|
||||
log_err("cannot parse stub %s ip address: '%s'",
|
||||
s->name, p->str);
|
||||
return 0;
|
||||
}
|
||||
if(!delegpt_add_addr_mlc(dp, &addr, addrlen, 0, 0)) {
|
||||
#ifndef HAVE_SSL_SET1_HOST
|
||||
if(auth_name)
|
||||
log_err("no name verification functionality in "
|
||||
"ssl library, ignored name for %s", p->str);
|
||||
#endif
|
||||
if(!delegpt_add_addr_mlc(dp, &addr, addrlen, 0, 0,
|
||||
auth_name)) {
|
||||
log_err("out of memory");
|
||||
return 0;
|
||||
}
|
||||
@@ -276,6 +283,8 @@ read_stubs(struct iter_hints* hints, struct config_file* cfg)
|
||||
* last resort will ask for parent-side NS record and thus
|
||||
* fallback to the internet name servers on a failure */
|
||||
dp->has_parent_side_NS = (uint8_t)!s->isfirst;
|
||||
/* Do not cache if set. */
|
||||
dp->no_cache = s->no_cache;
|
||||
/* ssl_upstream */
|
||||
dp->ssl_upstream = (uint8_t)s->ssl_upstream;
|
||||
delegpt_log(VERB_QUERY, dp);
|
||||
|
||||
@@ -437,7 +437,9 @@ scrub_normalize(sldns_buffer* pkt, struct msg_parse* msg,
|
||||
rrset->rrset_all_next =
|
||||
nx->rrset_all_next;
|
||||
nx->rrset_all_next = rrset;
|
||||
prev = nx;
|
||||
/* prev = nx; unused, enable if there
|
||||
* is other rrset removal code after
|
||||
* this */
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+44
-7
@@ -312,9 +312,9 @@ static int
|
||||
iter_filter_order(struct iter_env* iter_env, struct module_env* env,
|
||||
uint8_t* name, size_t namelen, uint16_t qtype, time_t now,
|
||||
struct delegpt* dp, int* selected_rtt, int open_target,
|
||||
struct sock_list* blacklist)
|
||||
struct sock_list* blacklist, time_t prefetch)
|
||||
{
|
||||
int got_num = 0, low_rtt = 0, swap_to_front;
|
||||
int got_num = 0, low_rtt = 0, swap_to_front, rtt_band = RTT_BAND;
|
||||
struct delegpt_addr* a, *n, *prev=NULL;
|
||||
|
||||
/* fillup sel_rtt and find best rtt in the bunch */
|
||||
@@ -329,6 +329,16 @@ iter_filter_order(struct iter_env* iter_env, struct module_env* env,
|
||||
return 0 to force the caller to fetch more */
|
||||
}
|
||||
|
||||
if(env->cfg->low_rtt_permil != 0 && prefetch == 0 &&
|
||||
low_rtt < env->cfg->low_rtt &&
|
||||
ub_random_max(env->rnd, 1000) < env->cfg->low_rtt_permil) {
|
||||
/* the query is not prefetch, but for a downstream client,
|
||||
* there is a low_rtt (fast) server. We choose that x% of the
|
||||
* time */
|
||||
/* pick rtt numbers from 0..LOWBAND_RTT */
|
||||
rtt_band = env->cfg->low_rtt - low_rtt;
|
||||
}
|
||||
|
||||
got_num = 0;
|
||||
a = dp->result_list;
|
||||
while(a) {
|
||||
@@ -340,10 +350,10 @@ iter_filter_order(struct iter_env* iter_env, struct module_env* env,
|
||||
}
|
||||
/* classify the server address and determine what to do */
|
||||
swap_to_front = 0;
|
||||
if(a->sel_rtt >= low_rtt && a->sel_rtt - low_rtt <= RTT_BAND) {
|
||||
if(a->sel_rtt >= low_rtt && a->sel_rtt - low_rtt <= rtt_band) {
|
||||
got_num++;
|
||||
swap_to_front = 1;
|
||||
} else if(a->sel_rtt<low_rtt && low_rtt-a->sel_rtt<=RTT_BAND) {
|
||||
} else if(a->sel_rtt<low_rtt && low_rtt-a->sel_rtt<=rtt_band) {
|
||||
got_num++;
|
||||
swap_to_front = 1;
|
||||
}
|
||||
@@ -365,11 +375,34 @@ iter_filter_order(struct iter_env* iter_env, struct module_env* env,
|
||||
int got_num6 = 0;
|
||||
int low_rtt6 = 0;
|
||||
int i;
|
||||
int attempt = -1; /* filter to make sure addresses have
|
||||
less attempts on them than the first, to force round
|
||||
robin when all the IPv6 addresses fail */
|
||||
int num4ok = 0; /* number ip4 at low attempt count */
|
||||
int num4_lowrtt = 0;
|
||||
prev = NULL;
|
||||
a = dp->result_list;
|
||||
for(i = 0; i < got_num; i++) {
|
||||
swap_to_front = 0;
|
||||
if(a->addr.ss_family != AF_INET6 && attempt == -1) {
|
||||
/* if we only have ip4 at low attempt count,
|
||||
* then ip6 is failing, and we need to
|
||||
* select one of the remaining IPv4 addrs */
|
||||
attempt = a->attempts;
|
||||
num4ok++;
|
||||
num4_lowrtt = a->sel_rtt;
|
||||
} else if(a->addr.ss_family != AF_INET6 && attempt == a->attempts) {
|
||||
num4ok++;
|
||||
if(num4_lowrtt == 0 || a->sel_rtt < num4_lowrtt) {
|
||||
num4_lowrtt = a->sel_rtt;
|
||||
}
|
||||
}
|
||||
if(a->addr.ss_family == AF_INET6) {
|
||||
if(attempt == -1) {
|
||||
attempt = a->attempts;
|
||||
} else if(a->attempts > attempt) {
|
||||
break;
|
||||
}
|
||||
got_num6++;
|
||||
swap_to_front = 1;
|
||||
if(low_rtt6 == 0 || a->sel_rtt < low_rtt6) {
|
||||
@@ -391,6 +424,9 @@ iter_filter_order(struct iter_env* iter_env, struct module_env* env,
|
||||
if(got_num6 > 0) {
|
||||
got_num = got_num6;
|
||||
*selected_rtt = low_rtt6;
|
||||
} else if(num4ok > 0) {
|
||||
got_num = num4ok;
|
||||
*selected_rtt = num4_lowrtt;
|
||||
}
|
||||
}
|
||||
return got_num;
|
||||
@@ -400,13 +436,14 @@ struct delegpt_addr*
|
||||
iter_server_selection(struct iter_env* iter_env,
|
||||
struct module_env* env, struct delegpt* dp,
|
||||
uint8_t* name, size_t namelen, uint16_t qtype, int* dnssec_lame,
|
||||
int* chase_to_rd, int open_target, struct sock_list* blacklist)
|
||||
int* chase_to_rd, int open_target, struct sock_list* blacklist,
|
||||
time_t prefetch)
|
||||
{
|
||||
int sel;
|
||||
int selrtt;
|
||||
struct delegpt_addr* a, *prev;
|
||||
int num = iter_filter_order(iter_env, env, name, namelen, qtype,
|
||||
*env->now, dp, &selrtt, open_target, blacklist);
|
||||
*env->now, dp, &selrtt, open_target, blacklist, prefetch);
|
||||
|
||||
if(num == 0)
|
||||
return NULL;
|
||||
@@ -625,7 +662,7 @@ iter_dp_is_useless(struct query_info* qinfo, uint16_t qflags,
|
||||
}
|
||||
|
||||
int
|
||||
iter_indicates_dnssec_fwd(struct module_env* env, struct query_info *qinfo)
|
||||
iter_qname_indicates_dnssec(struct module_env* env, struct query_info *qinfo)
|
||||
{
|
||||
struct trust_anchor* a;
|
||||
if(!env || !env->anchors || !qinfo || !qinfo->qname)
|
||||
|
||||
@@ -87,13 +87,18 @@ int iter_apply_cfg(struct iter_env* iter_env, struct config_file* cfg);
|
||||
* @param open_target: number of currently outstanding target queries.
|
||||
* If we wait for these, perhaps more server addresses become available.
|
||||
* @param blacklist: the IP blacklist to use.
|
||||
* @param prefetch: if not 0, prefetch is in use for this query.
|
||||
* This means the query can have different timing, because prefetch is
|
||||
* not waited upon by the downstream client, and thus a good time to
|
||||
* perform exploration of other targets.
|
||||
* @return best target or NULL if no target.
|
||||
* if not null, that target is removed from the result list in the dp.
|
||||
*/
|
||||
struct delegpt_addr* iter_server_selection(struct iter_env* iter_env,
|
||||
struct module_env* env, struct delegpt* dp, uint8_t* name,
|
||||
size_t namelen, uint16_t qtype, int* dnssec_lame,
|
||||
int* chase_to_rd, int open_target, struct sock_list* blacklist);
|
||||
int* chase_to_rd, int open_target, struct sock_list* blacklist,
|
||||
time_t prefetch);
|
||||
|
||||
/**
|
||||
* Allocate dns_msg from parsed msg, in regional.
|
||||
@@ -174,15 +179,14 @@ int iter_dp_is_useless(struct query_info* qinfo, uint16_t qflags,
|
||||
struct delegpt* dp);
|
||||
|
||||
/**
|
||||
* See if qname has DNSSEC needs in the forwarding case. This is true if
|
||||
* there is a trust anchor above it. Whether there is an insecure delegation
|
||||
* to the data is unknown, but CD-retry is needed.
|
||||
* See if qname has DNSSEC needs. This is true if there is a trust anchor above
|
||||
* it. Whether there is an insecure delegation to the data is unknown.
|
||||
* @param env: environment with anchors.
|
||||
* @param qinfo: query name and class.
|
||||
* @return true if trust anchor above qname, false if no anchor or insecure
|
||||
* point above qname.
|
||||
*/
|
||||
int iter_indicates_dnssec_fwd(struct module_env* env,
|
||||
int iter_qname_indicates_dnssec(struct module_env* env,
|
||||
struct query_info *qinfo);
|
||||
|
||||
/**
|
||||
|
||||
+250
-39
@@ -230,11 +230,12 @@ error_supers(struct module_qstate* qstate, int id, struct module_qstate* super)
|
||||
qstate->qinfo.qname, qstate->qinfo.qname_len);
|
||||
if(!dpns) {
|
||||
/* not interested */
|
||||
/* this can happen, for eg. qname minimisation asked
|
||||
* for an NXDOMAIN to be validated, and used qtype
|
||||
* A for that, and the error of that, the name, is
|
||||
* not listed in super_iq->dp */
|
||||
verbose(VERB_ALGO, "subq error, but not interested");
|
||||
log_query_info(VERB_ALGO, "superq", &super->qinfo);
|
||||
if(super_iq->dp)
|
||||
delegpt_log(VERB_ALGO, super_iq->dp);
|
||||
log_assert(0);
|
||||
return;
|
||||
} else {
|
||||
/* see if the failure did get (parent-lame) info */
|
||||
@@ -303,8 +304,20 @@ error_response_cache(struct module_qstate* qstate, int id, int rcode)
|
||||
if((msg=msg_cache_lookup(qstate->env,
|
||||
qstate->qinfo.qname, qstate->qinfo.qname_len,
|
||||
qstate->qinfo.qtype, qstate->qinfo.qclass,
|
||||
qstate->query_flags, 0, 0))
|
||||
qstate->query_flags, 0,
|
||||
qstate->env->cfg->serve_expired_ttl_reset))
|
||||
!= NULL) {
|
||||
if(qstate->env->cfg->serve_expired_ttl_reset) {
|
||||
struct reply_info* rep =
|
||||
(struct reply_info*)msg->entry.data;
|
||||
if(rep && *qstate->env->now +
|
||||
qstate->env->cfg->serve_expired_ttl >
|
||||
rep->serve_expired_ttl) {
|
||||
rep->serve_expired_ttl =
|
||||
*qstate->env->now +
|
||||
qstate->env->cfg->serve_expired_ttl;
|
||||
}
|
||||
}
|
||||
lock_rw_unlock(&msg->entry.lock);
|
||||
return error_response(qstate, id, rcode);
|
||||
}
|
||||
@@ -318,6 +331,7 @@ error_response_cache(struct module_qstate* qstate, int id, int rcode)
|
||||
err.qdcount = 1;
|
||||
err.ttl = NORR_TTL;
|
||||
err.prefetch_ttl = PREFETCH_TTL_CALC(err.ttl);
|
||||
err.serve_expired_ttl = NORR_TTL;
|
||||
/* do not waste time trying to validate this servfail */
|
||||
err.security = sec_status_indeterminate;
|
||||
verbose(VERB_ALGO, "store error response in message cache");
|
||||
@@ -536,7 +550,7 @@ handle_cname_response(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||
/** see if last resort is possible - does config allow queries to parent */
|
||||
static int
|
||||
can_have_last_resort(struct module_env* env, uint8_t* nm, size_t nmlen,
|
||||
uint16_t qclass)
|
||||
uint16_t qclass, struct delegpt** retdp)
|
||||
{
|
||||
struct delegpt* fwddp;
|
||||
struct iter_hints_stub* stub;
|
||||
@@ -549,12 +563,14 @@ can_have_last_resort(struct module_env* env, uint8_t* nm, size_t nmlen,
|
||||
/* has_parent side is turned off for stub_first, where we
|
||||
* are allowed to go to the parent */
|
||||
stub->dp->has_parent_side_NS) {
|
||||
if(retdp) *retdp = stub->dp;
|
||||
return 0;
|
||||
}
|
||||
if((fwddp = forwards_find(env->fwds, nm, qclass)) &&
|
||||
/* has_parent_side is turned off for forward_first, where
|
||||
* we are allowed to go to the parent */
|
||||
fwddp->has_parent_side_NS) {
|
||||
if(retdp) *retdp = fwddp;
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
@@ -787,6 +803,7 @@ prime_stub(struct module_qstate* qstate, struct iter_qstate* iq, int id,
|
||||
iq->dp = delegpt_copy(stub_dp, qstate->region);
|
||||
if(!iq->dp) {
|
||||
log_err("out of memory priming stub");
|
||||
errinf(qstate, "malloc failure, priming stub");
|
||||
(void)error_response(qstate, id, LDNS_RCODE_SERVFAIL);
|
||||
return 1; /* return 1 to make module stop, with error */
|
||||
}
|
||||
@@ -805,6 +822,7 @@ prime_stub(struct module_qstate* qstate, struct iter_qstate* iq, int id,
|
||||
LDNS_RR_TYPE_NS, qclass, qstate, id, iq,
|
||||
QUERYTARGETS_STATE, PRIME_RESP_STATE, &subq, 0)) {
|
||||
verbose(VERB_ALGO, "could not prime stub");
|
||||
errinf(qstate, "could not generate lookup for stub prime");
|
||||
(void)error_response(qstate, id, LDNS_RCODE_SERVFAIL);
|
||||
return 1; /* return 1 to make module stop, with error */
|
||||
}
|
||||
@@ -820,6 +838,7 @@ prime_stub(struct module_qstate* qstate, struct iter_qstate* iq, int id,
|
||||
fptr_ok(fptr_whitelist_modenv_kill_sub(
|
||||
qstate->env->kill_sub));
|
||||
(*qstate->env->kill_sub)(subq);
|
||||
errinf(qstate, "malloc failure, in stub prime");
|
||||
(void)error_response(qstate, id, LDNS_RCODE_SERVFAIL);
|
||||
return 1; /* return 1 to make module stop, with error */
|
||||
}
|
||||
@@ -903,6 +922,7 @@ auth_zone_delegpt(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||
return 1; /* just fallback */
|
||||
}
|
||||
lock_rw_unlock(&z->lock);
|
||||
errinf(qstate, "malloc failure");
|
||||
return 0;
|
||||
}
|
||||
dp->name = regional_alloc_init(qstate->region,
|
||||
@@ -914,6 +934,7 @@ auth_zone_delegpt(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||
return 1; /* just fallback */
|
||||
}
|
||||
lock_rw_unlock(&z->lock);
|
||||
errinf(qstate, "malloc failure");
|
||||
return 0;
|
||||
}
|
||||
dp->namelen = z->namelen;
|
||||
@@ -1000,7 +1021,7 @@ generate_ns_check(struct module_qstate* qstate, struct iter_qstate* iq, int id)
|
||||
if(iq->depth == ie->max_dependency_depth)
|
||||
return;
|
||||
if(!can_have_last_resort(qstate->env, iq->dp->name, iq->dp->namelen,
|
||||
iq->qchase.qclass))
|
||||
iq->qchase.qclass, NULL))
|
||||
return;
|
||||
/* is this query the same as the nscheck? */
|
||||
if(qstate->qinfo.qtype == LDNS_RR_TYPE_NS &&
|
||||
@@ -1104,7 +1125,7 @@ forward_request(struct module_qstate* qstate, struct iter_qstate* iq)
|
||||
struct delegpt* dp;
|
||||
uint8_t* delname = iq->qchase.qname;
|
||||
size_t delnamelen = iq->qchase.qname_len;
|
||||
if(iq->refetch_glue) {
|
||||
if(iq->refetch_glue && iq->dp) {
|
||||
delname = iq->dp->name;
|
||||
delnamelen = iq->dp->namelen;
|
||||
}
|
||||
@@ -1123,6 +1144,53 @@ forward_request(struct module_qstate* qstate, struct iter_qstate* iq)
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
iter_stub_fwd_no_cache(struct module_qstate *qstate, struct iter_qstate *iq)
|
||||
{
|
||||
struct iter_hints_stub *stub;
|
||||
struct delegpt *dp;
|
||||
|
||||
/* Check for stub. */
|
||||
stub = hints_lookup_stub(qstate->env->hints, iq->qchase.qname,
|
||||
iq->qchase.qclass, iq->dp);
|
||||
dp = forwards_lookup(qstate->env->fwds, iq->qchase.qname, iq->qchase.qclass);
|
||||
|
||||
/* see if forward or stub is more pertinent */
|
||||
if(stub && stub->dp && dp) {
|
||||
if(dname_strict_subdomain(dp->name, dp->namelabs,
|
||||
stub->dp->name, stub->dp->namelabs)) {
|
||||
stub = NULL; /* ignore stub, forward is lower */
|
||||
} else {
|
||||
dp = NULL; /* ignore forward, stub is lower */
|
||||
}
|
||||
}
|
||||
|
||||
/* check stub */
|
||||
if (stub != NULL && stub->dp != NULL) {
|
||||
if(stub->dp->no_cache) {
|
||||
char qname[255+1];
|
||||
char dpname[255+1];
|
||||
dname_str(iq->qchase.qname, qname);
|
||||
dname_str(stub->dp->name, dpname);
|
||||
verbose(VERB_ALGO, "stub for %s %s has no_cache", qname, dpname);
|
||||
}
|
||||
return (stub->dp->no_cache);
|
||||
}
|
||||
|
||||
/* Check for forward. */
|
||||
if (dp) {
|
||||
if(dp->no_cache) {
|
||||
char qname[255+1];
|
||||
char dpname[255+1];
|
||||
dname_str(iq->qchase.qname, qname);
|
||||
dname_str(dp->name, dpname);
|
||||
verbose(VERB_ALGO, "forward for %s %s has no_cache", qname, dpname);
|
||||
}
|
||||
return (dp->no_cache);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Process the initial part of the request handling. This state roughly
|
||||
* corresponds to resolver algorithms steps 1 (find answer in cache) and 2
|
||||
@@ -1157,6 +1225,10 @@ processInitRequest(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||
if(iq->query_restart_count > MAX_RESTART_COUNT) {
|
||||
verbose(VERB_QUERY, "request has exceeded the maximum number"
|
||||
" of query restarts with %d", iq->query_restart_count);
|
||||
errinf(qstate, "request has exceeded the maximum number "
|
||||
"restarts (eg. indirections)");
|
||||
if(iq->qchase.qname)
|
||||
errinf_dname(qstate, "stop at", iq->qchase.qname);
|
||||
return error_response(qstate, id, LDNS_RCODE_SERVFAIL);
|
||||
}
|
||||
|
||||
@@ -1168,6 +1240,8 @@ processInitRequest(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||
if(iq->depth > ie->max_dependency_depth) {
|
||||
verbose(VERB_QUERY, "request has exceeded the maximum "
|
||||
"dependency depth with depth of %d", iq->depth);
|
||||
errinf(qstate, "request has exceeded the maximum dependency "
|
||||
"depth (eg. nameserver lookup recursion)");
|
||||
return error_response(qstate, id, LDNS_RCODE_SERVFAIL);
|
||||
}
|
||||
|
||||
@@ -1184,10 +1258,8 @@ processInitRequest(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||
*/
|
||||
if (iq->refetch_glue &&
|
||||
iq->dp &&
|
||||
!can_have_last_resort(qstate->env,
|
||||
iq->dp->name,
|
||||
iq->dp->namelen,
|
||||
iq->qchase.qclass)) {
|
||||
!can_have_last_resort(qstate->env, iq->dp->name,
|
||||
iq->dp->namelen, iq->qchase.qclass, NULL)) {
|
||||
iq->refetch_glue = 0;
|
||||
}
|
||||
|
||||
@@ -1196,7 +1268,13 @@ processInitRequest(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||
/* This either results in a query restart (CNAME cache response), a
|
||||
* terminating response (ANSWER), or a cache miss (null). */
|
||||
|
||||
if(qstate->blacklist) {
|
||||
if (iter_stub_fwd_no_cache(qstate, iq)) {
|
||||
/* Asked to not query cache. */
|
||||
verbose(VERB_ALGO, "no-cache set, going to the network");
|
||||
qstate->no_cache_lookup = 1;
|
||||
qstate->no_cache_store = 1;
|
||||
msg = NULL;
|
||||
} else if(qstate->blacklist) {
|
||||
/* if cache, or anything else, was blacklisted then
|
||||
* getting older results from cache is a bad idea, no cache */
|
||||
verbose(VERB_ALGO, "cache blacklisted, going to the network");
|
||||
@@ -1206,7 +1284,8 @@ processInitRequest(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||
iq->qchase.qname_len, iq->qchase.qtype,
|
||||
iq->qchase.qclass, qstate->query_flags,
|
||||
qstate->region, qstate->env->scratch, 0);
|
||||
if(!msg && qstate->env->neg_cache) {
|
||||
if(!msg && qstate->env->neg_cache &&
|
||||
iter_qname_indicates_dnssec(qstate->env, &iq->qchase)) {
|
||||
/* lookup in negative cache; may result in
|
||||
* NOERROR/NODATA or NXDOMAIN answers that need validation */
|
||||
msg = val_neg_getmsg(qstate->env->neg_cache, &iq->qchase,
|
||||
@@ -1239,9 +1318,12 @@ processInitRequest(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||
verbose(VERB_ALGO, "returning CNAME response from "
|
||||
"cache");
|
||||
if(!handle_cname_response(qstate, iq, msg,
|
||||
&sname, &slen))
|
||||
&sname, &slen)) {
|
||||
errinf(qstate, "failed to prepend CNAME "
|
||||
"components, malloc failure");
|
||||
return error_response(qstate, id,
|
||||
LDNS_RCODE_SERVFAIL);
|
||||
}
|
||||
iq->qchase.qname = sname;
|
||||
iq->qchase.qname_len = slen;
|
||||
/* This *is* a query restart, even if it is a cheap
|
||||
@@ -1259,6 +1341,8 @@ processInitRequest(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||
/* if from cache, NULL, else insert 'cache IP' len=0 */
|
||||
if(qstate->reply_origin)
|
||||
sock_list_insert(&qstate->reply_origin, NULL, 0, qstate->region);
|
||||
if(FLAGS_GET_RCODE(msg->rep->flags) == LDNS_RCODE_SERVFAIL)
|
||||
errinf(qstate, "SERVFAIL in cache");
|
||||
/* it is an answer, response, to final state */
|
||||
verbose(VERB_ALGO, "returning answer from cache.");
|
||||
iq->response = msg;
|
||||
@@ -1270,6 +1354,7 @@ processInitRequest(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||
{
|
||||
if(!iq->dp) {
|
||||
log_err("alloc failure for forward dp");
|
||||
errinf(qstate, "malloc failure for forward zone");
|
||||
return error_response(qstate, id, LDNS_RCODE_SERVFAIL);
|
||||
}
|
||||
iq->refetch_glue = 0;
|
||||
@@ -1289,6 +1374,7 @@ processInitRequest(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||
if(iq->refetch_glue) {
|
||||
if(!iq->dp) {
|
||||
log_err("internal or malloc fail: no dp for refetch");
|
||||
errinf(qstate, "malloc failure, for delegation info");
|
||||
return error_response(qstate, id, LDNS_RCODE_SERVFAIL);
|
||||
}
|
||||
delname = iq->dp->name;
|
||||
@@ -1298,7 +1384,8 @@ processInitRequest(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||
delnamelen = iq->qchase.qname_len;
|
||||
}
|
||||
if(iq->qchase.qtype == LDNS_RR_TYPE_DS || iq->refetch_glue ||
|
||||
(iq->qchase.qtype == LDNS_RR_TYPE_NS && qstate->prefetch_leeway)) {
|
||||
(iq->qchase.qtype == LDNS_RR_TYPE_NS && qstate->prefetch_leeway
|
||||
&& can_have_last_resort(qstate->env, delname, delnamelen, iq->qchase.qclass, NULL))) {
|
||||
/* remove first label from delname, root goes to hints,
|
||||
* but only to fetch glue, not for qtype=DS. */
|
||||
/* also when prefetching an NS record, fetch it again from
|
||||
@@ -1347,12 +1434,14 @@ processInitRequest(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||
iq->qchase.qclass);
|
||||
if(!iq->dp) {
|
||||
log_err("internal error: no hints dp");
|
||||
errinf(qstate, "no hints for this class");
|
||||
return error_response(qstate, id,
|
||||
LDNS_RCODE_SERVFAIL);
|
||||
}
|
||||
iq->dp = delegpt_copy(iq->dp, qstate->region);
|
||||
if(!iq->dp) {
|
||||
log_err("out of memory in safety belt");
|
||||
errinf(qstate, "malloc failure, in safety belt");
|
||||
return error_response(qstate, id,
|
||||
LDNS_RCODE_SERVFAIL);
|
||||
}
|
||||
@@ -1396,6 +1485,9 @@ processInitRequest(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||
log_nametypeclass(VERB_ALGO, "ratelimit exceeded with "
|
||||
"delegation point", iq->dp->name,
|
||||
LDNS_RR_TYPE_NS, LDNS_RR_CLASS_IN);
|
||||
qstate->was_ratelimited = 1;
|
||||
errinf(qstate, "query was ratelimited");
|
||||
errinf_dname(qstate, "for zone", iq->dp->name);
|
||||
return error_response(qstate, id, LDNS_RCODE_SERVFAIL);
|
||||
}
|
||||
}
|
||||
@@ -1414,6 +1506,32 @@ processInitRequest(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||
*/
|
||||
if(iter_dp_is_useless(&qstate->qinfo, qstate->query_flags,
|
||||
iq->dp)) {
|
||||
struct delegpt* retdp = NULL;
|
||||
if(!can_have_last_resort(qstate->env, iq->dp->name, iq->dp->namelen, iq->qchase.qclass, &retdp)) {
|
||||
if(retdp) {
|
||||
verbose(VERB_QUERY, "cache has stub "
|
||||
"or fwd but no addresses, "
|
||||
"fallback to config");
|
||||
iq->dp = delegpt_copy(retdp,
|
||||
qstate->region);
|
||||
if(!iq->dp) {
|
||||
log_err("out of memory in "
|
||||
"stub/fwd fallback");
|
||||
errinf(qstate, "malloc failure, for fallback to config");
|
||||
return error_response(qstate,
|
||||
id, LDNS_RCODE_SERVFAIL);
|
||||
}
|
||||
break;
|
||||
}
|
||||
verbose(VERB_ALGO, "useless dp "
|
||||
"but cannot go up, servfail");
|
||||
delegpt_log(VERB_ALGO, iq->dp);
|
||||
errinf(qstate, "no useful nameservers, "
|
||||
"and cannot go up");
|
||||
errinf_dname(qstate, "for zone", iq->dp->name);
|
||||
return error_response(qstate, id,
|
||||
LDNS_RCODE_SERVFAIL);
|
||||
}
|
||||
if(dname_is_root(iq->dp->name)) {
|
||||
/* use safety belt */
|
||||
verbose(VERB_QUERY, "Cache has root NS but "
|
||||
@@ -1430,6 +1548,7 @@ processInitRequest(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||
iq->dp = delegpt_copy(iq->dp, qstate->region);
|
||||
if(!iq->dp) {
|
||||
log_err("out of memory in safety belt");
|
||||
errinf(qstate, "malloc failure, in safety belt, for root");
|
||||
return error_response(qstate, id,
|
||||
LDNS_RCODE_SERVFAIL);
|
||||
}
|
||||
@@ -1484,6 +1603,7 @@ processInitRequest2(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||
struct iter_hints_stub* stub;
|
||||
if(!iq->dp) {
|
||||
log_err("internal or malloc fail: no dp for refetch");
|
||||
errinf(qstate, "malloc failure, no delegation info");
|
||||
return error_response(qstate, id, LDNS_RCODE_SERVFAIL);
|
||||
}
|
||||
/* Do not send queries above stub, do not set delname to dp if
|
||||
@@ -1771,9 +1891,11 @@ processLastResort(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||
log_assert(iq->dp);
|
||||
|
||||
if(!can_have_last_resort(qstate->env, iq->dp->name, iq->dp->namelen,
|
||||
iq->qchase.qclass)) {
|
||||
iq->qchase.qclass, NULL)) {
|
||||
/* fail -- no more targets, no more hope of targets, no hope
|
||||
* of a response. */
|
||||
errinf(qstate, "all the configured stub or forward servers failed,");
|
||||
errinf_dname(qstate, "at zone", iq->dp->name);
|
||||
verbose(VERB_QUERY, "configured stub or forward servers failed -- returning SERVFAIL");
|
||||
return error_response_cache(qstate, id, LDNS_RCODE_SERVFAIL);
|
||||
}
|
||||
@@ -1791,7 +1913,7 @@ processLastResort(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||
for(a = p->target_list; a; a=a->next_target) {
|
||||
(void)delegpt_add_addr(iq->dp, qstate->region,
|
||||
&a->addr, a->addrlen, a->bogus,
|
||||
a->lame);
|
||||
a->lame, a->tls_auth_name);
|
||||
}
|
||||
}
|
||||
iq->dp->has_parent_side_NS = 1;
|
||||
@@ -1833,6 +1955,8 @@ processLastResort(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||
int qs = 0;
|
||||
verbose(VERB_ALGO, "try parent-side target name");
|
||||
if(!query_for_targets(qstate, iq, ie, id, 1, &qs)) {
|
||||
errinf(qstate, "could not fetch nameserver");
|
||||
errinf_dname(qstate, "at zone", iq->dp->name);
|
||||
return error_response(qstate, id, LDNS_RCODE_SERVFAIL);
|
||||
}
|
||||
iq->num_target_queries += qs;
|
||||
@@ -1844,6 +1968,7 @@ processLastResort(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||
}
|
||||
if(iq->depth == ie->max_dependency_depth) {
|
||||
verbose(VERB_QUERY, "maxdepth and need more nameservers, fail");
|
||||
errinf(qstate, "cannot fetch more nameservers because at max dependency depth");
|
||||
return error_response_cache(qstate, id, LDNS_RCODE_SERVFAIL);
|
||||
}
|
||||
if(iq->depth > 0 && iq->target_count &&
|
||||
@@ -1852,6 +1977,7 @@ processLastResort(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||
dname_str(qstate->qinfo.qname, s);
|
||||
verbose(VERB_QUERY, "request %s has exceeded the maximum "
|
||||
"number of glue fetches %d", s, iq->target_count[1]);
|
||||
errinf(qstate, "exceeded the maximum number of glue fetches");
|
||||
return error_response_cache(qstate, id, LDNS_RCODE_SERVFAIL);
|
||||
}
|
||||
/* mark cycle targets for parent-side lookups */
|
||||
@@ -1864,7 +1990,7 @@ processLastResort(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||
if( ((ie->supports_ipv6 && !ns->done_pside6) ||
|
||||
(ie->supports_ipv4 && !ns->done_pside4)) &&
|
||||
!can_have_last_resort(qstate->env, ns->name, ns->namelen,
|
||||
iq->qchase.qclass)) {
|
||||
iq->qchase.qclass, NULL)) {
|
||||
log_nametypeclass(VERB_ALGO, "cannot pside lookup ns "
|
||||
"because it is also a stub/forward,",
|
||||
ns->name, LDNS_RR_TYPE_NS, iq->qchase.qclass);
|
||||
@@ -1877,9 +2003,11 @@ processLastResort(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||
/* Send the AAAA request. */
|
||||
if(!generate_parentside_target_query(qstate, iq, id,
|
||||
ns->name, ns->namelen,
|
||||
LDNS_RR_TYPE_AAAA, iq->qchase.qclass))
|
||||
LDNS_RR_TYPE_AAAA, iq->qchase.qclass)) {
|
||||
errinf_dname(qstate, "could not generate nameserver AAAA lookup for", ns->name);
|
||||
return error_response(qstate, id,
|
||||
LDNS_RCODE_SERVFAIL);
|
||||
}
|
||||
ns->done_pside6 = 1;
|
||||
query_count++;
|
||||
}
|
||||
@@ -1887,9 +2015,11 @@ processLastResort(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||
/* Send the A request. */
|
||||
if(!generate_parentside_target_query(qstate, iq, id,
|
||||
ns->name, ns->namelen,
|
||||
LDNS_RR_TYPE_A, iq->qchase.qclass))
|
||||
LDNS_RR_TYPE_A, iq->qchase.qclass)) {
|
||||
errinf_dname(qstate, "could not generate nameserver A lookup for", ns->name);
|
||||
return error_response(qstate, id,
|
||||
LDNS_RCODE_SERVFAIL);
|
||||
}
|
||||
ns->done_pside4 = 1;
|
||||
query_count++;
|
||||
}
|
||||
@@ -1910,6 +2040,8 @@ processLastResort(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||
iq->deleg_msg?iq->deleg_msg->rep:
|
||||
(iq->response?iq->response->rep:NULL));
|
||||
|
||||
errinf(qstate, "all servers for this domain failed,");
|
||||
errinf_dname(qstate, "at zone", iq->dp->name);
|
||||
verbose(VERB_QUERY, "out of query targets -- returning SERVFAIL");
|
||||
/* fail -- no more targets, no more hope of targets, no hope
|
||||
* of a response. */
|
||||
@@ -1943,6 +2075,7 @@ processDSNSFind(struct module_qstate* qstate, struct iter_qstate* iq, int id)
|
||||
}
|
||||
/* robustcheck for internal error: we are not underneath the dp */
|
||||
if(!dname_subdomain_c(iq->dsns_point, iq->dp->name)) {
|
||||
errinf_dname(qstate, "for DS query parent-child nameserver search the query is not under the zone", iq->dp->name);
|
||||
return error_response_cache(qstate, id, LDNS_RCODE_SERVFAIL);
|
||||
}
|
||||
|
||||
@@ -1963,6 +2096,7 @@ processDSNSFind(struct module_qstate* qstate, struct iter_qstate* iq, int id)
|
||||
if(!generate_sub_request(iq->dsns_point, iq->dsns_point_len,
|
||||
LDNS_RR_TYPE_NS, iq->qchase.qclass, qstate, id, iq,
|
||||
INIT_REQUEST_STATE, FINISHED_STATE, &subq, 0)) {
|
||||
errinf_dname(qstate, "for DS query parent-child nameserver search, could not generate NS lookup for", iq->dsns_point);
|
||||
return error_response_cache(qstate, id, LDNS_RCODE_SERVFAIL);
|
||||
}
|
||||
|
||||
@@ -2008,11 +2142,13 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||
if(iq->referral_count > MAX_REFERRAL_COUNT) {
|
||||
verbose(VERB_QUERY, "request has exceeded the maximum "
|
||||
"number of referrrals with %d", iq->referral_count);
|
||||
errinf(qstate, "exceeded the maximum of referrals");
|
||||
return error_response(qstate, id, LDNS_RCODE_SERVFAIL);
|
||||
}
|
||||
if(iq->sent_count > MAX_SENT_COUNT) {
|
||||
verbose(VERB_QUERY, "request has exceeded the maximum "
|
||||
"number of sends with %d", iq->sent_count);
|
||||
errinf(qstate, "exceeded the maximum number of sends");
|
||||
return error_response(qstate, id, LDNS_RCODE_SERVFAIL);
|
||||
}
|
||||
|
||||
@@ -2020,6 +2156,7 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||
* or another failure occurred */
|
||||
if(!iq->dp) {
|
||||
verbose(VERB_QUERY, "Failed to get a delegation, giving up");
|
||||
errinf(qstate, "failed to get a delegation (eg. prime failure)");
|
||||
return error_response(qstate, id, LDNS_RCODE_SERVFAIL);
|
||||
}
|
||||
if(!ie->supports_ipv6)
|
||||
@@ -2037,7 +2174,8 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(iq->minimisation_state == INIT_MINIMISE_STATE) {
|
||||
if(iq->minimisation_state == INIT_MINIMISE_STATE
|
||||
&& !(iq->chase_flags & BIT_RD)) {
|
||||
/* (Re)set qinfo_out to (new) delegation point, except when
|
||||
* qinfo_out is already a subdomain of dp. This happens when
|
||||
* increasing by more than one label at once (QNAMEs with more
|
||||
@@ -2160,11 +2298,18 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||
log_dns_msg("msg from auth zone",
|
||||
&iq->response->qinfo, iq->response->rep);
|
||||
}
|
||||
iq->num_current_queries++;
|
||||
iq->chase_to_rd = 0;
|
||||
iq->dnssec_lame_query = 0;
|
||||
iq->auth_zone_response = 1;
|
||||
return next_state(iq, QUERY_RESP_STATE);
|
||||
if((iq->chase_flags&BIT_RD) && !(iq->response->rep->flags&BIT_AA)) {
|
||||
verbose(VERB_ALGO, "forwarder, ignoring referral from auth zone");
|
||||
} else {
|
||||
lock_rw_wrlock(&qstate->env->auth_zones->lock);
|
||||
qstate->env->auth_zones->num_query_up++;
|
||||
lock_rw_unlock(&qstate->env->auth_zones->lock);
|
||||
iq->num_current_queries++;
|
||||
iq->chase_to_rd = 0;
|
||||
iq->dnssec_lame_query = 0;
|
||||
iq->auth_zone_response = 1;
|
||||
return next_state(iq, QUERY_RESP_STATE);
|
||||
}
|
||||
}
|
||||
iq->auth_zone_response = 0;
|
||||
if(auth_fallback == 0) {
|
||||
@@ -2172,6 +2317,7 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||
* no internet fallback */
|
||||
verbose(VERB_ALGO, "auth zone lookup failed, no fallback,"
|
||||
" servfail");
|
||||
errinf(qstate, "auth zone lookup failed, fallback is off");
|
||||
return error_response(qstate, id, LDNS_RCODE_SERVFAIL);
|
||||
}
|
||||
if(iq->dp && iq->dp->auth_dp) {
|
||||
@@ -2197,6 +2343,7 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||
int extra = 0;
|
||||
size_t naddr, nres, navail;
|
||||
if(!query_for_targets(qstate, iq, ie, id, -1, &extra)) {
|
||||
errinf(qstate, "could not fetch nameservers for 0x20 fallback");
|
||||
return error_response(qstate, id, LDNS_RCODE_SERVFAIL);
|
||||
}
|
||||
iq->num_target_queries += extra;
|
||||
@@ -2253,7 +2400,8 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||
target = iter_server_selection(ie, qstate->env, iq->dp,
|
||||
iq->dp->name, iq->dp->namelen, iq->qchase.qtype,
|
||||
&iq->dnssec_lame_query, &iq->chase_to_rd,
|
||||
iq->num_target_queries, qstate->blacklist);
|
||||
iq->num_target_queries, qstate->blacklist,
|
||||
qstate->prefetch_leeway);
|
||||
|
||||
/* If no usable target was selected... */
|
||||
if(!target) {
|
||||
@@ -2276,6 +2424,8 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||
"missing target");
|
||||
if(!query_for_targets(qstate, iq, ie, id,
|
||||
1, &qs)) {
|
||||
errinf(qstate, "could not fetch nameserver");
|
||||
errinf_dname(qstate, "at zone", iq->dp->name);
|
||||
return error_response(qstate, id,
|
||||
LDNS_RCODE_SERVFAIL);
|
||||
}
|
||||
@@ -2346,6 +2496,9 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||
ie->num_queries_ratelimited++;
|
||||
lock_basic_unlock(&ie->queries_ratelimit_lock);
|
||||
verbose(VERB_ALGO, "query exceeded ratelimits");
|
||||
qstate->was_ratelimited = 1;
|
||||
errinf_dname(qstate, "exceeded ratelimit for zone",
|
||||
iq->dp->name);
|
||||
return error_response(qstate, id, LDNS_RCODE_SERVFAIL);
|
||||
}
|
||||
}
|
||||
@@ -2366,12 +2519,13 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||
* (blacklist nonempty) and no trust-anchors are configured
|
||||
* above the qname or on the first attempt when dnssec is on */
|
||||
EDNS_DO| ((iq->chase_to_rd||(iq->chase_flags&BIT_RD)!=0)&&
|
||||
!qstate->blacklist&&(!iter_indicates_dnssec_fwd(qstate->env,
|
||||
!qstate->blacklist&&(!iter_qname_indicates_dnssec(qstate->env,
|
||||
&iq->qinfo_out)||target->attempts==1)?0:BIT_CD),
|
||||
iq->dnssec_expected, iq->caps_fallback || is_caps_whitelisted(
|
||||
ie, iq), &target->addr, target->addrlen,
|
||||
iq->dp->name, iq->dp->namelen,
|
||||
(iq->dp->ssl_upstream || qstate->env->cfg->ssl_upstream), qstate);
|
||||
(iq->dp->ssl_upstream || qstate->env->cfg->ssl_upstream),
|
||||
target->tls_auth_name, qstate);
|
||||
if(!outq) {
|
||||
log_addr(VERB_DETAIL, "error sending query to auth server",
|
||||
&target->addr, target->addrlen);
|
||||
@@ -2440,9 +2594,10 @@ processQueryResponse(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||
}
|
||||
type = response_type_from_server(
|
||||
(int)((iq->chase_flags&BIT_RD) || iq->chase_to_rd),
|
||||
iq->response, &iq->qchase, iq->dp);
|
||||
iq->response, &iq->qinfo_out, iq->dp);
|
||||
iq->chase_to_rd = 0;
|
||||
if(type == RESPONSE_TYPE_REFERRAL && (iq->chase_flags&BIT_RD)) {
|
||||
if(type == RESPONSE_TYPE_REFERRAL && (iq->chase_flags&BIT_RD) &&
|
||||
!iq->auth_zone_response) {
|
||||
/* When forwarding (RD bit is set), we handle referrals
|
||||
* differently. No queries should be sent elsewhere */
|
||||
type = RESPONSE_TYPE_ANSWER;
|
||||
@@ -2508,6 +2663,15 @@ processQueryResponse(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||
/* DNAME to a subdomain loop; do not recurse */
|
||||
type = RESPONSE_TYPE_ANSWER;
|
||||
}
|
||||
} else if(type == RESPONSE_TYPE_CNAME &&
|
||||
iq->qchase.qtype == LDNS_RR_TYPE_CNAME &&
|
||||
iq->minimisation_state == MINIMISE_STATE &&
|
||||
query_dname_compare(iq->qchase.qname, iq->qinfo_out.qname) == 0) {
|
||||
/* The minimised query for full QTYPE and hidden QTYPE can be
|
||||
* classified as CNAME response type, even when the original
|
||||
* QTYPE=CNAME. This should be treated as answer response type.
|
||||
*/
|
||||
type = RESPONSE_TYPE_ANSWER;
|
||||
}
|
||||
|
||||
/* handle each of the type cases */
|
||||
@@ -2552,7 +2716,8 @@ processQueryResponse(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||
sock_list_insert(&qstate->reply_origin,
|
||||
&qstate->reply->addr, qstate->reply->addrlen,
|
||||
qstate->region);
|
||||
if(iq->minimisation_state != DONOT_MINIMISE_STATE) {
|
||||
if(iq->minimisation_state != DONOT_MINIMISE_STATE
|
||||
&& !(iq->chase_flags & BIT_RD)) {
|
||||
if(FLAGS_GET_RCODE(iq->response->rep->flags) !=
|
||||
LDNS_RCODE_NOERROR) {
|
||||
if(qstate->env->cfg->qname_minimisation_strict)
|
||||
@@ -2589,6 +2754,12 @@ processQueryResponse(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||
verbose(VERB_ALGO,
|
||||
"could not validate NXDOMAIN "
|
||||
"response");
|
||||
outbound_list_clear(&iq->outlist);
|
||||
iq->num_current_queries = 0;
|
||||
fptr_ok(fptr_whitelist_modenv_detach_subs(
|
||||
qstate->env->detach_subs));
|
||||
(*qstate->env->detach_subs)(qstate);
|
||||
iq->num_target_queries = 0;
|
||||
}
|
||||
}
|
||||
return next_state(iq, QUERYTARGETS_STATE);
|
||||
@@ -2656,11 +2827,15 @@ processQueryResponse(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||
iq->dp = delegpt_from_message(iq->response, qstate->region);
|
||||
if (qstate->env->cfg->qname_minimisation)
|
||||
iq->minimisation_state = INIT_MINIMISE_STATE;
|
||||
if(!iq->dp)
|
||||
if(!iq->dp) {
|
||||
errinf(qstate, "malloc failure, for delegation point");
|
||||
return error_response(qstate, id, LDNS_RCODE_SERVFAIL);
|
||||
}
|
||||
if(!cache_fill_missing(qstate->env, iq->qchase.qclass,
|
||||
qstate->region, iq->dp))
|
||||
qstate->region, iq->dp)) {
|
||||
errinf(qstate, "malloc failure, copy extra info into delegation point");
|
||||
return error_response(qstate, id, LDNS_RCODE_SERVFAIL);
|
||||
}
|
||||
if(iq->store_parent_NS && query_dname_compare(iq->dp->name,
|
||||
iq->store_parent_NS->name) == 0)
|
||||
iter_merge_retry_counts(iq->dp, iq->store_parent_NS);
|
||||
@@ -2722,8 +2897,10 @@ processQueryResponse(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||
}
|
||||
/* Process the CNAME response. */
|
||||
if(!handle_cname_response(qstate, iq, iq->response,
|
||||
&sname, &snamelen))
|
||||
&sname, &snamelen)) {
|
||||
errinf(qstate, "malloc failure, CNAME info");
|
||||
return error_response(qstate, id, LDNS_RCODE_SERVFAIL);
|
||||
}
|
||||
/* cache the CNAME response under the current query */
|
||||
/* NOTE : set referral=1, so that rrsets get stored but not
|
||||
* the partial query answer (CNAME only). */
|
||||
@@ -2736,16 +2913,18 @@ processQueryResponse(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||
/* set the current request's qname to the new value. */
|
||||
iq->qchase.qname = sname;
|
||||
iq->qchase.qname_len = snamelen;
|
||||
if (qstate->env->cfg->qname_minimisation)
|
||||
iq->minimisation_state = INIT_MINIMISE_STATE;
|
||||
/* Clear the query state, since this is a query restart. */
|
||||
iq->deleg_msg = NULL;
|
||||
iq->dp = NULL;
|
||||
iq->dsns_point = NULL;
|
||||
iq->auth_zone_response = 0;
|
||||
/* Note the query restart. */
|
||||
iq->query_restart_count++;
|
||||
iq->sent_count = 0;
|
||||
if(iq->minimisation_state != MINIMISE_STATE)
|
||||
/* Only count as query restart when it is not an extra
|
||||
* query as result of qname minimisation. */
|
||||
iq->query_restart_count++;
|
||||
if(qstate->env->cfg->qname_minimisation)
|
||||
iq->minimisation_state = INIT_MINIMISE_STATE;
|
||||
|
||||
/* stop current outstanding queries.
|
||||
* FIXME: should the outstanding queries be waited for and
|
||||
@@ -2822,6 +3001,8 @@ processQueryResponse(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||
iq->dp->name, iq->dp->namelen, qstate->qinfo.qclass)) {
|
||||
verbose(VERB_ALGO, "auth zone response bad, and no"
|
||||
" fallback possible, servfail");
|
||||
errinf_dname(qstate, "response is bad, no fallback, "
|
||||
"for auth zone", iq->dp->name);
|
||||
return error_response(qstate, id, LDNS_RCODE_SERVFAIL);
|
||||
}
|
||||
verbose(VERB_ALGO, "auth zone response was bad, "
|
||||
@@ -2912,6 +3093,8 @@ processPrimeResponse(struct module_qstate* qstate, int id)
|
||||
qstate->return_rcode = LDNS_RCODE_NOERROR;
|
||||
qstate->return_msg = iq->response;
|
||||
} else {
|
||||
errinf(qstate, "prime response did not get an answer");
|
||||
errinf_dname(qstate, "for", qstate->qinfo.qname);
|
||||
qstate->return_rcode = LDNS_RCODE_SERVFAIL;
|
||||
qstate->return_msg = NULL;
|
||||
}
|
||||
@@ -3055,6 +3238,7 @@ processDSNSResponse(struct module_qstate* qstate, int id,
|
||||
foriq->dp = delegpt_from_message(qstate->return_msg, forq->region);
|
||||
if(!foriq->dp) {
|
||||
log_err("out of memory in dsns dp alloc");
|
||||
errinf(qstate, "malloc failure, in DS search");
|
||||
return; /* dp==NULL in QUERYTARGETS makes SERVFAIL */
|
||||
}
|
||||
/* success, go query the querytargets in the new dp (and go down) */
|
||||
@@ -3155,6 +3339,8 @@ processClassResponse(struct module_qstate* qstate, int id,
|
||||
to->rep->ttl = from->rep->ttl;
|
||||
if(from->rep->prefetch_ttl < to->rep->prefetch_ttl)
|
||||
to->rep->prefetch_ttl = from->rep->prefetch_ttl;
|
||||
if(from->rep->serve_expired_ttl < to->rep->serve_expired_ttl)
|
||||
to->rep->serve_expired_ttl = from->rep->serve_expired_ttl;
|
||||
}
|
||||
/* are we done? */
|
||||
foriq->num_current_queries --;
|
||||
@@ -3193,6 +3379,8 @@ processCollectClass(struct module_qstate* qstate, int id)
|
||||
c, qstate, id, iq, INIT_REQUEST_STATE,
|
||||
FINISHED_STATE, &subq,
|
||||
(int)!(qstate->query_flags&BIT_CD))) {
|
||||
errinf(qstate, "could not generate class ANY"
|
||||
" lookup query");
|
||||
return error_response(qstate, id,
|
||||
LDNS_RCODE_SERVFAIL);
|
||||
}
|
||||
@@ -3239,6 +3427,7 @@ processFinished(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||
(iq->response?iq->response->rep:NULL));
|
||||
if(!iq->response) {
|
||||
verbose(VERB_ALGO, "No response is set, servfail");
|
||||
errinf(qstate, "(no response found at query finish)");
|
||||
return error_response(qstate, id, LDNS_RCODE_SERVFAIL);
|
||||
}
|
||||
|
||||
@@ -3409,6 +3598,7 @@ process_response(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||
iq->caps_server = 0;
|
||||
iq->caps_reply = NULL;
|
||||
iq->caps_response = NULL;
|
||||
iq->caps_minimisation_state = DONOT_MINIMISE_STATE;
|
||||
iq->state = QUERYTARGETS_STATE;
|
||||
iq->num_current_queries--;
|
||||
/* need fresh attempts for the 0x20 fallback, if
|
||||
@@ -3423,6 +3613,7 @@ process_response(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||
|| !qstate->reply) {
|
||||
log_err("Bad event combined with response");
|
||||
outbound_list_remove(&iq->outlist, outbound);
|
||||
errinf(qstate, "module iterator received wrong internal event with a response message");
|
||||
(void)error_response(qstate, id, LDNS_RCODE_SERVFAIL);
|
||||
return;
|
||||
}
|
||||
@@ -3475,6 +3666,7 @@ process_response(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||
iq->caps_server = 0;
|
||||
iq->caps_reply = NULL;
|
||||
iq->caps_response = NULL;
|
||||
iq->caps_minimisation_state = DONOT_MINIMISE_STATE;
|
||||
iq->state = QUERYTARGETS_STATE;
|
||||
iq->num_current_queries--;
|
||||
verbose(VERB_DETAIL, "Capsforid: scrub failed, starting fallback with no response");
|
||||
@@ -3494,15 +3686,30 @@ process_response(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||
iq->response->rep);
|
||||
|
||||
if(event == module_event_capsfail || iq->caps_fallback) {
|
||||
if(qstate->env->cfg->qname_minimisation &&
|
||||
iq->minimisation_state != DONOT_MINIMISE_STATE) {
|
||||
/* Skip QNAME minimisation for next query, since that
|
||||
* one has to match the current query. */
|
||||
iq->minimisation_state = SKIP_MINIMISE_STATE;
|
||||
}
|
||||
/* for fallback we care about main answer, not additionals */
|
||||
/* removing that makes comparison more likely to succeed */
|
||||
caps_strip_reply(iq->response->rep);
|
||||
|
||||
if(iq->caps_fallback &&
|
||||
iq->caps_minimisation_state != iq->minimisation_state) {
|
||||
/* QNAME minimisation state has changed, restart caps
|
||||
* fallback. */
|
||||
iq->caps_fallback = 0;
|
||||
}
|
||||
|
||||
if(!iq->caps_fallback) {
|
||||
/* start fallback */
|
||||
iq->caps_fallback = 1;
|
||||
iq->caps_server = 0;
|
||||
iq->caps_reply = iq->response->rep;
|
||||
iq->caps_response = iq->response;
|
||||
iq->caps_minimisation_state = iq->minimisation_state;
|
||||
iq->state = QUERYTARGETS_STATE;
|
||||
iq->num_current_queries--;
|
||||
verbose(VERB_DETAIL, "Capsforid: starting fallback");
|
||||
@@ -3534,6 +3741,7 @@ process_response(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||
verbose(VERB_DETAIL, "Capsforid fallback: "
|
||||
"getting different replies, failed");
|
||||
outbound_list_remove(&iq->outlist, outbound);
|
||||
errinf(qstate, "0x20 failed, then got different replies in fallback");
|
||||
(void)error_response(qstate, id,
|
||||
LDNS_RCODE_SERVFAIL);
|
||||
return;
|
||||
@@ -3572,6 +3780,7 @@ iter_operate(struct module_qstate* qstate, enum module_ev event, int id,
|
||||
if((event == module_event_new || event == module_event_pass) &&
|
||||
iq == NULL) {
|
||||
if(!iter_new(qstate, id)) {
|
||||
errinf(qstate, "malloc failure, new iterator module allocation");
|
||||
(void)error_response(qstate, id, LDNS_RCODE_SERVFAIL);
|
||||
return;
|
||||
}
|
||||
@@ -3589,11 +3798,13 @@ iter_operate(struct module_qstate* qstate, enum module_ev event, int id,
|
||||
}
|
||||
if(event == module_event_error) {
|
||||
verbose(VERB_ALGO, "got called with event error, giving up");
|
||||
errinf(qstate, "iterator module got the error event");
|
||||
(void)error_response(qstate, id, LDNS_RCODE_SERVFAIL);
|
||||
return;
|
||||
}
|
||||
|
||||
log_err("bad event for iterator");
|
||||
errinf(qstate, "iterator module received wrong event");
|
||||
(void)error_response(qstate, id, LDNS_RCODE_SERVFAIL);
|
||||
}
|
||||
|
||||
|
||||
@@ -371,6 +371,9 @@ struct iter_qstate {
|
||||
/** QNAME minimisation state, RFC7816 */
|
||||
enum minimisation_state minimisation_state;
|
||||
|
||||
/** State for capsfail: QNAME minimisation state for comparisons. */
|
||||
enum minimisation_state caps_minimisation_state;
|
||||
|
||||
/**
|
||||
* The query info that is sent upstream. Will be a subset of qchase
|
||||
* when qname minimisation is enabled.
|
||||
|
||||
+24
-19
@@ -71,9 +71,8 @@ context_finalize(struct ub_ctx* ctx)
|
||||
return UB_INITFAIL;
|
||||
if(!auth_zones_apply_cfg(ctx->env->auth_zones, cfg, 1))
|
||||
return UB_INITFAIL;
|
||||
if(!ctx->env->msg_cache ||
|
||||
cfg->msg_cache_size != slabhash_get_size(ctx->env->msg_cache) ||
|
||||
cfg->msg_cache_slabs != ctx->env->msg_cache->size) {
|
||||
if(!slabhash_is_size(ctx->env->msg_cache, cfg->msg_cache_size,
|
||||
cfg->msg_cache_slabs)) {
|
||||
slabhash_delete(ctx->env->msg_cache);
|
||||
ctx->env->msg_cache = slabhash_create(cfg->msg_cache_slabs,
|
||||
HASH_DEFAULT_STARTARRAY, cfg->msg_cache_size,
|
||||
@@ -130,7 +129,7 @@ find_id(struct ub_ctx* ctx, int* id)
|
||||
|
||||
struct ctx_query*
|
||||
context_new(struct ub_ctx* ctx, const char* name, int rrtype, int rrclass,
|
||||
ub_callback_type cb, void* cbarg)
|
||||
ub_callback_type cb, ub_event_callback_type cb_event, void* cbarg)
|
||||
{
|
||||
struct ctx_query* q = (struct ctx_query*)calloc(1, sizeof(*q));
|
||||
if(!q) return NULL;
|
||||
@@ -142,8 +141,9 @@ context_new(struct ub_ctx* ctx, const char* name, int rrtype, int rrclass,
|
||||
}
|
||||
lock_basic_unlock(&ctx->cfglock);
|
||||
q->node.key = &q->querynum;
|
||||
q->async = (cb != NULL);
|
||||
q->async = (cb != NULL || cb_event != NULL);
|
||||
q->cb = cb;
|
||||
q->cb_event = cb_event;
|
||||
q->cb_arg = cbarg;
|
||||
q->res = (struct ub_result*)calloc(1, sizeof(*q->res));
|
||||
if(!q->res) {
|
||||
@@ -293,26 +293,29 @@ context_serialize_answer(struct ctx_query* q, int err, sldns_buffer* pkt,
|
||||
* o uint32 id
|
||||
* o uint32 error_code
|
||||
* o uint32 msg_security
|
||||
* o uint32 was_ratelimited
|
||||
* o uint32 length of why_bogus string (+1 for eos); 0 absent.
|
||||
* o why_bogus_string
|
||||
* o the remainder is the answer msg from resolver lookup.
|
||||
* remainder can be length 0.
|
||||
*/
|
||||
size_t size_of_uint32s = 6 * sizeof(uint32_t);
|
||||
size_t pkt_len = pkt?sldns_buffer_remaining(pkt):0;
|
||||
size_t wlen = (pkt&&q->res->why_bogus)?strlen(q->res->why_bogus)+1:0;
|
||||
uint8_t* p;
|
||||
*len = sizeof(uint32_t)*5 + pkt_len + wlen;
|
||||
*len = size_of_uint32s + pkt_len + wlen;
|
||||
p = (uint8_t*)malloc(*len);
|
||||
if(!p) return NULL;
|
||||
sldns_write_uint32(p, UB_LIBCMD_ANSWER);
|
||||
sldns_write_uint32(p+sizeof(uint32_t), (uint32_t)q->querynum);
|
||||
sldns_write_uint32(p+2*sizeof(uint32_t), (uint32_t)err);
|
||||
sldns_write_uint32(p+3*sizeof(uint32_t), (uint32_t)q->msg_security);
|
||||
sldns_write_uint32(p+4*sizeof(uint32_t), (uint32_t)wlen);
|
||||
sldns_write_uint32(p+4*sizeof(uint32_t), (uint32_t)q->res->was_ratelimited);
|
||||
sldns_write_uint32(p+5*sizeof(uint32_t), (uint32_t)wlen);
|
||||
if(wlen > 0)
|
||||
memmove(p+5*sizeof(uint32_t), q->res->why_bogus, wlen);
|
||||
memmove(p+size_of_uint32s, q->res->why_bogus, wlen);
|
||||
if(pkt_len > 0)
|
||||
memmove(p+5*sizeof(uint32_t)+wlen,
|
||||
memmove(p+size_of_uint32s+wlen,
|
||||
sldns_buffer_begin(pkt), pkt_len);
|
||||
return p;
|
||||
}
|
||||
@@ -321,21 +324,23 @@ struct ctx_query*
|
||||
context_deserialize_answer(struct ub_ctx* ctx,
|
||||
uint8_t* p, uint32_t len, int* err)
|
||||
{
|
||||
size_t size_of_uint32s = 6 * sizeof(uint32_t);
|
||||
struct ctx_query* q = NULL ;
|
||||
int id;
|
||||
size_t wlen;
|
||||
if(len < 5*sizeof(uint32_t)) return NULL;
|
||||
if(len < size_of_uint32s) return NULL;
|
||||
log_assert( sldns_read_uint32(p) == UB_LIBCMD_ANSWER);
|
||||
id = (int)sldns_read_uint32(p+sizeof(uint32_t));
|
||||
q = (struct ctx_query*)rbtree_search(&ctx->queries, &id);
|
||||
if(!q) return NULL;
|
||||
*err = (int)sldns_read_uint32(p+2*sizeof(uint32_t));
|
||||
q->msg_security = sldns_read_uint32(p+3*sizeof(uint32_t));
|
||||
wlen = (size_t)sldns_read_uint32(p+4*sizeof(uint32_t));
|
||||
if(len > 5*sizeof(uint32_t) && wlen > 0) {
|
||||
if(len >= 5*sizeof(uint32_t)+wlen)
|
||||
q->res->was_ratelimited = (int)sldns_read_uint32(p+4*sizeof(uint32_t));
|
||||
wlen = (size_t)sldns_read_uint32(p+5*sizeof(uint32_t));
|
||||
if(len > size_of_uint32s && wlen > 0) {
|
||||
if(len >= size_of_uint32s+wlen)
|
||||
q->res->why_bogus = (char*)memdup(
|
||||
p+5*sizeof(uint32_t), wlen);
|
||||
p+size_of_uint32s, wlen);
|
||||
if(!q->res->why_bogus) {
|
||||
/* pass malloc failure to the user callback */
|
||||
q->msg_len = 0;
|
||||
@@ -344,9 +349,9 @@ context_deserialize_answer(struct ub_ctx* ctx,
|
||||
}
|
||||
q->res->why_bogus[wlen-1] = 0; /* zero terminated for sure */
|
||||
}
|
||||
if(len > 5*sizeof(uint32_t)+wlen) {
|
||||
q->msg_len = len - 5*sizeof(uint32_t) - wlen;
|
||||
q->msg = (uint8_t*)memdup(p+5*sizeof(uint32_t)+wlen,
|
||||
if(len > size_of_uint32s+wlen) {
|
||||
q->msg_len = len - size_of_uint32s - wlen;
|
||||
q->msg = (uint8_t*)memdup(p+size_of_uint32s+wlen,
|
||||
q->msg_len);
|
||||
if(!q->msg) {
|
||||
/* pass malloc failure to the user callback */
|
||||
@@ -387,12 +392,12 @@ struct ctx_query* context_deserialize_cancel(struct ub_ctx* ctx,
|
||||
uint8_t*
|
||||
context_serialize_quit(uint32_t* len)
|
||||
{
|
||||
uint8_t* p = (uint8_t*)malloc(sizeof(uint32_t));
|
||||
uint32_t* p = (uint32_t*)malloc(sizeof(uint32_t));
|
||||
if(!p)
|
||||
return NULL;
|
||||
*len = sizeof(uint32_t);
|
||||
sldns_write_uint32(p, UB_LIBCMD_QUIT);
|
||||
return p;
|
||||
return (uint8_t*)p;
|
||||
}
|
||||
|
||||
enum ub_ctx_cmd context_serial_getcmd(uint8_t* p, uint32_t len)
|
||||
|
||||
@@ -45,6 +45,7 @@
|
||||
#include "util/rbtree.h"
|
||||
#include "services/modstack.h"
|
||||
#include "libunbound/unbound.h"
|
||||
#include "libunbound/unbound-event.h"
|
||||
#include "util/data/packed_rrset.h"
|
||||
struct libworker;
|
||||
struct tube;
|
||||
@@ -148,8 +149,10 @@ struct ctx_query {
|
||||
/** was this query cancelled (for bg worker) */
|
||||
int cancelled;
|
||||
|
||||
/** for async query, the callback function */
|
||||
/** for async query, the callback function of type ub_callback_type */
|
||||
ub_callback_type cb;
|
||||
/** for event callbacks the type is ub_event_callback_type */
|
||||
ub_event_callback_type cb_event;
|
||||
/** for async query, the callback user arg */
|
||||
void* cb_arg;
|
||||
|
||||
@@ -238,11 +241,13 @@ void context_query_delete(struct ctx_query* q);
|
||||
* @param rrtype: type
|
||||
* @param rrclass: class
|
||||
* @param cb: callback for async, or NULL for sync.
|
||||
* @param cb_event: event callback for async, or NULL for sync.
|
||||
* @param cbarg: user arg for async queries.
|
||||
* @return new ctx_query or NULL for malloc failure.
|
||||
*/
|
||||
struct ctx_query* context_new(struct ub_ctx* ctx, const char* name, int rrtype,
|
||||
int rrclass, ub_callback_type cb, void* cbarg);
|
||||
int rrclass, ub_callback_type cb, ub_event_callback_type cb_event,
|
||||
void* cbarg);
|
||||
|
||||
/**
|
||||
* Get a new alloc. Creates a new one or uses a cached one.
|
||||
|
||||
+5
-13
@@ -109,13 +109,13 @@ static struct ub_ctx* ub_ctx_create_nopipe(void)
|
||||
alloc_init(&ctx->superalloc, NULL, 0);
|
||||
seed = (unsigned int)time(NULL) ^ (unsigned int)getpid();
|
||||
if(!(ctx->seed_rnd = ub_initstate(seed, NULL))) {
|
||||
seed = 0;
|
||||
explicit_bzero(&seed, sizeof(seed));
|
||||
ub_randfree(ctx->seed_rnd);
|
||||
free(ctx);
|
||||
errno = ENOMEM;
|
||||
return NULL;
|
||||
}
|
||||
seed = 0;
|
||||
explicit_bzero(&seed, sizeof(seed));
|
||||
lock_basic_init(&ctx->qqpipe_lock);
|
||||
lock_basic_init(&ctx->rrpipe_lock);
|
||||
lock_basic_init(&ctx->cfglock);
|
||||
@@ -392,7 +392,6 @@ ub_ctx_add_ta(struct ub_ctx* ctx, const char* ta)
|
||||
}
|
||||
if(!cfg_strlist_insert(&ctx->env->cfg->trust_anchor_list, dup)) {
|
||||
lock_basic_unlock(&ctx->cfglock);
|
||||
free(dup);
|
||||
return UB_NOMEM;
|
||||
}
|
||||
lock_basic_unlock(&ctx->cfglock);
|
||||
@@ -412,7 +411,6 @@ ub_ctx_add_ta_file(struct ub_ctx* ctx, const char* fname)
|
||||
}
|
||||
if(!cfg_strlist_insert(&ctx->env->cfg->trust_anchor_file_list, dup)) {
|
||||
lock_basic_unlock(&ctx->cfglock);
|
||||
free(dup);
|
||||
return UB_NOMEM;
|
||||
}
|
||||
lock_basic_unlock(&ctx->cfglock);
|
||||
@@ -432,7 +430,6 @@ int ub_ctx_add_ta_autr(struct ub_ctx* ctx, const char* fname)
|
||||
if(!cfg_strlist_insert(&ctx->env->cfg->auto_trust_anchor_file_list,
|
||||
dup)) {
|
||||
lock_basic_unlock(&ctx->cfglock);
|
||||
free(dup);
|
||||
return UB_NOMEM;
|
||||
}
|
||||
lock_basic_unlock(&ctx->cfglock);
|
||||
@@ -452,7 +449,6 @@ ub_ctx_trustedkeys(struct ub_ctx* ctx, const char* fname)
|
||||
}
|
||||
if(!cfg_strlist_insert(&ctx->env->cfg->trusted_keys_file_list, dup)) {
|
||||
lock_basic_unlock(&ctx->cfglock);
|
||||
free(dup);
|
||||
return UB_NOMEM;
|
||||
}
|
||||
lock_basic_unlock(&ctx->cfglock);
|
||||
@@ -690,7 +686,7 @@ ub_resolve(struct ub_ctx* ctx, const char* name, int rrtype,
|
||||
}
|
||||
/* create new ctx_query and attempt to add to the list */
|
||||
lock_basic_unlock(&ctx->cfglock);
|
||||
q = context_new(ctx, name, rrtype, rrclass, NULL, NULL);
|
||||
q = context_new(ctx, name, rrtype, rrclass, NULL, NULL, NULL);
|
||||
if(!q)
|
||||
return UB_NOMEM;
|
||||
/* become a resolver thread for a bit */
|
||||
@@ -747,8 +743,7 @@ ub_resolve_event(struct ub_ctx* ctx, const char* name, int rrtype,
|
||||
ub_comm_base_now(ctx->event_worker->base);
|
||||
|
||||
/* create new ctx_query and attempt to add to the list */
|
||||
q = context_new(ctx, name, rrtype, rrclass, (ub_callback_type)callback,
|
||||
mydata);
|
||||
q = context_new(ctx, name, rrtype, rrclass, NULL, callback, mydata);
|
||||
if(!q)
|
||||
return UB_NOMEM;
|
||||
|
||||
@@ -793,7 +788,7 @@ ub_resolve_async(struct ub_ctx* ctx, const char* name, int rrtype,
|
||||
}
|
||||
|
||||
/* create new ctx_query and attempt to add to the list */
|
||||
q = context_new(ctx, name, rrtype, rrclass, callback, mydata);
|
||||
q = context_new(ctx, name, rrtype, rrclass, callback, NULL, mydata);
|
||||
if(!q)
|
||||
return UB_NOMEM;
|
||||
|
||||
@@ -963,7 +958,6 @@ ub_ctx_set_fwd(struct ub_ctx* ctx, const char* addr)
|
||||
return UB_NOMEM;
|
||||
}
|
||||
if(!cfg_strlist_insert(&s->addrs, dupl)) {
|
||||
free(dupl);
|
||||
lock_basic_unlock(&ctx->cfglock);
|
||||
errno=ENOMEM;
|
||||
return UB_NOMEM;
|
||||
@@ -1046,7 +1040,6 @@ int ub_ctx_set_stub(struct ub_ctx* ctx, const char* zone, const char* addr,
|
||||
}
|
||||
if(!cfg_strlist_insert(&elem->addrs, a)) {
|
||||
lock_basic_unlock(&ctx->cfglock);
|
||||
free(a);
|
||||
errno = ENOMEM;
|
||||
return UB_NOMEM;
|
||||
}
|
||||
@@ -1234,7 +1227,6 @@ ub_ctx_hosts(struct ub_ctx* ctx, const char* fname)
|
||||
ins)) {
|
||||
lock_basic_unlock(&ctx->cfglock);
|
||||
fclose(in);
|
||||
free(ins);
|
||||
errno=ENOMEM;
|
||||
return UB_NOMEM;
|
||||
}
|
||||
|
||||
+50
-36
@@ -158,9 +158,9 @@ libworker_setup(struct ub_ctx* ctx, int is_bg, struct ub_event_base* eb)
|
||||
hints_delete(w->env->hints);
|
||||
w->env->hints = NULL;
|
||||
}
|
||||
if(cfg->ssl_upstream) {
|
||||
if(cfg->ssl_upstream || (cfg->tls_cert_bundle && cfg->tls_cert_bundle[0]) || cfg->tls_win_cert) {
|
||||
w->sslctx = connect_sslctx_create(NULL, NULL,
|
||||
cfg->tls_cert_bundle);
|
||||
cfg->tls_cert_bundle, cfg->tls_win_cert);
|
||||
if(!w->sslctx) {
|
||||
/* to make the setup fail after unlock */
|
||||
hints_delete(w->env->hints);
|
||||
@@ -187,7 +187,7 @@ libworker_setup(struct ub_ctx* ctx, int is_bg, struct ub_event_base* eb)
|
||||
if(!w->is_bg || w->is_bg_thread) {
|
||||
lock_basic_unlock(&ctx->cfglock);
|
||||
}
|
||||
seed = 0;
|
||||
explicit_bzero(&seed, sizeof(seed));
|
||||
libworker_delete(w);
|
||||
return NULL;
|
||||
}
|
||||
@@ -207,7 +207,7 @@ libworker_setup(struct ub_ctx* ctx, int is_bg, struct ub_event_base* eb)
|
||||
hash_set_raninit((uint32_t)ub_random(w->env->rnd));
|
||||
}
|
||||
}
|
||||
seed = 0;
|
||||
explicit_bzero(&seed, sizeof(seed));
|
||||
|
||||
if(eb)
|
||||
w->base = comm_base_create_event(eb);
|
||||
@@ -365,6 +365,7 @@ libworker_dobg(void* arg)
|
||||
|
||||
/* cleanup */
|
||||
m = UB_LIBCMD_QUIT;
|
||||
w->want_quit = 1;
|
||||
tube_remove_bg_listen(w->ctx->qq_pipe);
|
||||
tube_remove_bg_write(w->ctx->rr_pipe);
|
||||
libworker_delete(w);
|
||||
@@ -512,15 +513,17 @@ libworker_enter_result(struct ub_result* res, sldns_buffer* buf,
|
||||
res->nxdomain = 1;
|
||||
if(msg_security == sec_status_secure)
|
||||
res->secure = 1;
|
||||
if(msg_security == sec_status_bogus)
|
||||
if(msg_security == sec_status_bogus ||
|
||||
msg_security == sec_status_secure_sentinel_fail)
|
||||
res->bogus = 1;
|
||||
}
|
||||
|
||||
/** fillup fg results */
|
||||
static void
|
||||
libworker_fillup_fg(struct ctx_query* q, int rcode, sldns_buffer* buf,
|
||||
enum sec_status s, char* why_bogus)
|
||||
enum sec_status s, char* why_bogus, int was_ratelimited)
|
||||
{
|
||||
q->res->was_ratelimited = was_ratelimited;
|
||||
if(why_bogus)
|
||||
q->res->why_bogus = strdup(why_bogus);
|
||||
if(rcode != 0) {
|
||||
@@ -544,13 +547,13 @@ libworker_fillup_fg(struct ctx_query* q, int rcode, sldns_buffer* buf,
|
||||
|
||||
void
|
||||
libworker_fg_done_cb(void* arg, int rcode, sldns_buffer* buf, enum sec_status s,
|
||||
char* why_bogus)
|
||||
char* why_bogus, int was_ratelimited)
|
||||
{
|
||||
struct ctx_query* q = (struct ctx_query*)arg;
|
||||
/* fg query is done; exit comm base */
|
||||
comm_base_exit(q->w->base);
|
||||
|
||||
libworker_fillup_fg(q, rcode, buf, s, why_bogus);
|
||||
libworker_fillup_fg(q, rcode, buf, s, why_bogus, was_ratelimited);
|
||||
}
|
||||
|
||||
/** setup qinfo and edns */
|
||||
@@ -601,16 +604,16 @@ int libworker_fg(struct ub_ctx* ctx, struct ctx_query* q)
|
||||
NULL, 0, NULL, 0, NULL)) {
|
||||
regional_free_all(w->env->scratch);
|
||||
libworker_fillup_fg(q, LDNS_RCODE_NOERROR,
|
||||
w->back->udp_buff, sec_status_insecure, NULL);
|
||||
w->back->udp_buff, sec_status_insecure, NULL, 0);
|
||||
libworker_delete(w);
|
||||
free(qinfo.qname);
|
||||
return UB_NOERROR;
|
||||
}
|
||||
if(ctx->env->auth_zones && auth_zones_answer(ctx->env->auth_zones,
|
||||
w->env, &qinfo, &edns, w->back->udp_buff, w->env->scratch)) {
|
||||
w->env, &qinfo, &edns, NULL, w->back->udp_buff, w->env->scratch)) {
|
||||
regional_free_all(w->env->scratch);
|
||||
libworker_fillup_fg(q, LDNS_RCODE_NOERROR,
|
||||
w->back->udp_buff, sec_status_insecure, NULL);
|
||||
w->back->udp_buff, sec_status_insecure, NULL, 0);
|
||||
libworker_delete(w);
|
||||
free(qinfo.qname);
|
||||
return UB_NOERROR;
|
||||
@@ -632,10 +635,10 @@ int libworker_fg(struct ub_ctx* ctx, struct ctx_query* q)
|
||||
|
||||
void
|
||||
libworker_event_done_cb(void* arg, int rcode, sldns_buffer* buf,
|
||||
enum sec_status s, char* why_bogus)
|
||||
enum sec_status s, char* why_bogus, int was_ratelimited)
|
||||
{
|
||||
struct ctx_query* q = (struct ctx_query*)arg;
|
||||
ub_event_callback_type cb = (ub_event_callback_type)q->cb;
|
||||
ub_event_callback_type cb = q->cb_event;
|
||||
void* cb_arg = q->cb_arg;
|
||||
int cancelled = q->cancelled;
|
||||
|
||||
@@ -655,7 +658,7 @@ libworker_event_done_cb(void* arg, int rcode, sldns_buffer* buf,
|
||||
else if(s == sec_status_secure)
|
||||
sec = 2;
|
||||
(*cb)(cb_arg, rcode, (void*)sldns_buffer_begin(buf),
|
||||
(int)sldns_buffer_limit(buf), sec, why_bogus);
|
||||
(int)sldns_buffer_limit(buf), sec, why_bogus, was_ratelimited);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -682,15 +685,15 @@ int libworker_attach_mesh(struct ub_ctx* ctx, struct ctx_query* q,
|
||||
regional_free_all(w->env->scratch);
|
||||
free(qinfo.qname);
|
||||
libworker_event_done_cb(q, LDNS_RCODE_NOERROR,
|
||||
w->back->udp_buff, sec_status_insecure, NULL);
|
||||
w->back->udp_buff, sec_status_insecure, NULL, 0);
|
||||
return UB_NOERROR;
|
||||
}
|
||||
if(ctx->env->auth_zones && auth_zones_answer(ctx->env->auth_zones,
|
||||
w->env, &qinfo, &edns, w->back->udp_buff, w->env->scratch)) {
|
||||
w->env, &qinfo, &edns, NULL, w->back->udp_buff, w->env->scratch)) {
|
||||
regional_free_all(w->env->scratch);
|
||||
free(qinfo.qname);
|
||||
libworker_event_done_cb(q, LDNS_RCODE_NOERROR,
|
||||
w->back->udp_buff, sec_status_insecure, NULL);
|
||||
w->back->udp_buff, sec_status_insecure, NULL, 0);
|
||||
return UB_NOERROR;
|
||||
}
|
||||
/* process new query */
|
||||
@@ -708,29 +711,37 @@ int libworker_attach_mesh(struct ub_ctx* ctx, struct ctx_query* q,
|
||||
/** add result to the bg worker result queue */
|
||||
static void
|
||||
add_bg_result(struct libworker* w, struct ctx_query* q, sldns_buffer* pkt,
|
||||
int err, char* reason)
|
||||
int err, char* reason, int was_ratelimited)
|
||||
{
|
||||
uint8_t* msg = NULL;
|
||||
uint32_t len = 0;
|
||||
|
||||
if(w->want_quit) {
|
||||
context_query_delete(q);
|
||||
return;
|
||||
}
|
||||
/* serialize and delete unneeded q */
|
||||
if(w->is_bg_thread) {
|
||||
lock_basic_lock(&w->ctx->cfglock);
|
||||
if(reason)
|
||||
q->res->why_bogus = strdup(reason);
|
||||
q->res->was_ratelimited = was_ratelimited;
|
||||
if(pkt) {
|
||||
q->msg_len = sldns_buffer_remaining(pkt);
|
||||
q->msg = memdup(sldns_buffer_begin(pkt), q->msg_len);
|
||||
if(!q->msg)
|
||||
msg = context_serialize_answer(q, UB_NOMEM,
|
||||
NULL, &len);
|
||||
else msg = context_serialize_answer(q, err,
|
||||
NULL, &len);
|
||||
} else msg = context_serialize_answer(q, err, NULL, &len);
|
||||
if(!q->msg) {
|
||||
msg = context_serialize_answer(q, UB_NOMEM, NULL, &len);
|
||||
} else {
|
||||
msg = context_serialize_answer(q, err, NULL, &len);
|
||||
}
|
||||
} else {
|
||||
msg = context_serialize_answer(q, err, NULL, &len);
|
||||
}
|
||||
lock_basic_unlock(&w->ctx->cfglock);
|
||||
} else {
|
||||
if(reason)
|
||||
q->res->why_bogus = strdup(reason);
|
||||
q->res->was_ratelimited = was_ratelimited;
|
||||
msg = context_serialize_answer(q, err, pkt, &len);
|
||||
(void)rbtree_delete(&w->ctx->queries, q->node.key);
|
||||
w->ctx->num_async--;
|
||||
@@ -749,7 +760,7 @@ add_bg_result(struct libworker* w, struct ctx_query* q, sldns_buffer* pkt,
|
||||
|
||||
void
|
||||
libworker_bg_done_cb(void* arg, int rcode, sldns_buffer* buf, enum sec_status s,
|
||||
char* why_bogus)
|
||||
char* why_bogus, int was_ratelimited)
|
||||
{
|
||||
struct ctx_query* q = (struct ctx_query*)arg;
|
||||
|
||||
@@ -767,12 +778,13 @@ libworker_bg_done_cb(void* arg, int rcode, sldns_buffer* buf, enum sec_status s,
|
||||
return;
|
||||
}
|
||||
q->msg_security = s;
|
||||
if(!buf)
|
||||
if(!buf) {
|
||||
buf = q->w->env->scratch_buffer;
|
||||
}
|
||||
if(rcode != 0) {
|
||||
error_encode(buf, rcode, NULL, 0, BIT_RD, NULL);
|
||||
}
|
||||
add_bg_result(q->w, q, buf, UB_NOERROR, why_bogus);
|
||||
add_bg_result(q->w, q, buf, UB_NOERROR, why_bogus, was_ratelimited);
|
||||
}
|
||||
|
||||
|
||||
@@ -797,7 +809,7 @@ handle_newq(struct libworker* w, uint8_t* buf, uint32_t len)
|
||||
return;
|
||||
}
|
||||
if(!setup_qinfo_edns(w, q, &qinfo, &edns)) {
|
||||
add_bg_result(w, q, NULL, UB_SYNTAX, NULL);
|
||||
add_bg_result(w, q, NULL, UB_SYNTAX, NULL, 0);
|
||||
return;
|
||||
}
|
||||
qid = 0;
|
||||
@@ -810,15 +822,15 @@ handle_newq(struct libworker* w, uint8_t* buf, uint32_t len)
|
||||
NULL, 0, NULL, 0, NULL)) {
|
||||
regional_free_all(w->env->scratch);
|
||||
q->msg_security = sec_status_insecure;
|
||||
add_bg_result(w, q, w->back->udp_buff, UB_NOERROR, NULL);
|
||||
add_bg_result(w, q, w->back->udp_buff, UB_NOERROR, NULL, 0);
|
||||
free(qinfo.qname);
|
||||
return;
|
||||
}
|
||||
if(w->ctx->env->auth_zones && auth_zones_answer(w->ctx->env->auth_zones,
|
||||
w->env, &qinfo, &edns, w->back->udp_buff, w->env->scratch)) {
|
||||
w->env, &qinfo, &edns, NULL, w->back->udp_buff, w->env->scratch)) {
|
||||
regional_free_all(w->env->scratch);
|
||||
q->msg_security = sec_status_insecure;
|
||||
add_bg_result(w, q, w->back->udp_buff, UB_NOERROR, NULL);
|
||||
add_bg_result(w, q, w->back->udp_buff, UB_NOERROR, NULL, 0);
|
||||
free(qinfo.qname);
|
||||
return;
|
||||
}
|
||||
@@ -826,7 +838,7 @@ handle_newq(struct libworker* w, uint8_t* buf, uint32_t len)
|
||||
/* process new query */
|
||||
if(!mesh_new_callback(w->env->mesh, &qinfo, qflags, &edns,
|
||||
w->back->udp_buff, qid, libworker_bg_done_cb, q)) {
|
||||
add_bg_result(w, q, NULL, UB_NOMEM, NULL);
|
||||
add_bg_result(w, q, NULL, UB_NOMEM, NULL, 0);
|
||||
}
|
||||
free(qinfo.qname);
|
||||
}
|
||||
@@ -841,7 +853,8 @@ void libworker_alloc_cleanup(void* arg)
|
||||
struct outbound_entry* libworker_send_query(struct query_info* qinfo,
|
||||
uint16_t flags, int dnssec, int want_dnssec, int nocaps,
|
||||
struct sockaddr_storage* addr, socklen_t addrlen, uint8_t* zone,
|
||||
size_t zonelen, int ssl_upstream, struct module_qstate* q)
|
||||
size_t zonelen, int ssl_upstream, char* tls_auth_name,
|
||||
struct module_qstate* q)
|
||||
{
|
||||
struct libworker* w = (struct libworker*)q->env->worker;
|
||||
struct outbound_entry* e = (struct outbound_entry*)regional_alloc(
|
||||
@@ -851,8 +864,8 @@ struct outbound_entry* libworker_send_query(struct query_info* qinfo,
|
||||
e->qstate = q;
|
||||
e->qsent = outnet_serviced_query(w->back, qinfo, flags, dnssec,
|
||||
want_dnssec, nocaps, q->env->cfg->tcp_upstream, ssl_upstream,
|
||||
addr, addrlen, zone, zonelen, q, libworker_handle_service_reply,
|
||||
e, w->back->udp_buff, q->env);
|
||||
tls_auth_name, addr, addrlen, zone, zonelen, q,
|
||||
libworker_handle_service_reply, e, w->back->udp_buff, q->env);
|
||||
if(!e->qsent) {
|
||||
return NULL;
|
||||
}
|
||||
@@ -972,7 +985,8 @@ struct outbound_entry* worker_send_query(struct query_info* ATTR_UNUSED(qinfo),
|
||||
int ATTR_UNUSED(want_dnssec), int ATTR_UNUSED(nocaps),
|
||||
struct sockaddr_storage* ATTR_UNUSED(addr), socklen_t ATTR_UNUSED(addrlen),
|
||||
uint8_t* ATTR_UNUSED(zone), size_t ATTR_UNUSED(zonelen),
|
||||
int ATTR_UNUSED(ssl_upstream), struct module_qstate* ATTR_UNUSED(q))
|
||||
int ATTR_UNUSED(ssl_upstream), char* ATTR_UNUSED(tls_auth_name),
|
||||
struct module_qstate* ATTR_UNUSED(q))
|
||||
{
|
||||
log_assert(0);
|
||||
return 0;
|
||||
|
||||
@@ -75,6 +75,8 @@ struct libworker {
|
||||
int is_bg;
|
||||
/** is this a bg worker that is threaded (not forked)? */
|
||||
int is_bg_thread;
|
||||
/** want to quit, stop handling new content */
|
||||
int want_quit;
|
||||
|
||||
/** copy of the module environment with worker local entries. */
|
||||
struct module_env* env;
|
||||
|
||||
@@ -29,6 +29,7 @@ def dnssecParse(domain, rrType=RR_TYPE_A):
|
||||
|
||||
resolver = ub_ctx()
|
||||
resolver.add_ta(". IN DS 19036 8 2 49AAC11D7B6F6446702E54A1607371607A1A41855200FD2CE1CDDE32F24E8FB5")
|
||||
resolver.add_ta(". IN DS 20326 8 2 E06D44B80B8F1D39A95C0B0D7C65D08458E880409BBC683457104237C7F8EC8D")
|
||||
|
||||
dnssecParse("nic.cz")
|
||||
dnssecParse("nonexistent-domain-blablabla.cz")
|
||||
|
||||
@@ -170,7 +170,7 @@ struct ub_event {
|
||||
struct ub_event_vmt* vmt;
|
||||
};
|
||||
|
||||
typedef void (*ub_event_callback_type)(void*, int, void*, int, int, char*);
|
||||
typedef void (*ub_event_callback_type)(void*, int, void*, int, int, char*, int);
|
||||
|
||||
/**
|
||||
* Create a resolving and validation context.
|
||||
|
||||
@@ -203,6 +203,12 @@ struct ub_result {
|
||||
*/
|
||||
char* why_bogus;
|
||||
|
||||
/**
|
||||
* If the query or one of its subqueries was ratelimited. Useful if
|
||||
* ratelimiting is enabled and answer is SERVFAIL.
|
||||
*/
|
||||
int was_ratelimited;
|
||||
|
||||
/**
|
||||
* TTL for the result, in seconds. If the security is bogus, then
|
||||
* you also cannot trust this value.
|
||||
@@ -674,6 +680,8 @@ struct ub_server_stats {
|
||||
long long qtcp;
|
||||
/** number of outgoing queries over TCP */
|
||||
long long qtcp_outgoing;
|
||||
/** number of queries over (DNS over) TLS */
|
||||
long long qtls;
|
||||
/** number of queries over IPv6 */
|
||||
long long qipv6;
|
||||
/** number of queries with QR bit */
|
||||
@@ -747,6 +755,21 @@ struct ub_server_stats {
|
||||
long long num_query_dnscrypt_replay;
|
||||
/** number of dnscrypt nonces cache entries */
|
||||
long long nonce_cache_count;
|
||||
/** number of queries for unbound's auth_zones, upstream query */
|
||||
long long num_query_authzone_up;
|
||||
/** number of queries for unbound's auth_zones, downstream answers */
|
||||
long long num_query_authzone_down;
|
||||
/** number of times neg cache records were used to generate NOERROR
|
||||
* responses. */
|
||||
long long num_neg_cache_noerror;
|
||||
/** number of times neg cache records were used to generate NXDOMAIN
|
||||
* responses. */
|
||||
long long num_neg_cache_nxdomain;
|
||||
/** number of queries answered from edns-subnet specific data */
|
||||
long long num_query_subnet;
|
||||
/** number of queries answered from edns-subnet specific data, and
|
||||
* the answer was from the edns-subnet cache. */
|
||||
long long num_query_subnet_cache;
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
+11
-5
@@ -63,6 +63,8 @@ struct query_info;
|
||||
* @param zone: delegation point name.
|
||||
* @param zonelen: length of zone name wireformat dname.
|
||||
* @param ssl_upstream: use SSL for upstream queries.
|
||||
* @param tls_auth_name: if ssl_upstream, use this name with TLS
|
||||
* authentication.
|
||||
* @param q: wich query state to reactivate upon return.
|
||||
* @return: false on failure (memory or socket related). no query was
|
||||
* sent.
|
||||
@@ -70,7 +72,8 @@ struct query_info;
|
||||
struct outbound_entry* libworker_send_query(struct query_info* qinfo,
|
||||
uint16_t flags, int dnssec, int want_dnssec, int nocaps,
|
||||
struct sockaddr_storage* addr, socklen_t addrlen, uint8_t* zone,
|
||||
size_t zonelen, int ssl_upstream, struct module_qstate* q);
|
||||
size_t zonelen, int ssl_upstream, char* tls_auth_name,
|
||||
struct module_qstate* q);
|
||||
|
||||
/** process incoming replies from the network */
|
||||
int libworker_handle_reply(struct comm_point* c, void* arg, int error,
|
||||
@@ -86,15 +89,15 @@ void libworker_handle_control_cmd(struct tube* tube, uint8_t* msg, size_t len,
|
||||
|
||||
/** mesh callback with fg results */
|
||||
void libworker_fg_done_cb(void* arg, int rcode, sldns_buffer* buf,
|
||||
enum sec_status s, char* why_bogus);
|
||||
enum sec_status s, char* why_bogus, int was_ratelimited);
|
||||
|
||||
/** mesh callback with bg results */
|
||||
void libworker_bg_done_cb(void* arg, int rcode, sldns_buffer* buf,
|
||||
enum sec_status s, char* why_bogus);
|
||||
enum sec_status s, char* why_bogus, int was_ratelimited);
|
||||
|
||||
/** mesh callback with event results */
|
||||
void libworker_event_done_cb(void* arg, int rcode, struct sldns_buffer* buf,
|
||||
enum sec_status s, char* why_bogus);
|
||||
enum sec_status s, char* why_bogus, int was_ratelimited);
|
||||
|
||||
/**
|
||||
* Worker signal handler function. User argument is the worker itself.
|
||||
@@ -115,6 +118,8 @@ void worker_sighandler(int sig, void* arg);
|
||||
* @param zone: wireformat dname of the zone.
|
||||
* @param zonelen: length of zone name.
|
||||
* @param ssl_upstream: use SSL for upstream queries.
|
||||
* @param tls_auth_name: if ssl_upstream, use this name with TLS
|
||||
* authentication.
|
||||
* @param q: wich query state to reactivate upon return.
|
||||
* @return: false on failure (memory or socket related). no query was
|
||||
* sent.
|
||||
@@ -122,7 +127,8 @@ void worker_sighandler(int sig, void* arg);
|
||||
struct outbound_entry* worker_send_query(struct query_info* qinfo,
|
||||
uint16_t flags, int dnssec, int want_dnssec, int nocaps,
|
||||
struct sockaddr_storage* addr, socklen_t addrlen, uint8_t* zone,
|
||||
size_t zonelen, int ssl_upstream, struct module_qstate* q);
|
||||
size_t zonelen, int ssl_upstream, char* tls_auth_name,
|
||||
struct module_qstate* q);
|
||||
|
||||
/**
|
||||
* process control messages from the main thread. Frees the control
|
||||
|
||||
+51
-12
@@ -181,6 +181,7 @@ DOWIN="no"
|
||||
W64="yes"
|
||||
WINSSL=""
|
||||
WINEXPAT=""
|
||||
MINJ=""
|
||||
|
||||
# Parse the command line arguments.
|
||||
while [ "$1" ]; do
|
||||
@@ -239,6 +240,7 @@ if [ "$DOWIN" = "yes" ]; then
|
||||
makensis="makensis" # from mingw32-nsis package
|
||||
# flags for crosscompiled dependency libraries
|
||||
cross_flag=""
|
||||
shared_cross_flag=""
|
||||
|
||||
check_svn_root
|
||||
create_temp_dir
|
||||
@@ -249,39 +251,53 @@ if [ "$DOWIN" = "yes" ]; then
|
||||
info "winssl tar unpack"
|
||||
(cd ..; gzip -cd $WINSSL) | tar xf - || error_cleanup "tar unpack of $WINSSL failed"
|
||||
sslinstall="`pwd`/sslinstall"
|
||||
cp -r openssl-* openssl_shared
|
||||
cd openssl-* || error_cleanup "no openssl-X dir in tarball"
|
||||
# configure for crosscompile, without CAPI because it fails
|
||||
# cross-compilation and it is not used anyway
|
||||
# before 1.0.1i need --cross-compile-prefix=i686-w64-mingw32-
|
||||
if test "$mw64" = "mingw64"; then
|
||||
sslflags="no-shared no-asm -DOPENSSL_NO_CAPIENG mingw64"
|
||||
sslflags="no-asm -DOPENSSL_NO_CAPIENG mingw64"
|
||||
else
|
||||
sslflags="no-shared no-asm -DOPENSSL_NO_CAPIENG mingw"
|
||||
sslflags="no-asm -DOPENSSL_NO_CAPIENG mingw"
|
||||
fi
|
||||
info "winssl: Configure $sslflags"
|
||||
CC=${warch}-w64-mingw32-gcc AR=${warch}-w64-mingw32-ar RANLIB=${warch}-w64-mingw32-ranlib WINDRES=${warch}-w64-mingw32-windres ./Configure --prefix="$sslinstall" $sslflags || error_cleanup "OpenSSL Configure failed"
|
||||
info "winssl: Configure no-shared $sslflags"
|
||||
CC=${warch}-w64-mingw32-gcc AR=${warch}-w64-mingw32-ar RANLIB=${warch}-w64-mingw32-ranlib WINDRES=${warch}-w64-mingw32-windres ./Configure --prefix="$sslinstall" no-shared $sslflags || error_cleanup "OpenSSL Configure failed"
|
||||
info "winssl: make"
|
||||
make || error_cleanup "OpenSSL crosscompile failed"
|
||||
make $MINJ || error_cleanup "OpenSSL crosscompile failed"
|
||||
# only install sw not docs, which take a long time.
|
||||
info "winssl: make install_sw"
|
||||
make install_sw || error_cleanup "OpenSSL install failed"
|
||||
cross_flag="$cross_flag --with-ssl=$sslinstall"
|
||||
cd ..
|
||||
|
||||
# shared compile
|
||||
sslsharedinstall="`pwd`/sslsharedinstall"
|
||||
cd openssl_shared
|
||||
info "winssl: Configure shared $sslflags"
|
||||
CC=${warch}-w64-mingw32-gcc AR=${warch}-w64-mingw32-ar RANLIB=${warch}-w64-mingw32-ranlib WINDRES=${warch}-w64-mingw32-windres ./Configure --prefix="$sslsharedinstall" shared $sslflags || error_cleanup "OpenSSL Configure failed"
|
||||
info "winssl: make"
|
||||
make $MINJ || error_cleanup "OpenSSL crosscompile failed"
|
||||
info "winssl: make install_sw"
|
||||
make install_sw || error_cleanup "OpenSSL install failed"
|
||||
shared_cross_flag="$shared_cross_flag --with-ssl=$sslsharedinstall"
|
||||
cd ..
|
||||
fi
|
||||
|
||||
if test -n "$WINEXPAT"; then
|
||||
info "Cross compile $WINEXPAT"
|
||||
info "wxp: tar unpack"
|
||||
(cd ..; gzip -cd $WINEXPAT) | tar xf - || error_cleanup "tar unpack of $WINEXPAT failed"
|
||||
(cd ..; bzip2 -cd $WINEXPAT) | tar xf - || error_cleanup "tar unpack of $WINEXPAT failed"
|
||||
wxpinstall="`pwd`/wxpinstall"
|
||||
cd expat-* || error_cleanup "no expat-X dir in tarball"
|
||||
info "wxp: configure"
|
||||
$configure --prefix="$wxpinstall" --exec-prefix="$wxpinstall" --bindir="$wxpinstall/bin" --includedir="$wxpinstall/include" --mandir="$wxpinstall/man" --libdir="$wxpinstall/lib" || error_cleanup "libexpat configure failed"
|
||||
#info "wxp: make"
|
||||
#make || error_cleanup "libexpat crosscompile failed"
|
||||
info "wxp: make"
|
||||
make $MINJ || error_cleanup "libexpat crosscompile failed"
|
||||
info "wxp: make install"
|
||||
make install || error_cleanup "libexpat install failed"
|
||||
cross_flag="$cross_flag --with-libexpat=$wxpinstall"
|
||||
shared_cross_flag="$shared_cross_flag --with-libexpat=$wxpinstall"
|
||||
cd ..
|
||||
fi
|
||||
|
||||
@@ -320,6 +336,10 @@ if [ "$DOWIN" = "yes" ]; then
|
||||
rm -r autom4te* || echo "ignored"
|
||||
fi
|
||||
|
||||
if test "`uname`" = "Linux"; then
|
||||
(cd ..; cp -r unbound unbound_shared)
|
||||
fi
|
||||
|
||||
# procedure for making unbound installer on mingw.
|
||||
info "Creating windows dist unbound $version"
|
||||
info "Calling configure"
|
||||
@@ -338,9 +358,26 @@ if [ "$DOWIN" = "yes" ]; then
|
||||
|| error_cleanup "Could not configure"
|
||||
fi
|
||||
info "Calling make"
|
||||
make || error_cleanup "Could not make"
|
||||
make $MINJ || error_cleanup "Could not make"
|
||||
info "Make complete"
|
||||
|
||||
if test "`uname`" = "Linux"; then
|
||||
info "Make DLL"
|
||||
cd ../unbound_shared
|
||||
echo "$configure"' --enable-debug --disable-flto '"$* $shared_cross_flag "$file_flag" "$file2_flag" "$file3_flag""
|
||||
if test "$W64" = "no"; then
|
||||
$configure --enable-debug --disable-flto $* $shared_cross_flag "$file_flag" "$file2_flag" "$file3_flag" \
|
||||
|| error_cleanup "Could not configure"
|
||||
else
|
||||
$configure --enable-debug --disable-flto $* $shared_cross_flag \
|
||||
|| error_cleanup "Could not configure"
|
||||
fi
|
||||
info "Calling make for DLL"
|
||||
make $MINJ || error_cleanup "Could not make DLL"
|
||||
info "Make DLL complete"
|
||||
cd ../unbound
|
||||
fi
|
||||
|
||||
info "Unbound version: $version"
|
||||
file="unbound-$version.zip"
|
||||
rm -f $file
|
||||
@@ -360,17 +397,19 @@ if [ "$DOWIN" = "yes" ]; then
|
||||
cp ../root.key .
|
||||
cp ../doc/example.conf ../doc/Changelog .
|
||||
cp ../unbound.exe ../unbound-anchor.exe ../unbound-host.exe ../unbound-control.exe ../unbound-checkconf.exe ../unbound-service-install.exe ../unbound-service-remove.exe ../LICENSE ../winrc/unbound-control-setup.cmd ../winrc/unbound-website.url ../winrc/service.conf ../winrc/README.txt ../contrib/create_unbound_ad_servers.cmd ../contrib/warmup.cmd ../contrib/unbound_cache.cmd .
|
||||
mkdir libunbound
|
||||
cp ../../unbound_shared/unbound.h ../../unbound_shared/.libs/libunbound*.dll ../../unbound_shared/.libs/libunbound.dll.a ../../unbound_shared/.libs/libunbound.a ../../unbound_shared/.libs/libunbound*.def ../../sslsharedinstall/lib/libcrypto.dll.a ../../sslsharedinstall/lib/libssl.dll.a ../../sslsharedinstall/bin/libcrypto*.dll ../../sslsharedinstall/bin/libssl*.dll ../../wxpinstall/bin/libexpat*.dll ../../wxpinstall/lib/libexpat.dll.a libunbound/.
|
||||
# zipfile
|
||||
zip ../$file LICENSE README.txt unbound.exe unbound-anchor.exe unbound-host.exe unbound-control.exe unbound-checkconf.exe unbound-service-install.exe unbound-service-remove.exe unbound-control-setup.cmd example.conf service.conf root.key unbound-website.url create_unbound_ad_servers.cmd warmup.cmd unbound_cache.cmd Changelog
|
||||
zip -r ../$file LICENSE README.txt unbound.exe unbound-anchor.exe unbound-host.exe unbound-control.exe unbound-checkconf.exe unbound-service-install.exe unbound-service-remove.exe unbound-control-setup.cmd example.conf service.conf root.key unbound-website.url create_unbound_ad_servers.cmd warmup.cmd unbound_cache.cmd Changelog libunbound
|
||||
info "Testing $file"
|
||||
(cd .. ; zip -T $file )
|
||||
# installer
|
||||
info "Creating installer"
|
||||
quadversion=`cat ../config.h | grep RSRC_PACKAGE_VERSION | sed -e 's/#define RSRC_PACKAGE_VERSION //' -e 's/,/\\./g'`
|
||||
cat ../winrc/setup.nsi | sed -e 's/define VERSION.*$/define VERSION "'$version'"/' -e 's/define QUADVERSION.*$/define QUADVERSION "'$quadversion'"/' > ../winrc/setup_ed.nsi
|
||||
if test "$W64" = "yes"; then
|
||||
if test "$W64" = "no"; then
|
||||
mv ../winrc/setup_ed.nsi ../winrc/setup_ed_old.nsi
|
||||
cat ../winrc/setup_ed_old.nsi | sed -e 's/PROGRAMFILES/PROGRAMFILES64/' > ../winrc/setup_ed.nsi
|
||||
cat ../winrc/setup_ed_old.nsi | sed -e 's/PROGRAMFILES64/PROGRAMFILES/' -e 's/SetRegView 64/SetRegView 32/' > ../winrc/setup_ed.nsi
|
||||
fi
|
||||
"$makensis" ../winrc/setup_ed.nsi
|
||||
info "Created installer"
|
||||
|
||||
@@ -40,9 +40,12 @@ The callback function's prototype is the following:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
def inplace_reply_callback(qinfo, qstate, rep, rcode, edns, opt_list_out, region):
|
||||
"""Function that will be registered as an inplace callback function.
|
||||
def inplace_reply_callback(qinfo, qstate, rep, rcode, edns, opt_list_out,
|
||||
region, **kwargs):
|
||||
"""
|
||||
Function that will be registered as an inplace callback function.
|
||||
It will be called when answering with a resolved query.
|
||||
|
||||
:param qinfo: query_info struct;
|
||||
:param qstate: module qstate. It contains the available opt_lists; It
|
||||
SHOULD NOT be altered;
|
||||
@@ -54,7 +57,13 @@ The callback function's prototype is the following:
|
||||
reply. It can be populated with EDNS options;
|
||||
:param region: region to allocate temporary data. Needs to be used when we
|
||||
want to append a new option to opt_list_out.
|
||||
:param **kwargs: Dictionary that may contain parameters added in a future
|
||||
release. Current parameters:
|
||||
``repinfo``: Reply information for a communication point (comm_reply).
|
||||
It is None when the callback happens in the mesh states.
|
||||
|
||||
:return: True on success, False on failure.
|
||||
|
||||
"""
|
||||
|
||||
.. note:: The function's name is irrelevant.
|
||||
@@ -76,9 +85,12 @@ The callback function's prototype is the following:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
def inplace_cache_callback(qinfo, qstate, rep, rcode, edns, opt_list_out, region):
|
||||
"""Function that will be registered as an inplace callback function.
|
||||
def inplace_cache_callback(qinfo, qstate, rep, rcode, edns, opt_list_out,
|
||||
region, **kwargs):
|
||||
"""
|
||||
Function that will be registered as an inplace callback function.
|
||||
It will be called when answering from the cache.
|
||||
|
||||
:param qinfo: query_info struct;
|
||||
:param qstate: module qstate. None;
|
||||
:param rep: reply_info struct;
|
||||
@@ -90,7 +102,17 @@ The callback function's prototype is the following:
|
||||
reply. It can be populated with EDNS options;
|
||||
:param region: region to allocate temporary data. Needs to be used when we
|
||||
want to append a new option to opt_list_out.
|
||||
:param **kwargs: Dictionary that may contain parameters added in a future
|
||||
release. Current parameters:
|
||||
``repinfo``: Reply information for a communication point (comm_reply).
|
||||
It is None when the callback happens in the mesh
|
||||
states(modules).
|
||||
|
||||
:return: True on success, False on failure.
|
||||
|
||||
For demonstration purposes we want to see if EDNS option 65002 is present
|
||||
and reply with a new value.
|
||||
|
||||
"""
|
||||
|
||||
.. note:: The function's name is irrelevant.
|
||||
@@ -112,9 +134,12 @@ The callback function's prototype is the following:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
def inplace_local_callback(qinfo, qstate, rep, rcode, edns, opt_list_out, region):
|
||||
"""Function that will be registered as an inplace callback function.
|
||||
def inplace_local_callback(qinfo, qstate, rep, rcode, edns, opt_list_out,
|
||||
region, **kwargs):
|
||||
"""
|
||||
Function that will be registered as an inplace callback function.
|
||||
It will be called when answering from local data.
|
||||
|
||||
:param qinfo: query_info struct;
|
||||
:param qstate: module qstate. None;
|
||||
:param rep: reply_info struct;
|
||||
@@ -126,7 +151,14 @@ The callback function's prototype is the following:
|
||||
reply. It can be populated with EDNS options;
|
||||
:param region: region to allocate temporary data. Needs to be used when we
|
||||
want to append a new option to opt_list_out.
|
||||
:param **kwargs: Dictionary that may contain parameters added in a future
|
||||
release. Current parameters:
|
||||
``repinfo``: Reply information for a communication point (comm_reply).
|
||||
It is None when the callback happens in the mesh
|
||||
states(modules).
|
||||
|
||||
:return: True on success, False on failure.
|
||||
|
||||
"""
|
||||
|
||||
.. note:: The function's name is irrelevant.
|
||||
@@ -148,9 +180,12 @@ The callback function's prototype is the following:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
def inplace_servfail_callback(qinfo, qstate, rep, rcode, edns, opt_list_out, region):
|
||||
"""Function that will be registered as an inplace callback function.
|
||||
def inplace_servfail_callback(qinfo, qstate, rep, rcode, edns, opt_list_out,
|
||||
region, **kwargs):
|
||||
"""
|
||||
Function that will be registered as an inplace callback function.
|
||||
It will be called when answering with SERVFAIL.
|
||||
|
||||
:param qinfo: query_info struct;
|
||||
:param qstate: module qstate. If not None the relevant opt_lists are
|
||||
available here;
|
||||
@@ -163,7 +198,17 @@ The callback function's prototype is the following:
|
||||
reply. It can be populated with EDNS options;
|
||||
:param region: region to allocate temporary data. Needs to be used when we
|
||||
want to append a new option to opt_list_out.
|
||||
:param **kwargs: Dictionary that may contain parameters added in a future
|
||||
release. Current parameters:
|
||||
``repinfo``: Reply information for a communication point (comm_reply).
|
||||
It is None when the callback happens in the mesh
|
||||
states(modules).
|
||||
|
||||
:return: True on success, False on failure.
|
||||
|
||||
For demonstration purposes we want to reply with an empty EDNS code '65003'
|
||||
and log the IP address(es) of the client(s).
|
||||
|
||||
"""
|
||||
|
||||
.. note:: The function's name is irrelevant.
|
||||
|
||||
@@ -6,18 +6,18 @@
|
||||
Copyright (c) 2016, NLnet Labs.
|
||||
|
||||
This software is open source.
|
||||
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
|
||||
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
|
||||
* Neither the name of the organization nor the names of its
|
||||
contributors may be used to endorse or promote products derived from this
|
||||
software without specific prior written permission.
|
||||
@@ -43,6 +43,8 @@
|
||||
# This query returns SERVFAIL as the txt record of bogus.nlnetlabs.nl is
|
||||
# intentionally bogus. The reply will contain an empty EDNS option
|
||||
# with option code 65003.
|
||||
# Unbound will also log the source address(es) of the client(s) that made
|
||||
# the request.
|
||||
# (unbound needs to be validating for this example to work)
|
||||
|
||||
# Useful functions:
|
||||
@@ -70,9 +72,11 @@
|
||||
|
||||
|
||||
def inplace_reply_callback(qinfo, qstate, rep, rcode, edns, opt_list_out,
|
||||
region):
|
||||
"""Function that will be registered as an inplace callback function.
|
||||
region, **kwargs):
|
||||
"""
|
||||
Function that will be registered as an inplace callback function.
|
||||
It will be called when answering with a resolved query.
|
||||
|
||||
:param qinfo: query_info struct;
|
||||
:param qstate: module qstate. It contains the available opt_lists; It
|
||||
SHOULD NOT be altered;
|
||||
@@ -84,16 +88,25 @@ def inplace_reply_callback(qinfo, qstate, rep, rcode, edns, opt_list_out,
|
||||
reply. It can be populated with EDNS options;
|
||||
:param region: region to allocate temporary data. Needs to be used when we
|
||||
want to append a new option to opt_list_out.
|
||||
:param **kwargs: Dictionary that may contain parameters added in a future
|
||||
release. Current parameters:
|
||||
``repinfo``: Reply information for a communication point (comm_reply).
|
||||
It is None when the callback happens in the mesh
|
||||
states(modules).
|
||||
|
||||
:return: True on success, False on failure.
|
||||
|
||||
"""
|
||||
log_info("python: called back while replying.")
|
||||
return True
|
||||
|
||||
|
||||
def inplace_cache_callback(qinfo, qstate, rep, rcode, edns, opt_list_out,
|
||||
region):
|
||||
"""Function that will be registered as an inplace callback function.
|
||||
region, **kwargs):
|
||||
"""
|
||||
Function that will be registered as an inplace callback function.
|
||||
It will be called when answering from the cache.
|
||||
|
||||
:param qinfo: query_info struct;
|
||||
:param qstate: module qstate. None;
|
||||
:param rep: reply_info struct;
|
||||
@@ -105,10 +118,17 @@ def inplace_cache_callback(qinfo, qstate, rep, rcode, edns, opt_list_out,
|
||||
reply. It can be populated with EDNS options;
|
||||
:param region: region to allocate temporary data. Needs to be used when we
|
||||
want to append a new option to opt_list_out.
|
||||
:param **kwargs: Dictionary that may contain parameters added in a future
|
||||
release. Current parameters:
|
||||
``repinfo``: Reply information for a communication point (comm_reply).
|
||||
It is None when the callback happens in the mesh
|
||||
states(modules).
|
||||
|
||||
:return: True on success, False on failure.
|
||||
|
||||
For demonstration purposes we want to see if EDNS option 65002 is present
|
||||
and reply with a new value.
|
||||
|
||||
"""
|
||||
log_info("python: called back while answering from cache.")
|
||||
# Inspect the incoming EDNS options.
|
||||
@@ -134,9 +154,11 @@ def inplace_cache_callback(qinfo, qstate, rep, rcode, edns, opt_list_out,
|
||||
|
||||
|
||||
def inplace_local_callback(qinfo, qstate, rep, rcode, edns, opt_list_out,
|
||||
region):
|
||||
"""Function that will be registered as an inplace callback function.
|
||||
region, **kwargs):
|
||||
"""
|
||||
Function that will be registered as an inplace callback function.
|
||||
It will be called when answering from local data.
|
||||
|
||||
:param qinfo: query_info struct;
|
||||
:param qstate: module qstate. None;
|
||||
:param rep: reply_info struct;
|
||||
@@ -148,7 +170,14 @@ def inplace_local_callback(qinfo, qstate, rep, rcode, edns, opt_list_out,
|
||||
reply. It can be populated with EDNS options;
|
||||
:param region: region to allocate temporary data. Needs to be used when we
|
||||
want to append a new option to opt_list_out.
|
||||
:param **kwargs: Dictionary that may contain parameters added in a future
|
||||
release. Current parameters:
|
||||
``repinfo``: Reply information for a communication point (comm_reply).
|
||||
It is None when the callback happens in the mesh
|
||||
states(modules).
|
||||
|
||||
:return: True on success, False on failure.
|
||||
|
||||
"""
|
||||
log_info("python: called back while replying with local data or chaos"
|
||||
" reply.")
|
||||
@@ -156,9 +185,11 @@ def inplace_local_callback(qinfo, qstate, rep, rcode, edns, opt_list_out,
|
||||
|
||||
|
||||
def inplace_servfail_callback(qinfo, qstate, rep, rcode, edns, opt_list_out,
|
||||
region):
|
||||
"""Function that will be registered as an inplace callback function.
|
||||
region, **kwargs):
|
||||
"""
|
||||
Function that will be registered as an inplace callback function.
|
||||
It will be called when answering with SERVFAIL.
|
||||
|
||||
:param qinfo: query_info struct;
|
||||
:param qstate: module qstate. If not None the relevant opt_lists are
|
||||
available here;
|
||||
@@ -171,23 +202,62 @@ def inplace_servfail_callback(qinfo, qstate, rep, rcode, edns, opt_list_out,
|
||||
reply. It can be populated with EDNS options;
|
||||
:param region: region to allocate temporary data. Needs to be used when we
|
||||
want to append a new option to opt_list_out.
|
||||
:param **kwargs: Dictionary that may contain parameters added in a future
|
||||
release. Current parameters:
|
||||
``repinfo``: Reply information for a communication point (comm_reply).
|
||||
It is None when the callback happens in the mesh
|
||||
states(modules).
|
||||
|
||||
:return: True on success, False on failure.
|
||||
|
||||
For demonstration purposes we want to reply with an empty EDNS code '65003'.
|
||||
For demonstration purposes we want to reply with an empty EDNS code '65003'
|
||||
and log the IP address(es) of the client(s).
|
||||
|
||||
"""
|
||||
log_info("python: called back while servfail.")
|
||||
# Append the example ENDS option
|
||||
b = bytearray.fromhex("")
|
||||
edns_opt_list_append(opt_list_out, 65003, b, region)
|
||||
|
||||
# Log the client(s) IP address(es)
|
||||
comm_reply = kwargs['repinfo']
|
||||
if comm_reply:
|
||||
# If it is not None this callback was called before the query reached
|
||||
# the mesh states(modules). There is only one client associated with
|
||||
# this query.
|
||||
addr = comm_reply.addr
|
||||
port = comm_reply.port
|
||||
addr_family = comm_reply.family
|
||||
log_info("python: Client IP: {}({}), port: {}"
|
||||
"".format(addr, addr_family, port))
|
||||
else:
|
||||
# If it is not None this callback was called while the query is in the
|
||||
# mesh states(modules). In this case they may be multiple clients
|
||||
# waiting for this query.
|
||||
# The following code is the same as with the resip.py example.
|
||||
rl = qstate.mesh_info.reply_list
|
||||
while (rl):
|
||||
if rl.query_reply:
|
||||
q = rl.query_reply
|
||||
log_info("python: Client IP: {}({}), port: {}"
|
||||
"".format(q.addr, q.family, q.port))
|
||||
rl = rl.next
|
||||
|
||||
|
||||
return True
|
||||
|
||||
|
||||
def init_standard(id, env):
|
||||
"""New version of the init function.
|
||||
"""
|
||||
New version of the init function.
|
||||
|
||||
The function's signature is the same as the C counterpart and allows for
|
||||
extra functionality during init.
|
||||
|
||||
..note:: This function is preferred by unbound over the old init function.
|
||||
..note:: The previously accessible configuration options can now be found in
|
||||
env.cgf.
|
||||
|
||||
"""
|
||||
log_info("python: inited script {}".format(env.cfg.python_script))
|
||||
|
||||
@@ -215,11 +285,14 @@ def init_standard(id, env):
|
||||
|
||||
|
||||
def init(id, cfg):
|
||||
"""Previous version init function.
|
||||
"""
|
||||
Previous version of the init function.
|
||||
|
||||
..note:: This function is still supported for backwards compatibility when
|
||||
the init_standard function is missing. When init_standard is
|
||||
present this function SHOULD be omitted to avoid confusion to the
|
||||
reader.
|
||||
|
||||
"""
|
||||
return True
|
||||
|
||||
|
||||
+10
-10
@@ -47,7 +47,7 @@ def deinit(id): return True
|
||||
def inform_super(id, qstate, superqstate, qdata): return True
|
||||
|
||||
def operate(id, event, qstate, qdata):
|
||||
print "Operate", event,"state:",qstate
|
||||
print("Operate {} state: {}".format(event, qstate))
|
||||
|
||||
# Please note that if this module blocks, by moving to the validator
|
||||
# to validate or iterator to lookup or spawn a subquery to look up,
|
||||
@@ -61,14 +61,14 @@ def operate(id, event, qstate, qdata):
|
||||
msg = DNSMessage(qstate.qinfo.qname_str, RR_TYPE_TXT, RR_CLASS_IN, PKT_QR | PKT_RA | PKT_AA)
|
||||
#append RR
|
||||
if (qstate.qinfo.qtype == RR_TYPE_TXT) or (qstate.qinfo.qtype == RR_TYPE_ANY):
|
||||
rl = qstate.mesh_info.reply_list
|
||||
while (rl):
|
||||
if rl.query_reply:
|
||||
q = rl.query_reply
|
||||
# The TTL of 0 is mandatory, otherwise it ends up in
|
||||
# the cache, and is returned to other IP addresses.
|
||||
msg.answer.append("%s 0 IN TXT \"%s %d (%s)\"" % (qstate.qinfo.qname_str, q.addr,q.port,q.family))
|
||||
rl = rl.next
|
||||
rl = qstate.mesh_info.reply_list
|
||||
while (rl):
|
||||
if rl.query_reply:
|
||||
q = rl.query_reply
|
||||
# The TTL of 0 is mandatory, otherwise it ends up in
|
||||
# the cache, and is returned to other IP addresses.
|
||||
msg.answer.append("%s 0 IN TXT \"%s %d (%s)\"" % (qstate.qinfo.qname_str, q.addr,q.port,q.family))
|
||||
rl = rl.next
|
||||
|
||||
#set qstate.return_msg
|
||||
if not msg.set_return_msg(qstate):
|
||||
@@ -90,7 +90,7 @@ def operate(id, event, qstate, qdata):
|
||||
log_info("pythonmod: iterator module done")
|
||||
qstate.ext_state[id] = MODULE_FINISHED
|
||||
return True
|
||||
|
||||
|
||||
log_err("pythonmod: bad event")
|
||||
qstate.ext_state[id] = MODULE_ERROR
|
||||
return True
|
||||
|
||||
+14
-7
@@ -574,7 +574,7 @@ struct module_env {
|
||||
struct outbound_entry* (*send_query)(struct query_info* qinfo,
|
||||
uint16_t flags, int dnssec, int want_dnssec, int nocaps,
|
||||
struct sockaddr_storage* addr, socklen_t addrlen,
|
||||
uint8_t* zone, size_t zonelen, int ssl_upstream,
|
||||
uint8_t* zone, size_t zonelen, int ssl_upstream, char* tls_auth_name,
|
||||
struct module_qstate* q);
|
||||
void (*detach_subs)(struct module_qstate* qstate);
|
||||
int (*attach_sub)(struct module_qstate* qstate,
|
||||
@@ -883,7 +883,7 @@ struct config_file {
|
||||
struct config_strlist* local_zones_nodefault;
|
||||
struct config_strlist* local_data;
|
||||
int remote_control_enable;
|
||||
struct config_strlist* control_ifs;
|
||||
struct config_strlist_head control_ifs;
|
||||
int control_port;
|
||||
char* server_key_file;
|
||||
char* server_cert_file;
|
||||
@@ -1365,11 +1365,12 @@ int edns_opt_list_append(struct edns_option** list, uint16_t code, size_t len,
|
||||
int python_inplace_cb_reply_generic(struct query_info* qinfo,
|
||||
struct module_qstate* qstate, struct reply_info* rep, int rcode,
|
||||
struct edns_data* edns, struct edns_option** opt_list_out,
|
||||
struct regional* region, int id, void* python_callback)
|
||||
struct comm_reply* repinfo, struct regional* region, int id,
|
||||
void* python_callback)
|
||||
{
|
||||
PyObject *func, *py_edns, *py_qstate, *py_opt_list_out, *py_qinfo;
|
||||
PyObject *py_rep, *py_region;
|
||||
PyObject *result;
|
||||
PyObject *py_rep, *py_repinfo, *py_region;
|
||||
PyObject *py_args, *py_kwargs, *result;
|
||||
int res = 0;
|
||||
|
||||
PyGILState_STATE gstate = PyGILState_Ensure();
|
||||
@@ -1381,15 +1382,21 @@ int edns_opt_list_append(struct edns_option** list, uint16_t code, size_t len,
|
||||
SWIGTYPE_p_p_edns_option, 0);
|
||||
py_qinfo = SWIG_NewPointerObj((void*) qinfo, SWIGTYPE_p_query_info, 0);
|
||||
py_rep = SWIG_NewPointerObj((void*) rep, SWIGTYPE_p_reply_info, 0);
|
||||
py_repinfo = SWIG_NewPointerObj((void*) repinfo, SWIGTYPE_p_comm_reply, 0);
|
||||
py_region = SWIG_NewPointerObj((void*) region, SWIGTYPE_p_regional, 0);
|
||||
result = PyObject_CallFunction(func, "OOOiOOO", py_qinfo, py_qstate,
|
||||
py_rep, rcode, py_edns, py_opt_list_out, py_region);
|
||||
py_args = Py_BuildValue("(OOOiOOO)", py_qinfo, py_qstate, py_rep,
|
||||
rcode, py_edns, py_opt_list_out, py_region);
|
||||
py_kwargs = Py_BuildValue("{s:O}", "repinfo", py_repinfo);
|
||||
result = PyObject_Call(func, py_args, py_kwargs);
|
||||
Py_XDECREF(py_edns);
|
||||
Py_XDECREF(py_qstate);
|
||||
Py_XDECREF(py_opt_list_out);
|
||||
Py_XDECREF(py_qinfo);
|
||||
Py_XDECREF(py_rep);
|
||||
Py_XDECREF(py_repinfo);
|
||||
Py_XDECREF(py_region);
|
||||
Py_XDECREF(py_args);
|
||||
Py_XDECREF(py_kwargs);
|
||||
if (result) {
|
||||
res = PyInt_AsLong(result);
|
||||
}
|
||||
|
||||
@@ -72,5 +72,6 @@ size_t pythonmod_get_mem(struct module_env* env, int id);
|
||||
int python_inplace_cb_reply_generic(struct query_info* qinfo,
|
||||
struct module_qstate* qstate, struct reply_info* rep, int rcode,
|
||||
struct edns_data* edns, struct edns_option** opt_list_out,
|
||||
struct regional* region, int id, void* python_callback);
|
||||
struct comm_reply* repinfo, struct regional* region, int id,
|
||||
void* python_callback);
|
||||
#endif /* PYTHONMOD_H */
|
||||
|
||||
+4
-3
@@ -172,7 +172,7 @@ respip_action_cfg(struct respip_set* set, const char* ipstr,
|
||||
if(!(node=respip_find_or_create(set, ipstr, 1)))
|
||||
return 0;
|
||||
if(node->action != respip_none) {
|
||||
log_warn("duplicate response-ip action for '%s', overridden.",
|
||||
verbose(VERB_QUERY, "duplicate response-ip action for '%s', overridden.",
|
||||
ipstr);
|
||||
}
|
||||
if(strcmp(actnstr, "deny") == 0)
|
||||
@@ -611,8 +611,9 @@ make_new_reply_info(const struct reply_info* rep, struct regional* region,
|
||||
* EDNS0 OPT RR in the additional section appended on sending it out),
|
||||
* so the total number of RRsets is an_numrrsets. */
|
||||
new_rep = construct_reply_info_base(region, rep->flags,
|
||||
rep->qdcount, rep->ttl, rep->prefetch_ttl, an_numrrsets,
|
||||
0, 0, an_numrrsets, sec_status_insecure);
|
||||
rep->qdcount, rep->ttl, rep->prefetch_ttl,
|
||||
rep->serve_expired_ttl, an_numrrsets, 0, 0, an_numrrsets,
|
||||
sec_status_insecure);
|
||||
if(!new_rep)
|
||||
return NULL;
|
||||
if(!reply_info_alloc_rrset_keys(new_rep, NULL, region))
|
||||
|
||||
+694
-103
File diff suppressed because it is too large
Load Diff
+66
-4
@@ -77,6 +77,10 @@ struct auth_zones {
|
||||
rbtree_type xtree;
|
||||
/** do we have downstream enabled */
|
||||
int have_downstream;
|
||||
/** number of queries upstream */
|
||||
size_t num_query_up;
|
||||
/** number of queries downstream */
|
||||
size_t num_query_down;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -122,6 +126,10 @@ struct auth_zone {
|
||||
/** for upstream: this zone answers queries that unbound intends to
|
||||
* send upstream. */
|
||||
int for_upstream;
|
||||
/** zone has been deleted */
|
||||
int zone_deleted;
|
||||
/** deletelist pointer, unused normally except during delete */
|
||||
struct auth_zone* delete_next;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -214,8 +222,14 @@ struct auth_xfer {
|
||||
* Hold the lock to access this member (and the serial).
|
||||
*/
|
||||
int notify_received;
|
||||
/** true if the notify_received has a serial number */
|
||||
int notify_has_serial;
|
||||
/** serial number of the notify */
|
||||
uint32_t notify_serial;
|
||||
/** the list of masters for checking notifies. This list is
|
||||
* empty on start, and a copy of the list from the probe_task when
|
||||
* it is done looking them up. */
|
||||
struct auth_master* allow_notify_list;
|
||||
|
||||
/* protected by the lock on the structure, information about
|
||||
* the loaded authority zone. */
|
||||
@@ -292,6 +306,12 @@ struct auth_probe {
|
||||
struct auth_master* lookup_target;
|
||||
/** are we looking up A or AAAA, first A, then AAAA (if ip6 enabled) */
|
||||
int lookup_aaaa;
|
||||
/** we only want to do lookups for making config work (for notify),
|
||||
* don't proceed with UDP SOA probe queries */
|
||||
int only_lookup;
|
||||
/** we have seen a new lease this scan, because one of the masters
|
||||
* replied with the current SOA serial version */
|
||||
int have_new_lease;
|
||||
|
||||
/** once notified, or the timeout has been reached. a scan starts. */
|
||||
/** the scan specific target (notify source), or NULL if none */
|
||||
@@ -400,6 +420,9 @@ struct auth_master {
|
||||
int http;
|
||||
/** use IXFR for this master */
|
||||
int ixfr;
|
||||
/** this is an allow notify member, the master can send notifies
|
||||
* to us, but we don't send SOA probes, or zone transfer from it */
|
||||
int allow_notify;
|
||||
/** use ssl for channel */
|
||||
int ssl;
|
||||
/** the port number (for urls) */
|
||||
@@ -489,12 +512,13 @@ int auth_zones_lookup(struct auth_zones* az, struct query_info* qinfo,
|
||||
* @param qinfo: query info (parsed).
|
||||
* @param edns: edns info (parsed).
|
||||
* @param buf: buffer with query ID and flags, also for reply.
|
||||
* @param repinfo: reply information for a communication point.
|
||||
* @param temp: temporary storage region.
|
||||
* @return false if not answered
|
||||
*/
|
||||
int auth_zones_answer(struct auth_zones* az, struct module_env* env,
|
||||
struct query_info* qinfo, struct edns_data* edns, struct sldns_buffer* buf,
|
||||
struct regional* temp);
|
||||
struct query_info* qinfo, struct edns_data* edns,
|
||||
struct comm_reply* repinfo, struct sldns_buffer* buf, struct regional* temp);
|
||||
|
||||
/**
|
||||
* Find the auth zone that is above the given qname.
|
||||
@@ -541,9 +565,45 @@ int auth_zone_set_fallback(struct auth_zone* z, char* fallbackstr);
|
||||
int auth_zones_can_fallback(struct auth_zones* az, uint8_t* nm, size_t nmlen,
|
||||
uint16_t dclass);
|
||||
|
||||
/** process notify for auth zones.
|
||||
* first checks the access list. Then processes the notify. This starts
|
||||
* the probe sequence or it notes the serial number (if any)
|
||||
* @param az: auth zones structure.
|
||||
* @param env: module env of the worker that is handling the notify. it will
|
||||
* pick up the task probe (or transfer), unless already in progress by
|
||||
* another worker.
|
||||
* @param nm: name of the zone. Uncompressed. from query.
|
||||
* @param nmlen: length of name.
|
||||
* @param dclass: class of zone.
|
||||
* @param addr: source address of notify
|
||||
* @param addrlen: length of addr.
|
||||
* @param has_serial: if true, the notify has a serial attached.
|
||||
* @param serial: the serial number, if has_serial is true.
|
||||
* @param refused: is set to true on failure to note refused access.
|
||||
* @return fail on failures (refused is false) and when access is
|
||||
* denied (refused is true). True when processed.
|
||||
*/
|
||||
int auth_zones_notify(struct auth_zones* az, struct module_env* env,
|
||||
uint8_t* nm, size_t nmlen, uint16_t dclass,
|
||||
struct sockaddr_storage* addr, socklen_t addrlen, int has_serial,
|
||||
uint32_t serial, int* refused);
|
||||
|
||||
/** process notify packet and read serial number from SOA.
|
||||
* returns 0 if no soa record in the notify */
|
||||
int auth_zone_parse_notify_serial(struct sldns_buffer* pkt, uint32_t *serial);
|
||||
|
||||
/** for the zone and if not already going, starts the probe sequence.
|
||||
* false if zone cannot be found. This is like a notify arrived and was
|
||||
* accepted for that zone. */
|
||||
int auth_zones_startprobesequence(struct auth_zones* az,
|
||||
struct module_env* env, uint8_t* nm, size_t nmlen, uint16_t dclass);
|
||||
|
||||
/** read auth zone from zonefile. caller must lock zone. false on failure */
|
||||
int auth_zone_read_zonefile(struct auth_zone* z);
|
||||
|
||||
/** find serial number of zone or false if none (no SOA record) */
|
||||
int auth_zone_get_serial(struct auth_zone* z, uint32_t* serial);
|
||||
|
||||
/** compare auth_zones for sorted rbtree */
|
||||
int auth_zone_cmp(const void* z1, const void* z2);
|
||||
|
||||
@@ -587,10 +647,12 @@ int auth_xfer_transfer_http_callback(struct comm_point* c, void* arg, int err,
|
||||
void auth_xfer_probe_timer_callback(void* arg);
|
||||
/** mesh callback for task_probe on lookup of host names */
|
||||
void auth_xfer_probe_lookup_callback(void* arg, int rcode,
|
||||
struct sldns_buffer* buf, enum sec_status sec, char* why_bogus);
|
||||
struct sldns_buffer* buf, enum sec_status sec, char* why_bogus,
|
||||
int was_ratelimited);
|
||||
/** mesh callback for task_transfer on lookup of host names */
|
||||
void auth_xfer_transfer_lookup_callback(void* arg, int rcode,
|
||||
struct sldns_buffer* buf, enum sec_status sec, char* why_bogus);
|
||||
struct sldns_buffer* buf, enum sec_status sec, char* why_bogus,
|
||||
int was_ratelimited);
|
||||
|
||||
/*
|
||||
* Compares two 32-bit serial numbers as defined in RFC1982. Returns
|
||||
|
||||
Vendored
+52
@@ -108,6 +108,48 @@ store_rrsets(struct module_env* env, struct reply_info* rep, time_t now,
|
||||
}
|
||||
}
|
||||
|
||||
/** delete message from message cache */
|
||||
void
|
||||
msg_cache_remove(struct module_env* env, uint8_t* qname, size_t qnamelen,
|
||||
uint16_t qtype, uint16_t qclass, uint16_t flags)
|
||||
{
|
||||
struct query_info k;
|
||||
hashvalue_type h;
|
||||
|
||||
k.qname = qname;
|
||||
k.qname_len = qnamelen;
|
||||
k.qtype = qtype;
|
||||
k.qclass = qclass;
|
||||
k.local_alias = NULL;
|
||||
h = query_info_hash(&k, flags);
|
||||
slabhash_remove(env->msg_cache, h, &k);
|
||||
}
|
||||
|
||||
/** remove servfail msg cache entry */
|
||||
static void
|
||||
msg_del_servfail(struct module_env* env, struct query_info* qinfo,
|
||||
uint32_t flags)
|
||||
{
|
||||
struct msgreply_entry* e;
|
||||
/* see if the entry is servfail, and then remove it, so that
|
||||
* lookups move from the cacheresponse stage to the recursionresponse
|
||||
* stage */
|
||||
e = msg_cache_lookup(env, qinfo->qname, qinfo->qname_len,
|
||||
qinfo->qtype, qinfo->qclass, flags, 0, 0);
|
||||
if(!e) return;
|
||||
/* we don't check for the ttl here, also expired servfail entries
|
||||
* are removed. If the user uses serve-expired, they would still be
|
||||
* used to answer from cache */
|
||||
if(FLAGS_GET_RCODE(((struct reply_info*)e->entry.data)->flags)
|
||||
!= LDNS_RCODE_SERVFAIL) {
|
||||
lock_rw_unlock(&e->entry.lock);
|
||||
return;
|
||||
}
|
||||
lock_rw_unlock(&e->entry.lock);
|
||||
msg_cache_remove(env, qinfo->qname, qinfo->qname_len, qinfo->qtype,
|
||||
qinfo->qclass, flags);
|
||||
}
|
||||
|
||||
void
|
||||
dns_cache_store_msg(struct module_env* env, struct query_info* qinfo,
|
||||
hashvalue_type hash, struct reply_info* rep, time_t leeway, int pside,
|
||||
@@ -132,6 +174,12 @@ dns_cache_store_msg(struct module_env* env, struct query_info* qinfo,
|
||||
* which could be useful for delegation information */
|
||||
verbose(VERB_ALGO, "TTL 0: dropped msg from cache");
|
||||
free(rep);
|
||||
/* if the message is SERVFAIL in cache, remove that SERVFAIL,
|
||||
* so that the TTL 0 response can be returned for future
|
||||
* responses (i.e. don't get answered by the servfail from
|
||||
* cache, but instead go to recursion to get this TTL0
|
||||
* response). */
|
||||
msg_del_servfail(env, qinfo, flags);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -499,6 +547,7 @@ tomsg(struct module_env* env, struct query_info* q, struct reply_info* r,
|
||||
if(r->prefetch_ttl > now)
|
||||
msg->rep->prefetch_ttl = r->prefetch_ttl - now;
|
||||
else msg->rep->prefetch_ttl = PREFETCH_TTL_CALC(msg->rep->ttl);
|
||||
msg->rep->serve_expired_ttl = msg->rep->ttl + SERVE_EXPIRED_TTL;
|
||||
msg->rep->security = r->security;
|
||||
msg->rep->an_numrrsets = r->an_numrrsets;
|
||||
msg->rep->ns_numrrsets = r->ns_numrrsets;
|
||||
@@ -553,6 +602,7 @@ rrset_msg(struct ub_packed_rrset_key* rrset, struct regional* region,
|
||||
msg->rep->qdcount = 1;
|
||||
msg->rep->ttl = d->ttl - now;
|
||||
msg->rep->prefetch_ttl = PREFETCH_TTL_CALC(msg->rep->ttl);
|
||||
msg->rep->serve_expired_ttl = msg->rep->ttl + SERVE_EXPIRED_TTL;
|
||||
msg->rep->security = sec_status_unchecked;
|
||||
msg->rep->an_numrrsets = 1;
|
||||
msg->rep->ns_numrrsets = 0;
|
||||
@@ -590,6 +640,7 @@ synth_dname_msg(struct ub_packed_rrset_key* rrset, struct regional* region,
|
||||
msg->rep->qdcount = 1;
|
||||
msg->rep->ttl = d->ttl - now;
|
||||
msg->rep->prefetch_ttl = PREFETCH_TTL_CALC(msg->rep->ttl);
|
||||
msg->rep->serve_expired_ttl = msg->rep->ttl + SERVE_EXPIRED_TTL;
|
||||
msg->rep->security = sec_status_unchecked;
|
||||
msg->rep->an_numrrsets = 1;
|
||||
msg->rep->ns_numrrsets = 0;
|
||||
@@ -648,6 +699,7 @@ synth_dname_msg(struct ub_packed_rrset_key* rrset, struct regional* region,
|
||||
newd->rr_ttl[0] = newd->ttl;
|
||||
msg->rep->ttl = newd->ttl;
|
||||
msg->rep->prefetch_ttl = PREFETCH_TTL_CALC(newd->ttl);
|
||||
msg->rep->serve_expired_ttl = newd->ttl + SERVE_EXPIRED_TTL;
|
||||
sldns_write_uint16(newd->rr_data[0], newlen);
|
||||
memmove(newd->rr_data[0] + sizeof(uint16_t), newname, newlen);
|
||||
msg->rep->an_numrrsets ++;
|
||||
|
||||
Vendored
+12
@@ -238,4 +238,16 @@ struct msgreply_entry* msg_cache_lookup(struct module_env* env,
|
||||
uint8_t* qname, size_t qnamelen, uint16_t qtype, uint16_t qclass,
|
||||
uint16_t flags, time_t now, int wr);
|
||||
|
||||
/**
|
||||
* Remove entry from the message cache. For unwanted entries.
|
||||
* @param env: with message cache.
|
||||
* @param qname: query name, in wireformat
|
||||
* @param qnamelen: length of qname, including terminating 0.
|
||||
* @param qtype: query type, host order.
|
||||
* @param qclass: query class, host order.
|
||||
* @param flags: flags
|
||||
*/
|
||||
void msg_cache_remove(struct module_env* env, uint8_t* qname, size_t qnamelen,
|
||||
uint16_t qtype, uint16_t qclass, uint16_t flags);
|
||||
|
||||
#endif /* SERVICES_CACHE_DNS_H */
|
||||
|
||||
Vendored
+44
-20
@@ -215,6 +215,18 @@ static int infra_ratelimit_cfg_insert(struct infra_cache* infra,
|
||||
return 1;
|
||||
}
|
||||
|
||||
/** setup domain limits tree (0 on failure) */
|
||||
static int
|
||||
setup_domain_limits(struct infra_cache* infra, struct config_file* cfg)
|
||||
{
|
||||
name_tree_init(&infra->domain_limits);
|
||||
if(!infra_ratelimit_cfg_insert(infra, cfg)) {
|
||||
return 0;
|
||||
}
|
||||
name_tree_init_parents(&infra->domain_limits);
|
||||
return 1;
|
||||
}
|
||||
|
||||
struct infra_cache*
|
||||
infra_create(struct config_file* cfg)
|
||||
{
|
||||
@@ -230,23 +242,19 @@ infra_create(struct config_file* cfg)
|
||||
return NULL;
|
||||
}
|
||||
infra->host_ttl = cfg->host_ttl;
|
||||
name_tree_init(&infra->domain_limits);
|
||||
infra_dp_ratelimit = cfg->ratelimit;
|
||||
if(cfg->ratelimit != 0) {
|
||||
infra->domain_rates = slabhash_create(cfg->ratelimit_slabs,
|
||||
INFRA_HOST_STARTSIZE, cfg->ratelimit_size,
|
||||
&rate_sizefunc, &rate_compfunc, &rate_delkeyfunc,
|
||||
&rate_deldatafunc, NULL);
|
||||
if(!infra->domain_rates) {
|
||||
infra_delete(infra);
|
||||
return NULL;
|
||||
}
|
||||
/* insert config data into ratelimits */
|
||||
if(!infra_ratelimit_cfg_insert(infra, cfg)) {
|
||||
infra_delete(infra);
|
||||
return NULL;
|
||||
}
|
||||
name_tree_init_parents(&infra->domain_limits);
|
||||
infra->domain_rates = slabhash_create(cfg->ratelimit_slabs,
|
||||
INFRA_HOST_STARTSIZE, cfg->ratelimit_size,
|
||||
&rate_sizefunc, &rate_compfunc, &rate_delkeyfunc,
|
||||
&rate_deldatafunc, NULL);
|
||||
if(!infra->domain_rates) {
|
||||
infra_delete(infra);
|
||||
return NULL;
|
||||
}
|
||||
/* insert config data into ratelimits */
|
||||
if(!setup_domain_limits(infra, cfg)) {
|
||||
infra_delete(infra);
|
||||
return NULL;
|
||||
}
|
||||
infra_ip_ratelimit = cfg->ip_ratelimit;
|
||||
infra->client_ip_rates = slabhash_create(cfg->ip_ratelimit_slabs,
|
||||
@@ -287,12 +295,28 @@ infra_adjust(struct infra_cache* infra, struct config_file* cfg)
|
||||
if(!infra)
|
||||
return infra_create(cfg);
|
||||
infra->host_ttl = cfg->host_ttl;
|
||||
infra_dp_ratelimit = cfg->ratelimit;
|
||||
infra_ip_ratelimit = cfg->ip_ratelimit;
|
||||
maxmem = cfg->infra_cache_numhosts * (sizeof(struct infra_key)+
|
||||
sizeof(struct infra_data)+INFRA_BYTES_NAME);
|
||||
if(maxmem != slabhash_get_size(infra->hosts) ||
|
||||
cfg->infra_cache_slabs != infra->hosts->size) {
|
||||
/* divide cachesize by slabs and multiply by slabs, because if the
|
||||
* cachesize is not an even multiple of slabs, that is the resulting
|
||||
* size of the slabhash */
|
||||
if(!slabhash_is_size(infra->hosts, maxmem, cfg->infra_cache_slabs) ||
|
||||
!slabhash_is_size(infra->domain_rates, cfg->ratelimit_size,
|
||||
cfg->ratelimit_slabs) ||
|
||||
!slabhash_is_size(infra->client_ip_rates, cfg->ip_ratelimit_size,
|
||||
cfg->ip_ratelimit_slabs)) {
|
||||
infra_delete(infra);
|
||||
infra = infra_create(cfg);
|
||||
} else {
|
||||
/* reapply domain limits */
|
||||
traverse_postorder(&infra->domain_limits, domain_limit_free,
|
||||
NULL);
|
||||
if(!setup_domain_limits(infra, cfg)) {
|
||||
infra_delete(infra);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
return infra;
|
||||
}
|
||||
@@ -989,8 +1013,8 @@ int infra_ip_ratelimit_inc(struct infra_cache* infra,
|
||||
char client_ip[128];
|
||||
addr_to_str((struct sockaddr_storage *)&repinfo->addr,
|
||||
repinfo->addrlen, client_ip, sizeof(client_ip));
|
||||
verbose(VERB_OPS, "ratelimit exceeded %s %d", client_ip,
|
||||
infra_ip_ratelimit);
|
||||
verbose(VERB_OPS, "ip_ratelimit exceeded %s %d",
|
||||
client_ip, infra_ip_ratelimit);
|
||||
}
|
||||
return (max <= infra_ip_ratelimit);
|
||||
}
|
||||
|
||||
Vendored
+4
-2
@@ -81,8 +81,8 @@ void rrset_cache_delete(struct rrset_cache* r)
|
||||
struct rrset_cache* rrset_cache_adjust(struct rrset_cache *r,
|
||||
struct config_file* cfg, struct alloc_cache* alloc)
|
||||
{
|
||||
if(!r || !cfg || cfg->rrset_cache_slabs != r->table.size ||
|
||||
cfg->rrset_cache_size != slabhash_get_size(&r->table))
|
||||
if(!r || !cfg || !slabhash_is_size(&r->table, cfg->rrset_cache_size,
|
||||
cfg->rrset_cache_slabs))
|
||||
{
|
||||
rrset_cache_delete(r);
|
||||
r = rrset_cache_create(cfg, alloc);
|
||||
@@ -255,9 +255,11 @@ void rrset_cache_update_wildcard(struct rrset_cache* rrset_cache,
|
||||
wc_dname[1] = (uint8_t)'*';
|
||||
memmove(wc_dname+2, ce, ce_len);
|
||||
|
||||
free(rrset->rk.dname);
|
||||
rrset->rk.dname_len = ce_len + 2;
|
||||
rrset->rk.dname = (uint8_t*)memdup(wc_dname, rrset->rk.dname_len);
|
||||
if(!rrset->rk.dname) {
|
||||
alloc_special_release(alloc, rrset);
|
||||
log_err("memdup failure in rrset_cache_update_wildcard");
|
||||
return;
|
||||
}
|
||||
|
||||
+45
-18
@@ -564,7 +564,8 @@ create_udp_sock(int family, int socktype, struct sockaddr* addr,
|
||||
/* detect freebsd jail with no ipv6 permission */
|
||||
if(family==AF_INET6 && errno==EINVAL)
|
||||
*noproto = 1;
|
||||
else if(errno != EADDRINUSE) {
|
||||
else if(errno != EADDRINUSE &&
|
||||
!(errno == EACCES && verbosity < 4 && !listen)) {
|
||||
log_err_addr("can't bind socket", strerror(errno),
|
||||
(struct sockaddr_storage*)addr, addrlen);
|
||||
}
|
||||
@@ -572,7 +573,8 @@ create_udp_sock(int family, int socktype, struct sockaddr* addr,
|
||||
close(s);
|
||||
#else /* USE_WINSOCK */
|
||||
if(WSAGetLastError() != WSAEADDRINUSE &&
|
||||
WSAGetLastError() != WSAEADDRNOTAVAIL) {
|
||||
WSAGetLastError() != WSAEADDRNOTAVAIL &&
|
||||
!(WSAGetLastError() == WSAEACCES && verbosity < 4 && !listen)) {
|
||||
log_err_addr("can't bind socket",
|
||||
wsa_strerror(WSAGetLastError()),
|
||||
(struct sockaddr_storage*)addr, addrlen);
|
||||
@@ -1056,6 +1058,26 @@ set_recvpktinfo(int s, int family)
|
||||
return 1;
|
||||
}
|
||||
|
||||
/** see if interface is ssl, its port number == the ssl port number */
|
||||
static int
|
||||
if_is_ssl(const char* ifname, const char* port, int ssl_port,
|
||||
struct config_strlist* tls_additional_port)
|
||||
{
|
||||
struct config_strlist* s;
|
||||
char* p = strchr(ifname, '@');
|
||||
if(!p && atoi(port) == ssl_port)
|
||||
return 1;
|
||||
if(p && atoi(p+1) == ssl_port)
|
||||
return 1;
|
||||
for(s = tls_additional_port; s; s = s->next) {
|
||||
if(p && atoi(p+1) == atoi(s->str))
|
||||
return 1;
|
||||
if(!p && atoi(port) == atoi(s->str))
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper for ports_open. Creates one interface (or NULL for default).
|
||||
* @param ifname: The interface ip address.
|
||||
@@ -1069,6 +1091,7 @@ set_recvpktinfo(int s, int family)
|
||||
* @param rcv: receive buffer size for UDP
|
||||
* @param snd: send buffer size for UDP
|
||||
* @param ssl_port: ssl service port number
|
||||
* @param tls_additional_port: list of additional ssl service port numbers.
|
||||
* @param reuseport: try to set SO_REUSEPORT if nonNULL and true.
|
||||
* set to false on exit if reuseport failed due to no kernel support.
|
||||
* @param transparent: set IP_TRANSPARENT socket option.
|
||||
@@ -1081,8 +1104,10 @@ set_recvpktinfo(int s, int family)
|
||||
static int
|
||||
ports_create_if(const char* ifname, int do_auto, int do_udp, int do_tcp,
|
||||
struct addrinfo *hints, const char* port, struct listen_port** list,
|
||||
size_t rcv, size_t snd, int ssl_port, int* reuseport, int transparent,
|
||||
int tcp_mss, int freebind, int use_systemd, int dnscrypt_port)
|
||||
size_t rcv, size_t snd, int ssl_port,
|
||||
struct config_strlist* tls_additional_port, int* reuseport,
|
||||
int transparent, int tcp_mss, int freebind, int use_systemd,
|
||||
int dnscrypt_port)
|
||||
{
|
||||
int s, noip6=0;
|
||||
#ifdef USE_DNSCRYPT
|
||||
@@ -1146,9 +1171,8 @@ ports_create_if(const char* ifname, int do_auto, int do_udp, int do_tcp,
|
||||
}
|
||||
}
|
||||
if(do_tcp) {
|
||||
int is_ssl = ((strchr(ifname, '@') &&
|
||||
atoi(strchr(ifname, '@')+1) == ssl_port) ||
|
||||
(!strchr(ifname, '@') && atoi(port) == ssl_port));
|
||||
int is_ssl = if_is_ssl(ifname, port, ssl_port,
|
||||
tls_additional_port);
|
||||
if((s = make_sock_port(SOCK_STREAM, ifname, port, hints, 1,
|
||||
&noip6, 0, 0, reuseport, transparent, tcp_mss,
|
||||
freebind, use_systemd)) == -1) {
|
||||
@@ -1194,7 +1218,8 @@ listen_cp_insert(struct comm_point* c, struct listen_dnsport* front)
|
||||
|
||||
struct listen_dnsport*
|
||||
listen_create(struct comm_base* base, struct listen_port* ports,
|
||||
size_t bufsize, int tcp_accept_count, void* sslctx,
|
||||
size_t bufsize, int tcp_accept_count, int tcp_idle_timeout,
|
||||
struct tcl_list* tcp_conn_limit, void* sslctx,
|
||||
struct dt_env* dtenv, comm_point_callback_type* cb, void *cb_arg)
|
||||
{
|
||||
struct listen_dnsport* front = (struct listen_dnsport*)
|
||||
@@ -1221,10 +1246,12 @@ listen_create(struct comm_base* base, struct listen_port* ports,
|
||||
else if(ports->ftype == listen_type_tcp ||
|
||||
ports->ftype == listen_type_tcp_dnscrypt)
|
||||
cp = comm_point_create_tcp(base, ports->fd,
|
||||
tcp_accept_count, bufsize, cb, cb_arg);
|
||||
tcp_accept_count, tcp_idle_timeout,
|
||||
tcp_conn_limit, bufsize, cb, cb_arg);
|
||||
else if(ports->ftype == listen_type_ssl) {
|
||||
cp = comm_point_create_tcp(base, ports->fd,
|
||||
tcp_accept_count, bufsize, cb, cb_arg);
|
||||
tcp_accept_count, tcp_idle_timeout,
|
||||
tcp_conn_limit, bufsize, cb, cb_arg);
|
||||
cp->ssl = sslctx;
|
||||
} else if(ports->ftype == listen_type_udpancil ||
|
||||
ports->ftype == listen_type_udpancil_dnscrypt)
|
||||
@@ -1334,8 +1361,8 @@ listening_ports_open(struct config_file* cfg, int* reuseport)
|
||||
do_auto, cfg->do_udp, do_tcp,
|
||||
&hints, portbuf, &list,
|
||||
cfg->so_rcvbuf, cfg->so_sndbuf,
|
||||
cfg->ssl_port, reuseport,
|
||||
cfg->ip_transparent,
|
||||
cfg->ssl_port, cfg->tls_additional_port,
|
||||
reuseport, cfg->ip_transparent,
|
||||
cfg->tcp_mss, cfg->ip_freebind, cfg->use_systemd,
|
||||
cfg->dnscrypt_port)) {
|
||||
listening_ports_free(list);
|
||||
@@ -1348,8 +1375,8 @@ listening_ports_open(struct config_file* cfg, int* reuseport)
|
||||
do_auto, cfg->do_udp, do_tcp,
|
||||
&hints, portbuf, &list,
|
||||
cfg->so_rcvbuf, cfg->so_sndbuf,
|
||||
cfg->ssl_port, reuseport,
|
||||
cfg->ip_transparent,
|
||||
cfg->ssl_port, cfg->tls_additional_port,
|
||||
reuseport, cfg->ip_transparent,
|
||||
cfg->tcp_mss, cfg->ip_freebind, cfg->use_systemd,
|
||||
cfg->dnscrypt_port)) {
|
||||
listening_ports_free(list);
|
||||
@@ -1364,8 +1391,8 @@ listening_ports_open(struct config_file* cfg, int* reuseport)
|
||||
if(!ports_create_if(cfg->ifs[i], 0, cfg->do_udp,
|
||||
do_tcp, &hints, portbuf, &list,
|
||||
cfg->so_rcvbuf, cfg->so_sndbuf,
|
||||
cfg->ssl_port, reuseport,
|
||||
cfg->ip_transparent,
|
||||
cfg->ssl_port, cfg->tls_additional_port,
|
||||
reuseport, cfg->ip_transparent,
|
||||
cfg->tcp_mss, cfg->ip_freebind, cfg->use_systemd,
|
||||
cfg->dnscrypt_port)) {
|
||||
listening_ports_free(list);
|
||||
@@ -1378,8 +1405,8 @@ listening_ports_open(struct config_file* cfg, int* reuseport)
|
||||
if(!ports_create_if(cfg->ifs[i], 0, cfg->do_udp,
|
||||
do_tcp, &hints, portbuf, &list,
|
||||
cfg->so_rcvbuf, cfg->so_sndbuf,
|
||||
cfg->ssl_port, reuseport,
|
||||
cfg->ip_transparent,
|
||||
cfg->ssl_port, cfg->tls_additional_port,
|
||||
reuseport, cfg->ip_transparent,
|
||||
cfg->tcp_mss, cfg->ip_freebind, cfg->use_systemd,
|
||||
cfg->dnscrypt_port)) {
|
||||
listening_ports_free(list);
|
||||
|
||||
@@ -47,6 +47,7 @@ struct listen_list;
|
||||
struct config_file;
|
||||
struct addrinfo;
|
||||
struct sldns_buffer;
|
||||
struct tcl_list;
|
||||
|
||||
/**
|
||||
* Listening for queries structure.
|
||||
@@ -137,6 +138,8 @@ void listening_ports_free(struct listen_port* list);
|
||||
* @param bufsize: size of datagram buffer.
|
||||
* @param tcp_accept_count: max number of simultaneous TCP connections
|
||||
* from clients.
|
||||
* @param tcp_idle_timeout: idle timeout for TCP connections in msec.
|
||||
* @param tcp_conn_limit: TCP connection limit info.
|
||||
* @param sslctx: nonNULL if ssl context.
|
||||
* @param dtenv: nonNULL if dnstap enabled.
|
||||
* @param cb: callback function when a request arrives. It is passed
|
||||
@@ -145,9 +148,10 @@ void listening_ports_free(struct listen_port* list);
|
||||
* @return: the malloced listening structure, ready for use. NULL on error.
|
||||
*/
|
||||
struct listen_dnsport* listen_create(struct comm_base* base,
|
||||
struct listen_port* ports, size_t bufsize, int tcp_accept_count,
|
||||
void* sslctx, struct dt_env *dtenv, comm_point_callback_type* cb,
|
||||
void* cb_arg);
|
||||
struct listen_port* ports, size_t bufsize,
|
||||
int tcp_accept_count, int tcp_idle_timeout,
|
||||
struct tcl_list* tcp_conn_limit, void* sslctx,
|
||||
struct dt_env *dtenv, comm_point_callback_type* cb, void* cb_arg);
|
||||
|
||||
/**
|
||||
* delete the listening structure
|
||||
|
||||
+88
-40
@@ -1146,8 +1146,9 @@ void local_zones_print(struct local_zones* zones)
|
||||
/** encode answer consisting of 1 rrset */
|
||||
static int
|
||||
local_encode(struct query_info* qinfo, struct module_env* env,
|
||||
struct edns_data* edns, sldns_buffer* buf, struct regional* temp,
|
||||
struct ub_packed_rrset_key* rrset, int ansec, int rcode)
|
||||
struct edns_data* edns, struct comm_reply* repinfo, sldns_buffer* buf,
|
||||
struct regional* temp, struct ub_packed_rrset_key* rrset, int ansec,
|
||||
int rcode)
|
||||
{
|
||||
struct reply_info rep;
|
||||
uint16_t udpsize;
|
||||
@@ -1165,23 +1166,22 @@ local_encode(struct query_info* qinfo, struct module_env* env,
|
||||
edns->udp_size = EDNS_ADVERTISED_SIZE;
|
||||
edns->ext_rcode = 0;
|
||||
edns->bits &= EDNS_DO;
|
||||
if(!inplace_cb_reply_local_call(env, qinfo, NULL, &rep, rcode, edns, temp)
|
||||
|| !reply_info_answer_encode(qinfo, &rep,
|
||||
*(uint16_t*)sldns_buffer_begin(buf),
|
||||
sldns_buffer_read_u16_at(buf, 2),
|
||||
buf, 0, 0, temp, udpsize, edns,
|
||||
(int)(edns->bits&EDNS_DO), 0))
|
||||
if(!inplace_cb_reply_local_call(env, qinfo, NULL, &rep, rcode, edns,
|
||||
repinfo, temp) || !reply_info_answer_encode(qinfo, &rep,
|
||||
*(uint16_t*)sldns_buffer_begin(buf), sldns_buffer_read_u16_at(buf, 2),
|
||||
buf, 0, 0, temp, udpsize, edns, (int)(edns->bits&EDNS_DO), 0)) {
|
||||
error_encode(buf, (LDNS_RCODE_SERVFAIL|BIT_AA), qinfo,
|
||||
*(uint16_t*)sldns_buffer_begin(buf),
|
||||
sldns_buffer_read_u16_at(buf, 2), edns);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/** encode local error answer */
|
||||
static void
|
||||
local_error_encode(struct query_info* qinfo, struct module_env* env,
|
||||
struct edns_data* edns, sldns_buffer* buf, struct regional* temp,
|
||||
int rcode, int r)
|
||||
struct edns_data* edns, struct comm_reply* repinfo, sldns_buffer* buf,
|
||||
struct regional* temp, int rcode, int r)
|
||||
{
|
||||
edns->edns_version = EDNS_ADVERTISED_VERSION;
|
||||
edns->udp_size = EDNS_ADVERTISED_SIZE;
|
||||
@@ -1189,7 +1189,7 @@ local_error_encode(struct query_info* qinfo, struct module_env* env,
|
||||
edns->bits &= EDNS_DO;
|
||||
|
||||
if(!inplace_cb_reply_local_call(env, qinfo, NULL, NULL,
|
||||
rcode, edns, temp))
|
||||
rcode, edns, repinfo, temp))
|
||||
edns->opt_list = NULL;
|
||||
error_encode(buf, r, qinfo, *(uint16_t*)sldns_buffer_begin(buf),
|
||||
sldns_buffer_read_u16_at(buf, 2), edns);
|
||||
@@ -1310,7 +1310,8 @@ find_tag_datas(struct query_info* qinfo, struct config_strlist* list,
|
||||
/** answer local data match */
|
||||
static int
|
||||
local_data_answer(struct local_zone* z, struct module_env* env,
|
||||
struct query_info* qinfo, struct edns_data* edns, sldns_buffer* buf,
|
||||
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)
|
||||
@@ -1339,7 +1340,7 @@ local_data_answer(struct local_zone* z, struct module_env* env,
|
||||
* chain. */
|
||||
if(qinfo->local_alias)
|
||||
return 1;
|
||||
return local_encode(qinfo, env, edns, buf, temp,
|
||||
return local_encode(qinfo, env, edns, repinfo, buf, temp,
|
||||
&r, 1, LDNS_RCODE_NOERROR);
|
||||
}
|
||||
}
|
||||
@@ -1374,29 +1375,60 @@ local_data_answer(struct local_zone* z, struct module_env* env,
|
||||
struct ub_packed_rrset_key r = *lr->rrset;
|
||||
r.rk.dname = qinfo->qname;
|
||||
r.rk.dname_len = qinfo->qname_len;
|
||||
return local_encode(qinfo, env, edns, buf, temp, &r, 1,
|
||||
return local_encode(qinfo, env, edns, repinfo, buf, temp, &r, 1,
|
||||
LDNS_RCODE_NOERROR);
|
||||
}
|
||||
return local_encode(qinfo, env, edns, buf, temp, lr->rrset, 1,
|
||||
return local_encode(qinfo, env, edns, repinfo, buf, temp, lr->rrset, 1,
|
||||
LDNS_RCODE_NOERROR);
|
||||
}
|
||||
|
||||
/**
|
||||
* See if the local zone does not cover the name, eg. the name is not
|
||||
* in the zone and the zone is transparent */
|
||||
static int
|
||||
local_zone_does_not_cover(struct local_zone* z, struct query_info* qinfo,
|
||||
int labs)
|
||||
{
|
||||
struct local_data key;
|
||||
struct local_data* ld = NULL;
|
||||
struct local_rrset* lr = NULL;
|
||||
if(z->type == local_zone_always_transparent)
|
||||
return 1;
|
||||
if(z->type != local_zone_transparent
|
||||
&& z->type != local_zone_typetransparent
|
||||
&& z->type != local_zone_inform)
|
||||
return 0;
|
||||
key.node.key = &key;
|
||||
key.name = qinfo->qname;
|
||||
key.namelen = qinfo->qname_len;
|
||||
key.namelabs = labs;
|
||||
ld = (struct local_data*)rbtree_search(&z->data, &key.node);
|
||||
if(z->type == local_zone_transparent || z->type == local_zone_inform)
|
||||
return (ld == NULL);
|
||||
if(ld)
|
||||
lr = local_data_find_type(ld, qinfo->qtype, 1);
|
||||
/* local_zone_typetransparent */
|
||||
return (lr == NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* answer in case where no exact match is found
|
||||
* @param z: zone for query
|
||||
* @param env: module environment
|
||||
* @param qinfo: query
|
||||
* @param edns: edns from query
|
||||
* Answer in case where no exact match is found.
|
||||
* @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 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
|
||||
* @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, sldns_buffer* buf,
|
||||
struct regional* temp, struct local_data* ld, enum localzone_type lz_type)
|
||||
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)
|
||||
{
|
||||
if(lz_type == local_zone_deny || lz_type == local_zone_inform_deny) {
|
||||
/** no reply at all, signal caller by clearing buffer. */
|
||||
@@ -1405,7 +1437,7 @@ lz_zone_answer(struct local_zone* z, struct module_env* env,
|
||||
return 1;
|
||||
} else if(lz_type == local_zone_refuse
|
||||
|| lz_type == local_zone_always_refuse) {
|
||||
local_error_encode(qinfo, env, edns, buf, temp,
|
||||
local_error_encode(qinfo, env, edns, repinfo, buf, temp,
|
||||
LDNS_RCODE_REFUSED, (LDNS_RCODE_REFUSED|BIT_AA));
|
||||
return 1;
|
||||
} else if(lz_type == local_zone_static ||
|
||||
@@ -1421,9 +1453,9 @@ lz_zone_answer(struct local_zone* z, struct module_env* env,
|
||||
int rcode = (ld || lz_type == local_zone_redirect)?
|
||||
LDNS_RCODE_NOERROR:LDNS_RCODE_NXDOMAIN;
|
||||
if(z->soa)
|
||||
return local_encode(qinfo, env, edns, buf, temp,
|
||||
return local_encode(qinfo, env, edns, repinfo, buf, temp,
|
||||
z->soa, 0, rcode);
|
||||
local_error_encode(qinfo, env, edns, buf, temp, rcode,
|
||||
local_error_encode(qinfo, env, edns, repinfo, buf, temp, rcode,
|
||||
(rcode|BIT_AA));
|
||||
return 1;
|
||||
} else if(lz_type == local_zone_typetransparent
|
||||
@@ -1438,9 +1470,9 @@ lz_zone_answer(struct local_zone* z, struct module_env* env,
|
||||
if(ld && ld->rrsets) {
|
||||
int rcode = LDNS_RCODE_NOERROR;
|
||||
if(z->soa)
|
||||
return local_encode(qinfo, env, edns, buf, temp,
|
||||
return local_encode(qinfo, env, edns, repinfo, buf, temp,
|
||||
z->soa, 0, rcode);
|
||||
local_error_encode(qinfo, env, edns, buf, temp, rcode,
|
||||
local_error_encode(qinfo, env, edns, repinfo, buf, temp, rcode,
|
||||
(rcode|BIT_AA));
|
||||
return 1;
|
||||
}
|
||||
@@ -1459,7 +1491,7 @@ lz_inform_print(struct local_zone* z, struct query_info* qinfo,
|
||||
uint16_t port = ntohs(((struct sockaddr_in*)&repinfo->addr)->sin_port);
|
||||
dname_str(z->name, zname);
|
||||
addr_to_str(&repinfo->addr, repinfo->addrlen, ip, sizeof(ip));
|
||||
snprintf(txt, sizeof(txt), "%s inform %s@%u", zname, ip,
|
||||
snprintf(txt, sizeof(txt), "%s %s %s@%u", zname, local_zone_type2str(z->type), ip,
|
||||
(unsigned)port);
|
||||
log_nametypeclass(0, txt, qinfo->qname, qinfo->qtype, qinfo->qclass);
|
||||
}
|
||||
@@ -1543,10 +1575,6 @@ local_zones_answer(struct local_zones* zones, struct module_env* env,
|
||||
(z = local_zones_lookup(view->local_zones,
|
||||
qinfo->qname, qinfo->qname_len, labs,
|
||||
qinfo->qclass, qinfo->qtype))) {
|
||||
if(z->type != local_zone_noview)
|
||||
verbose(VERB_ALGO,
|
||||
"using localzone from view: %s",
|
||||
view->name);
|
||||
lock_rw_rdlock(&z->lock);
|
||||
lzt = z->type;
|
||||
}
|
||||
@@ -1554,10 +1582,24 @@ local_zones_answer(struct local_zones* zones, struct module_env* env,
|
||||
lock_rw_unlock(&z->lock);
|
||||
z = NULL;
|
||||
}
|
||||
if(z && (lzt == local_zone_transparent ||
|
||||
lzt == local_zone_typetransparent ||
|
||||
lzt == local_zone_inform ||
|
||||
lzt == local_zone_always_transparent) &&
|
||||
local_zone_does_not_cover(z, qinfo, labs)) {
|
||||
lock_rw_unlock(&z->lock);
|
||||
z = NULL;
|
||||
}
|
||||
if(view->local_zones && !z && !view->isfirst){
|
||||
lock_rw_unlock(&view->lock);
|
||||
return 0;
|
||||
}
|
||||
if(z && verbosity >= VERB_ALGO) {
|
||||
char zname[255+1];
|
||||
dname_str(z->name, zname);
|
||||
verbose(VERB_ALGO, "using localzone %s %s from view %s",
|
||||
zname, local_zone_type2str(lzt), view->name);
|
||||
}
|
||||
lock_rw_unlock(&view->lock);
|
||||
}
|
||||
if(!z) {
|
||||
@@ -1570,27 +1612,33 @@ local_zones_answer(struct local_zones* zones, struct module_env* env,
|
||||
return 0;
|
||||
}
|
||||
lock_rw_rdlock(&z->lock);
|
||||
|
||||
lzt = lz_type(taglist, taglen, z->taglist, z->taglen,
|
||||
tagactions, tagactionssize, z->type, repinfo,
|
||||
z->override_tree, &tag, tagname, num_tags);
|
||||
lock_rw_unlock(&zones->lock);
|
||||
if(z && verbosity >= VERB_ALGO) {
|
||||
char zname[255+1];
|
||||
dname_str(z->name, zname);
|
||||
verbose(VERB_ALGO, "using localzone %s %s", zname,
|
||||
local_zone_type2str(lzt));
|
||||
}
|
||||
}
|
||||
if((lzt == local_zone_inform || lzt == local_zone_inform_deny)
|
||||
&& repinfo)
|
||||
if((env->cfg->log_local_actions ||
|
||||
lzt == local_zone_inform || lzt == local_zone_inform_deny)
|
||||
&& repinfo)
|
||||
lz_inform_print(z, qinfo, repinfo);
|
||||
|
||||
if(lzt != local_zone_always_refuse
|
||||
&& lzt != local_zone_always_transparent
|
||||
&& lzt != local_zone_always_nxdomain
|
||||
&& local_data_answer(z, env, qinfo, edns, buf, temp, labs, &ld, lzt,
|
||||
tag, tag_datas, tag_datas_size, tagname, num_tags)) {
|
||||
&& local_data_answer(z, env, qinfo, edns, repinfo, buf, temp, labs,
|
||||
&ld, lzt, tag, tag_datas, tag_datas_size, tagname, num_tags)) {
|
||||
lock_rw_unlock(&z->lock);
|
||||
/* We should tell the caller that encode is deferred if we found
|
||||
* a local alias. */
|
||||
return !qinfo->local_alias;
|
||||
}
|
||||
r = lz_zone_answer(z, env, qinfo, edns, buf, temp, ld, lzt);
|
||||
r = lz_zone_answer(z, env, qinfo, edns, repinfo, buf, temp, ld, lzt);
|
||||
lock_rw_unlock(&z->lock);
|
||||
return r && !qinfo->local_alias; /* see above */
|
||||
}
|
||||
|
||||
+53
-22
@@ -55,6 +55,7 @@
|
||||
#include "util/fptr_wlist.h"
|
||||
#include "util/alloc.h"
|
||||
#include "util/config_file.h"
|
||||
#include "util/edns.h"
|
||||
#include "sldns/sbuffer.h"
|
||||
#include "sldns/wire2str.h"
|
||||
#include "services/localzone.h"
|
||||
@@ -385,7 +386,7 @@ void mesh_new_client(struct mesh_area* mesh, struct query_info* qinfo,
|
||||
if(!s) {
|
||||
log_err("mesh_state_create: out of memory; SERVFAIL");
|
||||
if(!inplace_cb_reply_servfail_call(mesh->env, qinfo, NULL, NULL,
|
||||
LDNS_RCODE_SERVFAIL, edns, mesh->env->scratch))
|
||||
LDNS_RCODE_SERVFAIL, edns, rep, mesh->env->scratch))
|
||||
edns->opt_list = NULL;
|
||||
error_encode(rep->c->buffer, LDNS_RCODE_SERVFAIL,
|
||||
qinfo, qid, qflags, edns);
|
||||
@@ -401,7 +402,7 @@ void mesh_new_client(struct mesh_area* mesh, struct query_info* qinfo,
|
||||
if(!s->s.edns_opts_front_in) {
|
||||
log_err("mesh_state_create: out of memory; SERVFAIL");
|
||||
if(!inplace_cb_reply_servfail_call(mesh->env, qinfo, NULL,
|
||||
NULL, LDNS_RCODE_SERVFAIL, edns, mesh->env->scratch))
|
||||
NULL, LDNS_RCODE_SERVFAIL, edns, rep, mesh->env->scratch))
|
||||
edns->opt_list = NULL;
|
||||
error_encode(rep->c->buffer, LDNS_RCODE_SERVFAIL,
|
||||
qinfo, qid, qflags, edns);
|
||||
@@ -429,7 +430,7 @@ void mesh_new_client(struct mesh_area* mesh, struct query_info* qinfo,
|
||||
if(!mesh_state_add_reply(s, edns, rep, qid, qflags, qinfo)) {
|
||||
log_err("mesh_new_client: out of memory; SERVFAIL");
|
||||
if(!inplace_cb_reply_servfail_call(mesh->env, qinfo, &s->s,
|
||||
NULL, LDNS_RCODE_SERVFAIL, edns, mesh->env->scratch))
|
||||
NULL, LDNS_RCODE_SERVFAIL, edns, rep, mesh->env->scratch))
|
||||
edns->opt_list = NULL;
|
||||
error_encode(rep->c->buffer, LDNS_RCODE_SERVFAIL,
|
||||
qinfo, qid, qflags, edns);
|
||||
@@ -631,8 +632,8 @@ void mesh_report_reply(struct mesh_area* mesh, struct outbound_entry* e,
|
||||
mesh_run(mesh, e->qstate->mesh_info, event, e);
|
||||
}
|
||||
|
||||
struct mesh_state*
|
||||
mesh_state_create(struct module_env* env, struct query_info* qinfo,
|
||||
struct mesh_state*
|
||||
mesh_state_create(struct module_env* env, struct query_info* qinfo,
|
||||
struct respip_client_info* cinfo, uint16_t qflags, int prime,
|
||||
int valrec)
|
||||
{
|
||||
@@ -693,6 +694,7 @@ mesh_state_create(struct module_env* env, struct query_info* qinfo,
|
||||
mstate->s.no_cache_lookup = 0;
|
||||
mstate->s.no_cache_store = 0;
|
||||
mstate->s.need_refetch = 0;
|
||||
mstate->s.was_ratelimited = 0;
|
||||
|
||||
/* init modules */
|
||||
for(i=0; i<env->mesh->mods.num; i++) {
|
||||
@@ -736,10 +738,11 @@ mesh_state_cleanup(struct mesh_state* mstate)
|
||||
comm_point_drop_reply(&rep->query_reply);
|
||||
mesh->num_reply_addrs--;
|
||||
}
|
||||
for(cb=mstate->cb_list; cb; cb=cb->next) {
|
||||
while((cb = mstate->cb_list)!=NULL) {
|
||||
mstate->cb_list = cb->next;
|
||||
fptr_ok(fptr_whitelist_mesh_cb(cb->cb));
|
||||
(*cb->cb)(cb->cb_arg, LDNS_RCODE_SERVFAIL, NULL,
|
||||
sec_status_unchecked, NULL);
|
||||
sec_status_unchecked, NULL, 0);
|
||||
mesh->num_reply_addrs--;
|
||||
}
|
||||
}
|
||||
@@ -967,30 +970,33 @@ mesh_do_callback(struct mesh_state* m, int rcode, struct reply_info* rep,
|
||||
{
|
||||
int secure;
|
||||
char* reason = NULL;
|
||||
/* bogus messages are not made into servfail, sec_status passed
|
||||
int was_ratelimited = m->s.was_ratelimited;
|
||||
/* bogus messages are not made into servfail, sec_status passed
|
||||
* to the callback function */
|
||||
if(rep && rep->security == sec_status_secure)
|
||||
secure = 1;
|
||||
else secure = 0;
|
||||
if(!rep && rcode == LDNS_RCODE_NOERROR)
|
||||
rcode = LDNS_RCODE_SERVFAIL;
|
||||
if(!rcode && rep->security == sec_status_bogus) {
|
||||
if(!(reason = errinf_to_str(&m->s)))
|
||||
if(!rcode && (rep->security == sec_status_bogus ||
|
||||
rep->security == sec_status_secure_sentinel_fail)) {
|
||||
if(!(reason = errinf_to_str_bogus(&m->s)))
|
||||
rcode = LDNS_RCODE_SERVFAIL;
|
||||
}
|
||||
/* send the reply */
|
||||
if(rcode) {
|
||||
if(rcode == LDNS_RCODE_SERVFAIL) {
|
||||
if(!inplace_cb_reply_servfail_call(m->s.env, &m->s.qinfo, &m->s,
|
||||
rep, rcode, &r->edns, m->s.region))
|
||||
rep, rcode, &r->edns, NULL, m->s.region))
|
||||
r->edns.opt_list = NULL;
|
||||
} else {
|
||||
if(!inplace_cb_reply_call(m->s.env, &m->s.qinfo, &m->s, rep, rcode,
|
||||
&r->edns, m->s.region))
|
||||
&r->edns, NULL, m->s.region))
|
||||
r->edns.opt_list = NULL;
|
||||
}
|
||||
fptr_ok(fptr_whitelist_mesh_cb(r->cb));
|
||||
(*r->cb)(r->cb_arg, rcode, r->buf, sec_status_unchecked, NULL);
|
||||
(*r->cb)(r->cb_arg, rcode, r->buf, sec_status_unchecked, NULL,
|
||||
was_ratelimited);
|
||||
} else {
|
||||
size_t udp_size = r->edns.udp_size;
|
||||
sldns_buffer_clear(r->buf);
|
||||
@@ -1000,7 +1006,7 @@ mesh_do_callback(struct mesh_state* m, int rcode, struct reply_info* rep,
|
||||
r->edns.bits &= EDNS_DO;
|
||||
|
||||
if(!inplace_cb_reply_call(m->s.env, &m->s.qinfo, &m->s, rep,
|
||||
LDNS_RCODE_NOERROR, &r->edns, m->s.region) ||
|
||||
LDNS_RCODE_NOERROR, &r->edns, NULL, m->s.region) ||
|
||||
!reply_info_answer_encode(&m->s.qinfo, rep, r->qid,
|
||||
r->qflags, r->buf, 0, 1,
|
||||
m->s.env->scratch, udp_size, &r->edns,
|
||||
@@ -1008,11 +1014,11 @@ mesh_do_callback(struct mesh_state* m, int rcode, struct reply_info* rep,
|
||||
{
|
||||
fptr_ok(fptr_whitelist_mesh_cb(r->cb));
|
||||
(*r->cb)(r->cb_arg, LDNS_RCODE_SERVFAIL, r->buf,
|
||||
sec_status_unchecked, NULL);
|
||||
sec_status_unchecked, NULL, 0);
|
||||
} else {
|
||||
fptr_ok(fptr_whitelist_mesh_cb(r->cb));
|
||||
(*r->cb)(r->cb_arg, LDNS_RCODE_NOERROR, r->buf,
|
||||
rep->security, reason);
|
||||
rep->security, reason, was_ratelimited);
|
||||
}
|
||||
}
|
||||
free(reason);
|
||||
@@ -1040,7 +1046,8 @@ mesh_send_reply(struct mesh_state* m, int rcode, struct reply_info* rep,
|
||||
/* examine security status */
|
||||
if(m->s.env->need_to_validate && (!(r->qflags&BIT_CD) ||
|
||||
m->s.env->cfg->ignore_cd) && rep &&
|
||||
rep->security <= sec_status_bogus) {
|
||||
(rep->security <= sec_status_bogus ||
|
||||
rep->security == sec_status_secure_sentinel_fail)) {
|
||||
rcode = LDNS_RCODE_SERVFAIL;
|
||||
if(m->s.env->cfg->stat_extended)
|
||||
m->s.env->mesh->ans_bogus++;
|
||||
@@ -1077,11 +1084,11 @@ mesh_send_reply(struct mesh_state* m, int rcode, struct reply_info* rep,
|
||||
m->s.qinfo.local_alias = r->local_alias;
|
||||
if(rcode == LDNS_RCODE_SERVFAIL) {
|
||||
if(!inplace_cb_reply_servfail_call(m->s.env, &m->s.qinfo, &m->s,
|
||||
rep, rcode, &r->edns, m->s.region))
|
||||
rep, rcode, &r->edns, NULL, m->s.region))
|
||||
r->edns.opt_list = NULL;
|
||||
} else {
|
||||
if(!inplace_cb_reply_call(m->s.env, &m->s.qinfo, &m->s, rep, rcode,
|
||||
&r->edns, m->s.region))
|
||||
&r->edns, NULL, m->s.region))
|
||||
r->edns.opt_list = NULL;
|
||||
}
|
||||
error_encode(r->query_reply.c->buffer, rcode, &m->s.qinfo,
|
||||
@@ -1096,14 +1103,17 @@ mesh_send_reply(struct mesh_state* m, int rcode, struct reply_info* rep,
|
||||
m->s.qinfo.qname = r->qname;
|
||||
m->s.qinfo.local_alias = r->local_alias;
|
||||
if(!inplace_cb_reply_call(m->s.env, &m->s.qinfo, &m->s, rep,
|
||||
LDNS_RCODE_NOERROR, &r->edns, m->s.region) ||
|
||||
LDNS_RCODE_NOERROR, &r->edns, NULL, m->s.region) ||
|
||||
!apply_edns_options(&r->edns, &edns_bak,
|
||||
m->s.env->cfg, r->query_reply.c,
|
||||
m->s.region) ||
|
||||
!reply_info_answer_encode(&m->s.qinfo, rep, r->qid,
|
||||
r->qflags, r->query_reply.c->buffer, 0, 1,
|
||||
m->s.env->scratch, udp_size, &r->edns,
|
||||
(int)(r->edns.bits & EDNS_DO), secure))
|
||||
{
|
||||
if(!inplace_cb_reply_servfail_call(m->s.env, &m->s.qinfo, &m->s,
|
||||
rep, LDNS_RCODE_SERVFAIL, &r->edns, m->s.region))
|
||||
rep, LDNS_RCODE_SERVFAIL, &r->edns, NULL, m->s.region))
|
||||
r->edns.opt_list = NULL;
|
||||
error_encode(r->query_reply.c->buffer,
|
||||
LDNS_RCODE_SERVFAIL, &m->s.qinfo, r->qid,
|
||||
@@ -1145,6 +1155,15 @@ void mesh_query_done(struct mesh_state* mstate)
|
||||
struct mesh_cb* c;
|
||||
struct reply_info* rep = (mstate->s.return_msg?
|
||||
mstate->s.return_msg->rep:NULL);
|
||||
if((mstate->s.return_rcode == LDNS_RCODE_SERVFAIL ||
|
||||
(rep && FLAGS_GET_RCODE(rep->flags) == LDNS_RCODE_SERVFAIL))
|
||||
&& mstate->s.env->cfg->log_servfail
|
||||
&& !mstate->s.env->cfg->val_log_squelch) {
|
||||
char* err = errinf_to_str_servfail(&mstate->s);
|
||||
if(err)
|
||||
log_err("%s", err);
|
||||
free(err);
|
||||
}
|
||||
for(r = mstate->reply_list; r; r = r->next) {
|
||||
/* if a response-ip address block has been stored the
|
||||
* information should be logged for each client. */
|
||||
@@ -1167,7 +1186,17 @@ void mesh_query_done(struct mesh_state* mstate)
|
||||
}
|
||||
}
|
||||
mstate->replies_sent = 1;
|
||||
for(c = mstate->cb_list; c; c = c->next) {
|
||||
while((c = mstate->cb_list) != NULL) {
|
||||
/* take this cb off the list; so that the list can be
|
||||
* changed, eg. by adds from the callback routine */
|
||||
if(!mstate->reply_list && mstate->cb_list && !c->next) {
|
||||
/* was a reply state, not anymore */
|
||||
mstate->s.env->mesh->num_reply_states--;
|
||||
}
|
||||
mstate->cb_list = c->next;
|
||||
if(!mstate->reply_list && !mstate->cb_list &&
|
||||
mstate->super_set.count == 0)
|
||||
mstate->s.env->mesh->num_detached_states++;
|
||||
mesh_do_callback(mstate, mstate->s.return_rcode, rep, c);
|
||||
}
|
||||
}
|
||||
@@ -1184,6 +1213,8 @@ void mesh_walk_supers(struct mesh_area* mesh, struct mesh_state* mstate)
|
||||
mesh->mods.mod[ref->s->s.curmod]->inform_super));
|
||||
(*mesh->mods.mod[ref->s->s.curmod]->inform_super)(&mstate->s,
|
||||
ref->s->s.curmod, &ref->s->s);
|
||||
/* copy state that is always relevant to super */
|
||||
copy_state_to_super(&mstate->s, ref->s->s.curmod, &ref->s->s);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+5
-5
@@ -223,10 +223,11 @@ struct mesh_reply {
|
||||
|
||||
/**
|
||||
* Mesh result callback func.
|
||||
* called as func(cb_arg, rcode, buffer_with_reply, security, why_bogus);
|
||||
* called as func(cb_arg, rcode, buffer_with_reply, security, why_bogus,
|
||||
* was_ratelimited);
|
||||
*/
|
||||
typedef void (*mesh_cb_func_type)(void*, int, struct sldns_buffer*, enum sec_status,
|
||||
char*);
|
||||
typedef void (*mesh_cb_func_type)(void* cb_arg, int rcode, struct sldns_buffer*,
|
||||
enum sec_status, char* why_bogus, int was_ratelimited);
|
||||
|
||||
/**
|
||||
* Callback to result routine
|
||||
@@ -242,9 +243,8 @@ struct mesh_cb {
|
||||
uint16_t qflags;
|
||||
/** buffer for reply */
|
||||
struct sldns_buffer* buf;
|
||||
|
||||
/** callback routine for results. if rcode != 0 buf has message.
|
||||
* called as cb(cb_arg, rcode, buf, sec_state);
|
||||
* called as cb(cb_arg, rcode, buf, sec_state, why_bogus, was_ratelimited);
|
||||
*/
|
||||
mesh_cb_func_type cb;
|
||||
/** user arg for callback */
|
||||
|
||||
+106
-38
@@ -48,6 +48,7 @@
|
||||
#include "services/outside_network.h"
|
||||
#include "services/listen_dnsport.h"
|
||||
#include "services/cache/infra.h"
|
||||
#include "iterator/iterator.h"
|
||||
#include "util/data/msgparse.h"
|
||||
#include "util/data/msgreply.h"
|
||||
#include "util/data/msgencode.h"
|
||||
@@ -364,6 +365,27 @@ outnet_tcp_take_into_use(struct waiting_tcp* w, uint8_t* pkt, size_t pkt_len)
|
||||
comm_point_tcp_win_bio_cb(pend->c, pend->c->ssl);
|
||||
#endif
|
||||
pend->c->ssl_shake_state = comm_ssl_shake_write;
|
||||
if(w->tls_auth_name) {
|
||||
#ifdef HAVE_SSL
|
||||
(void)SSL_set_tlsext_host_name(pend->c->ssl, w->tls_auth_name);
|
||||
#endif
|
||||
}
|
||||
#ifdef HAVE_SSL_SET1_HOST
|
||||
if(w->tls_auth_name) {
|
||||
SSL_set_verify(pend->c->ssl, SSL_VERIFY_PEER, NULL);
|
||||
/* setting the hostname makes openssl verify the
|
||||
* host name in the x509 certificate in the
|
||||
* SSL connection*/
|
||||
if(!SSL_set1_host(pend->c->ssl, w->tls_auth_name)) {
|
||||
log_err("SSL_set1_host failed");
|
||||
pend->c->fd = s;
|
||||
SSL_free(pend->c->ssl);
|
||||
pend->c->ssl = NULL;
|
||||
comm_point_close(pend->c);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
#endif /* HAVE_SSL_SET1_HOST */
|
||||
}
|
||||
w->pkt = NULL;
|
||||
w->next_waiting = (void*)pend;
|
||||
@@ -851,6 +873,7 @@ serviced_node_del(rbnode_type* node, void* ATTR_UNUSED(arg))
|
||||
struct service_callback* p = sq->cblist, *np;
|
||||
free(sq->qbuf);
|
||||
free(sq->zone);
|
||||
free(sq->tls_auth_name);
|
||||
edns_opt_list_free(sq->opt_list);
|
||||
while(p) {
|
||||
np = p->next;
|
||||
@@ -1021,6 +1044,8 @@ udp_sockport(struct sockaddr_storage* addr, socklen_t addrlen, int pfxlen,
|
||||
int freebind = 0;
|
||||
struct sockaddr_in6 sa = *(struct sockaddr_in6*)addr;
|
||||
sa.sin6_port = (in_port_t)htons((uint16_t)port);
|
||||
sa.sin6_flowinfo = 0;
|
||||
sa.sin6_scope_id = 0;
|
||||
if(pfxlen != 0) {
|
||||
freebind = 1;
|
||||
sai6_putrandom(&sa, pfxlen, rnd);
|
||||
@@ -1243,6 +1268,13 @@ outnet_tcptimer(void* arg)
|
||||
} else {
|
||||
/* it was in use */
|
||||
struct pending_tcp* pend=(struct pending_tcp*)w->next_waiting;
|
||||
if(pend->c->ssl) {
|
||||
#ifdef HAVE_SSL
|
||||
SSL_shutdown(pend->c->ssl);
|
||||
SSL_free(pend->c->ssl);
|
||||
pend->c->ssl = NULL;
|
||||
#endif
|
||||
}
|
||||
comm_point_close(pend->c);
|
||||
pend->query = NULL;
|
||||
pend->next_free = outnet->tcp_free;
|
||||
@@ -1284,9 +1316,10 @@ pending_tcp_query(struct serviced_query* sq, sldns_buffer* packet,
|
||||
w->cb = callback;
|
||||
w->cb_arg = callback_arg;
|
||||
w->ssl_upstream = sq->ssl_upstream;
|
||||
w->tls_auth_name = sq->tls_auth_name;
|
||||
#ifndef S_SPLINT_S
|
||||
tv.tv_sec = timeout;
|
||||
tv.tv_usec = 0;
|
||||
tv.tv_sec = timeout/1000;
|
||||
tv.tv_usec = (timeout%1000)*1000;
|
||||
#endif
|
||||
comm_timer_set(w->timer, &tv);
|
||||
if(pend) {
|
||||
@@ -1357,8 +1390,8 @@ lookup_serviced(struct outside_network* outnet, sldns_buffer* buff, int dnssec,
|
||||
static struct serviced_query*
|
||||
serviced_create(struct outside_network* outnet, sldns_buffer* buff, int dnssec,
|
||||
int want_dnssec, int nocaps, int tcp_upstream, int ssl_upstream,
|
||||
struct sockaddr_storage* addr, socklen_t addrlen, uint8_t* zone,
|
||||
size_t zonelen, int qtype, struct edns_option* opt_list)
|
||||
char* tls_auth_name, struct sockaddr_storage* addr, socklen_t addrlen,
|
||||
uint8_t* zone, size_t zonelen, int qtype, struct edns_option* opt_list)
|
||||
{
|
||||
struct serviced_query* sq = (struct serviced_query*)malloc(sizeof(*sq));
|
||||
#ifdef UNBOUND_DEBUG
|
||||
@@ -1386,12 +1419,24 @@ serviced_create(struct outside_network* outnet, sldns_buffer* buff, int dnssec,
|
||||
sq->nocaps = nocaps;
|
||||
sq->tcp_upstream = tcp_upstream;
|
||||
sq->ssl_upstream = ssl_upstream;
|
||||
if(tls_auth_name) {
|
||||
sq->tls_auth_name = strdup(tls_auth_name);
|
||||
if(!sq->tls_auth_name) {
|
||||
free(sq->zone);
|
||||
free(sq->qbuf);
|
||||
free(sq);
|
||||
return NULL;
|
||||
}
|
||||
} else {
|
||||
sq->tls_auth_name = NULL;
|
||||
}
|
||||
memcpy(&sq->addr, addr, addrlen);
|
||||
sq->addrlen = addrlen;
|
||||
sq->opt_list = NULL;
|
||||
if(opt_list) {
|
||||
sq->opt_list = edns_opt_copy_alloc(opt_list);
|
||||
if(!sq->opt_list) {
|
||||
free(sq->tls_auth_name);
|
||||
free(sq->zone);
|
||||
free(sq->qbuf);
|
||||
free(sq);
|
||||
@@ -1784,7 +1829,12 @@ serviced_tcp_callback(struct comm_point* c, void* arg, int error,
|
||||
}
|
||||
if(sq->tcp_upstream || sq->ssl_upstream) {
|
||||
struct timeval now = *sq->outnet->now_tv;
|
||||
if(now.tv_sec > sq->last_sent_time.tv_sec ||
|
||||
if(error!=NETEVENT_NOERROR) {
|
||||
if(!infra_rtt_update(sq->outnet->infra, &sq->addr,
|
||||
sq->addrlen, sq->zone, sq->zonelen, sq->qtype,
|
||||
-1, sq->last_rtt, (time_t)now.tv_sec))
|
||||
log_err("out of memory in TCP exponential backoff.");
|
||||
} else if(now.tv_sec > sq->last_sent_time.tv_sec ||
|
||||
(now.tv_sec == sq->last_sent_time.tv_sec &&
|
||||
now.tv_usec > sq->last_sent_time.tv_usec)) {
|
||||
/* convert from microseconds to milliseconds */
|
||||
@@ -1794,7 +1844,7 @@ serviced_tcp_callback(struct comm_point* c, void* arg, int error,
|
||||
log_assert(roundtime >= 0);
|
||||
/* only store if less then AUTH_TIMEOUT seconds, it could be
|
||||
* huge due to system-hibernated and we woke up */
|
||||
if(roundtime < TCP_AUTH_QUERY_TIMEOUT*1000) {
|
||||
if(roundtime < 60000) {
|
||||
if(!infra_rtt_update(sq->outnet->infra, &sq->addr,
|
||||
sq->addrlen, sq->zone, sq->zonelen, sq->qtype,
|
||||
roundtime, sq->last_rtt, (time_t)now.tv_sec))
|
||||
@@ -1835,18 +1885,26 @@ serviced_tcp_initiate(struct serviced_query* sq, sldns_buffer* buff)
|
||||
static int
|
||||
serviced_tcp_send(struct serviced_query* sq, sldns_buffer* buff)
|
||||
{
|
||||
int vs, rtt;
|
||||
int vs, rtt, timeout;
|
||||
uint8_t edns_lame_known;
|
||||
if(!infra_host(sq->outnet->infra, &sq->addr, sq->addrlen, sq->zone,
|
||||
sq->zonelen, *sq->outnet->now_secs, &vs, &edns_lame_known,
|
||||
&rtt))
|
||||
return 0;
|
||||
sq->last_rtt = rtt;
|
||||
if(vs != -1)
|
||||
sq->status = serviced_query_TCP_EDNS;
|
||||
else sq->status = serviced_query_TCP;
|
||||
serviced_encode(sq, buff, sq->status == serviced_query_TCP_EDNS);
|
||||
sq->last_sent_time = *sq->outnet->now_tv;
|
||||
sq->pending = pending_tcp_query(sq, buff, TCP_AUTH_QUERY_TIMEOUT,
|
||||
if(sq->tcp_upstream || sq->ssl_upstream) {
|
||||
timeout = rtt;
|
||||
if(rtt >= UNKNOWN_SERVER_NICENESS && rtt < TCP_AUTH_QUERY_TIMEOUT)
|
||||
timeout = TCP_AUTH_QUERY_TIMEOUT;
|
||||
} else {
|
||||
timeout = TCP_AUTH_QUERY_TIMEOUT;
|
||||
}
|
||||
sq->pending = pending_tcp_query(sq, buff, timeout,
|
||||
serviced_tcp_callback, sq);
|
||||
return sq->pending != NULL;
|
||||
}
|
||||
@@ -1935,7 +1993,7 @@ serviced_udp_callback(struct comm_point* c, void* arg, int error,
|
||||
return 0;
|
||||
}
|
||||
if(rto >= RTT_MAX_TIMEOUT) {
|
||||
fallback_tcp = 1;
|
||||
/* fallback_tcp = 1; */
|
||||
/* UDP does not work, fallback to TCP below */
|
||||
} else {
|
||||
serviced_callbacks(sq, NETEVENT_TIMEOUT, c, rep);
|
||||
@@ -2055,7 +2113,7 @@ serviced_udp_callback(struct comm_point* c, void* arg, int error,
|
||||
struct serviced_query*
|
||||
outnet_serviced_query(struct outside_network* outnet,
|
||||
struct query_info* qinfo, uint16_t flags, int dnssec, int want_dnssec,
|
||||
int nocaps, int tcp_upstream, int ssl_upstream,
|
||||
int nocaps, int tcp_upstream, int ssl_upstream, char* tls_auth_name,
|
||||
struct sockaddr_storage* addr, socklen_t addrlen, uint8_t* zone,
|
||||
size_t zonelen, struct module_qstate* qstate,
|
||||
comm_point_callback_type* callback, void* callback_arg, sldns_buffer* buff,
|
||||
@@ -2078,8 +2136,9 @@ outnet_serviced_query(struct outside_network* outnet,
|
||||
if(!sq) {
|
||||
/* make new serviced query entry */
|
||||
sq = serviced_create(outnet, buff, dnssec, want_dnssec, nocaps,
|
||||
tcp_upstream, ssl_upstream, addr, addrlen, zone,
|
||||
zonelen, (int)qinfo->qtype, qstate->edns_opts_back_out);
|
||||
tcp_upstream, ssl_upstream, tls_auth_name, addr,
|
||||
addrlen, zone, zonelen, (int)qinfo->qtype,
|
||||
qstate->edns_opts_back_out);
|
||||
if(!sq) {
|
||||
free(cb);
|
||||
return NULL;
|
||||
@@ -2148,39 +2207,48 @@ fd_for_dest(struct outside_network* outnet, struct sockaddr_storage* to_addr,
|
||||
{
|
||||
struct sockaddr_storage* addr;
|
||||
socklen_t addrlen;
|
||||
int i;
|
||||
int try;
|
||||
|
||||
/* select interface */
|
||||
if(addr_is_ip6(to_addr, to_addrlen)) {
|
||||
if(outnet->num_ip6 == 0) {
|
||||
char to[64];
|
||||
addr_to_str(to_addr, to_addrlen, to, sizeof(to));
|
||||
verbose(VERB_QUERY, "need ipv6 to send, but no ipv6 outgoing interfaces, for %s", to);
|
||||
return -1;
|
||||
}
|
||||
i = ub_random_max(outnet->rnd, outnet->num_ip6);
|
||||
addr = &outnet->ip6_ifs[i].addr;
|
||||
addrlen = outnet->ip6_ifs[i].addrlen;
|
||||
} else {
|
||||
if(outnet->num_ip4 == 0) {
|
||||
char to[64];
|
||||
addr_to_str(to_addr, to_addrlen, to, sizeof(to));
|
||||
verbose(VERB_QUERY, "need ipv4 to send, but no ipv4 outgoing interfaces, for %s", to);
|
||||
return -1;
|
||||
}
|
||||
i = ub_random_max(outnet->rnd, outnet->num_ip4);
|
||||
addr = &outnet->ip4_ifs[i].addr;
|
||||
addrlen = outnet->ip4_ifs[i].addrlen;
|
||||
}
|
||||
int i, try, pnum;
|
||||
struct port_if* pif;
|
||||
|
||||
/* create fd */
|
||||
for(try = 0; try<1000; try++) {
|
||||
int port = 0;
|
||||
int freebind = 0;
|
||||
int noproto = 0;
|
||||
int inuse = 0;
|
||||
int port = ub_random(outnet->rnd)&0xffff;
|
||||
int fd = -1;
|
||||
|
||||
/* select interface */
|
||||
if(addr_is_ip6(to_addr, to_addrlen)) {
|
||||
if(outnet->num_ip6 == 0) {
|
||||
char to[64];
|
||||
addr_to_str(to_addr, to_addrlen, to, sizeof(to));
|
||||
verbose(VERB_QUERY, "need ipv6 to send, but no ipv6 outgoing interfaces, for %s", to);
|
||||
return -1;
|
||||
}
|
||||
i = ub_random_max(outnet->rnd, outnet->num_ip6);
|
||||
pif = &outnet->ip6_ifs[i];
|
||||
} else {
|
||||
if(outnet->num_ip4 == 0) {
|
||||
char to[64];
|
||||
addr_to_str(to_addr, to_addrlen, to, sizeof(to));
|
||||
verbose(VERB_QUERY, "need ipv4 to send, but no ipv4 outgoing interfaces, for %s", to);
|
||||
return -1;
|
||||
}
|
||||
i = ub_random_max(outnet->rnd, outnet->num_ip4);
|
||||
pif = &outnet->ip4_ifs[i];
|
||||
}
|
||||
addr = &pif->addr;
|
||||
addrlen = pif->addrlen;
|
||||
pnum = ub_random_max(outnet->rnd, pif->avail_total);
|
||||
if(pnum < pif->inuse) {
|
||||
/* port already open */
|
||||
port = pif->out[pnum]->number;
|
||||
} else {
|
||||
/* unused ports in start part of array */
|
||||
port = pif->avail_ports[pnum - pif->inuse];
|
||||
}
|
||||
|
||||
if(addr_is_ip6(to_addr, to_addrlen)) {
|
||||
struct sockaddr_in6 sa = *(struct sockaddr_in6*)addr;
|
||||
sa.sin6_port = (in_port_t)htons((uint16_t)port);
|
||||
|
||||
@@ -290,6 +290,8 @@ struct waiting_tcp {
|
||||
void* cb_arg;
|
||||
/** if it uses ssl upstream */
|
||||
int ssl_upstream;
|
||||
/** ref to the tls_auth_name from the serviced_query */
|
||||
char* tls_auth_name;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -332,6 +334,9 @@ struct serviced_query {
|
||||
int nocaps;
|
||||
/** tcp upstream used, use tcp, or ssl_upstream for SSL */
|
||||
int tcp_upstream, ssl_upstream;
|
||||
/** the name of the tls authentication name, eg. 'ns.example.com'
|
||||
* or NULL */
|
||||
char* tls_auth_name;
|
||||
/** where to send it */
|
||||
struct sockaddr_storage addr;
|
||||
/** length of addr field in use. */
|
||||
@@ -371,7 +376,7 @@ struct serviced_query {
|
||||
int retry;
|
||||
/** time last UDP was sent */
|
||||
struct timeval last_sent_time;
|
||||
/** rtt of last (UDP) message */
|
||||
/** rtt of last message */
|
||||
int last_rtt;
|
||||
/** do we know edns probe status already, for UDP_EDNS queries */
|
||||
int edns_lame_known;
|
||||
@@ -451,7 +456,7 @@ struct pending* pending_udp_query(struct serviced_query* sq,
|
||||
* checks id.
|
||||
* @param sq: serviced query.
|
||||
* @param packet: wireformat query to send to destination. copied from.
|
||||
* @param timeout: in seconds from now.
|
||||
* @param timeout: in milliseconds from now.
|
||||
* Timer starts running now. Timer may expire if all buffers are used,
|
||||
* without any query been sent to the server yet.
|
||||
* @param callback: function to call on error, timeout or reply.
|
||||
@@ -484,6 +489,8 @@ void pending_delete(struct outside_network* outnet, struct pending* p);
|
||||
* @param nocaps: ignore use_caps_for_id and use unperturbed qname.
|
||||
* @param tcp_upstream: use TCP for upstream queries.
|
||||
* @param ssl_upstream: use SSL for upstream queries.
|
||||
* @param tls_auth_name: when ssl_upstream is true, use this name to check
|
||||
* the server's peer certificate.
|
||||
* @param addr: to which server to send the query.
|
||||
* @param addrlen: length of addr.
|
||||
* @param zone: name of the zone of the delegation point. wireformat dname.
|
||||
@@ -501,7 +508,7 @@ void pending_delete(struct outside_network* outnet, struct pending* p);
|
||||
*/
|
||||
struct serviced_query* outnet_serviced_query(struct outside_network* outnet,
|
||||
struct query_info* qinfo, uint16_t flags, int dnssec, int want_dnssec,
|
||||
int nocaps, int tcp_upstream, int ssl_upstream,
|
||||
int nocaps, int tcp_upstream, int ssl_upstream, char* tls_auth_name,
|
||||
struct sockaddr_storage* addr, socklen_t addrlen, uint8_t* zone,
|
||||
size_t zonelen, struct module_qstate* qstate,
|
||||
comm_point_callback_type* callback, void* callback_arg,
|
||||
|
||||
@@ -89,6 +89,14 @@ sldns_rr_dnskey_key_size_raw(const unsigned char* keydata,
|
||||
return 256;
|
||||
case LDNS_ECDSAP384SHA384:
|
||||
return 384;
|
||||
#endif
|
||||
#ifdef USE_ED25519
|
||||
case LDNS_ED25519:
|
||||
return 256;
|
||||
#endif
|
||||
#ifdef USE_ED448
|
||||
case LDNS_ED448:
|
||||
return 456;
|
||||
#endif
|
||||
default:
|
||||
return 0;
|
||||
@@ -409,6 +417,27 @@ sldns_ed255192pkey_raw(const unsigned char* key, size_t keylen)
|
||||
}
|
||||
#endif /* USE_ED25519 */
|
||||
|
||||
#ifdef USE_ED448
|
||||
EVP_PKEY*
|
||||
sldns_ed4482pkey_raw(const unsigned char* key, size_t keylen)
|
||||
{
|
||||
/* ASN1 for ED448 is 3043300506032b6571033a00 <57byteskey> */
|
||||
uint8_t pre[] = {0x30, 0x43, 0x30, 0x05, 0x06, 0x03, 0x2b, 0x65,
|
||||
0x71, 0x03, 0x3a, 0x00};
|
||||
int pre_len = 12;
|
||||
uint8_t buf[256];
|
||||
EVP_PKEY *evp_key;
|
||||
/* pp gets modified by d2i() */
|
||||
const unsigned char* pp = (unsigned char*)buf;
|
||||
if(keylen != 57 || keylen + pre_len > sizeof(buf))
|
||||
return NULL; /* wrong length */
|
||||
memmove(buf, pre, pre_len);
|
||||
memmove(buf+pre_len, key, keylen);
|
||||
evp_key = d2i_PUBKEY(NULL, &pp, (int)(pre_len+keylen));
|
||||
return evp_key;
|
||||
}
|
||||
#endif /* USE_ED448 */
|
||||
|
||||
int
|
||||
sldns_digest_evp(unsigned char* data, unsigned int len, unsigned char* dest,
|
||||
const EVP_MD* md)
|
||||
|
||||
@@ -101,6 +101,15 @@ RSA *sldns_key_buf2rsa_raw(unsigned char* key, size_t len);
|
||||
*/
|
||||
EVP_PKEY* sldns_ed255192pkey_raw(const unsigned char* key, size_t len);
|
||||
|
||||
/**
|
||||
* Converts a holding buffer with key material to EVP PKEY in openssl.
|
||||
* Only available if ldns was compiled with ED448.
|
||||
* \param[in] key the uncompressed wireformat of the key.
|
||||
* \param[in] len length of key data
|
||||
* \return the key or NULL on error.
|
||||
*/
|
||||
EVP_PKEY* sldns_ed4482pkey_raw(const unsigned char* key, size_t len);
|
||||
|
||||
/**
|
||||
* Utility function to calculate hash using generic EVP_MD pointer.
|
||||
* \param[in] data the data to hash.
|
||||
|
||||
+2
-5
@@ -341,12 +341,9 @@ static sldns_rr_descriptor rdata_field_descriptors[] = {
|
||||
{LDNS_RR_TYPE_NSEC3PARAM, "NSEC3PARAM", 4, 4, type_nsec3param_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
/* 52 */
|
||||
{LDNS_RR_TYPE_TLSA, "TLSA", 4, 4, type_tlsa_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
/*53 */
|
||||
#ifdef DRAFT_RRTYPES
|
||||
/* 53 */
|
||||
{LDNS_RR_TYPE_SMIMEA, "SMIMEA", 4, 4, type_tlsa_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
#else
|
||||
{LDNS_RR_TYPE_NULL, "TYPE53", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
#endif
|
||||
/* 54 */
|
||||
{LDNS_RR_TYPE_NULL, "TYPE54", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
|
||||
/* 55
|
||||
* Hip ends with 0 or more Rendezvous Servers represented as dname's.
|
||||
|
||||
+1
-3
@@ -182,9 +182,7 @@ enum sldns_enum_rr_type
|
||||
LDNS_RR_TYPE_NSEC3PARAM = 51, /* RFC 5155 */
|
||||
LDNS_RR_TYPE_NSEC3PARAMS = 51,
|
||||
LDNS_RR_TYPE_TLSA = 52, /* RFC 6698 */
|
||||
LDNS_RR_TYPE_SMIMEA = 53, /* draft-ietf-dane-smime, TLSA-like but may
|
||||
be extended */
|
||||
|
||||
LDNS_RR_TYPE_SMIMEA = 53, /* RFC 8162 */
|
||||
LDNS_RR_TYPE_HIP = 55, /* RFC 5205 */
|
||||
|
||||
/** draft-reid-dnsext-zs */
|
||||
|
||||
+2
-2
@@ -130,7 +130,7 @@ struct sldns_buffer
|
||||
/** If the buffer is fixed it cannot be resized */
|
||||
unsigned _fixed : 1;
|
||||
|
||||
/** If the buffer is vfixed, no more than capacity bytes willl be
|
||||
/** If the buffer is vfixed, no more than capacity bytes will be
|
||||
* written to _data, however the _position counter will be updated
|
||||
* with the amount that would have been written in consecutive
|
||||
* writes. This allows for a modus operandi in which a sequence is
|
||||
@@ -160,7 +160,7 @@ sldns_buffer_invariant(sldns_buffer *buffer)
|
||||
assert(buffer != NULL);
|
||||
assert(buffer->_position <= buffer->_limit || buffer->_vfixed);
|
||||
assert(buffer->_limit <= buffer->_capacity);
|
||||
assert(buffer->_data != NULL || (buffer->_vfixed && buffer->_capacity == 0));
|
||||
assert(buffer->_data != NULL || (buffer->_vfixed && buffer->_capacity == 0 && buffer->_limit == 0));
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
+12
-1
@@ -1225,6 +1225,17 @@ int sldns_str2wire_b32_ext_buf(const char* str, uint8_t* rd, size_t* len)
|
||||
return LDNS_WIREPARSE_ERR_OK;
|
||||
}
|
||||
|
||||
/** see if the string ends, or ends in whitespace */
|
||||
static int
|
||||
sldns_is_last_of_string(const char* str)
|
||||
{
|
||||
if(*str == 0) return 1;
|
||||
while(isspace((unsigned char)*str))
|
||||
str++;
|
||||
if(*str == 0) return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sldns_str2wire_hex_buf(const char* str, uint8_t* rd, size_t* len)
|
||||
{
|
||||
const char* s = str;
|
||||
@@ -1234,7 +1245,7 @@ int sldns_str2wire_hex_buf(const char* str, uint8_t* rd, size_t* len)
|
||||
s++;
|
||||
continue;
|
||||
}
|
||||
if(dlen == 0 && *s == '0' && *(s+1) == 0) {
|
||||
if(dlen == 0 && *s == '0' && sldns_is_last_of_string(s+1)) {
|
||||
*len = 0;
|
||||
return LDNS_WIREPARSE_ERR_OK;
|
||||
}
|
||||
|
||||
+58
-36
@@ -192,9 +192,10 @@ usage(void)
|
||||
printf("-n name signer's subject emailAddress, default %s\n", P7SIGNER);
|
||||
printf("-4 work using IPv4 only\n");
|
||||
printf("-6 work using IPv6 only\n");
|
||||
printf("-f resolv.conf use given resolv.conf to resolve -u name\n");
|
||||
printf("-r root.hints use given root.hints to resolve -u name\n"
|
||||
printf("-f resolv.conf use given resolv.conf\n");
|
||||
printf("-r root.hints use given root.hints\n"
|
||||
" builtin root hints are used by default\n");
|
||||
printf("-R fallback from -f to root query on error\n");
|
||||
printf("-v more verbose\n");
|
||||
printf("-C conf debug, read config\n");
|
||||
printf("-P port use port for https connect, default 443\n");
|
||||
@@ -1096,11 +1097,14 @@ read_http_result(SSL* ssl)
|
||||
}
|
||||
if(!data) return NULL;
|
||||
if(verb >= 4) print_data("read data", data, (int)len);
|
||||
m = BIO_new_mem_buf(data, (int)len);
|
||||
m = BIO_new(BIO_s_mem());
|
||||
if(!m) {
|
||||
if(verb) printf("out of memory\n");
|
||||
free(data);
|
||||
exit(0);
|
||||
}
|
||||
BIO_write(m, data, (int)len);
|
||||
free(data);
|
||||
return m;
|
||||
}
|
||||
|
||||
@@ -1167,17 +1171,6 @@ https(struct ip_list* ip_list, const char* pathname, const char* urlname)
|
||||
return bio;
|
||||
}
|
||||
|
||||
/** free up a downloaded file BIO */
|
||||
static void
|
||||
free_file_bio(BIO* bio)
|
||||
{
|
||||
char* pp = NULL;
|
||||
(void)BIO_reset(bio);
|
||||
(void)BIO_get_mem_data(bio, &pp);
|
||||
free(pp);
|
||||
BIO_free(bio);
|
||||
}
|
||||
|
||||
/** XML parse private data during the parse */
|
||||
struct xml_data {
|
||||
/** the parser, reference */
|
||||
@@ -1602,7 +1595,7 @@ xml_parse(BIO* xml, time_t now)
|
||||
xml_parse_setup(parser, &data, now);
|
||||
|
||||
/* parse it */
|
||||
(void)BIO_reset(xml);
|
||||
(void)BIO_seek(xml, 0);
|
||||
len = (int)BIO_get_mem_data(xml, &pp);
|
||||
if(!len || !pp) {
|
||||
if(verb) printf("out of memory\n");
|
||||
@@ -1776,8 +1769,8 @@ verify_p7sig(BIO* data, BIO* p7s, STACK_OF(X509)* trust, const char* p7signer)
|
||||
X509_VERIFY_PARAM_free(param);
|
||||
#endif
|
||||
|
||||
(void)BIO_reset(p7s);
|
||||
(void)BIO_reset(data);
|
||||
(void)BIO_seek(p7s, 0);
|
||||
(void)BIO_seek(data, 0);
|
||||
|
||||
/* convert p7s to p7 (the signature) */
|
||||
p7 = d2i_PKCS7_bio(p7s, NULL);
|
||||
@@ -1920,8 +1913,7 @@ static int
|
||||
do_certupdate(const char* root_anchor_file, const char* root_cert_file,
|
||||
const char* urlname, const char* xmlname, const char* p7sname,
|
||||
const char* p7signer, const char* res_conf, const char* root_hints,
|
||||
const char* debugconf, int ip4only, int ip6only, int port,
|
||||
struct ub_result* dnskey)
|
||||
const char* debugconf, int ip4only, int ip6only, int port)
|
||||
{
|
||||
STACK_OF(X509)* cert;
|
||||
BIO *xml, *p7s;
|
||||
@@ -1956,12 +1948,11 @@ do_certupdate(const char* root_anchor_file, const char* root_cert_file,
|
||||
if(verb) printf("success: the anchor has been updated "
|
||||
"using the cert\n");
|
||||
|
||||
free_file_bio(xml);
|
||||
free_file_bio(p7s);
|
||||
BIO_free(xml);
|
||||
BIO_free(p7s);
|
||||
#ifndef S_SPLINT_S
|
||||
sk_X509_pop_free(cert, X509_free);
|
||||
#endif
|
||||
ub_resolve_free(dnskey);
|
||||
ip_list_free(ip_list);
|
||||
return 1;
|
||||
}
|
||||
@@ -2199,16 +2190,33 @@ probe_date_allows_certupdate(const char* root_anchor_file)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct ub_result *
|
||||
fetch_root_key(const char* root_anchor_file, const char* res_conf,
|
||||
const char* root_hints, const char* debugconf,
|
||||
int ip4only, int ip6only)
|
||||
{
|
||||
struct ub_ctx* ctx;
|
||||
struct ub_result* dnskey;
|
||||
|
||||
ctx = create_unbound_context(res_conf, root_hints, debugconf,
|
||||
ip4only, ip6only);
|
||||
add_5011_probe_root(ctx, root_anchor_file);
|
||||
dnskey = prime_root_key(ctx);
|
||||
ub_ctx_delete(ctx);
|
||||
return dnskey;
|
||||
}
|
||||
|
||||
/** perform the unbound-anchor work */
|
||||
static int
|
||||
do_root_update_work(const char* root_anchor_file, const char* root_cert_file,
|
||||
const char* urlname, const char* xmlname, const char* p7sname,
|
||||
const char* p7signer, const char* res_conf, const char* root_hints,
|
||||
const char* debugconf, int ip4only, int ip6only, int force, int port)
|
||||
const char* debugconf, int ip4only, int ip6only, int force,
|
||||
int res_conf_fallback, int port)
|
||||
{
|
||||
struct ub_ctx* ctx;
|
||||
struct ub_result* dnskey;
|
||||
int used_builtin = 0;
|
||||
int rcode;
|
||||
|
||||
/* see if builtin rootanchor needs to be provided, or if
|
||||
* rootanchor is 'revoked-trust-point' */
|
||||
@@ -2217,12 +2225,22 @@ do_root_update_work(const char* root_anchor_file, const char* root_cert_file,
|
||||
|
||||
/* make unbound context with 5011-probe for root anchor,
|
||||
* and probe . DNSKEY */
|
||||
ctx = create_unbound_context(res_conf, root_hints, debugconf,
|
||||
ip4only, ip6only);
|
||||
add_5011_probe_root(ctx, root_anchor_file);
|
||||
dnskey = prime_root_key(ctx);
|
||||
ub_ctx_delete(ctx);
|
||||
|
||||
dnskey = fetch_root_key(root_anchor_file, res_conf,
|
||||
root_hints, debugconf, ip4only, ip6only);
|
||||
rcode = dnskey->rcode;
|
||||
|
||||
if (res_conf_fallback && res_conf && !dnskey->secure) {
|
||||
if (verb) printf("%s failed, retrying direct\n", res_conf);
|
||||
ub_resolve_free(dnskey);
|
||||
/* try direct query without res_conf */
|
||||
dnskey = fetch_root_key(root_anchor_file, NULL,
|
||||
root_hints, debugconf, ip4only, ip6only);
|
||||
if (rcode != 0 && dnskey->rcode == 0) {
|
||||
res_conf = NULL;
|
||||
rcode = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* if secure: exit */
|
||||
if(dnskey->secure && !force) {
|
||||
if(verb) printf("success: the anchor is ok\n");
|
||||
@@ -2230,18 +2248,18 @@ do_root_update_work(const char* root_anchor_file, const char* root_cert_file,
|
||||
return used_builtin;
|
||||
}
|
||||
if(force && verb) printf("debug cert update forced\n");
|
||||
ub_resolve_free(dnskey);
|
||||
|
||||
/* if not (and NOERROR): check date and do certupdate */
|
||||
if((dnskey->rcode == 0 &&
|
||||
if((rcode == 0 &&
|
||||
probe_date_allows_certupdate(root_anchor_file)) || force) {
|
||||
if(do_certupdate(root_anchor_file, root_cert_file, urlname,
|
||||
xmlname, p7sname, p7signer, res_conf, root_hints,
|
||||
debugconf, ip4only, ip6only, port, dnskey))
|
||||
debugconf, ip4only, ip6only, port))
|
||||
return 1;
|
||||
return used_builtin;
|
||||
}
|
||||
if(verb) printf("fail: the anchor is NOT ok and could not be fixed\n");
|
||||
ub_resolve_free(dnskey);
|
||||
return used_builtin;
|
||||
}
|
||||
|
||||
@@ -2264,8 +2282,9 @@ int main(int argc, char* argv[])
|
||||
const char* root_hints = NULL;
|
||||
const char* debugconf = NULL;
|
||||
int dolist=0, ip4only=0, ip6only=0, force=0, port = HTTPS_PORT;
|
||||
int res_conf_fallback = 0;
|
||||
/* parse the options */
|
||||
while( (c=getopt(argc, argv, "46C:FP:a:c:f:hln:r:s:u:vx:")) != -1) {
|
||||
while( (c=getopt(argc, argv, "46C:FRP:a:c:f:hln:r:s:u:vx:")) != -1) {
|
||||
switch(c) {
|
||||
case 'l':
|
||||
dolist = 1;
|
||||
@@ -2300,6 +2319,9 @@ int main(int argc, char* argv[])
|
||||
case 'r':
|
||||
root_hints = optarg;
|
||||
break;
|
||||
case 'R':
|
||||
res_conf_fallback = 1;
|
||||
break;
|
||||
case 'C':
|
||||
debugconf = optarg;
|
||||
break;
|
||||
@@ -2319,7 +2341,7 @@ int main(int argc, char* argv[])
|
||||
}
|
||||
}
|
||||
argc -= optind;
|
||||
argv += optind;
|
||||
/* argv += optind; not using further arguments */
|
||||
if(argc != 0)
|
||||
usage();
|
||||
|
||||
@@ -2346,5 +2368,5 @@ int main(int argc, char* argv[])
|
||||
|
||||
return do_root_update_work(root_anchor_file, root_cert_file, urlname,
|
||||
xmlname, p7sname, p7signer, res_conf, root_hints, debugconf,
|
||||
ip4only, ip6only, force, port);
|
||||
ip4only, ip6only, force, res_conf_fallback, port);
|
||||
}
|
||||
|
||||
@@ -43,6 +43,7 @@
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include <ctype.h>
|
||||
#include "util/log.h"
|
||||
#include "util/config_file.h"
|
||||
#include "util/module.h"
|
||||
@@ -252,6 +253,23 @@ aclchecks(struct config_file* cfg)
|
||||
}
|
||||
}
|
||||
|
||||
/** check tcp connection limit ips */
|
||||
static void
|
||||
tcpconnlimitchecks(struct config_file* cfg)
|
||||
{
|
||||
int d;
|
||||
struct sockaddr_storage a;
|
||||
socklen_t alen;
|
||||
struct config_str2list* tcl;
|
||||
for(tcl=cfg->tcp_connection_limits; tcl; tcl = tcl->next) {
|
||||
if(!netblockstrtoaddr(tcl->str, UNBOUND_DNS_PORT, &a, &alen,
|
||||
&d)) {
|
||||
fatal_exit("cannot parse tcp connection limit address %s %s",
|
||||
tcl->str, tcl->str2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** true if fname is a file */
|
||||
static int
|
||||
is_file(const char* fname)
|
||||
@@ -373,6 +391,44 @@ ecs_conf_checks(struct config_file* cfg)
|
||||
}
|
||||
#endif /* CLIENT_SUBNET */
|
||||
|
||||
/** check that the modules exist, are compiled in */
|
||||
static void
|
||||
check_modules_exist(const char* module_conf)
|
||||
{
|
||||
const char** names = module_list_avail();
|
||||
const char* s = module_conf;
|
||||
while(*s) {
|
||||
int i = 0;
|
||||
int is_ok = 0;
|
||||
while(*s && isspace((unsigned char)*s))
|
||||
s++;
|
||||
if(!*s) break;
|
||||
while(names[i]) {
|
||||
if(strncmp(names[i], s, strlen(names[i])) == 0) {
|
||||
is_ok = 1;
|
||||
break;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
if(is_ok == 0) {
|
||||
char n[64];
|
||||
size_t j;
|
||||
n[0]=0;
|
||||
n[sizeof(n)-1]=0;
|
||||
for(j=0; j<sizeof(n)-1; j++) {
|
||||
if(!s[j] || isspace((unsigned char)s[j])) {
|
||||
n[j] = 0;
|
||||
break;
|
||||
}
|
||||
n[j] = s[j];
|
||||
}
|
||||
fatal_exit("module_conf lists module '%s' but that "
|
||||
"module is not available.", n);
|
||||
}
|
||||
s += strlen(names[i]);
|
||||
}
|
||||
}
|
||||
|
||||
/** check configuration for errors */
|
||||
static void
|
||||
morechecks(struct config_file* cfg, const char* fname)
|
||||
@@ -381,6 +437,7 @@ morechecks(struct config_file* cfg, const char* fname)
|
||||
warn_hosts("forward-host", cfg->forwards);
|
||||
interfacechecks(cfg);
|
||||
aclchecks(cfg);
|
||||
tcpconnlimitchecks(cfg);
|
||||
|
||||
if(cfg->verbosity < 0)
|
||||
fatal_exit("verbosity value < 0");
|
||||
@@ -465,6 +522,9 @@ morechecks(struct config_file* cfg, const char* fname)
|
||||
free(cfg->chrootdir);
|
||||
cfg->chrootdir = NULL;
|
||||
|
||||
/* check that the modules listed in module_conf exist */
|
||||
check_modules_exist(cfg->module_conf);
|
||||
|
||||
/* There should be no reason for 'respip' module not to work with
|
||||
* dns64, but it's not explicitly confirmed, so the combination is
|
||||
* excluded below. It's simply unknown yet for the combination of
|
||||
@@ -511,7 +571,6 @@ morechecks(struct config_file* cfg, const char* fname)
|
||||
#if defined(WITH_PYTHONMODULE) && defined(CLIENT_SUBNET)
|
||||
&& strcmp(cfg->module_conf, "python subnetcache iterator") != 0
|
||||
&& strcmp(cfg->module_conf, "subnetcache python iterator") != 0
|
||||
&& strcmp(cfg->module_conf, "subnetcache validator iterator") != 0
|
||||
&& strcmp(cfg->module_conf, "python subnetcache validator iterator") != 0
|
||||
&& strcmp(cfg->module_conf, "subnetcache python validator iterator") != 0
|
||||
&& strcmp(cfg->module_conf, "subnetcache validator python iterator") != 0
|
||||
@@ -542,7 +601,8 @@ morechecks(struct config_file* cfg, const char* fname)
|
||||
# endif
|
||||
}
|
||||
#endif
|
||||
if(cfg->remote_control_enable && cfg->remote_control_use_cert) {
|
||||
if(cfg->remote_control_enable && options_remote_is_address(cfg)
|
||||
&& cfg->control_use_cert) {
|
||||
check_chroot_string("server-key-file", &cfg->server_key_file,
|
||||
cfg->chrootdir, cfg);
|
||||
check_chroot_string("server-cert-file", &cfg->server_cert_file,
|
||||
|
||||
+147
-77
@@ -73,6 +73,10 @@
|
||||
#include <sys/un.h>
|
||||
#endif
|
||||
|
||||
static void usage(void) ATTR_NORETURN;
|
||||
static void ssl_err(const char* s) ATTR_NORETURN;
|
||||
static void ssl_path_err(const char* s, const char *path) ATTR_NORETURN;
|
||||
|
||||
/** Give unbound-control usage, and exit (1). */
|
||||
static void
|
||||
usage(void)
|
||||
@@ -142,6 +146,9 @@ usage(void)
|
||||
printf(" ratelimit_list [+a] list ratelimited domains\n");
|
||||
printf(" ip_ratelimit_list [+a] list ratelimited ip addresses\n");
|
||||
printf(" +a list all, also not ratelimited\n");
|
||||
printf(" list_auth_zones list auth zones\n");
|
||||
printf(" auth_zone_reload zone reload auth zone from zonefile\n");
|
||||
printf(" auth_zone_transfer zone transfer auth zone from master\n");
|
||||
printf(" view_list_local_zones view list local-zones in view\n");
|
||||
printf(" view_list_local_data view list local-data RRs in view\n");
|
||||
printf(" view_local_zone view name type add local-zone in view\n");
|
||||
@@ -318,6 +325,7 @@ static void print_extended(struct ub_stats_info* s)
|
||||
/* transport */
|
||||
PR_UL("num.query.tcp", s->svr.qtcp);
|
||||
PR_UL("num.query.tcpout", s->svr.qtcp_outgoing);
|
||||
PR_UL("num.query.tls", s->svr.qtls);
|
||||
PR_UL("num.query.ipv6", s->svr.qipv6);
|
||||
|
||||
/* flags */
|
||||
@@ -349,6 +357,8 @@ static void print_extended(struct ub_stats_info* s)
|
||||
PR_UL("num.answer.secure", s->svr.ans_secure);
|
||||
PR_UL("num.answer.bogus", s->svr.ans_bogus);
|
||||
PR_UL("num.rrset.bogus", s->svr.rrset_bogus);
|
||||
PR_UL("num.query.aggressive.NOERROR", s->svr.num_neg_cache_noerror);
|
||||
PR_UL("num.query.aggressive.NXDOMAIN", s->svr.num_neg_cache_nxdomain);
|
||||
/* threat detection */
|
||||
PR_UL("unwanted.queries", s->svr.unwanted_queries);
|
||||
PR_UL("unwanted.replies", s->svr.unwanted_replies);
|
||||
@@ -366,6 +376,12 @@ static void print_extended(struct ub_stats_info* s)
|
||||
PR_UL("num.query.dnscrypt.replay",
|
||||
s->svr.num_query_dnscrypt_replay);
|
||||
#endif /* USE_DNSCRYPT */
|
||||
PR_UL("num.query.authzone.up", s->svr.num_query_authzone_up);
|
||||
PR_UL("num.query.authzone.down", s->svr.num_query_authzone_down);
|
||||
#ifdef CLIENT_SUBNET
|
||||
PR_UL("num.query.subnet", s->svr.num_query_subnet);
|
||||
PR_UL("num.query.subnet_cache", s->svr.num_query_subnet_cache);
|
||||
#endif
|
||||
}
|
||||
|
||||
/** print statistics out of memory structures */
|
||||
@@ -439,6 +455,22 @@ static void ssl_err(const char* s)
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/** exit with ssl error related to a file path */
|
||||
static void ssl_path_err(const char* s, const char *path)
|
||||
{
|
||||
unsigned long err;
|
||||
err = ERR_peek_error();
|
||||
if (ERR_GET_LIB(err) == ERR_LIB_SYS &&
|
||||
(ERR_GET_FUNC(err) == SYS_F_FOPEN ||
|
||||
ERR_GET_FUNC(err) == SYS_F_FREAD) ) {
|
||||
fprintf(stderr, "error: %s\n%s: %s\n",
|
||||
s, path, ERR_reason_error_string(err));
|
||||
exit(1);
|
||||
} else {
|
||||
ssl_err(s);
|
||||
}
|
||||
}
|
||||
|
||||
/** setup SSL context */
|
||||
static SSL_CTX*
|
||||
setup_ctx(struct config_file* cfg)
|
||||
@@ -446,42 +478,36 @@ setup_ctx(struct config_file* cfg)
|
||||
char* s_cert=NULL, *c_key=NULL, *c_cert=NULL;
|
||||
SSL_CTX* ctx;
|
||||
|
||||
if(cfg->remote_control_use_cert) {
|
||||
s_cert = fname_after_chroot(cfg->server_cert_file, cfg, 1);
|
||||
c_key = fname_after_chroot(cfg->control_key_file, cfg, 1);
|
||||
c_cert = fname_after_chroot(cfg->control_cert_file, cfg, 1);
|
||||
if(!s_cert || !c_key || !c_cert)
|
||||
fatal_exit("out of memory");
|
||||
}
|
||||
if(!(options_remote_is_address(cfg) && cfg->control_use_cert))
|
||||
return NULL;
|
||||
s_cert = fname_after_chroot(cfg->server_cert_file, cfg, 1);
|
||||
c_key = fname_after_chroot(cfg->control_key_file, cfg, 1);
|
||||
c_cert = fname_after_chroot(cfg->control_cert_file, cfg, 1);
|
||||
if(!s_cert || !c_key || !c_cert)
|
||||
fatal_exit("out of memory");
|
||||
ctx = SSL_CTX_new(SSLv23_client_method());
|
||||
if(!ctx)
|
||||
ssl_err("could not allocate SSL_CTX pointer");
|
||||
if((SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv2) & SSL_OP_NO_SSLv2)
|
||||
!= SSL_OP_NO_SSLv2)
|
||||
ssl_err("could not set SSL_OP_NO_SSLv2");
|
||||
if(cfg->remote_control_use_cert) {
|
||||
if((SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv3) & SSL_OP_NO_SSLv3)
|
||||
!= SSL_OP_NO_SSLv3)
|
||||
ssl_err("could not set SSL_OP_NO_SSLv3");
|
||||
if(!SSL_CTX_use_certificate_chain_file(ctx,c_cert) ||
|
||||
!SSL_CTX_use_PrivateKey_file(ctx,c_key,SSL_FILETYPE_PEM)
|
||||
|| !SSL_CTX_check_private_key(ctx))
|
||||
ssl_err("Error setting up SSL_CTX client key and cert");
|
||||
if (SSL_CTX_load_verify_locations(ctx, s_cert, NULL) != 1)
|
||||
ssl_err("Error setting up SSL_CTX verify, server cert");
|
||||
SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, NULL);
|
||||
if((SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv3) & SSL_OP_NO_SSLv3)
|
||||
!= SSL_OP_NO_SSLv3)
|
||||
ssl_err("could not set SSL_OP_NO_SSLv3");
|
||||
if(!SSL_CTX_use_certificate_chain_file(ctx,c_cert))
|
||||
ssl_path_err("Error setting up SSL_CTX client cert", c_cert);
|
||||
if (!SSL_CTX_use_PrivateKey_file(ctx,c_key,SSL_FILETYPE_PEM))
|
||||
ssl_path_err("Error setting up SSL_CTX client key", c_key);
|
||||
if (!SSL_CTX_check_private_key(ctx))
|
||||
ssl_err("Error setting up SSL_CTX client key");
|
||||
if (SSL_CTX_load_verify_locations(ctx, s_cert, NULL) != 1)
|
||||
ssl_path_err("Error setting up SSL_CTX verify, server cert",
|
||||
s_cert);
|
||||
SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, NULL);
|
||||
|
||||
free(s_cert);
|
||||
free(c_key);
|
||||
free(c_cert);
|
||||
} else {
|
||||
/* Use ciphers that don't require authentication */
|
||||
#ifdef HAVE_SSL_CTX_SET_SECURITY_LEVEL
|
||||
SSL_CTX_set_security_level(ctx, 0);
|
||||
#endif
|
||||
if(!SSL_CTX_set_cipher_list(ctx, "aNULL, eNULL"))
|
||||
ssl_err("Error setting NULL cipher!");
|
||||
}
|
||||
free(s_cert);
|
||||
free(c_key);
|
||||
free(c_cert);
|
||||
return ctx;
|
||||
}
|
||||
|
||||
@@ -491,12 +517,12 @@ contact_server(const char* svr, struct config_file* cfg, int statuscmd)
|
||||
{
|
||||
struct sockaddr_storage addr;
|
||||
socklen_t addrlen;
|
||||
int addrfamily = 0;
|
||||
int fd;
|
||||
int addrfamily = 0, proto = IPPROTO_TCP;
|
||||
int fd, useport = 1;
|
||||
/* use svr or the first config entry */
|
||||
if(!svr) {
|
||||
if(cfg->control_ifs) {
|
||||
svr = cfg->control_ifs->str;
|
||||
if(cfg->control_ifs.first) {
|
||||
svr = cfg->control_ifs.first->str;
|
||||
} else if(cfg->do_ip4) {
|
||||
svr = "127.0.0.1";
|
||||
} else {
|
||||
@@ -524,6 +550,8 @@ contact_server(const char* svr, struct config_file* cfg, int statuscmd)
|
||||
(void)strlcpy(usock->sun_path, svr, sizeof(usock->sun_path));
|
||||
addrlen = (socklen_t)sizeof(struct sockaddr_un);
|
||||
addrfamily = AF_LOCAL;
|
||||
useport = 0;
|
||||
proto = 0;
|
||||
#endif
|
||||
} else {
|
||||
if(!ipstrtoaddr(svr, cfg->control_port, &addr, &addrlen))
|
||||
@@ -531,8 +559,8 @@ contact_server(const char* svr, struct config_file* cfg, int statuscmd)
|
||||
}
|
||||
|
||||
if(addrfamily == 0)
|
||||
addrfamily = addr_is_ip6(&addr, addrlen)?AF_INET6:AF_INET;
|
||||
fd = socket(addrfamily, SOCK_STREAM, 0);
|
||||
addrfamily = addr_is_ip6(&addr, addrlen)?PF_INET6:PF_INET;
|
||||
fd = socket(addrfamily, SOCK_STREAM, proto);
|
||||
if(fd == -1) {
|
||||
#ifndef USE_WINSOCK
|
||||
fatal_exit("socket: %s", strerror(errno));
|
||||
@@ -542,14 +570,18 @@ contact_server(const char* svr, struct config_file* cfg, int statuscmd)
|
||||
}
|
||||
if(connect(fd, (struct sockaddr*)&addr, addrlen) < 0) {
|
||||
#ifndef USE_WINSOCK
|
||||
log_err_addr("connect", strerror(errno), &addr, addrlen);
|
||||
if(errno == ECONNREFUSED && statuscmd) {
|
||||
int err = errno;
|
||||
if(!useport) log_err("connect: %s for %s", strerror(err), svr);
|
||||
else log_err_addr("connect", strerror(err), &addr, addrlen);
|
||||
if(err == ECONNREFUSED && statuscmd) {
|
||||
printf("unbound is stopped\n");
|
||||
exit(3);
|
||||
}
|
||||
#else
|
||||
log_err_addr("connect", wsa_strerror(WSAGetLastError()), &addr, addrlen);
|
||||
if(WSAGetLastError() == WSAECONNREFUSED && statuscmd) {
|
||||
int wsaerr = WSAGetLastError();
|
||||
if(!useport) log_err("connect: %s for %s", wsa_strerror(wsaerr), svr);
|
||||
else log_err_addr("connect", wsa_strerror(wsaerr), &addr, addrlen);
|
||||
if(wsaerr == WSAECONNREFUSED && statuscmd) {
|
||||
printf("unbound is stopped\n");
|
||||
exit(3);
|
||||
}
|
||||
@@ -561,12 +593,13 @@ contact_server(const char* svr, struct config_file* cfg, int statuscmd)
|
||||
|
||||
/** setup SSL on the connection */
|
||||
static SSL*
|
||||
setup_ssl(SSL_CTX* ctx, int fd, struct config_file* cfg)
|
||||
setup_ssl(SSL_CTX* ctx, int fd)
|
||||
{
|
||||
SSL* ssl;
|
||||
X509* x;
|
||||
int r;
|
||||
|
||||
if(!ctx) return NULL;
|
||||
ssl = SSL_new(ctx);
|
||||
if(!ssl)
|
||||
ssl_err("could not SSL_new");
|
||||
@@ -587,78 +620,115 @@ setup_ssl(SSL_CTX* ctx, int fd, struct config_file* cfg)
|
||||
/* check authenticity of server */
|
||||
if(SSL_get_verify_result(ssl) != X509_V_OK)
|
||||
ssl_err("SSL verification failed");
|
||||
if(cfg->remote_control_use_cert) {
|
||||
x = SSL_get_peer_certificate(ssl);
|
||||
if(!x)
|
||||
ssl_err("Server presented no peer certificate");
|
||||
X509_free(x);
|
||||
}
|
||||
x = SSL_get_peer_certificate(ssl);
|
||||
if(!x)
|
||||
ssl_err("Server presented no peer certificate");
|
||||
X509_free(x);
|
||||
|
||||
return ssl;
|
||||
}
|
||||
|
||||
/** read from ssl or fd, fatalexit on error, 0 EOF, 1 success */
|
||||
static int
|
||||
remote_read(SSL* ssl, int fd, char* buf, size_t len)
|
||||
{
|
||||
if(ssl) {
|
||||
int r;
|
||||
ERR_clear_error();
|
||||
if((r = SSL_read(ssl, buf, (int)len-1)) <= 0) {
|
||||
if(SSL_get_error(ssl, r) == SSL_ERROR_ZERO_RETURN) {
|
||||
/* EOF */
|
||||
return 0;
|
||||
}
|
||||
ssl_err("could not SSL_read");
|
||||
}
|
||||
buf[r] = 0;
|
||||
} else {
|
||||
ssize_t rr = recv(fd, buf, len-1, 0);
|
||||
if(rr <= 0) {
|
||||
if(rr == 0) {
|
||||
/* EOF */
|
||||
return 0;
|
||||
}
|
||||
#ifndef USE_WINSOCK
|
||||
fatal_exit("could not recv: %s", strerror(errno));
|
||||
#else
|
||||
fatal_exit("could not recv: %s", wsa_strerror(WSAGetLastError()));
|
||||
#endif
|
||||
}
|
||||
buf[rr] = 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/** write to ssl or fd, fatalexit on error */
|
||||
static void
|
||||
remote_write(SSL* ssl, int fd, const char* buf, size_t len)
|
||||
{
|
||||
if(ssl) {
|
||||
if(SSL_write(ssl, buf, (int)len) <= 0)
|
||||
ssl_err("could not SSL_write");
|
||||
} else {
|
||||
if(send(fd, buf, len, 0) < (ssize_t)len) {
|
||||
#ifndef USE_WINSOCK
|
||||
fatal_exit("could not send: %s", strerror(errno));
|
||||
#else
|
||||
fatal_exit("could not send: %s", wsa_strerror(WSAGetLastError()));
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** send stdin to server */
|
||||
static void
|
||||
send_file(SSL* ssl, FILE* in, char* buf, size_t sz)
|
||||
send_file(SSL* ssl, int fd, FILE* in, char* buf, size_t sz)
|
||||
{
|
||||
while(fgets(buf, (int)sz, in)) {
|
||||
if(SSL_write(ssl, buf, (int)strlen(buf)) <= 0)
|
||||
ssl_err("could not SSL_write contents");
|
||||
remote_write(ssl, fd, buf, strlen(buf));
|
||||
}
|
||||
}
|
||||
|
||||
/** send end-of-file marker to server */
|
||||
static void
|
||||
send_eof(SSL* ssl)
|
||||
send_eof(SSL* ssl, int fd)
|
||||
{
|
||||
char e[] = {0x04, 0x0a};
|
||||
if(SSL_write(ssl, e, (int)sizeof(e)) <= 0)
|
||||
ssl_err("could not SSL_write end-of-file marker");
|
||||
remote_write(ssl, fd, e, sizeof(e));
|
||||
}
|
||||
|
||||
/** send command and display result */
|
||||
static int
|
||||
go_cmd(SSL* ssl, int quiet, int argc, char* argv[])
|
||||
go_cmd(SSL* ssl, int fd, int quiet, int argc, char* argv[])
|
||||
{
|
||||
char pre[10];
|
||||
const char* space=" ";
|
||||
const char* newline="\n";
|
||||
int was_error = 0, first_line = 1;
|
||||
int r, i;
|
||||
int i;
|
||||
char buf[1024];
|
||||
snprintf(pre, sizeof(pre), "UBCT%d ", UNBOUND_CONTROL_VERSION);
|
||||
if(SSL_write(ssl, pre, (int)strlen(pre)) <= 0)
|
||||
ssl_err("could not SSL_write");
|
||||
remote_write(ssl, fd, pre, strlen(pre));
|
||||
for(i=0; i<argc; i++) {
|
||||
if(SSL_write(ssl, space, (int)strlen(space)) <= 0)
|
||||
ssl_err("could not SSL_write");
|
||||
if(SSL_write(ssl, argv[i], (int)strlen(argv[i])) <= 0)
|
||||
ssl_err("could not SSL_write");
|
||||
remote_write(ssl, fd, space, strlen(space));
|
||||
remote_write(ssl, fd, argv[i], strlen(argv[i]));
|
||||
}
|
||||
if(SSL_write(ssl, newline, (int)strlen(newline)) <= 0)
|
||||
ssl_err("could not SSL_write");
|
||||
remote_write(ssl, fd, newline, strlen(newline));
|
||||
|
||||
if(argc == 1 && strcmp(argv[0], "load_cache") == 0) {
|
||||
send_file(ssl, stdin, buf, sizeof(buf));
|
||||
send_file(ssl, fd, stdin, buf, sizeof(buf));
|
||||
}
|
||||
else if(argc == 1 && (strcmp(argv[0], "local_zones") == 0 ||
|
||||
strcmp(argv[0], "local_zones_remove") == 0 ||
|
||||
strcmp(argv[0], "local_datas") == 0 ||
|
||||
strcmp(argv[0], "local_datas_remove") == 0)) {
|
||||
send_file(ssl, stdin, buf, sizeof(buf));
|
||||
send_eof(ssl);
|
||||
send_file(ssl, fd, stdin, buf, sizeof(buf));
|
||||
send_eof(ssl, fd);
|
||||
}
|
||||
|
||||
while(1) {
|
||||
ERR_clear_error();
|
||||
if((r = SSL_read(ssl, buf, (int)sizeof(buf)-1)) <= 0) {
|
||||
if(SSL_get_error(ssl, r) == SSL_ERROR_ZERO_RETURN) {
|
||||
/* EOF */
|
||||
break;
|
||||
}
|
||||
ssl_err("could not SSL_read");
|
||||
if(remote_read(ssl, fd, buf, sizeof(buf)) == 0) {
|
||||
break; /* EOF */
|
||||
}
|
||||
buf[r] = 0;
|
||||
if(first_line && strncmp(buf, "error", 5) == 0) {
|
||||
printf("%s", buf);
|
||||
was_error = 1;
|
||||
@@ -693,18 +763,18 @@ go(const char* cfgfile, char* svr, int quiet, int argc, char* argv[])
|
||||
|
||||
/* contact server */
|
||||
fd = contact_server(svr, cfg, argc>0&&strcmp(argv[0],"status")==0);
|
||||
ssl = setup_ssl(ctx, fd, cfg);
|
||||
ssl = setup_ssl(ctx, fd);
|
||||
|
||||
/* send command */
|
||||
ret = go_cmd(ssl, quiet, argc, argv);
|
||||
ret = go_cmd(ssl, fd, quiet, argc, argv);
|
||||
|
||||
SSL_free(ssl);
|
||||
if(ssl) SSL_free(ssl);
|
||||
#ifndef USE_WINSOCK
|
||||
close(fd);
|
||||
#else
|
||||
closesocket(fd);
|
||||
#endif
|
||||
SSL_CTX_free(ctx);
|
||||
if(ctx) SSL_CTX_free(ctx);
|
||||
config_delete(cfg);
|
||||
return ret;
|
||||
}
|
||||
|
||||
+33
-3
@@ -66,6 +66,14 @@
|
||||
/* nss3 */
|
||||
#include "nss.h"
|
||||
#endif
|
||||
#ifdef HAVE_SSL
|
||||
#ifdef HAVE_OPENSSL_SSL_H
|
||||
#include <openssl/ssl.h>
|
||||
#endif
|
||||
#ifdef HAVE_OPENSSL_ERR_H
|
||||
#include <openssl/err.h>
|
||||
#endif
|
||||
#endif /* HAVE_SSL */
|
||||
|
||||
/** verbosity for unbound-host app */
|
||||
static int verb = 0;
|
||||
@@ -74,9 +82,8 @@ static int verb = 0;
|
||||
static void
|
||||
usage(void)
|
||||
{
|
||||
printf("Usage: unbound-host [-vdhr46] [-c class] [-t type] hostname\n");
|
||||
printf(" [-y key] [-f keyfile] [-F namedkeyfile]\n");
|
||||
printf(" [-C configfile]\n");
|
||||
printf("Usage: unbound-host [-C configfile] [-vdhr46] [-c class] [-t type]\n");
|
||||
printf(" [-y key] [-f keyfile] [-F namedkeyfile] hostname\n");
|
||||
printf(" Queries the DNS for information.\n");
|
||||
printf(" The hostname is looked up for IP4, IP6 and mail.\n");
|
||||
printf(" If an ip-address is given a reverse lookup is done.\n");
|
||||
@@ -90,6 +97,8 @@ usage(void)
|
||||
printf(" -f keyfile read trust anchors from file, with lines as -y.\n");
|
||||
printf(" -F keyfile read named.conf-style trust anchors.\n");
|
||||
printf(" -C config use the specified unbound.conf (none read by default)\n");
|
||||
printf(" pass as first argument if you want to override some\n");
|
||||
printf(" options with further arguments\n");
|
||||
printf(" -r read forwarder information from /etc/resolv.conf\n");
|
||||
printf(" breaks validation if the forwarder does not do DNSSEC.\n");
|
||||
printf(" -v be more verbose, shows nodata and security.\n");
|
||||
@@ -331,6 +340,7 @@ pretty_output(char* q, int t, int c, struct ub_result* result, int docname)
|
||||
exit(1);
|
||||
}
|
||||
printf("%s\n", s);
|
||||
free(s);
|
||||
} else printf(" has no %s record", tstr);
|
||||
printf(" %s\n", secstatus);
|
||||
}
|
||||
@@ -487,6 +497,26 @@ int main(int argc, char* argv[])
|
||||
if(argc != 1)
|
||||
usage();
|
||||
|
||||
#ifdef HAVE_SSL
|
||||
#ifdef HAVE_ERR_LOAD_CRYPTO_STRINGS
|
||||
ERR_load_crypto_strings();
|
||||
#endif
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10100000 || !defined(HAVE_OPENSSL_INIT_SSL)
|
||||
ERR_load_SSL_strings();
|
||||
#endif
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10100000 || !defined(HAVE_OPENSSL_INIT_CRYPTO)
|
||||
OpenSSL_add_all_algorithms();
|
||||
#else
|
||||
OPENSSL_init_crypto(OPENSSL_INIT_ADD_ALL_CIPHERS
|
||||
| OPENSSL_INIT_ADD_ALL_DIGESTS
|
||||
| OPENSSL_INIT_LOAD_CRYPTO_STRINGS, NULL);
|
||||
#endif
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10100000 || !defined(HAVE_OPENSSL_INIT_SSL)
|
||||
(void)SSL_library_init();
|
||||
#else
|
||||
(void)OPENSSL_init_ssl(OPENSSL_INIT_LOAD_SSL_STRINGS, NULL);
|
||||
#endif
|
||||
#endif /* HAVE_SSL */
|
||||
#ifdef HAVE_NSS
|
||||
if(NSS_NoDB_Init(".") != SECSuccess) {
|
||||
fprintf(stderr, "could not init NSS\n");
|
||||
|
||||
@@ -105,7 +105,7 @@ struct outbound_entry* worker_send_query(
|
||||
int ATTR_UNUSED(nocaps), struct sockaddr_storage* ATTR_UNUSED(addr),
|
||||
socklen_t ATTR_UNUSED(addrlen), uint8_t* ATTR_UNUSED(zone),
|
||||
size_t ATTR_UNUSED(zonelen), int ATTR_UNUSED(ssl_upstream),
|
||||
struct module_qstate* ATTR_UNUSED(q))
|
||||
char* ATTR_UNUSED(tls_auth_name), struct module_qstate* ATTR_UNUSED(q))
|
||||
{
|
||||
log_assert(0);
|
||||
return 0;
|
||||
@@ -137,7 +137,7 @@ struct outbound_entry* libworker_send_query(
|
||||
int ATTR_UNUSED(nocaps), struct sockaddr_storage* ATTR_UNUSED(addr),
|
||||
socklen_t ATTR_UNUSED(addrlen), uint8_t* ATTR_UNUSED(zone),
|
||||
size_t ATTR_UNUSED(zonelen), int ATTR_UNUSED(ssl_upstream),
|
||||
struct module_qstate* ATTR_UNUSED(q))
|
||||
char* ATTR_UNUSED(tls_auth_name), struct module_qstate* ATTR_UNUSED(q))
|
||||
{
|
||||
log_assert(0);
|
||||
return 0;
|
||||
@@ -168,21 +168,21 @@ void libworker_handle_control_cmd(struct tube* ATTR_UNUSED(tube),
|
||||
|
||||
void libworker_fg_done_cb(void* ATTR_UNUSED(arg), int ATTR_UNUSED(rcode),
|
||||
struct sldns_buffer* ATTR_UNUSED(buf), enum sec_status ATTR_UNUSED(s),
|
||||
char* ATTR_UNUSED(why_bogus))
|
||||
char* ATTR_UNUSED(why_bogus), int ATTR_UNUSED(was_ratelimited))
|
||||
{
|
||||
log_assert(0);
|
||||
}
|
||||
|
||||
void libworker_bg_done_cb(void* ATTR_UNUSED(arg), int ATTR_UNUSED(rcode),
|
||||
struct sldns_buffer* ATTR_UNUSED(buf), enum sec_status ATTR_UNUSED(s),
|
||||
char* ATTR_UNUSED(why_bogus))
|
||||
char* ATTR_UNUSED(why_bogus), int ATTR_UNUSED(was_ratelimited))
|
||||
{
|
||||
log_assert(0);
|
||||
}
|
||||
|
||||
void libworker_event_done_cb(void* ATTR_UNUSED(arg), int ATTR_UNUSED(rcode),
|
||||
struct sldns_buffer* ATTR_UNUSED(buf), enum sec_status ATTR_UNUSED(s),
|
||||
char* ATTR_UNUSED(why_bogus))
|
||||
char* ATTR_UNUSED(why_bogus), int ATTR_UNUSED(was_ratelimited))
|
||||
{
|
||||
log_assert(0);
|
||||
}
|
||||
|
||||
+44
-8
@@ -56,6 +56,15 @@
|
||||
#undef free
|
||||
#undef strdup
|
||||
#endif
|
||||
#ifdef HAVE_SSL
|
||||
#ifdef HAVE_OPENSSL_SSL_H
|
||||
#include <openssl/ssl.h>
|
||||
#endif
|
||||
#ifdef HAVE_OPENSSL_ERR_H
|
||||
#include <openssl/err.h>
|
||||
#endif
|
||||
#endif /* HAVE_SSL */
|
||||
|
||||
|
||||
/** keeping track of the async ids */
|
||||
struct track_id {
|
||||
@@ -173,6 +182,8 @@ struct ext_thr_info {
|
||||
char** argv;
|
||||
/** number of queries to do */
|
||||
int numq;
|
||||
/** list of ids to free once threads are done */
|
||||
struct track_id* id_list;
|
||||
};
|
||||
|
||||
/** if true, we are testing against 'localhost' and extra checking is done */
|
||||
@@ -300,6 +311,7 @@ ext_thread(void* arg)
|
||||
for(i=0; i<inf->numq; i++) {
|
||||
lock_basic_init(&async_ids[i].lock);
|
||||
}
|
||||
inf->id_list = async_ids;
|
||||
}
|
||||
for(i=0; i<inf->numq; i++) {
|
||||
if(async_ids) {
|
||||
@@ -338,14 +350,6 @@ ext_thread(void* arg)
|
||||
/* if these locks are destroyed, or if the async_ids is freed, then
|
||||
a use-after-free happens in another thread.
|
||||
The allocation is only part of this test, though. */
|
||||
/*
|
||||
if(async_ids) {
|
||||
for(i=0; i<inf->numq; i++) {
|
||||
lock_basic_destroy(&async_ids[i].lock);
|
||||
}
|
||||
}
|
||||
free(async_ids);
|
||||
*/
|
||||
|
||||
return NULL;
|
||||
}
|
||||
@@ -366,6 +370,7 @@ ext_test(struct ub_ctx* ctx, int argc, char** argv)
|
||||
inf[i].argc = argc;
|
||||
inf[i].argv = argv;
|
||||
inf[i].numq = 100;
|
||||
inf[i].id_list = NULL;
|
||||
ub_thread_create(&inf[i].tid, ext_thread, &inf[i]);
|
||||
}
|
||||
/* the work happens here */
|
||||
@@ -373,6 +378,16 @@ ext_test(struct ub_ctx* ctx, int argc, char** argv)
|
||||
ub_thread_join(inf[i].tid);
|
||||
}
|
||||
printf("extended test end\n");
|
||||
/* free the id lists */
|
||||
for(i=0; i<NUMTHR; i++) {
|
||||
if(inf[i].id_list) {
|
||||
int j;
|
||||
for(j=0; j<inf[i].numq; j++) {
|
||||
lock_basic_destroy(&inf[i].id_list[j].lock);
|
||||
}
|
||||
free(inf[i].id_list);
|
||||
}
|
||||
}
|
||||
ub_ctx_delete(ctx);
|
||||
checklock_stop();
|
||||
return 0;
|
||||
@@ -459,6 +474,27 @@ int main(int argc, char** argv)
|
||||
argc -= optind;
|
||||
argv += optind;
|
||||
|
||||
#ifdef HAVE_SSL
|
||||
#ifdef HAVE_ERR_LOAD_CRYPTO_STRINGS
|
||||
ERR_load_crypto_strings();
|
||||
#endif
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10100000 || !defined(HAVE_OPENSSL_INIT_SSL)
|
||||
ERR_load_SSL_strings();
|
||||
#endif
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10100000 || !defined(HAVE_OPENSSL_INIT_CRYPTO)
|
||||
OpenSSL_add_all_algorithms();
|
||||
#else
|
||||
OPENSSL_init_crypto(OPENSSL_INIT_ADD_ALL_CIPHERS
|
||||
| OPENSSL_INIT_ADD_ALL_DIGESTS
|
||||
| OPENSSL_INIT_LOAD_CRYPTO_STRINGS, NULL);
|
||||
#endif
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10100000 || !defined(HAVE_OPENSSL_INIT_SSL)
|
||||
(void)SSL_library_init();
|
||||
#else
|
||||
(void)OPENSSL_init_ssl(OPENSSL_INIT_LOAD_SSL_STRINGS, NULL);
|
||||
#endif
|
||||
#endif /* HAVE_SSL */
|
||||
|
||||
if(ext)
|
||||
return ext_test(ctx, argc, argv);
|
||||
|
||||
|
||||
+1
-1
@@ -788,7 +788,7 @@ service_tcp_relay(struct tcp_proxy** tcp_proxies, struct timeval* now,
|
||||
if(!tcp_relay_write(p->server_s, &p->querylist,
|
||||
&p->querylast, now))
|
||||
delete_it = 1;
|
||||
if(p->querylist && p->server_s != -1 &&
|
||||
if(p->querylist &&
|
||||
dl_tv_smaller(&p->querylist->wait, now))
|
||||
FD_SET(FD_SET_T p->server_s, worig);
|
||||
else FD_CLR(FD_SET_T p->server_s, worig);
|
||||
|
||||
+25
-11
@@ -374,8 +374,11 @@ answer_callback_from_entry(struct replay_runtime* runtime,
|
||||
c.fd = -1;
|
||||
c.buffer = sldns_buffer_new(runtime->bufsize);
|
||||
c.type = comm_udp;
|
||||
if(pend->transport == transport_tcp)
|
||||
if(pend->transport == transport_tcp) {
|
||||
c.type = comm_tcp;
|
||||
c.tcp_timeout_msec = 30000;
|
||||
c.tcp_keepalive = runtime->tcp_seen_keepalive;
|
||||
}
|
||||
fill_buffer_with_reply(c.buffer, entry, pend->pkt, pend->pkt_len,
|
||||
pend->tcp_pkt_counter);
|
||||
repinfo.c = &c;
|
||||
@@ -423,6 +426,8 @@ answer_check_it(struct replay_runtime* runtime)
|
||||
else runtime->answer_list = ans->next;
|
||||
if(!ans->next)
|
||||
runtime->answer_last = prev;
|
||||
if(ans->repinfo.c->tcp_keepalive)
|
||||
runtime->tcp_seen_keepalive = 1;
|
||||
delete_replay_answer(ans);
|
||||
return;
|
||||
} else {
|
||||
@@ -452,9 +457,12 @@ fake_front_query(struct replay_runtime* runtime, struct replay_moment *todo)
|
||||
repinfo.c->fd = -1;
|
||||
repinfo.c->ev = (struct internal_event*)runtime;
|
||||
repinfo.c->buffer = sldns_buffer_new(runtime->bufsize);
|
||||
if(todo->match->match_transport == transport_tcp)
|
||||
if(todo->match->match_transport == transport_tcp) {
|
||||
repinfo.c->type = comm_tcp;
|
||||
else repinfo.c->type = comm_udp;
|
||||
repinfo.c->tcp_timeout_msec = 30000;
|
||||
repinfo.c->tcp_keepalive = runtime->tcp_seen_keepalive;
|
||||
} else
|
||||
repinfo.c->type = comm_udp;
|
||||
fill_buffer_with_reply(repinfo.c->buffer, todo->match, NULL, 0, 0);
|
||||
log_info("testbound: incoming QUERY");
|
||||
log_pkt("query pkt", todo->match->reply_list->reply_pkt,
|
||||
@@ -488,8 +496,11 @@ fake_pending_callback(struct replay_runtime* runtime,
|
||||
cb = p->callback;
|
||||
c.buffer = sldns_buffer_new(runtime->bufsize);
|
||||
c.type = comm_udp;
|
||||
if(p->transport == transport_tcp)
|
||||
if(p->transport == transport_tcp) {
|
||||
c.type = comm_tcp;
|
||||
c.tcp_timeout_msec = 30000;
|
||||
c.tcp_keepalive = runtime->tcp_seen_keepalive;
|
||||
}
|
||||
if(todo->evt_type == repevt_back_reply && todo->match) {
|
||||
fill_buffer_with_reply(c.buffer, todo->match, p->pkt,
|
||||
p->pkt_len, p->tcp_pkt_counter);
|
||||
@@ -856,6 +867,8 @@ run_scenario(struct replay_runtime* runtime)
|
||||
struct listen_dnsport*
|
||||
listen_create(struct comm_base* base, struct listen_port* ATTR_UNUSED(ports),
|
||||
size_t bufsize, int ATTR_UNUSED(tcp_accept_count),
|
||||
int ATTR_UNUSED(tcp_idle_timeout),
|
||||
struct tcl_list* ATTR_UNUSED(tcp_conn_limit),
|
||||
void* ATTR_UNUSED(sslctx), struct dt_env* ATTR_UNUSED(dtenv),
|
||||
comm_point_callback_type* cb, void* cb_arg)
|
||||
{
|
||||
@@ -1125,7 +1138,7 @@ pending_tcp_query(struct serviced_query* sq, sldns_buffer* packet,
|
||||
pend->addrlen = sq->addrlen;
|
||||
pend->callback = callback;
|
||||
pend->cb_arg = callback_arg;
|
||||
pend->timeout = timeout;
|
||||
pend->timeout = timeout/1000;
|
||||
pend->transport = transport_tcp;
|
||||
pend->pkt = NULL;
|
||||
pend->zone = NULL;
|
||||
@@ -1161,10 +1174,11 @@ struct serviced_query* outnet_serviced_query(struct outside_network* outnet,
|
||||
struct query_info* qinfo, uint16_t flags, int dnssec,
|
||||
int ATTR_UNUSED(want_dnssec), int ATTR_UNUSED(nocaps),
|
||||
int ATTR_UNUSED(tcp_upstream), int ATTR_UNUSED(ssl_upstream),
|
||||
struct sockaddr_storage* addr, socklen_t addrlen, uint8_t* zone,
|
||||
size_t zonelen, struct module_qstate* qstate,
|
||||
comm_point_callback_type* callback, void* callback_arg,
|
||||
sldns_buffer* ATTR_UNUSED(buff), struct module_env* ATTR_UNUSED(env))
|
||||
char* ATTR_UNUSED(tls_auth_name), struct sockaddr_storage* addr,
|
||||
socklen_t addrlen, uint8_t* zone, size_t zonelen,
|
||||
struct module_qstate* qstate, comm_point_callback_type* callback,
|
||||
void* callback_arg, sldns_buffer* ATTR_UNUSED(buff),
|
||||
struct module_env* ATTR_UNUSED(env))
|
||||
{
|
||||
struct replay_runtime* runtime = (struct replay_runtime*)outnet->base;
|
||||
struct fake_pending* pend = (struct fake_pending*)calloc(1,
|
||||
@@ -1217,7 +1231,7 @@ struct serviced_query* outnet_serviced_query(struct outside_network* outnet,
|
||||
log_assert(pend->zone);
|
||||
pend->callback = callback;
|
||||
pend->cb_arg = callback_arg;
|
||||
pend->timeout = UDP_AUTH_QUERY_TIMEOUT;
|
||||
pend->timeout = UDP_AUTH_QUERY_TIMEOUT/1000;
|
||||
pend->transport = transport_udp; /* pretend UDP */
|
||||
pend->pkt = NULL;
|
||||
pend->runtime = runtime;
|
||||
@@ -1756,7 +1770,7 @@ int comm_point_send_udp_msg(struct comm_point *c, sldns_buffer* packet,
|
||||
}
|
||||
pend->callback = fc->cb;
|
||||
pend->cb_arg = fc->cb_arg;
|
||||
pend->timeout = UDP_AUTH_QUERY_TIMEOUT;
|
||||
pend->timeout = UDP_AUTH_QUERY_TIMEOUT/1000;
|
||||
pend->transport = transport_udp;
|
||||
pend->pkt = NULL;
|
||||
pend->runtime = runtime;
|
||||
|
||||
+3
-3
@@ -610,7 +610,7 @@ int main(int argc, char* argv[])
|
||||
case 'd':
|
||||
if(atoi(optarg)==0 && strcmp(optarg, "0")!=0) {
|
||||
printf("-d not a number %s", optarg);
|
||||
return 1;
|
||||
exit(1);
|
||||
}
|
||||
info.duration = atoi(optarg);
|
||||
break;
|
||||
@@ -635,11 +635,11 @@ int main(int argc, char* argv[])
|
||||
}
|
||||
if(!extstrtoaddr(argv[0], &info.dest, &info.destlen)) {
|
||||
printf("Could not parse ip: %s\n", argv[0]);
|
||||
return 1;
|
||||
exit(1);
|
||||
}
|
||||
if(info.qlist_size == 0) {
|
||||
printf("No queries to make, use -f or -a.\n");
|
||||
return 1;
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* do the performance test */
|
||||
|
||||
+6
-4
@@ -417,7 +417,7 @@ provide_file_10(SSL* ssl, char* fname)
|
||||
}
|
||||
fclose(in);
|
||||
at += len;
|
||||
avail -= len;
|
||||
/* avail -= len; unused */
|
||||
if(SSL_write(ssl, buf, at-buf) <= 0) {
|
||||
/* write failure */
|
||||
}
|
||||
@@ -506,7 +506,7 @@ provide_file_chunked(SSL* ssl, char* fname)
|
||||
snprintf(at, avail, "\r\n");
|
||||
r = strlen(at);
|
||||
at += r;
|
||||
avail -= r;
|
||||
/* avail -= r; unused */
|
||||
}
|
||||
/* send chunk */
|
||||
if(SSL_write(ssl, buf, at-buf) <= 0) {
|
||||
@@ -569,7 +569,9 @@ do_service(char* addr, int port, char* key, char* cert)
|
||||
while(go) {
|
||||
struct sockaddr_storage from;
|
||||
socklen_t flen = (socklen_t)sizeof(from);
|
||||
int s = accept(fd, (struct sockaddr*)&from, &flen);
|
||||
int s;
|
||||
memset(&from, 0, sizeof(from));
|
||||
s = accept(fd, (struct sockaddr*)&from, &flen);
|
||||
if(verb) fflush(stdout);
|
||||
if(s != -1) {
|
||||
SSL* ssl = setup_ssl(s, sslctx);
|
||||
@@ -633,7 +635,7 @@ int main(int argc, char* argv[])
|
||||
}
|
||||
}
|
||||
argc -= optind;
|
||||
argv += optind;
|
||||
/* argv += optind; not using further arguments */
|
||||
if(argc != 0)
|
||||
usage();
|
||||
|
||||
|
||||
+11
-4
@@ -458,6 +458,8 @@ replay_scenario_read(FILE* in, const char* name, int* lineno)
|
||||
if(parse_keyword(&parse, ";"))
|
||||
continue; /* comment */
|
||||
if(parse_keyword(&parse, "SCENARIO_BEGIN")) {
|
||||
if(scen)
|
||||
fatal_exit("%d: double SCENARIO_BEGIN", *lineno);
|
||||
scen = make_scenario(parse);
|
||||
if(!scen)
|
||||
fatal_exit("%d: could not make scen", *lineno);
|
||||
@@ -801,14 +803,19 @@ macro_expand(rbtree_type* store, struct replay_runtime* runtime, char** text)
|
||||
|
||||
/* check for functions */
|
||||
if(strcmp(buf, "time") == 0) {
|
||||
snprintf(buf, sizeof(buf), ARG_LL "d", (long long)runtime->now_secs);
|
||||
if(runtime)
|
||||
snprintf(buf, sizeof(buf), ARG_LL "d", (long long)runtime->now_secs);
|
||||
else
|
||||
snprintf(buf, sizeof(buf), ARG_LL "d", (long long)0);
|
||||
*text += len;
|
||||
return strdup(buf);
|
||||
} else if(strcmp(buf, "timeout") == 0) {
|
||||
time_t res = 0;
|
||||
struct fake_timer* t = first_timer(runtime);
|
||||
if(t && (time_t)t->tv.tv_sec >= runtime->now_secs)
|
||||
res = (time_t)t->tv.tv_sec - runtime->now_secs;
|
||||
if(runtime) {
|
||||
struct fake_timer* t = first_timer(runtime);
|
||||
if(t && (time_t)t->tv.tv_sec >= runtime->now_secs)
|
||||
res = (time_t)t->tv.tv_sec - runtime->now_secs;
|
||||
}
|
||||
snprintf(buf, sizeof(buf), ARG_LL "d", (long long)res);
|
||||
*text += len;
|
||||
return strdup(buf);
|
||||
|
||||
@@ -303,6 +303,9 @@ struct replay_runtime {
|
||||
/** the current time in microseconds */
|
||||
struct timeval now_tv;
|
||||
|
||||
/** has TCP connection seen a keepalive? */
|
||||
int tcp_seen_keepalive;
|
||||
|
||||
/** signal handler callback */
|
||||
void (*sig_cb)(int, void*);
|
||||
/** signal handler user arg */
|
||||
|
||||
@@ -12,6 +12,8 @@
|
||||
.RB [ \-unsh ]
|
||||
.RB [ \-f
|
||||
.IR ipaddr[@port] ]
|
||||
.RB [ \-d
|
||||
.IR secs ]
|
||||
.I name
|
||||
.I type
|
||||
.I class
|
||||
@@ -50,6 +52,10 @@ Print program usage.
|
||||
.TP
|
||||
.B \-f \fIipaddr[@port]
|
||||
Specify the server to send the queries to. If not specified localhost (127.0.0.1) is used.
|
||||
.TP
|
||||
.B \-d \fIsecs
|
||||
Delay after the connection before sending query. This tests the timeout
|
||||
on the other side, eg. if shorter the connection is closed.
|
||||
.SH "EXAMPLES"
|
||||
.LP
|
||||
Some examples of use.
|
||||
|
||||
+24
-4
@@ -44,6 +44,8 @@
|
||||
#include <getopt.h>
|
||||
#endif
|
||||
#include <signal.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include "util/locks.h"
|
||||
#include "util/log.h"
|
||||
#include "util/net_help.h"
|
||||
@@ -71,6 +73,7 @@ static void usage(char* argv[])
|
||||
printf("-f server what ipaddr@portnr to send the queries to\n");
|
||||
printf("-u use UDP. No retries are attempted.\n");
|
||||
printf("-n do not wait for an answer.\n");
|
||||
printf("-d secs delay after connection before sending query\n");
|
||||
printf("-s use ssl\n");
|
||||
printf("-h this help text\n");
|
||||
exit(1);
|
||||
@@ -275,7 +278,8 @@ static int get_random(void)
|
||||
|
||||
/** send the TCP queries and print answers */
|
||||
static void
|
||||
send_em(const char* svr, int udp, int usessl, int noanswer, int num, char** qs)
|
||||
send_em(const char* svr, int udp, int usessl, int noanswer, int delay,
|
||||
int num, char** qs)
|
||||
{
|
||||
sldns_buffer* buf = sldns_buffer_new(65553);
|
||||
int fd = open_svr(svr, udp);
|
||||
@@ -284,7 +288,7 @@ send_em(const char* svr, int udp, int usessl, int noanswer, int num, char** qs)
|
||||
SSL* ssl = NULL;
|
||||
if(!buf) fatal_exit("out of memory");
|
||||
if(usessl) {
|
||||
ctx = connect_sslctx_create(NULL, NULL, NULL);
|
||||
ctx = connect_sslctx_create(NULL, NULL, NULL, 0);
|
||||
if(!ctx) fatal_exit("cannot create ssl ctx");
|
||||
ssl = outgoing_ssl_fd(ctx, fd);
|
||||
if(!ssl) fatal_exit("cannot create ssl");
|
||||
@@ -310,6 +314,13 @@ send_em(const char* svr, int udp, int usessl, int noanswer, int num, char** qs)
|
||||
}
|
||||
}
|
||||
for(i=0; i<num; i+=3) {
|
||||
if (delay != 0) {
|
||||
#ifdef HAVE_SLEEP
|
||||
sleep((unsigned)delay);
|
||||
#else
|
||||
Sleep(delay*1000);
|
||||
#endif
|
||||
}
|
||||
printf("\nNext query is %s %s %s\n", qs[i], qs[i+1], qs[i+2]);
|
||||
write_q(fd, udp, ssl, buf, (uint16_t)get_random(), qs[i],
|
||||
qs[i+1], qs[i+2]);
|
||||
@@ -358,6 +369,7 @@ int main(int argc, char** argv)
|
||||
int udp = 0;
|
||||
int noanswer = 0;
|
||||
int usessl = 0;
|
||||
int delay = 0;
|
||||
|
||||
#ifdef USE_WINSOCK
|
||||
WSADATA wsa_data;
|
||||
@@ -382,7 +394,7 @@ int main(int argc, char** argv)
|
||||
if(argc == 1) {
|
||||
usage(argv);
|
||||
}
|
||||
while( (c=getopt(argc, argv, "f:hnsu")) != -1) {
|
||||
while( (c=getopt(argc, argv, "f:hnsud:")) != -1) {
|
||||
switch(c) {
|
||||
case 'f':
|
||||
svr = optarg;
|
||||
@@ -396,6 +408,14 @@ int main(int argc, char** argv)
|
||||
case 's':
|
||||
usessl = 1;
|
||||
break;
|
||||
case 'd':
|
||||
if(atoi(optarg)==0 && strcmp(optarg,"0")!=0) {
|
||||
printf("error parsing delay, "
|
||||
"number expected: %s\n", optarg);
|
||||
return 1;
|
||||
}
|
||||
delay = atoi(optarg);
|
||||
break;
|
||||
case 'h':
|
||||
case '?':
|
||||
default:
|
||||
@@ -426,7 +446,7 @@ int main(int argc, char** argv)
|
||||
(void)OPENSSL_init_ssl(OPENSSL_INIT_LOAD_SSL_STRINGS, NULL);
|
||||
#endif
|
||||
}
|
||||
send_em(svr, udp, usessl, noanswer, argc, argv);
|
||||
send_em(svr, udp, usessl, noanswer, delay, argc, argv);
|
||||
checklock_stop();
|
||||
#ifdef USE_WINSOCK
|
||||
WSACleanup();
|
||||
|
||||
@@ -177,7 +177,8 @@ spool_temp_file(FILE* in, int* lineno, char* id)
|
||||
while(isspace((unsigned char)*parse))
|
||||
parse++;
|
||||
if(strncmp(parse, "$INCLUDE_TEMPFILE", 17) == 0) {
|
||||
char l2[MAX_LINE_LEN];
|
||||
char l2[MAX_LINE_LEN-30]; /* -30 makes it fit with
|
||||
a preceding $INCLUDE in the buf line[] */
|
||||
char* tid = parse+17;
|
||||
while(isspace((unsigned char)*tid))
|
||||
tid++;
|
||||
@@ -428,14 +429,14 @@ main(int argc, char* argv[])
|
||||
case 'h':
|
||||
default:
|
||||
testbound_usage();
|
||||
return 1;
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
argc -= optind;
|
||||
argv += optind;
|
||||
/* argv += optind; not using further arguments */
|
||||
if(argc != 0) {
|
||||
testbound_usage();
|
||||
return 1;
|
||||
exit(1);
|
||||
}
|
||||
log_info("Start of %s testbound program.", PACKAGE_STRING);
|
||||
if(atexit(&remove_configfile) != 0)
|
||||
|
||||
@@ -46,6 +46,7 @@ enum verbosity_value { NO_VERBOSE=0 };
|
||||
#endif
|
||||
/** logging routine, provided by caller */
|
||||
void verbose(enum verbosity_value lvl, const char* msg, ...) ATTR_FORMAT(printf, 2, 3);
|
||||
static void error(const char* msg, ...) ATTR_NORETURN;
|
||||
|
||||
/** print error and exit */
|
||||
static void error(const char* msg, ...)
|
||||
|
||||
+14
-2
@@ -111,8 +111,9 @@ static const char* zone_example_com =
|
||||
/* just an RRSIG rrset with nothing else, 2 rrsigs */
|
||||
"z5.example.com. 3600 IN RRSIG A 8 3 10200 20170612005010 20170515005010 42393 nlnetlabs.nl. NhEDrHkuIgHkjWhDRVsGOIJWZpSs+QdduilWFe5d+/ZhOheLJbaTYD5w6+ZZ3yPh1tNud+jlg+GyiOSVapLEO31swDCIarL1UfRjRSpxxDCHGag5Zu+S4hF+KURxO3cJk8jLBELMQyRuMRHoKrw/wsiLGVu1YpAyAPPMcjFBNbk=\n"
|
||||
"z5.example.com. 3600 IN RRSIG A 8 3 10200 20170612005010 20170515005010 12345 nlnetlabs.nl. NhEDrHkuIgHkjWhDRVsGOIJWZpSs+QdduilWFe5d+/ZhOheLJbaTYD5w6+ZZ3yPh1tNud+jlg+GyiOSVapLEO31swDCIarL1UfRjRSpxxDCHGag5Zu+S4hF+KURxO3cJk8jLBELMQyRuMRHoKrw/wsiLGVu1YpAyAPPMcjFBNbk=\n"
|
||||
#if 0 /* comparison of file does not work on this part because duplicates */
|
||||
#if 1 /* comparison of file does not work on this part because duplicates */
|
||||
/* are removed and the rrsets are reordered */
|
||||
"end_of_check.z6.example.com. 3600 IN A 10.0.0.10\n"
|
||||
/* first rrsig, then A record */
|
||||
"z6.example.com. 3600 IN RRSIG A 8 3 10200 20170612005010 20170515005010 42393 nlnetlabs.nl. NhEDrHkuIgHkjWhDRVsGOIJWZpSs+QdduilWFe5d+/ZhOheLJbaTYD5w6+ZZ3yPh1tNud+jlg+GyiOSVapLEO31swDCIarL1UfRjRSpxxDCHGag5Zu+S4hF+KURxO3cJk8jLBELMQyRuMRHoKrw/wsiLGVu1YpAyAPPMcjFBNbk=\n"
|
||||
"z6.example.com. 3600 IN A 10.0.0.10\n"
|
||||
@@ -131,6 +132,12 @@ static const char* zone_example_com =
|
||||
"z9.example.com. 3600 IN A 10.0.0.10\n"
|
||||
"z9.example.com. 3600 IN RRSIG A 8 3 10200 20170612005010 20170515005010 42393 nlnetlabs.nl. NhEDrHkuIgHkjWhDRVsGOIJWZpSs+QdduilWFe5d+/ZhOheLJbaTYD5w6+ZZ3yPh1tNud+jlg+GyiOSVapLEO31swDCIarL1UfRjRSpxxDCHGag5Zu+S4hF+KURxO3cJk8jLBELMQyRuMRHoKrw/wsiLGVu1YpAyAPPMcjFBNbk=\n"
|
||||
"z9.example.com. 3600 IN RRSIG A 8 3 10200 20170612005010 20170515005010 42393 nlnetlabs.nl. NhEDrHkuIgHkjWhDRVsGOIJWZpSs+QdduilWFe5d+/ZhOheLJbaTYD5w6+ZZ3yPh1tNud+jlg+GyiOSVapLEO31swDCIarL1UfRjRSpxxDCHGag5Zu+S4hF+KURxO3cJk8jLBELMQyRuMRHoKrw/wsiLGVu1YpAyAPPMcjFBNbk=\n"
|
||||
/* different covered types, first RRSIGs then, RRs, then another RRSIG */
|
||||
"zz10.example.com. 3600 IN RRSIG AAAA 8 3 10200 20170612005010 20170515005010 42393 nlnetlabs.nl. NhEDrHkuIgHkjWhDRVsGOIJWZpSs+QdduilWFe5d+/ZhOheLJbaTYD5w6+ZZ3yPh1tNud+jlg+GyiOSVapLEO31swDCIarL1UfRjRSpxxDCHGag5Zu+S4hF+KURxO3cJk8jLBELMQyRuMRHoKrw/wsiLGVu1YpAyAPPMcjFBNbk=\n"
|
||||
"zz10.example.com. 3600 IN RRSIG A 8 3 10200 20170612005010 20170515005010 42393 nlnetlabs.nl. NhEDrHkuIgHkjWhDRVsGOIJWZpSs+QdduilWFe5d+/ZhOheLJbaTYD5w6+ZZ3yPh1tNud+jlg+GyiOSVapLEO31swDCIarL1UfRjRSpxxDCHGag5Zu+S4hF+KURxO3cJk8jLBELMQyRuMRHoKrw/wsiLGVu1YpAyAPPMcjFBNbk=\n"
|
||||
"zz10.example.com. 3600 IN A 10.0.0.10\n"
|
||||
"zz10.example.com. 3600 IN RRSIG CNAME 8 3 10200 20170612005010 20170515005010 42393 nlnetlabs.nl. NhEDrHkuIgHkjWhDRVsGOIJWZpSs+QdduilWFe5d+/ZhOheLJbaTYD5w6+ZZ3yPh1tNud+jlg+GyiOSVapLEO31swDCIarL1UfRjRSpxxDCHGag5Zu+S4hF+KURxO3cJk8jLBELMQyRuMRHoKrw/wsiLGVu1YpAyAPPMcjFBNbk=\n"
|
||||
"zz10.example.com. 3600 IN AAAA ::11\n"
|
||||
#endif /* if0 for duplicates and reordering */
|
||||
;
|
||||
|
||||
@@ -550,11 +557,16 @@ checkfile(char* f1, char *f2)
|
||||
cp2 = fgets(buf2, (int)sizeof(buf2), i2);
|
||||
if((!cp1 && !feof(i1)) || (!cp2 && !feof(i2)))
|
||||
fatal_exit("fgets failed: %s", strerror(errno));
|
||||
if(strncmp(buf1, "end_of_check", 12) == 0) {
|
||||
fclose(i1);
|
||||
fclose(i2);
|
||||
return;
|
||||
}
|
||||
if(strcmp(buf1, buf2) != 0) {
|
||||
log_info("in files %s and %s:%d", f1, f2, line);
|
||||
log_info("'%s'", buf1);
|
||||
log_info("'%s'", buf2);
|
||||
fatal_exit("files are not eqaul");
|
||||
fatal_exit("files are not equal");
|
||||
}
|
||||
}
|
||||
unit_assert(feof(i1) && feof(i2));
|
||||
|
||||
+15
-5
@@ -199,15 +199,25 @@ rr_test_file(const char* input, const char* check)
|
||||
free(back);
|
||||
}
|
||||
|
||||
#define xstr(s) str(s)
|
||||
#define str(s) #s
|
||||
|
||||
#define SRCDIRSTR xstr(SRCDIR)
|
||||
|
||||
/** read rrs to and from string, to and from wireformat */
|
||||
static void
|
||||
rr_tests(void)
|
||||
{
|
||||
rr_test_file("testdata/test_ldnsrr.1", "testdata/test_ldnsrr.c1");
|
||||
rr_test_file("testdata/test_ldnsrr.2", "testdata/test_ldnsrr.c2");
|
||||
rr_test_file("testdata/test_ldnsrr.3", "testdata/test_ldnsrr.c3");
|
||||
rr_test_file("testdata/test_ldnsrr.4", "testdata/test_ldnsrr.c4");
|
||||
rr_test_file("testdata/test_ldnsrr.5", "testdata/test_ldnsrr.c5");
|
||||
rr_test_file(SRCDIRSTR "/testdata/test_ldnsrr.1",
|
||||
SRCDIRSTR "/testdata/test_ldnsrr.c1");
|
||||
rr_test_file(SRCDIRSTR "/testdata/test_ldnsrr.2",
|
||||
SRCDIRSTR "/testdata/test_ldnsrr.c2");
|
||||
rr_test_file(SRCDIRSTR "/testdata/test_ldnsrr.3",
|
||||
SRCDIRSTR "/testdata/test_ldnsrr.c3");
|
||||
rr_test_file(SRCDIRSTR "/testdata/test_ldnsrr.4",
|
||||
SRCDIRSTR "/testdata/test_ldnsrr.c4");
|
||||
rr_test_file(SRCDIRSTR "/testdata/test_ldnsrr.5",
|
||||
SRCDIRSTR "/testdata/test_ldnsrr.c5");
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
+5
-1
@@ -404,12 +404,13 @@ config_tag_test(void)
|
||||
|
||||
#include "util/rtt.h"
|
||||
#include "util/timehist.h"
|
||||
#include "iterator/iterator.h"
|
||||
#include "libunbound/unbound.h"
|
||||
/** test RTT code */
|
||||
static void
|
||||
rtt_test(void)
|
||||
{
|
||||
int init = 376;
|
||||
int init = UNKNOWN_SERVER_NICENESS;
|
||||
int i;
|
||||
struct rtt_info r;
|
||||
unit_show_func("util/rtt.c", "rtt_timeout");
|
||||
@@ -905,6 +906,9 @@ main(int argc, char* argv[])
|
||||
#ifdef CLIENT_SUBNET
|
||||
ecs_test();
|
||||
#endif /* CLIENT_SUBNET */
|
||||
if(log_get_lock()) {
|
||||
lock_quick_destroy((lock_quick_type*)log_get_lock());
|
||||
}
|
||||
checklock_stop();
|
||||
printf("%d checks ok.\n", testcount);
|
||||
#ifdef HAVE_SSL
|
||||
|
||||
+14
-9
@@ -495,6 +495,11 @@ testfromdrillfile(sldns_buffer* pkt, struct alloc_cache* alloc,
|
||||
fclose(in);
|
||||
}
|
||||
|
||||
#define xstr(s) str(s)
|
||||
#define str(s) #s
|
||||
|
||||
#define SRCDIRSTR xstr(SRCDIR)
|
||||
|
||||
void msgparse_test(void)
|
||||
{
|
||||
time_t origttl = MAX_NEG_TTL;
|
||||
@@ -509,27 +514,27 @@ void msgparse_test(void)
|
||||
unit_show_feature("message parse");
|
||||
simpletest(pkt, &alloc, out);
|
||||
/* plain hex dumps, like pcat */
|
||||
testfromfile(pkt, &alloc, out, "testdata/test_packets.1");
|
||||
testfromfile(pkt, &alloc, out, "testdata/test_packets.2");
|
||||
testfromfile(pkt, &alloc, out, "testdata/test_packets.3");
|
||||
testfromfile(pkt, &alloc, out, SRCDIRSTR "/testdata/test_packets.1");
|
||||
testfromfile(pkt, &alloc, out, SRCDIRSTR "/testdata/test_packets.2");
|
||||
testfromfile(pkt, &alloc, out, SRCDIRSTR "/testdata/test_packets.3");
|
||||
/* like from drill -w - */
|
||||
testfromdrillfile(pkt, &alloc, out, "testdata/test_packets.4");
|
||||
testfromdrillfile(pkt, &alloc, out, "testdata/test_packets.5");
|
||||
testfromdrillfile(pkt, &alloc, out, SRCDIRSTR "/testdata/test_packets.4");
|
||||
testfromdrillfile(pkt, &alloc, out, SRCDIRSTR "/testdata/test_packets.5");
|
||||
|
||||
matches_nolocation = 1; /* RR order not important for the next test */
|
||||
testfromdrillfile(pkt, &alloc, out, "testdata/test_packets.6");
|
||||
testfromdrillfile(pkt, &alloc, out, SRCDIRSTR "/testdata/test_packets.6");
|
||||
check_rrsigs = 1;
|
||||
testfromdrillfile(pkt, &alloc, out, "testdata/test_packets.7");
|
||||
testfromdrillfile(pkt, &alloc, out, SRCDIRSTR "/testdata/test_packets.7");
|
||||
check_rrsigs = 0;
|
||||
matches_nolocation = 0;
|
||||
|
||||
check_formerr_gone = 1;
|
||||
testfromdrillfile(pkt, &alloc, out, "testdata/test_packets.8");
|
||||
testfromdrillfile(pkt, &alloc, out, SRCDIRSTR "/testdata/test_packets.8");
|
||||
check_formerr_gone = 0;
|
||||
|
||||
check_rrsigs = 1;
|
||||
check_nosameness = 1;
|
||||
testfromdrillfile(pkt, &alloc, out, "testdata/test_packets.9");
|
||||
testfromdrillfile(pkt, &alloc, out, SRCDIRSTR "/testdata/test_packets.9");
|
||||
check_nosameness = 0;
|
||||
check_rrsigs = 0;
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user