mirror of
https://github.com/NLnetLabs/unbound.git
synced 2026-09-07 10:27:44 +02:00
Compare commits
274
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
42730aad99 | ||
|
|
8def9c1043 | ||
|
|
ecf4deedbe | ||
|
|
139ab47dc6 | ||
|
|
608f82a1cd | ||
|
|
5cbf6d059b | ||
|
|
a11fbf9ca0 | ||
|
|
30a339d1a8 | ||
|
|
92e1ec3444 | ||
|
|
62eea87455 | ||
|
|
30602d5d59 | ||
|
|
b23ed42b55 | ||
|
|
784d659e91 | ||
|
|
4df60a1343 | ||
|
|
ca38a8bd55 | ||
|
|
6e9d8fb22c | ||
|
|
35140bb612 | ||
|
|
de82245d3e | ||
|
|
3922eed584 | ||
|
|
efb9c02d54 | ||
|
|
04fa474ac3 | ||
|
|
3c87eb6c49 | ||
|
|
fcc7f9dae0 | ||
|
|
654a9160f5 | ||
|
|
682ad09bc4 | ||
|
|
ffb54322cb | ||
|
|
cc763c103b | ||
|
|
9053ee101d | ||
|
|
0b0a580422 | ||
|
|
b4a089ff0d | ||
|
|
ee6f5c5b51 | ||
|
|
c2299a3c5f | ||
|
|
255d669e58 | ||
|
|
c07e17fda3 | ||
|
|
d8928e1b19 | ||
|
|
01dd4a3568 | ||
|
|
1550bc65f3 | ||
|
|
4011c3861b | ||
|
|
58c2cc2740 | ||
|
|
87296966ae | ||
|
|
eed924d7be | ||
|
|
36d5a75848 | ||
|
|
5996f3b2a9 | ||
|
|
5e2a137562 | ||
|
|
5a154aeb78 | ||
|
|
5ecf75d623 | ||
|
|
797ef20155 | ||
|
|
f7b911b120 | ||
|
|
5feb72d1eb | ||
|
|
22ac684cd9 | ||
|
|
e2dc829258 | ||
|
|
f5a97a3e8f | ||
|
|
790cb51775 | ||
|
|
eaee99fa3b | ||
|
|
583eabb13e | ||
|
|
4a746142cf | ||
|
|
62230b5e04 | ||
|
|
b25ebf0be2 | ||
|
|
35c3a25896 | ||
|
|
6457e97255 | ||
|
|
05e9f914c5 | ||
|
|
046143af20 | ||
|
|
c71f33ead4 | ||
|
|
0bc54677db | ||
|
|
003658eea0 | ||
|
|
15b14306ed | ||
|
|
daab92e954 | ||
|
|
f378068b32 | ||
|
|
e9582487d9 | ||
|
|
c4c8a65ff2 | ||
|
|
f8796f94f4 | ||
|
|
ecb9db442d | ||
|
|
bc7ac1981a | ||
|
|
57f309ab1d | ||
|
|
dd8e44ac37 | ||
|
|
9997255caa | ||
|
|
79f4ca6a28 | ||
|
|
78cc3d8ae1 | ||
|
|
5e62750fcd | ||
|
|
289f13bc25 | ||
|
|
8c5b3d3c8f | ||
|
|
e430e8cef8 | ||
|
|
95da05c4bc | ||
|
|
c9dbc9907a | ||
|
|
6976832ffe | ||
|
|
2fe65ab2b5 | ||
|
|
4e8ae039fa | ||
|
|
c140638659 | ||
|
|
0b30fca935 | ||
|
|
f41a92daf5 | ||
|
|
93e8ff1bb0 | ||
|
|
04e45f98d6 | ||
|
|
08c580bb32 | ||
|
|
d748bca7de | ||
|
|
a3a1119f54 | ||
|
|
74505ea3f2 | ||
|
|
98c4161631 | ||
|
|
4bc34509fa | ||
|
|
f625bfdd15 | ||
|
|
93ffd44608 | ||
|
|
fcf1157fa4 | ||
|
|
488aee467a | ||
|
|
ba340cd07a | ||
|
|
1eb0eea744 | ||
|
|
25ea68e730 | ||
|
|
881245fa9d | ||
|
|
d7a6b3f914 | ||
|
|
f794810a5f | ||
|
|
758a42643a | ||
|
|
fdfa7b2793 | ||
|
|
a6b302f117 | ||
|
|
498cc8ab88 | ||
|
|
a032ac2f61 | ||
|
|
a72fe210ca | ||
|
|
573ce5a4de | ||
|
|
4dca799fbf | ||
|
|
f2ae3e8167 | ||
|
|
d0f2287d44 | ||
|
|
5533861c28 | ||
|
|
2bdb094f7b | ||
|
|
25a2e1da5a | ||
|
|
ea85e23516 | ||
|
|
c5fe4a8bf3 | ||
|
|
2e9fa86c76 | ||
|
|
e238b47b0a | ||
|
|
8cf752e577 | ||
|
|
2645b3e634 | ||
|
|
e5e0a1c857 | ||
|
|
b20f11c6a7 | ||
|
|
614cbb3e92 | ||
|
|
a0b58301ca | ||
|
|
9fb312ec32 | ||
|
|
c60c5d188e | ||
|
|
39bbb1c9e9 | ||
|
|
abe1057c41 | ||
|
|
32a9e3a225 | ||
|
|
e922bf901a | ||
|
|
66b2b90f43 | ||
|
|
a26f3d70dc | ||
|
|
2584075a94 | ||
|
|
68103c0ffb | ||
|
|
5d2ef1f925 | ||
|
|
1b773f682f | ||
|
|
bc54fa3e58 | ||
|
|
b3254d663b | ||
|
|
cf72b1a55d | ||
|
|
64fba64826 | ||
|
|
46345c0809 | ||
|
|
236d4cea25 | ||
|
|
cb978ff7be | ||
|
|
00ae321bf4 | ||
|
|
f3a4dad2c8 | ||
|
|
a2e4d07a4b | ||
|
|
fb4a5492da | ||
|
|
b3e4186cf2 | ||
|
|
45ef5b2ad6 | ||
|
|
cbe4354928 | ||
|
|
57b3409e2a | ||
|
|
322b68dbf4 | ||
|
|
c9d34cdecf | ||
|
|
67897d9c0d | ||
|
|
560e1d7e8a | ||
|
|
05c403f805 | ||
|
|
b7f7a772fb | ||
|
|
e9d7301b0a | ||
|
|
eb696dc385 | ||
|
|
f64d9d0e43 | ||
|
|
741e28309e | ||
|
|
7e315dafcf | ||
|
|
61be6bc238 | ||
|
|
cf7ececb83 | ||
|
|
c007b34cc1 | ||
|
|
224d547178 | ||
|
|
a29d966678 | ||
|
|
023c2b7dd9 | ||
|
|
dcb871a755 | ||
|
|
6f0a64d3a2 | ||
|
|
eb3114596c | ||
|
|
9f44640fa7 | ||
|
|
8ef0b0ff30 | ||
|
|
1c2a8d977c | ||
|
|
1797024a4e | ||
|
|
d75bca38f9 | ||
|
|
18523f7620 | ||
|
|
e399b79baa | ||
|
|
aac3c03f72 | ||
|
|
3b8cc374e7 | ||
|
|
8b274b92aa | ||
|
|
6b69130f36 | ||
|
|
c3f180eebb | ||
|
|
bf3c0e07d6 | ||
|
|
67eb2bbc32 | ||
|
|
cf19a76bf6 | ||
|
|
2a6a51c465 | ||
|
|
95db04a64c | ||
|
|
f26b55ea7e | ||
|
|
01c1bd13db | ||
|
|
8ec31ebbcc | ||
|
|
723a54f948 | ||
|
|
599aec4a23 | ||
|
|
9d66b48885 | ||
|
|
38c435e0c2 | ||
|
|
7b406bc70a | ||
|
|
89845bca03 | ||
|
|
78216e8d02 | ||
|
|
118c2c60d8 | ||
|
|
179ec8ad20 | ||
|
|
89f459c8a1 | ||
|
|
a34fe6ea8a | ||
|
|
6021182b64 | ||
|
|
e0a0eafef0 | ||
|
|
40f8fe2815 | ||
|
|
71cab42c9b | ||
|
|
2e149c4ced | ||
|
|
b701d70147 | ||
|
|
7963430481 | ||
|
|
ca36fd0110 | ||
|
|
4c4671a63f | ||
|
|
0db4fd57a7 | ||
|
|
f54f117885 | ||
|
|
21477ad68a | ||
|
|
dccbb4e518 | ||
|
|
45f74a1497 | ||
|
|
f10b2c0b33 | ||
|
|
1aa6413b32 | ||
|
|
d437ccb141 | ||
|
|
3070cf38f0 | ||
|
|
d2f9be56a5 | ||
|
|
317f97fe8e | ||
|
|
67c16277ee | ||
|
|
0066333685 | ||
|
|
6df29c32e4 | ||
|
|
f042f0dd5d | ||
|
|
391e1912de | ||
|
|
3c79358ff7 | ||
|
|
7d9caee481 | ||
|
|
c188d259d6 | ||
|
|
d332a19aa0 | ||
|
|
bfc0ddd0e0 | ||
|
|
13a1ed01fd | ||
|
|
4e8095062b | ||
|
|
fe6b110393 | ||
|
|
9633600fff | ||
|
|
2e24678204 | ||
|
|
a71d4eab36 | ||
|
|
885cde085a | ||
|
|
654d66d6a7 | ||
|
|
56b100a692 | ||
|
|
518504ff5c | ||
|
|
6351307ab4 | ||
|
|
0a848d686c | ||
|
|
595eab57de | ||
|
|
14f178e486 | ||
|
|
60035e31a2 | ||
|
|
3088075574 | ||
|
|
e76cd88470 | ||
|
|
5c0fe2154f | ||
|
|
76280e3b7e | ||
|
|
907ee56090 | ||
|
|
4ed18b1108 | ||
|
|
afc09709ad | ||
|
|
c1128af87e | ||
|
|
6325974a0b | ||
|
|
d1a68958a9 | ||
|
|
9d406d199f | ||
|
|
ecbeaed66c | ||
|
|
1601f2fd6f | ||
|
|
f98a1e2d32 | ||
|
|
cb3b649707 | ||
|
|
75c811cc35 | ||
|
|
d7fec82eaa | ||
|
|
6070d61076 | ||
|
|
96df860673 | ||
|
|
2eaed3573b |
+87
-20
@@ -45,6 +45,11 @@ UB_ON_WINDOWS=@UB_ON_WINDOWS@
|
||||
WITH_PYTHONMODULE=@WITH_PYTHONMODULE@
|
||||
WITH_PYUNBOUND=@WITH_PYUNBOUND@
|
||||
PYTHON_SITE_PKG=@PYTHON_SITE_PKG@
|
||||
EXPORT_ALL_SYMBOLS=@EXPORT_ALL_SYMBOLS@
|
||||
|
||||
# override $U variable which is used by autotools for deansification (for
|
||||
# K&R C compilers), but causes problems if $U is defined in the env).
|
||||
U=
|
||||
|
||||
SWIG=@SWIG@
|
||||
YACC=@YACC@
|
||||
@@ -71,7 +76,8 @@ BUILD=build/
|
||||
|
||||
WINDRES=@WINDRES@
|
||||
LINT=splint
|
||||
LINTFLAGS=+quiet -weak -warnposix -unrecog -Din_addr_t=uint32_t -Du_int=unsigned -Du_char=uint8_t -preproc -Drlimit=rlimit64 -D__gnuc_va_list=va_list -Dglob64=glob -Dglobfree64=globfree
|
||||
LINTFLAGS=+quiet -weak -warnposix -unrecog -Din_addr_t=uint32_t -Du_int=unsigned -Du_char=uint8_t -preproc -Drlimit=rlimit64 -D__gnuc_va_list=va_list
|
||||
#-Dglob64=glob -Dglobfree64=globfree
|
||||
# compat with openssl linux edition.
|
||||
LINTFLAGS+="-DBN_ULONG=unsigned long" -Dkrb5_int32=int "-Dkrb5_ui_4=unsigned int" -DPQ_64BIT=uint64_t -DRC4_INT=unsigned -fixedformalarray -D"ENGINE=unsigned" -D"RSA=unsigned" -D"DSA=unsigned" -D"EVP_PKEY=unsigned" -D"EVP_MD=unsigned" -D"SSL=unsigned" -D"SSL_CTX=unsigned" -D"X509=unsigned" -D"RC4_KEY=unsigned" -D"EVP_MD_CTX=unsigned"
|
||||
# compat with NetBSD
|
||||
@@ -101,15 +107,29 @@ UNITTEST_SRC=$(patsubst $(srcdir)/%,%, \
|
||||
testcode/readhex.c testcode/ldns-testpkts.c smallapp/worker_cb.c \
|
||||
$(COMMON_SRC)
|
||||
UNITTEST_OBJ=$(addprefix $(BUILD),$(UNITTEST_SRC:.c=.lo)) $(COMPAT_OBJ)
|
||||
DAEMON_SRC=$(patsubst $(srcdir)/%,%, $(wildcard $(srcdir)/daemon/*.c)) \
|
||||
$(COMMON_SRC)
|
||||
|
||||
DAEMON_SRC=$(patsubst $(srcdir)/%,%, $(wildcard $(srcdir)/daemon/*.c))
|
||||
ifneq "$(EXPORT_ALL_SYMBOLS)" "yes"
|
||||
DAEMON_SRC+=$(COMMON_SRC)
|
||||
endif
|
||||
DAEMON_OBJ=$(addprefix $(BUILD),$(DAEMON_SRC:.c=.lo)) $(COMPAT_OBJ)
|
||||
CHECKCONF_SRC=smallapp/unbound-checkconf.c smallapp/worker_cb.c $(COMMON_SRC)
|
||||
|
||||
CHECKCONF_SRC=smallapp/unbound-checkconf.c smallapp/worker_cb.c
|
||||
ifneq "$(EXPORT_ALL_SYMBOLS)" "yes"
|
||||
CHECKCONF_SRC+=$(COMMON_SRC)
|
||||
endif
|
||||
CHECKCONF_OBJ=$(addprefix $(BUILD),$(CHECKCONF_SRC:.c=.lo)) $(COMPAT_OBJ)
|
||||
CONTROL_SRC=smallapp/unbound-control.c smallapp/worker_cb.c $(COMMON_SRC)
|
||||
|
||||
CONTROL_SRC=smallapp/unbound-control.c smallapp/worker_cb.c
|
||||
ifneq "$(EXPORT_ALL_SYMBOLS)" "yes"
|
||||
CONTROL_SRC+=$(COMMON_SRC)
|
||||
endif
|
||||
CONTROL_OBJ=$(addprefix $(BUILD),$(CONTROL_SRC:.c=.lo)) $(COMPAT_OBJ)
|
||||
|
||||
HOST_SRC=smallapp/unbound-host.c
|
||||
HOST_OBJ=$(addprefix $(BUILD),$(HOST_SRC:.c=.lo)) $(filter-out $(BUILD)compat/ctime_r.lo, $(COMPAT_OBJ))
|
||||
UBANCHOR_SRC=smallapp/unbound-anchor.c
|
||||
UBANCHOR_OBJ=$(addprefix $(BUILD),$(UBANCHOR_SRC:.c=.lo)) $(filter-out $(BUILD)compat/ctime_r.lo, $(COMPAT_OBJ))
|
||||
TESTBOUND_SRC=testcode/testbound.c testcode/ldns-testpkts.c \
|
||||
daemon/worker.c daemon/acl_list.c daemon/daemon.c daemon/stats.c \
|
||||
testcode/replay.c testcode/fake_event.c $(filter-out util/netevent.c \
|
||||
@@ -117,6 +137,8 @@ TESTBOUND_SRC=testcode/testbound.c testcode/ldns-testpkts.c \
|
||||
TESTBOUND_OBJ=$(addprefix $(BUILD),$(TESTBOUND_SRC:.c=.lo)) $(COMPAT_OBJ)
|
||||
LOCKVERIFY_SRC=testcode/lock_verify.c smallapp/worker_cb.c $(COMMON_SRC)
|
||||
LOCKVERIFY_OBJ=$(addprefix $(BUILD),$(LOCKVERIFY_SRC:.c=.lo)) $(COMPAT_OBJ)
|
||||
PETAL_SRC=testcode/petal.c
|
||||
PETAL_OBJ=$(addprefix $(BUILD),$(PETAL_SRC:.c=.lo)) $(filter-out $(BUILD)compat/ctime_r.lo, $(COMPAT_OBJ))
|
||||
PKTVIEW_SRC=testcode/pktview.c testcode/readhex.c smallapp/worker_cb.c \
|
||||
$(COMMON_SRC)
|
||||
PKTVIEW_OBJ=$(addprefix $(BUILD),$(PKTVIEW_SRC:.c=.lo)) $(COMPAT_OBJ)
|
||||
@@ -141,7 +163,7 @@ ALL_SRC=$(sort $(COMMON_SRC) $(UNITTEST_SRC) $(DAEMON_SRC) \
|
||||
$(TESTBOUND_SRC) $(LOCKVERIFY_SRC) $(PKTVIEW_SRC) $(SIGNIT_SRC) \
|
||||
$(MEMSTATS_SRC) $(CHECKCONF_SRC) $(LIBUNBOUND_SRC) $(HOST_SRC) \
|
||||
$(ASYNCLOOK_SRC) $(STREAMTCP_SRC) $(PERF_SRC) $(DELAYER_SRC) \
|
||||
$(HARVEST_SRC) $(CONTROL_SRC))
|
||||
$(HARVEST_SRC) $(CONTROL_SRC) $(UBANCHOR_SRC) $(PETAL_SRC))
|
||||
ALL_OBJ=$(addprefix $(BUILD),$(ALL_SRC:.c=.lo) \
|
||||
$(addprefix compat/,$(LIBOBJS:.o=.lo))) $(COMPAT_OBJ)
|
||||
|
||||
@@ -149,6 +171,7 @@ ifeq "$(UB_ON_WINDOWS)" "yes"
|
||||
DAEMON_SRC+=winrc/win_svc.c winrc/w_inst.c
|
||||
DAEMON_OBJ+=$(BUILD)winrc/rsrc_unbound.o $(BUILD)winrc/win_svc.lo
|
||||
HOST_OBJ+=$(BUILD)winrc/rsrc_unbound_host.o
|
||||
UBANCHOR_OBJ+=$(BUILD)winrc/rsrc_unbound_anchor.o
|
||||
CONTROL_OBJ+=$(BUILD)winrc/rsrc_unbound_control.o
|
||||
CHECKCONF_OBJ+=$(BUILD)winrc/rsrc_unbound_checkconf.o
|
||||
|
||||
@@ -179,7 +202,7 @@ COMPILE=$(LIBTOOL) --tag=CC --mode=compile $(CC) $(CPPFLAGS) $(CFLAGS)
|
||||
LINK=$(LIBTOOL) --tag=CC --mode=link $(strip $(CC) $(staticexe) $(RUNTIME_PATH) $(CFLAGS) $(LDFLAGS))
|
||||
LINK_LIB=$(LIBTOOL) --tag=CC --mode=link $(strip $(CC) $(RUNTIME_PATH) $(CFLAGS) $(LDFLAGS) $(staticexe) -version-number @LIBUNBOUND_CURRENT@:@LIBUNBOUND_REVISION@:@LIBUNBOUND_AGE@ -no-undefined)
|
||||
|
||||
.PHONY: clean realclean doc lint all install uninstall tests test download_ldns strip lib
|
||||
.PHONY: clean realclean doc lint all install uninstall tests test download_ldns strip lib longtest longcheck check
|
||||
|
||||
$(BUILD)%.lo: $(srcdir)/%.c
|
||||
$(INFO) Build $<
|
||||
@@ -188,13 +211,22 @@ $(BUILD)%.lo: $(srcdir)/%.c
|
||||
@-if test ! -d $(dir $@); then $(INSTALL) -d $(patsubst %/,%,$(dir $@)); fi
|
||||
$Q$(COMPILE) -o $@ -c $<
|
||||
|
||||
all: $(COMMON_OBJ) unbound$(EXEEXT) unbound-checkconf$(EXEEXT) lib unbound-host$(EXEEXT) unbound-control$(EXEEXT) unbound-control-setup $(WINAPPS)
|
||||
all: $(COMMON_OBJ) unbound$(EXEEXT) unbound-checkconf$(EXEEXT) lib unbound-host$(EXEEXT) unbound-control$(EXEEXT) unbound-anchor$(EXEEXT) unbound-control-setup $(WINAPPS)
|
||||
|
||||
TEST_BIN=$(addsuffix $(EXEEXT),asynclook delayer harvest lock-verify \
|
||||
memstats perf pktview signit streamtcp testbound unittest)
|
||||
memstats perf petal pktview signit streamtcp testbound unittest)
|
||||
tests: all $(TEST_BIN)
|
||||
|
||||
test: tests
|
||||
check: test
|
||||
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
|
||||
@echo test OK
|
||||
|
||||
longtest: tests
|
||||
if test -x "`which bash`"; then bash testcode/do-tests.sh; else sh testcode/do-tests.sh; fi
|
||||
|
||||
lib: libunbound.la
|
||||
@@ -209,26 +241,54 @@ else
|
||||
ldnslib=
|
||||
endif
|
||||
|
||||
UBSYMS+=-export-symbols $(srcdir)/libunbound/ubsyms.def
|
||||
CLUBSYMS=-export-symbols $(BUILD)clubsyms.def
|
||||
EXTRALINK=
|
||||
ifeq "$(EXPORT_ALL_SYMBOLS)" "yes"
|
||||
UBSYMS=
|
||||
CLUBSYMS=
|
||||
EXTRALINK=-L. -L.libs -lunbound
|
||||
endif
|
||||
|
||||
libunbound.la: $(LIBUNBOUND_OBJ) $(ldnslib)
|
||||
$(INFO) Link $@
|
||||
$Q$(LINK_LIB) -export-symbols $(srcdir)/libunbound/ubsyms.def -o $@ $(sort $(LIBUNBOUND_OBJ)) -rpath $(libdir) $(LIBS)
|
||||
ifeq ($(CHECKLOCK_SRC),)
|
||||
$Q$(LINK_LIB) $(UBSYMS) -o $@ $(sort $(LIBUNBOUND_OBJ)) -rpath $(libdir) $(LIBS)
|
||||
else
|
||||
cp $(srcdir)/libunbound/ubsyms.def $(BUILD)clubsyms.def
|
||||
echo lock_protect >> $(BUILD)clubsyms.def
|
||||
echo lock_unprotect >> $(BUILD)clubsyms.def
|
||||
echo lock_get_mem >> $(BUILD)clubsyms.def
|
||||
echo checklock_start >> $(BUILD)clubsyms.def
|
||||
echo checklock_stop >> $(BUILD)clubsyms.def
|
||||
echo checklock_lock >> $(BUILD)clubsyms.def
|
||||
echo checklock_unlock >> $(BUILD)clubsyms.def
|
||||
echo checklock_init >> $(BUILD)clubsyms.def
|
||||
echo checklock_thrcreate >> $(BUILD)clubsyms.def
|
||||
echo checklock_thrjoin >> $(BUILD)clubsyms.def
|
||||
$Q$(LINK_LIB) $(CLUBSYMS) -o $@ $(sort $(LIBUNBOUND_OBJ)) -rpath $(libdir) $(LIBS)
|
||||
endif
|
||||
|
||||
unbound$(EXEEXT): $(DAEMON_OBJ) $(ldnslib)
|
||||
unbound$(EXEEXT): $(DAEMON_OBJ) libunbound.la $(ldnslib)
|
||||
$(INFO) Link $@
|
||||
$Q$(LINK) -o $@ $(sort $(DAEMON_OBJ)) -lssl $(LIBS)
|
||||
$Q$(LINK) -o $@ $(sort $(DAEMON_OBJ)) $(EXTRALINK) -lssl $(LIBS)
|
||||
|
||||
unbound-checkconf$(EXEEXT): $(CHECKCONF_OBJ) $(ldnslib)
|
||||
unbound-checkconf$(EXEEXT): $(CHECKCONF_OBJ) libunbound.la $(ldnslib)
|
||||
$(INFO) Link $@
|
||||
$Q$(LINK) -o $@ $(sort $(CHECKCONF_OBJ)) $(LIBS)
|
||||
$Q$(LINK) -o $@ $(sort $(CHECKCONF_OBJ)) $(EXTRALINK) -lssl $(LIBS)
|
||||
|
||||
unbound-control$(EXEEXT): $(CONTROL_OBJ) $(ldnslib)
|
||||
unbound-control$(EXEEXT): $(CONTROL_OBJ) libunbound.la $(ldnslib)
|
||||
$(INFO) Link $@
|
||||
$Q$(LINK) -o $@ $(sort $(CONTROL_OBJ)) -lssl $(LIBS)
|
||||
$Q$(LINK) -o $@ $(sort $(CONTROL_OBJ)) $(EXTRALINK) -lssl $(LIBS)
|
||||
|
||||
unbound-host$(EXEEXT): $(HOST_OBJ) libunbound.la $(ldnslib)
|
||||
$(INFO) Link $@
|
||||
$Q$(LINK) -o $@ $(sort $(HOST_OBJ)) -L. -L.libs -lunbound $(LIBS)
|
||||
|
||||
unbound-anchor$(EXEEXT): $(UBANCHOR_OBJ) libunbound.la $(ldnslib)
|
||||
$(INFO) Link $@
|
||||
$Q$(LINK) -o $@ $(sort $(UBANCHOR_OBJ)) -L. -L.libs -lunbound -lexpat -lssl $(LIBS)
|
||||
|
||||
unbound-service-install$(EXEEXT): $(SVCINST_OBJ)
|
||||
$(INFO) Link $@
|
||||
$Q$(LINK) -o $@ $(sort $(SVCINST_OBJ)) $(LIBS)
|
||||
@@ -253,6 +313,10 @@ lock-verify$(EXEEXT): $(LOCKVERIFY_OBJ) $(ldnslib)
|
||||
$(INFO) Link $@
|
||||
$Q$(LINK) -o $@ $(sort $(LOCKVERIFY_OBJ)) $(LIBS)
|
||||
|
||||
petal$(EXEEXT): $(PETAL_OBJ)
|
||||
$(INFO) Link $@
|
||||
$Q$(LINK) -o $@ $(sort $(PETAL_OBJ)) -lssl $(LIBS)
|
||||
|
||||
pktview$(EXEEXT): $(PKTVIEW_OBJ) $(ldnslib)
|
||||
$(INFO) Link $@
|
||||
$Q$(LINK) -o $@ $(sort $(PKTVIEW_OBJ)) $(LIBS)
|
||||
@@ -334,7 +398,7 @@ util/configparser.c util/configparser.h: $(srcdir)/util/configparser.y
|
||||
|
||||
clean:
|
||||
rm -f *.o *.d *.lo *~ tags
|
||||
rm -f unbound$(EXEEXT) unbound-checkconf$(EXEEXT) unbound-host$(EXEEXT) unbound-control$(EXEEXT) unbound-control-setup libunbound.la
|
||||
rm -f unbound$(EXEEXT) unbound-checkconf$(EXEEXT) unbound-host$(EXEEXT) unbound-control$(EXEEXT) unbound-anchor$(EXEEXT) unbound-control-setup libunbound.la
|
||||
rm -rf autom4te.cache .libs build doc/html doc/xml
|
||||
|
||||
realclean: clean
|
||||
@@ -371,6 +435,7 @@ strip:
|
||||
$(STRIP) unbound-checkconf$(EXEEXT)
|
||||
$(STRIP) unbound-control$(EXEEXT)
|
||||
$(STRIP) unbound-host$(EXEEXT)
|
||||
$(STRIP) unbound-anchor$(EXEEXT)
|
||||
|
||||
install: all
|
||||
$(INSTALL) -m 755 -d $(DESTDIR)$(sbindir)
|
||||
@@ -385,6 +450,7 @@ install: all
|
||||
$(LIBTOOL) --mode=install cp unbound-checkconf$(EXEEXT) $(DESTDIR)$(sbindir)/unbound-checkconf$(EXEEXT)
|
||||
$(LIBTOOL) --mode=install cp unbound-control$(EXEEXT) $(DESTDIR)$(sbindir)/unbound-control$(EXEEXT)
|
||||
$(LIBTOOL) --mode=install cp unbound-host$(EXEEXT) $(DESTDIR)$(sbindir)/unbound-host$(EXEEXT)
|
||||
$(LIBTOOL) --mode=install cp unbound-anchor$(EXEEXT) $(DESTDIR)$(sbindir)/unbound-anchor$(EXEEXT)
|
||||
ifeq "$(WITH_PYTHONMODULE)" "yes"
|
||||
$(INSTALL) -m 755 -d $(DESTDIR)$(PYTHON_SITE_PKG)
|
||||
$(INSTALL) -c -m 644 pythonmod/unboundmodule.py $(DESTDIR)$(PYTHON_SITE_PKG)/unboundmodule.py
|
||||
@@ -398,6 +464,7 @@ endif
|
||||
$(INSTALL) -c -m 644 doc/unbound.8 $(DESTDIR)$(mandir)/man8
|
||||
$(INSTALL) -c -m 644 doc/unbound-checkconf.8 $(DESTDIR)$(mandir)/man8
|
||||
$(INSTALL) -c -m 644 doc/unbound-control.8 $(DESTDIR)$(mandir)/man8
|
||||
$(INSTALL) -c -m 644 doc/unbound-anchor.8 $(DESTDIR)$(mandir)/man8
|
||||
$(INSTALL) -c -m 644 doc/unbound.conf.5 $(DESTDIR)$(mandir)/man5
|
||||
$(INSTALL) -c -m 644 $(srcdir)/doc/unbound-host.1 $(DESTDIR)$(mandir)/man1
|
||||
$(INSTALL) -c -m 644 doc/libunbound.3 $(DESTDIR)$(mandir)/man3
|
||||
@@ -408,8 +475,8 @@ endif
|
||||
$(LIBTOOL) --mode=finish $(DESTDIR)$(libdir)
|
||||
|
||||
uninstall:
|
||||
rm -f -- $(DESTDIR)$(sbindir)/unbound$(EXEEXT) $(DESTDIR)$(sbindir)/unbound-checkconf$(EXEEXT) $(DESTDIR)$(sbindir)/unbound-host$(EXEEXT) $(DESTDIR)$(sbindir)/unbound-control$(EXEEXT) $(DESTDIR)$(sbindir)/unbound-control-setup
|
||||
rm -f -- $(DESTDIR)$(mandir)/man8/unbound.8 $(DESTDIR)$(mandir)/man8/unbound-checkconf.8 $(DESTDIR)$(mandir)/man5/unbound.conf.5 $(DESTDIR)$(mandir)/man8/unbound-control.8
|
||||
rm -f -- $(DESTDIR)$(sbindir)/unbound$(EXEEXT) $(DESTDIR)$(sbindir)/unbound-checkconf$(EXEEXT) $(DESTDIR)$(sbindir)/unbound-host$(EXEEXT) $(DESTDIR)$(sbindir)/unbound-control$(EXEEXT) $(DESTDIR)$(sbindir)/unbound-anchor$(EXEEXT) $(DESTDIR)$(sbindir)/unbound-control-setup
|
||||
rm -f -- $(DESTDIR)$(mandir)/man8/unbound.8 $(DESTDIR)$(mandir)/man8/unbound-checkconf.8 $(DESTDIR)$(mandir)/man5/unbound.conf.5 $(DESTDIR)$(mandir)/man8/unbound-control.8 $(DESTDIR)$(mandir)/man8/unbound-anchor.8
|
||||
rm -f -- $(DESTDIR)$(mandir)/man1/unbound-host.1 $(DESTDIR)$(mandir)/man3/libunbound.3
|
||||
rm -f -- $(DESTDIR)$(includedir)/unbound.h
|
||||
$(LIBTOOL) --mode=uninstall rm -f $(DESTDIR)$(libdir)/libunbound.la
|
||||
|
||||
Vendored
+562
-474
File diff suppressed because it is too large
Load Diff
+40
-3
@@ -2,7 +2,9 @@
|
||||
# Copyright 2009, Wouter Wijngaards, NLnet Labs.
|
||||
# BSD licensed.
|
||||
#
|
||||
# Version 9
|
||||
# Version 11
|
||||
# 2010-08-16 Fix FLAG_OMITTED for AS_TR_CPP changes in autoconf-2.66.
|
||||
# 2010-07-02 Add check for ss_family (for minix).
|
||||
# 2010-04-26 Fix to use CPPFLAGS for CHECK_COMPILER_FLAGS.
|
||||
# 2010-03-01 Fix RPATH using CONFIG_COMMANDS to run at the very end.
|
||||
# 2010-02-18 WITH_SSL outputs the LIBSSL_LDFLAGS, LIBS, CPPFLAGS seperate, -ldl
|
||||
@@ -74,6 +76,7 @@
|
||||
# AHX_CONFIG_EXT_FLAGS - define the stripped extension flags
|
||||
# ACX_CHECK_MEMCMP_SIGNED - check if memcmp uses signed characters.
|
||||
# AHX_MEMCMP_BROKEN - replace memcmp func for CHECK_MEMCMP_SIGNED.
|
||||
# ACX_CHECK_SS_FAMILY - check for sockaddr_storage.ss_family
|
||||
#
|
||||
|
||||
dnl Escape backslashes as \\, for C:\ paths, for the C preprocessor defines.
|
||||
@@ -1190,7 +1193,7 @@ AC_DEFUN([ACX_CFLAGS_STRIP],
|
||||
[
|
||||
if echo $CFLAGS | grep " $1" >/dev/null 2>&1; then
|
||||
CFLAGS="`echo $CFLAGS | sed -e 's/ $1//g'`"
|
||||
AC_DEFINE(AS_TR_CPP(OMITTED_$1), 1, Put $1 define in config.h)
|
||||
AC_DEFINE(m4_bpatsubst(OMITTED_$1,[[-=]],_), 1, Put $1 define in config.h)
|
||||
fi
|
||||
])
|
||||
|
||||
@@ -1221,7 +1224,7 @@ AC_DEFUN([AHX_CONFIG_FLAG_OMITTED],
|
||||
dnl Wrapper for AHX_CONFIG_FLAG_OMITTED for -D style flags
|
||||
dnl $1: the -DNAME or -DNAME=value string.
|
||||
AC_DEFUN([AHX_CONFIG_FLAG_EXT],
|
||||
[AHX_CONFIG_FLAG_OMITTED(AS_TR_CPP(OMITTED_$1),m4_bpatsubst(m4_bpatsubst($1,-D,),=.*$,),m4_if(m4_bregexp($1,=),-1,1,m4_bpatsubst($1,^.*=,)))
|
||||
[AHX_CONFIG_FLAG_OMITTED(m4_bpatsubst(OMITTED_$1,[[-=]],_),m4_bpatsubst(m4_bpatsubst($1,-D,),=.*$,),m4_if(m4_bregexp($1,=),-1,1,m4_bpatsubst($1,^.*=,)))
|
||||
])
|
||||
|
||||
dnl config.h part to define omitted cflags, use with ACX_STRIP_EXT_FLAGS.
|
||||
@@ -1270,4 +1273,38 @@ int memcmp(const void *x, const void *y, size_t n);
|
||||
#endif
|
||||
])
|
||||
|
||||
dnl ACX_CHECK_SS_FAMILY - check for sockaddr_storage.ss_family
|
||||
AC_DEFUN([ACX_CHECK_SS_FAMILY],
|
||||
[AC_CHECK_MEMBER([struct sockaddr_storage.ss_family], [], [
|
||||
AC_CHECK_MEMBER([struct sockaddr_storage.__ss_family], [
|
||||
AC_DEFINE([ss_family], [__ss_family], [Fallback member name for socket family in struct sockaddr_storage])
|
||||
],, [AC_INCLUDES_DEFAULT
|
||||
#ifdef HAVE_NETINET_IN_H
|
||||
#include <netinet/in.h>
|
||||
#endif
|
||||
#ifdef HAVE_SYS_SOCKET_H
|
||||
#include <sys/socket.h>
|
||||
#endif
|
||||
#ifdef HAVE_NETDB_H
|
||||
#include <netdb.h>
|
||||
#endif
|
||||
#ifdef HAVE_ARPA_INET_H
|
||||
#include <arpa/inet.h>
|
||||
#endif
|
||||
])
|
||||
], [AC_INCLUDES_DEFAULT
|
||||
#ifdef HAVE_NETINET_IN_H
|
||||
#include <netinet/in.h>
|
||||
#endif
|
||||
#ifdef HAVE_SYS_SOCKET_H
|
||||
#include <sys/socket.h>
|
||||
#endif
|
||||
#ifdef HAVE_NETDB_H
|
||||
#include <netdb.h>
|
||||
#endif
|
||||
#ifdef HAVE_ARPA_INET_H
|
||||
#include <arpa/inet.h>
|
||||
#endif
|
||||
]) ])
|
||||
|
||||
dnl End of file
|
||||
|
||||
+4
-1
@@ -32,8 +32,11 @@ char *ctime_r(const time_t *timep, char *buf)
|
||||
}
|
||||
lock_basic_lock(&ctime_lock);
|
||||
result = ctime(timep);
|
||||
if(buf && result)
|
||||
if(buf && result) {
|
||||
if(strlen(result) > 10 && result[7]==' ' && result[8]=='0')
|
||||
result[8]=' '; /* fix error in windows ctime */
|
||||
strcpy(buf, result);
|
||||
}
|
||||
lock_basic_unlock(&ctime_lock);
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,347 @@
|
||||
/** strptime workaround (for oa macos leopard)
|
||||
* This strptime follows the man strptime (2001-11-12)
|
||||
* conforming to SUSv2, POSIX.1-2001
|
||||
*
|
||||
* This very simple version of strptime has no:
|
||||
* - E alternatives
|
||||
* - O alternatives
|
||||
* - Glibc additions
|
||||
* - Does not process week numbers
|
||||
* - Does not properly processes year day
|
||||
*
|
||||
* LICENSE
|
||||
* Copyright (c) 2008, NLnet Labs, Matthijs Mekking
|
||||
* All rights reserved.
|
||||
*
|
||||
* 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 NLnetLabs 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 OWNER 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.
|
||||
**/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#ifndef HAVE_CONFIG_H
|
||||
#include <time.h>
|
||||
#endif
|
||||
|
||||
#ifndef STRPTIME_WORKS
|
||||
|
||||
#define TM_YEAR_BASE 1900
|
||||
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
|
||||
static const char *abb_weekdays[] = {
|
||||
"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", NULL
|
||||
};
|
||||
static const char *full_weekdays[] = {
|
||||
"Sunday", "Monday", "Tuesday", "Wednesday",
|
||||
"Thursday", "Friday", "Saturday", NULL
|
||||
};
|
||||
static const char *abb_months[] = {
|
||||
"Jan", "Feb", "Mar", "Apr", "May", "Jun",
|
||||
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec", NULL
|
||||
};
|
||||
static const char *full_months[] = {
|
||||
"January", "February", "March", "April", "May", "June",
|
||||
"July", "August", "September", "October", "November", "December", NULL
|
||||
};
|
||||
static const char *ampm[] = {
|
||||
"am", "pm", NULL
|
||||
};
|
||||
|
||||
static int
|
||||
match_string(const char **buf, const char **strs)
|
||||
{
|
||||
int i = 0;
|
||||
|
||||
for (i = 0; strs[i] != NULL; i++) {
|
||||
int len = strlen(strs[i]);
|
||||
if (strncasecmp (*buf, strs[i], len) == 0) {
|
||||
*buf += len;
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int
|
||||
str2int(const char **buf, int max)
|
||||
{
|
||||
int ret=0, count=0;
|
||||
|
||||
while (*buf[0] != '\0' && isdigit(*buf[0]) && count<max) {
|
||||
ret = ret*10 + (*buf[0] - '0');
|
||||
(*buf)++;
|
||||
count++;
|
||||
}
|
||||
|
||||
if (!count)
|
||||
return -1;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/** Converts the character string s to values which are stored in tm
|
||||
* using the format specified by format
|
||||
**/
|
||||
char *
|
||||
unbound_strptime(const char *s, const char *format, struct tm *tm)
|
||||
{
|
||||
int c, alt_format, ret;
|
||||
int split_year = 0;
|
||||
|
||||
while ((c = *format) != '\0') {
|
||||
alt_format = 0;
|
||||
|
||||
/* whitespace, literal or format */
|
||||
if (isspace(c)) { /* whitespace */
|
||||
/** whitespace matches zero or more whitespace characters in the
|
||||
* input string.
|
||||
**/
|
||||
while (isspace(*s))
|
||||
s++;
|
||||
}
|
||||
else if (c == '%') { /* format */
|
||||
format++;
|
||||
c = *format;
|
||||
switch (c) {
|
||||
case '%': /* %% is converted to % */
|
||||
if (*s != c) {
|
||||
return NULL;
|
||||
}
|
||||
s++;
|
||||
break;
|
||||
case 'a': /* weekday name, abbreviated or full */
|
||||
case 'A':
|
||||
ret = match_string(&s, full_weekdays);
|
||||
if (ret < 0)
|
||||
ret = match_string(&s, abb_weekdays);
|
||||
if (ret < 0) {
|
||||
return NULL;
|
||||
}
|
||||
tm->tm_wday = ret;
|
||||
break;
|
||||
case 'b': /* month name, abbreviated or full */
|
||||
case 'B':
|
||||
case 'h':
|
||||
ret = match_string(&s, full_months);
|
||||
if (ret < 0)
|
||||
ret = match_string(&s, abb_months);
|
||||
if (ret < 0) {
|
||||
return NULL;
|
||||
}
|
||||
tm->tm_mon = ret;
|
||||
break;
|
||||
case 'c': /* date and time representation */
|
||||
if (!(s = unbound_strptime(s, "%x %X", tm))) {
|
||||
return NULL;
|
||||
}
|
||||
break;
|
||||
case 'C': /* century number */
|
||||
ret = str2int(&s, 2);
|
||||
if (ret < 0 || ret > 99) { /* must be in [00,99] */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (split_year) {
|
||||
tm->tm_year = ret*100 + (tm->tm_year%100);
|
||||
}
|
||||
else {
|
||||
tm->tm_year = ret*100 - TM_YEAR_BASE;
|
||||
split_year = 1;
|
||||
}
|
||||
break;
|
||||
case 'd': /* day of month */
|
||||
case 'e':
|
||||
ret = str2int(&s, 2);
|
||||
if (ret < 1 || ret > 31) { /* must be in [01,31] */
|
||||
return NULL;
|
||||
}
|
||||
tm->tm_mday = ret;
|
||||
break;
|
||||
case 'D': /* equivalent to %m/%d/%y */
|
||||
if (!(s = unbound_strptime(s, "%m/%d/%y", tm))) {
|
||||
return NULL;
|
||||
}
|
||||
break;
|
||||
case 'H': /* hour */
|
||||
ret = str2int(&s, 2);
|
||||
if (ret < 0 || ret > 23) { /* must be in [00,23] */
|
||||
return NULL;
|
||||
}
|
||||
tm->tm_hour = ret;
|
||||
break;
|
||||
case 'I': /* 12hr clock hour */
|
||||
ret = str2int(&s, 2);
|
||||
if (ret < 1 || ret > 12) { /* must be in [01,12] */
|
||||
return NULL;
|
||||
}
|
||||
if (ret == 12) /* actually [0,11] */
|
||||
ret = 0;
|
||||
tm->tm_hour = ret;
|
||||
break;
|
||||
case 'j': /* day of year */
|
||||
ret = str2int(&s, 2);
|
||||
if (ret < 1 || ret > 366) { /* must be in [001,366] */
|
||||
return NULL;
|
||||
}
|
||||
tm->tm_yday = ret;
|
||||
break;
|
||||
case 'm': /* month */
|
||||
ret = str2int(&s, 2);
|
||||
if (ret < 1 || ret > 12) { /* must be in [01,12] */
|
||||
return NULL;
|
||||
}
|
||||
/* months go from 0-11 */
|
||||
tm->tm_mon = (ret-1);
|
||||
break;
|
||||
case 'M': /* minute */
|
||||
ret = str2int(&s, 2);
|
||||
if (ret < 0 || ret > 59) { /* must be in [00,59] */
|
||||
return NULL;
|
||||
}
|
||||
tm->tm_min = ret;
|
||||
break;
|
||||
case 'n': /* arbitrary whitespace */
|
||||
case 't':
|
||||
while (isspace(*s))
|
||||
s++;
|
||||
break;
|
||||
case 'p': /* am pm */
|
||||
ret = match_string(&s, ampm);
|
||||
if (ret < 0) {
|
||||
return NULL;
|
||||
}
|
||||
if (tm->tm_hour < 0 || tm->tm_hour > 11) { /* %I */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (ret == 1) /* pm */
|
||||
tm->tm_hour += 12;
|
||||
break;
|
||||
case 'r': /* equivalent of %I:%M:%S %p */
|
||||
if (!(s = unbound_strptime(s, "%I:%M:%S %p", tm))) {
|
||||
return NULL;
|
||||
}
|
||||
break;
|
||||
case 'R': /* equivalent of %H:%M */
|
||||
if (!(s = unbound_strptime(s, "%H:%M", tm))) {
|
||||
return NULL;
|
||||
}
|
||||
break;
|
||||
case 'S': /* seconds */
|
||||
ret = str2int(&s, 2);
|
||||
/* 60 may occur for leap seconds */
|
||||
/* earlier 61 was also allowed */
|
||||
if (ret < 0 || ret > 60) { /* must be in [00,60] */
|
||||
return NULL;
|
||||
}
|
||||
tm->tm_sec = ret;
|
||||
break;
|
||||
case 'T': /* equivalent of %H:%M:%S */
|
||||
if (!(s = unbound_strptime(s, "%H:%M:%S", tm))) {
|
||||
return NULL;
|
||||
}
|
||||
break;
|
||||
case 'U': /* week number, with the first Sun of Jan being w1 */
|
||||
ret = str2int(&s, 2);
|
||||
if (ret < 0 || ret > 53) { /* must be in [00,53] */
|
||||
return NULL;
|
||||
}
|
||||
/** it is hard (and not necessary for nsd) to determine time
|
||||
* data from week number.
|
||||
**/
|
||||
break;
|
||||
case 'w': /* day of week */
|
||||
ret = str2int(&s, 1);
|
||||
if (ret < 0 || ret > 6) { /* must be in [0,6] */
|
||||
return NULL;
|
||||
}
|
||||
tm->tm_wday = ret;
|
||||
break;
|
||||
case 'W': /* week number, with the first Mon of Jan being w1 */
|
||||
ret = str2int(&s, 2);
|
||||
if (ret < 0 || ret > 53) { /* must be in [00,53] */
|
||||
return NULL;
|
||||
}
|
||||
/** it is hard (and not necessary for nsd) to determine time
|
||||
* data from week number.
|
||||
**/
|
||||
break;
|
||||
case 'x': /* date format */
|
||||
if (!(s = unbound_strptime(s, "%m/%d/%y", tm))) {
|
||||
return NULL;
|
||||
}
|
||||
break;
|
||||
case 'X': /* time format */
|
||||
if (!(s = unbound_strptime(s, "%H:%M:%S", tm))) {
|
||||
return NULL;
|
||||
}
|
||||
break;
|
||||
case 'y': /* last two digits of a year */
|
||||
ret = str2int(&s, 2);
|
||||
if (ret < 0 || ret > 99) { /* must be in [00,99] */
|
||||
return NULL;
|
||||
}
|
||||
if (split_year) {
|
||||
tm->tm_year = ((tm->tm_year/100) * 100) + ret;
|
||||
}
|
||||
else {
|
||||
split_year = 1;
|
||||
|
||||
/** currently:
|
||||
* if in [0,68] we are in 21th century,
|
||||
* if in [69,99] we are in 20th century.
|
||||
**/
|
||||
if (ret < 69) /* 2000 */
|
||||
ret += 100;
|
||||
tm->tm_year = ret;
|
||||
}
|
||||
break;
|
||||
case 'Y': /* year */
|
||||
ret = str2int(&s, 4);
|
||||
if (ret < 0 || ret > 9999) {
|
||||
return NULL;
|
||||
}
|
||||
tm->tm_year = ret - TM_YEAR_BASE;
|
||||
break;
|
||||
case '\0':
|
||||
default: /* unsupported, cannot match format */
|
||||
return NULL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else { /* literal */
|
||||
/* if input cannot match format, return NULL */
|
||||
if (*s != c)
|
||||
return NULL;
|
||||
s++;
|
||||
}
|
||||
|
||||
format++;
|
||||
}
|
||||
|
||||
/* return pointer to remainder of s */
|
||||
return (char*) s;
|
||||
}
|
||||
|
||||
#endif /* STRPTIME_WORKS */
|
||||
+53
-1
@@ -6,6 +6,15 @@
|
||||
/* Pathname to the Unbound configuration file */
|
||||
#undef CONFIGFILE
|
||||
|
||||
/* configure flags */
|
||||
#undef CONFIGURE_BUILD_WITH
|
||||
|
||||
/* configure date */
|
||||
#undef CONFIGURE_DATE
|
||||
|
||||
/* configure target system */
|
||||
#undef CONFIGURE_TARGET
|
||||
|
||||
/* Define this if on macOSX10.4-darwin8 and setreuid and setregid do not work
|
||||
*/
|
||||
#undef DARWIN_BROKEN_SETREUID
|
||||
@@ -37,6 +46,10 @@
|
||||
/* Define to 1 if you have the `daemon' function. */
|
||||
#undef HAVE_DAEMON
|
||||
|
||||
/* Define to 1 if you have the declaration of `sk_SSL_COMP_pop_free', and to 0
|
||||
if you don't. */
|
||||
#undef HAVE_DECL_SK_SSL_COMP_POP_FREE
|
||||
|
||||
/* Define to 1 if you have the declaration of
|
||||
`SSL_COMP_get_compression_methods', and to 0 if you don't. */
|
||||
#undef HAVE_DECL_SSL_COMP_GET_COMPRESSION_METHODS
|
||||
@@ -68,9 +81,15 @@
|
||||
/* Define to 1 if you have the `EVP_sha512' function. */
|
||||
#undef HAVE_EVP_SHA512
|
||||
|
||||
/* Define to 1 if you have the `ev_default_loop' function. */
|
||||
#undef HAVE_EV_DEFAULT_LOOP
|
||||
|
||||
/* Define to 1 if you have the `ev_loop' function. */
|
||||
#undef HAVE_EV_LOOP
|
||||
|
||||
/* Define to 1 if you have the <expat.h> header file. */
|
||||
#undef HAVE_EXPAT_H
|
||||
|
||||
/* Define to 1 if you have the `fcntl' function. */
|
||||
#undef HAVE_FCNTL
|
||||
|
||||
@@ -131,6 +150,9 @@
|
||||
/* Define to 1 if you have the `kill' function. */
|
||||
#undef HAVE_KILL
|
||||
|
||||
/* Define to 1 if you have the `ldns_key_EVP_unload_gost' function. */
|
||||
#undef HAVE_LDNS_KEY_EVP_UNLOAD_GOST
|
||||
|
||||
/* Define to 1 if you have the <ldns/ldns.h> header file. */
|
||||
#undef HAVE_LDNS_LDNS_H
|
||||
|
||||
@@ -216,6 +238,9 @@
|
||||
/* Define to 1 if you have the `setreuid' function. */
|
||||
#undef HAVE_SETREUID
|
||||
|
||||
/* Define to 1 if you have the `setrlimit' function. */
|
||||
#undef HAVE_SETRLIMIT
|
||||
|
||||
/* Define to 1 if you have the `setsid' function. */
|
||||
#undef HAVE_SETSID
|
||||
|
||||
@@ -231,6 +256,9 @@
|
||||
/* Define to 1 if you have the `snprintf' function. */
|
||||
#undef HAVE_SNPRINTF
|
||||
|
||||
/* Define to 1 if you have the `socketpair' function. */
|
||||
#undef HAVE_SOCKETPAIR
|
||||
|
||||
/* Using Solaris threads */
|
||||
#undef HAVE_SOLARIS_THREADS
|
||||
|
||||
@@ -264,6 +292,9 @@
|
||||
/* Define to 1 if you have the `strlcpy' function. */
|
||||
#undef HAVE_STRLCPY
|
||||
|
||||
/* Define to 1 if you have the `strptime' function. */
|
||||
#undef HAVE_STRPTIME
|
||||
|
||||
/* Define if you have Swig libraries and header files. */
|
||||
#undef HAVE_SWIG
|
||||
|
||||
@@ -405,6 +436,12 @@
|
||||
/* Define as the return type of signal handlers (`int' or `void'). */
|
||||
#undef RETSIGTYPE
|
||||
|
||||
/* default rootkey location */
|
||||
#undef ROOT_ANCHOR_FILE
|
||||
|
||||
/* default rootcert location */
|
||||
#undef ROOT_CERT_FILE
|
||||
|
||||
/* version number for resource files */
|
||||
#undef RSRC_PACKAGE_VERSION
|
||||
|
||||
@@ -417,6 +454,9 @@
|
||||
/* Define to 1 if you have the ANSI C header files. */
|
||||
#undef STDC_HEADERS
|
||||
|
||||
/* use default strptime. */
|
||||
#undef STRPTIME_WORKS
|
||||
|
||||
/* Use win32 resources and API */
|
||||
#undef UB_ON_WINDOWS
|
||||
|
||||
@@ -781,7 +821,13 @@ int memcmp(const void *x, const void *y, size_t n);
|
||||
char *ctime_r(const time_t *timep, char *buf);
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_EVENT_H) && !defined(HAVE_EVENT_BASE_ONCE) && (defined(HAVE_PTHREAD) || defined(HAVE_SOLARIS_THREADS))
|
||||
#if !defined(HAVE_STRPTIME) || !defined(STRPTIME_WORKS)
|
||||
#define strptime unbound_strptime
|
||||
struct tm;
|
||||
char *strptime(const char *s, const char *format, struct tm *tm);
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_EVENT_H) && !defined(HAVE_EVENT_BASE_ONCE) && !(defined(HAVE_EV_LOOP) || defined(HAVE_EV_DEFAULT_LOOP)) && (defined(HAVE_PTHREAD) || defined(HAVE_SOLARIS_THREADS))
|
||||
/* using version of libevent that is not threadsafe. */
|
||||
# define LIBEVENT_SIGNAL_PROBLEM 1
|
||||
#endif
|
||||
@@ -825,4 +871,10 @@ 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 unbound control traffic, registered port with IANA,
|
||||
ub-dns-control 8953/tcp unbound dns nameserver control */
|
||||
#define UNBOUND_CONTROL_PORT 8953
|
||||
/** the version of unbound-control that this software implements */
|
||||
#define UNBOUND_CONTROL_VERSION 1
|
||||
|
||||
|
||||
|
||||
+163
-29
@@ -6,10 +6,10 @@ sinclude(acx_pthread.m4)
|
||||
sinclude(acx_python.m4)
|
||||
sinclude(ac_pkg_swig.m4)
|
||||
|
||||
AC_INIT(unbound, 1.4.5, unbound-bugs@nlnetlabs.nl, unbound)
|
||||
AC_INIT(unbound, 1.4.11, unbound-bugs@nlnetlabs.nl, unbound)
|
||||
|
||||
LIBUNBOUND_CURRENT=2
|
||||
LIBUNBOUND_REVISION=5
|
||||
LIBUNBOUND_REVISION=11
|
||||
LIBUNBOUND_AGE=0
|
||||
# 1.0.0 had 0:12:0
|
||||
# 1.0.1 had 0:13:0
|
||||
@@ -30,6 +30,12 @@ LIBUNBOUND_AGE=0
|
||||
# 1.4.3 had 2:3:0
|
||||
# 1.4.4 had 2:4:0
|
||||
# 1.4.5 had 2:5:0
|
||||
# 1.4.6 had 2:6:0
|
||||
# 1.4.7 had 2:7:0
|
||||
# 1.4.8 had 2:8:0
|
||||
# 1.4.9 had 2:9:0
|
||||
# 1.4.10 had 2:10:0
|
||||
# 1.4.11 had 2:11:0
|
||||
|
||||
# Current -- the number of the binary API that we're implementing
|
||||
# Revision -- which iteration of the implementation of the binary
|
||||
@@ -53,6 +59,19 @@ AC_SUBST(LIBUNBOUND_CURRENT)
|
||||
AC_SUBST(LIBUNBOUND_REVISION)
|
||||
AC_SUBST(LIBUNBOUND_AGE)
|
||||
|
||||
pretty_cmdline() {
|
||||
cmdline=""
|
||||
while test -n "$1"; do
|
||||
cmdline="$cmdline '"`echo $1 | sed -e 's/\\\\/\\\\\\\\/g' | sed -e 's/"/\\\\"/g' `"'"
|
||||
shift
|
||||
done
|
||||
}
|
||||
pretty_cmdline $@
|
||||
AC_DEFINE_UNQUOTED(CONFIGURE_BUILD_WITH, ["$cmdline"], [configure flags])
|
||||
AC_CANONICAL_TARGET
|
||||
AC_DEFINE_UNQUOTED(CONFIGURE_TARGET, ["$target"], [configure target system])
|
||||
AC_DEFINE_UNQUOTED(CONFIGURE_DATE, ["`date`"], [configure date])
|
||||
|
||||
CFLAGS="$CFLAGS"
|
||||
AC_AIX
|
||||
|
||||
@@ -139,6 +158,34 @@ AC_SUBST(UNBOUND_PIDFILE)
|
||||
ACX_ESCAPE_BACKSLASH($UNBOUND_PIDFILE, hdr_pid)
|
||||
AC_DEFINE_UNQUOTED(PIDFILE, ["$hdr_pid"], [default pidfile location])
|
||||
|
||||
AC_ARG_WITH(rootkey-file,
|
||||
AC_HELP_STRING([--with-rootkey-file=filename],
|
||||
[set default pathname to root key file (default run-dir/root.key). This file is read and written.]),
|
||||
UNBOUND_ROOTKEY_FILE="$withval",
|
||||
if test $on_mingw = no; then
|
||||
UNBOUND_ROOTKEY_FILE="$UNBOUND_RUN_DIR/root.key"
|
||||
else
|
||||
UNBOUND_ROOTKEY_FILE="C:\\Program Files\\Unbound\\root.key"
|
||||
fi
|
||||
)
|
||||
AC_SUBST(UNBOUND_ROOTKEY_FILE)
|
||||
ACX_ESCAPE_BACKSLASH($UNBOUND_ROOTKEY_FILE, hdr_rkey)
|
||||
AC_DEFINE_UNQUOTED(ROOT_ANCHOR_FILE, ["$hdr_rkey"], [default rootkey location])
|
||||
|
||||
AC_ARG_WITH(rootcert-file,
|
||||
AC_HELP_STRING([--with-rootcert-file=filename],
|
||||
[set default pathname to root update certificate file (default run-dir/icannbundle.pem). This file need not exist if you are content with the builtin.]),
|
||||
UNBOUND_ROOTCERT_FILE="$withval",
|
||||
if test $on_mingw = no; then
|
||||
UNBOUND_ROOTCERT_FILE="$UNBOUND_RUN_DIR/icannbundle.pem"
|
||||
else
|
||||
UNBOUND_ROOTCERT_FILE="C:\\Program Files\\Unbound\\icannbundle.pem"
|
||||
fi
|
||||
)
|
||||
AC_SUBST(UNBOUND_ROOTCERT_FILE)
|
||||
ACX_ESCAPE_BACKSLASH($UNBOUND_ROOTCERT_FILE, hdr_rpem)
|
||||
AC_DEFINE_UNQUOTED(ROOT_CERT_FILE, ["$hdr_rpem"], [default rootcert location])
|
||||
|
||||
AC_ARG_WITH(username,
|
||||
AC_HELP_STRING([--with-username=user],
|
||||
[set default user that unbound changes to (default user is unbound)]),
|
||||
@@ -160,10 +207,6 @@ AC_PROG_CC
|
||||
ACX_DEPFLAG
|
||||
ACX_DETERMINE_EXT_FLAGS_UNBOUND
|
||||
|
||||
# for Sun studio 11.
|
||||
ACX_CHECK_COMPILER_FLAG(xO4, [CFLAGS="$CFLAGS -xO4"])
|
||||
ACX_CHECK_COMPILER_FLAG(xtarget=generic, [CFLAGS="$CFLAGS -xtarget=generic"])
|
||||
|
||||
# debug mode flags warnings
|
||||
AC_ARG_ENABLE(checking, AC_HELP_STRING([--enable-checking], [Enable warnings, asserts, makefile-dependencies]))
|
||||
AC_ARG_ENABLE(debug, AC_HELP_STRING([--enable-debug], [same as enable-checking]))
|
||||
@@ -182,6 +225,7 @@ case "$debug_enabled" in
|
||||
# nothing to do.
|
||||
;;
|
||||
esac
|
||||
ACX_CHECK_COMPILER_FLAG(flto, [CFLAGS="$CFLAGS -flto"])
|
||||
|
||||
AC_C_INLINE
|
||||
ACX_CHECK_FORMAT_ATTRIBUTE
|
||||
@@ -393,7 +437,7 @@ ACX_LIB_SSL
|
||||
AC_CHECK_HEADERS([openssl/conf.h],,, [AC_INCLUDES_DEFAULT])
|
||||
AC_CHECK_HEADERS([openssl/engine.h],,, [AC_INCLUDES_DEFAULT])
|
||||
AC_CHECK_FUNCS([OPENSSL_config EVP_sha1 EVP_sha256 EVP_sha512])
|
||||
AC_CHECK_DECLS([SSL_COMP_get_compression_methods], [], [], [
|
||||
AC_CHECK_DECLS([SSL_COMP_get_compression_methods,sk_SSL_COMP_pop_free], [], [], [
|
||||
AC_INCLUDES_DEFAULT
|
||||
#ifdef HAVE_OPENSSL_ERR_H
|
||||
#include <openssl/err.h>
|
||||
@@ -423,21 +467,16 @@ case "$enable_sha2" in
|
||||
;;
|
||||
esac
|
||||
|
||||
AC_ARG_ENABLE(gost, AC_HELP_STRING([--enable-gost], [Enable GOST support, experimental]))
|
||||
AC_ARG_ENABLE(gost, AC_HELP_STRING([--disable-gost], [Disable GOST support]))
|
||||
use_gost="no"
|
||||
case "$enable_gost" in
|
||||
yes)
|
||||
AC_CHECK_FUNC(EVP_PKEY_set_type_str, [:],[AC_MSG_ERROR([OpenSSL 1.0.0 is needed for GOST support])])
|
||||
use_gost="yes"
|
||||
AC_DEFINE([USE_GOST], [1], [Define this to enable GOST support.])
|
||||
;;
|
||||
no)
|
||||
;;
|
||||
*) dnl default
|
||||
dnl Disabled-by-default, RFC not ready.
|
||||
dnl AC_CHECK_FUNC(EVP_PKEY_set_type_str, [
|
||||
dnl use_gost="yes"
|
||||
dnl AC_DEFINE([USE_GOST], [1], [Define this to enable GOST support.])])
|
||||
*)
|
||||
AC_CHECK_FUNC(EVP_PKEY_set_type_str, [:],[AC_MSG_ERROR([OpenSSL 1.0.0 is needed for GOST support])])
|
||||
AC_CHECK_FUNC(EC_KEY_new, [], [AC_MSG_ERROR([OpenSSL does not support ECC, needed for GOST support])])
|
||||
use_gost="yes"
|
||||
AC_DEFINE([USE_GOST], [1], [Define this to enable GOST support.])
|
||||
;;
|
||||
esac
|
||||
|
||||
@@ -511,6 +550,7 @@ large outgoing port ranges. ])
|
||||
AC_CHECK_FUNCS([event_base_new]) # only in libevent 1.4.1 and later
|
||||
AC_CHECK_FUNCS([event_base_get_method]) # only in libevent 1.4.3 and later
|
||||
AC_CHECK_FUNCS([ev_loop]) # only in libev. (tested on 3.51)
|
||||
AC_CHECK_FUNCS([ev_default_loop]) # only in libev. (tested on 4.00)
|
||||
if test -n "$BAK_LDFLAGS_SET"; then
|
||||
LDFLAGS="$BAK_LDFLAGS"
|
||||
fi
|
||||
@@ -518,6 +558,29 @@ else
|
||||
AC_DEFINE(USE_MINI_EVENT, 1, [Define if you want to use internal select based events])
|
||||
fi
|
||||
|
||||
# check for libexpat
|
||||
AC_ARG_WITH(libexpat, AC_HELP_STRING([--with-libexpat=path],
|
||||
[specify explicit path for libexpat.]),
|
||||
[ ],[ withval="/usr/local /opt/local /usr/lib /usr/pkg /usr/sfw /usr" ])
|
||||
AC_MSG_CHECKING(for libexpat)
|
||||
found_libexpat="no"
|
||||
for dir in $withval ; do
|
||||
if test -f "$dir/include/expat.h"; then
|
||||
found_libexpat="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)
|
||||
break;
|
||||
fi
|
||||
done
|
||||
if test x_$found_libexpat != x_yes; then
|
||||
AC_ERROR([Could not find libexpat, expat.h])
|
||||
fi
|
||||
AC_CHECK_HEADERS([expat.h],,, [AC_INCLUDES_DEFAULT])
|
||||
|
||||
# set static linking if requested
|
||||
AC_SUBST(staticexe)
|
||||
staticexe=""
|
||||
@@ -593,8 +656,31 @@ if test $ac_cv_func_daemon = yes; then
|
||||
])
|
||||
fi
|
||||
|
||||
# check wether strptime also works
|
||||
AC_DEFUN([AC_CHECK_STRPTIME_WORKS],
|
||||
[AC_REQUIRE([AC_PROG_CC])
|
||||
AC_MSG_CHECKING(whether strptime works)
|
||||
if test c${cross_compiling} = cno; then
|
||||
AC_TRY_RUN([
|
||||
#define _XOPEN_SOURCE
|
||||
#include <time.h>
|
||||
int main(void) { struct tm tm; char *res;
|
||||
res = strptime("20070207111842", "%Y%m%d%H%M%S", &tm);
|
||||
if (!res) return 1; return 0; }
|
||||
] , [eval "ac_cv_c_strptime_works=yes"], [eval "ac_cv_c_strptime_works=no"])
|
||||
else
|
||||
eval "ac_cv_c_strptime_works=maybe"
|
||||
fi
|
||||
AC_MSG_RESULT($ac_cv_c_strptime_works)
|
||||
if test $ac_cv_c_strptime_works = no; then
|
||||
AC_LIBOBJ(strptime)
|
||||
else
|
||||
AC_DEFINE_UNQUOTED([STRPTIME_WORKS], 1, [use default strptime.])
|
||||
fi
|
||||
])dnl
|
||||
AC_CHECK_FUNCS([strptime],[AC_CHECK_STRPTIME_WORKS],[AC_LIBOBJ([strptime])])
|
||||
AC_SEARCH_LIBS([setusercontext], [util])
|
||||
AC_CHECK_FUNCS([tzset sigprocmask fcntl getpwnam getrlimit setsid sbrk chroot kill sleep usleep random srandom recvmsg sendmsg writev glob initgroups strftime localtime_r setusercontext _beginthreadex])
|
||||
AC_CHECK_FUNCS([tzset sigprocmask fcntl getpwnam getrlimit setrlimit setsid sbrk chroot kill sleep usleep random srandom recvmsg sendmsg writev socketpair glob initgroups strftime localtime_r setusercontext _beginthreadex])
|
||||
AC_CHECK_FUNCS([setresuid],,[AC_CHECK_FUNCS([setreuid])])
|
||||
AC_CHECK_FUNCS([setresgid],,[AC_CHECK_FUNCS([setregid])])
|
||||
|
||||
@@ -611,19 +697,32 @@ AC_REPLACE_FUNCS(memmove)
|
||||
AC_REPLACE_FUNCS(gmtime_r)
|
||||
AC_REPLACE_FUNCS(ctime_r)
|
||||
|
||||
AC_ARG_ENABLE(allsymbols, AC_HELP_STRING([--enable-allsymbols], [export all symbols from libunbound and link binaries to it, smaller install size but libunbound export table is polluted by internal symbols]))
|
||||
case "$enable_allsymbols" in
|
||||
no)
|
||||
EXPORT_ALL_SYMBOLS=no
|
||||
;;
|
||||
yes)
|
||||
EXPORT_ALL_SYMBOLS=yes
|
||||
;;
|
||||
esac
|
||||
AC_SUBST(EXPORT_ALL_SYMBOLS)
|
||||
|
||||
# check this after all other compilation checks, since the linking of the lib
|
||||
# may break checks after this.
|
||||
use_ldns_builtin="no"
|
||||
AC_ARG_WITH(ldns, AC_HELP_STRING([--with-ldns=PATH],
|
||||
[specify prefix of path of ldns library to use]),
|
||||
[ specialldnsdir="$withval"
|
||||
if test "$withval" != ""; then
|
||||
CPPFLAGS="-I$withval/include $CPPFLAGS"
|
||||
LDFLAGS="-L$withval -L$withval/lib $LDFLAGS"
|
||||
ACX_RUNTIME_PATH_ADD([$withval/lib])
|
||||
if test "$withval" != "yes"; then
|
||||
if test "$withval" != "/usr" -a "$withval" != ""; then
|
||||
CPPFLAGS="-I$withval/include $CPPFLAGS"
|
||||
LDFLAGS="-L$withval/lib $LDFLAGS"
|
||||
ACX_RUNTIME_PATH_ADD([$withval/lib])
|
||||
fi
|
||||
ldnsdir="$withval"
|
||||
AC_SUBST(ldnsdir)
|
||||
fi
|
||||
ldnsdir="$withval"
|
||||
AC_SUBST(ldnsdir)
|
||||
])
|
||||
|
||||
AC_ARG_WITH(ldns-builtin, AC_HELP_STRING([--with-ldns-builtin],
|
||||
@@ -635,22 +734,45 @@ AC_ARG_WITH(ldns-builtin, AC_HELP_STRING([--with-ldns-builtin],
|
||||
if test "$use_ldns_builtin" = "no"; then
|
||||
AC_CHECK_LIB(ldns, ldns_buffer_copy)
|
||||
AC_CHECK_FUNC(ldns_key_buf2rsa_raw)
|
||||
AC_CHECK_FUNC(ldns_get_random)
|
||||
AC_CHECK_FUNC(ldns_b32_ntop_extended_hex)
|
||||
if test x$use_gost = xyes; then
|
||||
AC_CHECK_FUNC(ldns_key_EVP_load_gost_id)
|
||||
AC_CHECK_FUNCS([ldns_key_EVP_unload_gost])
|
||||
else
|
||||
ac_cv_func_ldns_key_EVP_load_gost_id="yes"
|
||||
fi
|
||||
AC_CHECK_HEADERS([ldns/ldns.h],,, [AC_INCLUDES_DEFAULT])
|
||||
AC_CHECK_HEADERS([ldns/ldns.h],,, [AC_INCLUDES_DEFAULT
|
||||
#ifdef HAVE_SYS_SOCKET_H
|
||||
#include <sys/socket.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_NETINET_IN_H
|
||||
#include <netinet/in.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_ARPA_INET_H
|
||||
#include <arpa/inet.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_WINSOCK2_H
|
||||
#include <winsock2.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_WS2TCPIP_H
|
||||
#include <ws2tcpip.h>
|
||||
#endif
|
||||
])
|
||||
if test $ac_cv_lib_ldns_ldns_buffer_copy = yes \
|
||||
-a $ac_cv_func_ldns_key_buf2rsa_raw = yes \
|
||||
-a $ac_cv_func_ldns_get_random = yes \
|
||||
-a $ac_cv_header_ldns_ldns_h = yes \
|
||||
-a $ac_cv_func_ldns_b32_ntop_extended_hex = yes \
|
||||
-a $ac_cv_func_ldns_key_EVP_load_gost_id = yes; then
|
||||
dnl ldns was found
|
||||
:
|
||||
else
|
||||
use_ldns_builtin="yes"
|
||||
AC_MSG_ERROR([No ldns library found (or not recent); install or update ldns library, use --with-ldns=path or --with-ldns-builtin])
|
||||
fi
|
||||
fi
|
||||
|
||||
@@ -759,7 +881,13 @@ AHX_MEMCMP_BROKEN(unbound)
|
||||
char *ctime_r(const time_t *timep, char *buf);
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_EVENT_H) && !defined(HAVE_EVENT_BASE_ONCE) && (defined(HAVE_PTHREAD) || defined(HAVE_SOLARIS_THREADS))
|
||||
#if !defined(HAVE_STRPTIME) || !defined(STRPTIME_WORKS)
|
||||
#define strptime unbound_strptime
|
||||
struct tm;
|
||||
char *strptime(const char *s, const char *format, struct tm *tm);
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_EVENT_H) && !defined(HAVE_EVENT_BASE_ONCE) && !(defined(HAVE_EV_LOOP) || defined(HAVE_EV_DEFAULT_LOOP)) && (defined(HAVE_PTHREAD) || defined(HAVE_SOLARIS_THREADS))
|
||||
/* using version of libevent that is not threadsafe. */
|
||||
# define LIBEVENT_SIGNAL_PROBLEM 1
|
||||
#endif
|
||||
@@ -803,8 +931,14 @@ 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 unbound control traffic, registered port with IANA,
|
||||
ub-dns-control 8953/tcp unbound dns nameserver control */
|
||||
#define UNBOUND_CONTROL_PORT 8953
|
||||
/** the version of unbound-control that this software implements */
|
||||
#define UNBOUND_CONTROL_VERSION 1
|
||||
|
||||
])
|
||||
|
||||
AC_CONFIG_FILES([Makefile doc/example.conf doc/libunbound.3 doc/unbound.8 doc/unbound-checkconf.8 doc/unbound.conf.5 doc/unbound-control.8])
|
||||
AC_CONFIG_FILES([Makefile doc/example.conf doc/libunbound.3 doc/unbound.8 doc/unbound-anchor.8 doc/unbound-checkconf.8 doc/unbound.conf.5 doc/unbound-control.8])
|
||||
AC_CONFIG_HEADER([config.h])
|
||||
AC_OUTPUT
|
||||
|
||||
@@ -7,9 +7,6 @@ distribution but may be helpful.
|
||||
* unbound.spec and unbound.init: RPM specfile and Linux rc.d initfile.
|
||||
* update-anchor.sh: shell script that uses unbound-host to update a set
|
||||
of trust anchor files. Run from cron twice a month.
|
||||
* update-itar.sh: shell script that updates from itar.iana.org. Run from cron.
|
||||
* split-itar.sh: shell script to split anchors.mf from itar.iana.org into
|
||||
multiple key files so it can be used with auto-trust-anchor-file.
|
||||
* unbound_munin_ : plugin for munin statistics report
|
||||
* unbound_cacti.tar.gz : setup files for cacti statistics report
|
||||
* selinux: the .fc and .te files for SElinux protection of the unbound daemon
|
||||
|
||||
@@ -1,46 +0,0 @@
|
||||
#/usr/bin/env bash
|
||||
# Contributed by Tom Hendrikx <tom@whyscream.net>
|
||||
|
||||
PROGNAME=$(basename $0)
|
||||
|
||||
usage() {
|
||||
echo "$PROGNAME: split the anchors.mf file from IANA into separate files." >&2
|
||||
echo "" >&2
|
||||
echo "$PROGNAME uses 2 arguments:" >&2
|
||||
echo " - the path to the anchors.mf, available at: https://itar.iana.org/" >&2
|
||||
echo " - the directory to leave the files, defaults to '.' (current working dir)" >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
if [ -n "$1" ] && [ -r "$1" ]; then
|
||||
itar="$1"
|
||||
echo "Reading from: $itar"
|
||||
else
|
||||
echo "Error: no anchors file given" >&2
|
||||
usage
|
||||
fi
|
||||
|
||||
if [ -n "$2" ]; then
|
||||
dir="$2"
|
||||
else
|
||||
dir=$(pwd)
|
||||
fi
|
||||
|
||||
if [ ! -d "$dir" ]; then
|
||||
echo "Error: $dir is not a directory" >&2
|
||||
usage
|
||||
fi
|
||||
|
||||
while read cn line; do
|
||||
if [ $(expr match "$cn" '[a-zA-Z0-9-]*\.') -gt 0 ]; then
|
||||
# first line of key
|
||||
out="$dir/$cn"anchor
|
||||
echo "writing key for $cn to: $out"
|
||||
echo "$cn $line" > $out
|
||||
elif [ "$cn" == "DS" ]; then
|
||||
# second or later line of earlier defined key
|
||||
echo " $cn $line" >> $out
|
||||
fi
|
||||
done < "$itar"
|
||||
|
||||
echo "Done."
|
||||
+12
-3
@@ -1,6 +1,6 @@
|
||||
Summary: Validating, recursive, and caching DNS resolver
|
||||
Name: unbound
|
||||
Version: 1.4.4
|
||||
Version: 1.4.8
|
||||
Release: 1%{?dist}
|
||||
License: BSD
|
||||
Url: http://www.nlnetlabs.nl/unbound/
|
||||
@@ -8,7 +8,7 @@ Source: http://www.unbound.net/downloads/%{name}-%{version}.tar.gz
|
||||
#Source1: unbound.init
|
||||
Group: System Environment/Daemons
|
||||
BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
|
||||
BuildRequires: flex, openssl-devel
|
||||
BuildRequires: flex, openssl-devel, expat-devel
|
||||
|
||||
%description
|
||||
Unbound is a validating, recursive, and caching DNS resolver.
|
||||
@@ -32,7 +32,7 @@ The source code is under a BSD License.
|
||||
# This is a build using libldns builtin version, the resulting binaries
|
||||
# do not require libldns and this package does not have version dependencies.
|
||||
# Could be smaller using a dependency on libldns (use --with-ldns=).
|
||||
%configure --with-conf-file=%{_localstatedir}/%{name}/unbound.conf --disable-rpath
|
||||
%configure --with-conf-file=%{_localstatedir}/%{name}/unbound.conf --disable-rpath --with-ldns-builtin
|
||||
|
||||
%build
|
||||
#%{__make} %{?_smp_mflags}
|
||||
@@ -92,6 +92,15 @@ if [ "$1" -ge "1" ]; then
|
||||
fi
|
||||
|
||||
%changelog
|
||||
* Thu Mar 17 2011 Wouter Wijngaards <wouter@nlnetlabs.nl> - 1.4.8
|
||||
- removed --disable-gost, assume recent openssl on the destination platform.
|
||||
|
||||
* Wed Mar 16 2011 Harold Jones <hajones@verisign.com> - 1.4.8
|
||||
- Bump version number to latest
|
||||
- Add expat-devel to BuildRequires
|
||||
- Added --disable-gost for building on CentOS 5.x
|
||||
- Added --with-ldns-builtin for CentOS 5.x
|
||||
|
||||
* Thu May 22 2008 Wouter Wijngaards <wouter@nlnetlabs.nl> - 1.0.0
|
||||
- contrib changes from Patrick Vande Walle.
|
||||
|
||||
|
||||
@@ -1,128 +0,0 @@
|
||||
#!/bin/sh
|
||||
# update-itar.sh - update from the interim trust anchor repository
|
||||
# Copyright 2009, W.C.A. Wijngaards
|
||||
# This file is BSD licensed, see doc/LICENSE.
|
||||
|
||||
# --- Some settings
|
||||
|
||||
# directory where unbound works
|
||||
thedir="."
|
||||
# where is the file that unbound is going to read
|
||||
ub_ta_file="$thedir/anchors.mf"
|
||||
# where is the itar master file format
|
||||
itar_url="ftp://ftp.iana.org/itar/anchors.mf"
|
||||
# where is the itar PGP signature
|
||||
itar_sig="ftp://ftp.iana.org/itar/anchors.mf.sig"
|
||||
|
||||
# which command to fetch urls, cmd $dest $url. "wget -O" "curl -o"
|
||||
fetch_cmd="wget -O"
|
||||
# file with pgp public key
|
||||
pgp_pub_key_file="$thedir/update-itar.key"
|
||||
# our pgp keyring (goes into .gnupg directory)
|
||||
pgp_keyring_file="update-itar.ring"
|
||||
# pgp command to use
|
||||
pgp_cmd="gpg"
|
||||
|
||||
|
||||
# --- The script is below
|
||||
usage ( )
|
||||
{
|
||||
echo "usage: update-itar"
|
||||
echo " Updates the trust anchors from the interim trust"
|
||||
echo " anchor repository, https://itar.iana.org, and checks PGP sig."
|
||||
echo
|
||||
echo " Updates $ub_ta_file with the latest keys."
|
||||
echo " Read that file from the unbound config with"
|
||||
echo " trust-anchor-file: "'"'"$ub_ta_file"'"'
|
||||
echo
|
||||
echo " Exit code 0 means anchors updated, 1 no changes, "
|
||||
echo " others are errors. So, in a cronjob you can do:"
|
||||
echo " cd /usr/local/etc/unbound # your unbound work dir"
|
||||
echo " ./update-itar.sh && unbound-control reload"
|
||||
exit 2
|
||||
}
|
||||
|
||||
if test $# -ne 0; then
|
||||
usage
|
||||
fi
|
||||
tmpf="/tmp/update-itar.$$"
|
||||
|
||||
# one argument: explanation string
|
||||
error_exit ( )
|
||||
{
|
||||
if test -f $tmpf.log; then cat $tmpf.log; fi
|
||||
rm -f $tmpf $tmpf.sig $tmpf.log
|
||||
echo "Error updating trust anchors: $1"
|
||||
exit 2
|
||||
}
|
||||
|
||||
if test ! -f $pgp_pub_key_file || test ! -f $HOME/.gnupg/$pgp_keyring_file || \
|
||||
test "$pgp_pub_key_file" -nt $HOME/.gnupg/$pgp_keyring_file; then
|
||||
# default key contents right here
|
||||
if test ! -f $pgp_pub_key_file; then
|
||||
echo "creating default IANA ITAR pgp key file"
|
||||
cat >$pgp_pub_key_file <<EOF
|
||||
-----BEGIN PGP PUBLIC KEY BLOCK-----
|
||||
Version: GnuPG v1.4.5
|
||||
|
||||
mQGiBElr2DcRBAC+6YK6eSP7rzstvnMPQXMrpvVfuIR5FeTpGuwae9JP78V/iOXr
|
||||
N0yW8Dn6kdAztCMuRizL1Ij9IgaD7pjn8h09VgR4cN4LDv75rcQeWLzNxKy4UNRF
|
||||
aStL77RcIoTblBeCgHAK9FLzd0XfTGZCNaLNy9BYVSLyADOVDIqgBcrvBwCglz03
|
||||
QhOMIgaSx/XuRh6kYtynZ6kD/2GXx6pFs57b7rww8yOpdurCSOMB1wuEXiIXznTI
|
||||
06ARiib0G5VDvOdpy0LDU2526Q9f/WAERlhcExTgnTFigG4mRksUiDrrai4GIr+6
|
||||
JaivcGFVYdZZ4mZ088jcwujS/UY3C0ryGR9ufYUDAnfx6frhSl6o6j5is+jeGndF
|
||||
JYRAA/9B/1OXNVwFSiIxnP2aPUwsT1li1vaW8dhA/5PcuPLOVvEjPc1Pc16HGLhE
|
||||
8CRmMn66LqB1ccInE5hLKGGvV3pctjan+IOhaq3OHt/a+buDtTPgykchMZ2k1AzT
|
||||
RYk+gksxpIl6yTZsBH4hoRt8auxEJW8AiYbNtXXkNuWcoQL40bQsSUFOQSBUcnVz
|
||||
dCBBbmNob3IgUmVwb3NpdG9yeSA8aXRhckBpYW5hLm9yZz6IYAQTEQIAIAUCSWvY
|
||||
NwIbAwYLCQgHAwIEFQIIAwQWAgMBAh4BAheAAAoJEPR9+zCB1GT0GUAAn29/TacF
|
||||
Teh87dls8pmkjxS4pKf1AKCJS/MvzR54AblO4DNMyc9q0G4frrkCDQRJa9g3EAgA
|
||||
ywoLxF4HVb9o926UIXw8JxNIzDPkt8galAcKRUmHQMNa/QA80WMl9Ia6DIxavGlV
|
||||
I5O1fvms297RV2KSSBjKWn6G+0me80A7aw0eHNg7habM5VtzDz5DhJbQFdJV9aYV
|
||||
DoTSnY6uR6iSSRrdZNaYdlCwDS8lBCnOKoGMArHzVCa2EdCBeCUY/eObOXtu8Gm3
|
||||
nDkuWeLPv08/0lvtr6d6VoDUEVPEsJAPONEYtpz/D+EZddUraF+3JscWqfRApBOz
|
||||
/8WHaeTNdzIH+h1ntktiizA6eH40EM6coQQxtIRsxg1DPTxofdovreMkcMI0EUUP
|
||||
awDn8gDtgG3g6Ud5zCdknwAEDQf/W3rxrEN6OZxJvWti8Iu6KOgxtuINiAsimPPX
|
||||
qy9KHowyEE9EMPzgADjWC9Reyusr4CwcootjWw7ryUwU0fXvVULKhg32NzLsx/Ci
|
||||
WtgCPSR58WZ1KKhnoB05+PTrwzhU+u64Cd/vJtFqGxSrANl2FAkPswHJMr8dMwAz
|
||||
uni7zzLJ+homW1T5AaixwmN3jeDHWshJH9E9JIhr5Y/8AzMl1V10r2u1c2ej0lBJ
|
||||
Y4GegI5cYAEBerS9d+mrbPlvbJ8AfuAuEf0y/PWJh0z1+Kck5qIbXMn/rpMBYvLJ
|
||||
Uj5CfqWlh8+hxqSYJDXtLm8hBiQFiMEew0jOc2Tw4F91OZ+jyYhJBBgRAgAJBQJJ
|
||||
a9g3AhsMAAoJEPR9+zCB1GT0AUwAn2ZtBwAyVxppdeTqilXufUvAkvjbAJ9dUpR1
|
||||
9a17/5BvDDJcIxSEKTJmDw==
|
||||
=zCNZ
|
||||
-----END PGP PUBLIC KEY BLOCK-----
|
||||
EOF
|
||||
fi
|
||||
# import the new key
|
||||
$pgp_cmd --no-default-keyring --keyring $pgp_keyring_file \
|
||||
--primary-keyring $pgp_keyring_file \
|
||||
--import $pgp_pub_key_file >$tmpf.log 2>&1 \
|
||||
|| error_exit "could not import pgp public key into keyring"
|
||||
fi
|
||||
|
||||
$fetch_cmd $tmpf $itar_url >$tmpf.log 2>&1 \
|
||||
|| error_exit "fetching $itar_url failed"
|
||||
tail -2 $tmpf | grep "; End of file" >/dev/null 2>&1 || \
|
||||
error_exit "The file fetched from $itar_url was partial"
|
||||
$fetch_cmd $tmpf.sig $itar_sig >$tmpf.log 2>&1 \
|
||||
|| error_exit "fetching $itar_sig failed"
|
||||
|
||||
# check the file with pgp
|
||||
$pgp_cmd --no-default-keyring --keyring $pgp_keyring_file \
|
||||
--verify $tmpf.sig $tmpf >$tmpf.log 2>&1 \
|
||||
|| error_exit "the PGP signature failed!"
|
||||
|
||||
# check for differences
|
||||
val=1
|
||||
if diff "$ub_ta_file" $tmpf 2>/dev/null ; then
|
||||
# echo "The interim trust anchor repository did not change."
|
||||
:
|
||||
else
|
||||
echo "Updating $ub_ta_file"
|
||||
cp $tmpf $ub_ta_file
|
||||
val=0
|
||||
fi
|
||||
|
||||
rm -f $tmpf $tmpf.sig $tmpf.log
|
||||
exit $val
|
||||
Executable
+117
@@ -0,0 +1,117 @@
|
||||
#!/bin/sh
|
||||
# validation reporter - reports validation failures to a collection server.
|
||||
# Copyright NLnet Labs, 2010
|
||||
# BSD license.
|
||||
|
||||
|
||||
###
|
||||
# Here is the configuration for the validation reporter
|
||||
# it greps the failure lines out of the log and sends them to a server.
|
||||
|
||||
# The pidfile for the reporter daemon.
|
||||
pidfile="/var/run/validation-reporter.pid"
|
||||
|
||||
# The logfile to watch for logged validation failures.
|
||||
logfile="/var/log/unbound.log"
|
||||
|
||||
# how to notify the upstream
|
||||
# nc is netcat, it sends tcp to given host port. It makes a tcp connection
|
||||
# and writes one log-line to it (grepped from the logfile).
|
||||
# the notify command can be: "nc the.server.name.org 1234"
|
||||
# the listening daemon could be: nc -lk 127.0.0.1 1234 >> outputfile &
|
||||
notify_cmd="nc localhost 1234"
|
||||
|
||||
|
||||
###
|
||||
# Below this line is the code for the validation reporter,
|
||||
# first the daemon itself, then the controller for the daemon.
|
||||
reporter_daemon() {
|
||||
trap "rm -f \"$pidfile\"" EXIT
|
||||
tail -f $logfile | grep "unbound.*info: validation failure" | \
|
||||
while read x; do
|
||||
echo "$x" | $notify_cmd
|
||||
done
|
||||
}
|
||||
|
||||
|
||||
###
|
||||
# controller for daemon.
|
||||
start_daemon() {
|
||||
echo "starting reporter"
|
||||
nohup $0 rundaemon </dev/null >/dev/null 2>&1 &
|
||||
echo $! > "$pidfile"
|
||||
}
|
||||
|
||||
kill_daemon() {
|
||||
echo "stopping reporter"
|
||||
if test -s "$pidfile"; then
|
||||
kill `cat "$pidfile"`
|
||||
# check it is really dead
|
||||
if kill -0 `cat "$pidfile"` >/dev/null 2>&1; then
|
||||
sleep 1
|
||||
while kill -0 `cat "$pidfile"` >/dev/null 2>&1; do
|
||||
kill `cat "$pidfile"` >/dev/null 2>&1
|
||||
echo "waiting for reporter to stop"
|
||||
sleep 1
|
||||
done
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
get_status_daemon() {
|
||||
if test -s "$pidfile"; then
|
||||
if kill -0 `cat "$pidfile"`; then
|
||||
return 0;
|
||||
fi
|
||||
fi
|
||||
return 1;
|
||||
}
|
||||
|
||||
restart_daemon() {
|
||||
kill_daemon
|
||||
start_daemon
|
||||
}
|
||||
|
||||
condrestart_daemon() {
|
||||
if get_status_daemon; then
|
||||
echo "reporter ("`cat "$pidfile"`") is running"
|
||||
exit 0
|
||||
fi
|
||||
start_daemon
|
||||
exit 0
|
||||
}
|
||||
|
||||
status_daemon() {
|
||||
if get_status_daemon; then
|
||||
echo "reporter ("`cat "$pidfile"`") is running"
|
||||
exit 0
|
||||
fi
|
||||
echo "reporter is not running"
|
||||
exit 1
|
||||
}
|
||||
|
||||
case "$1" in
|
||||
rundaemon)
|
||||
reporter_daemon
|
||||
;;
|
||||
start)
|
||||
start_daemon
|
||||
;;
|
||||
stop)
|
||||
kill_daemon
|
||||
;;
|
||||
restart)
|
||||
restart_daemon
|
||||
;;
|
||||
condrestart)
|
||||
condrestart_daemon
|
||||
;;
|
||||
status)
|
||||
status_daemon
|
||||
;;
|
||||
*)
|
||||
echo "Usage: $0 {start|stop|restart|condrestart|status}"
|
||||
exit 2
|
||||
;;
|
||||
esac
|
||||
exit $?
|
||||
+1
-1
@@ -47,7 +47,7 @@
|
||||
#include "util/net_help.h"
|
||||
|
||||
struct acl_list*
|
||||
acl_list_create()
|
||||
acl_list_create(void)
|
||||
{
|
||||
struct acl_list* acl = (struct acl_list*)calloc(1,
|
||||
sizeof(struct acl_list));
|
||||
|
||||
+1
-1
@@ -89,7 +89,7 @@ struct acl_addr {
|
||||
* Create acl structure
|
||||
* @return new structure or NULL on error.
|
||||
*/
|
||||
struct acl_list* acl_list_create();
|
||||
struct acl_list* acl_list_create(void);
|
||||
|
||||
/**
|
||||
* Delete acl structure.
|
||||
|
||||
+27
-8
@@ -802,7 +802,8 @@ print_dp_details(SSL* ssl, struct worker* worker, struct delegpt* dp)
|
||||
{
|
||||
char buf[257];
|
||||
struct delegpt_addr* a;
|
||||
int lame, dlame, rlame, rtt, edns_vs, to, lost;
|
||||
int lame, dlame, rlame, rto, edns_vs, to, delay, entry_ttl;
|
||||
struct rtt_info ri;
|
||||
uint8_t edns_lame_known;
|
||||
for(a = dp->target_list; a; a = a->next_target) {
|
||||
addr_to_str(&a->addr, a->addrlen, buf, sizeof(buf));
|
||||
@@ -813,30 +814,48 @@ print_dp_details(SSL* ssl, struct worker* worker, struct delegpt* dp)
|
||||
return;
|
||||
}
|
||||
/* lookup in infra cache */
|
||||
entry_ttl = infra_get_host_rto(worker->env.infra_cache,
|
||||
&a->addr, a->addrlen, &ri, &delay, *worker->env.now);
|
||||
if(entry_ttl == -2 && ri.rto >= USEFUL_SERVER_TOP_TIMEOUT) {
|
||||
if(!ssl_printf(ssl, "expired, rto %d msec.\n", ri.rto))
|
||||
return;
|
||||
continue;
|
||||
}
|
||||
if(entry_ttl == -1 || entry_ttl == -2) {
|
||||
if(!ssl_printf(ssl, "not in infra cache.\n"))
|
||||
return;
|
||||
continue; /* skip stuff not in infra cache */
|
||||
}
|
||||
|
||||
/* uses type_A because most often looked up, but other
|
||||
* lameness won't be reported then */
|
||||
if(!infra_get_lame_rtt(worker->env.infra_cache,
|
||||
&a->addr, a->addrlen, dp->name, dp->namelen,
|
||||
LDNS_RR_TYPE_A, &lame, &dlame, &rlame, &rtt, &lost,
|
||||
LDNS_RR_TYPE_A, &lame, &dlame, &rlame, &rto,
|
||||
*worker->env.now)) {
|
||||
if(!ssl_printf(ssl, "not in infra cache.\n"))
|
||||
return;
|
||||
continue; /* skip stuff not in infra cache */
|
||||
}
|
||||
if(!ssl_printf(ssl, "%s%s%s%srtt %d msec, %d lost. ",
|
||||
if(!ssl_printf(ssl, "%s%s%s%srto %d msec, ttl %d, ping %d "
|
||||
"var %d rtt %d",
|
||||
lame?"LAME ":"", dlame?"NoDNSSEC ":"",
|
||||
a->lame?"AddrWasParentSide ":"",
|
||||
rlame?"NoAuthButRecursive ":"", rtt, lost))
|
||||
rlame?"NoAuthButRecursive ":"", rto, entry_ttl,
|
||||
ri.srtt, ri.rttvar, rtt_notimeout(&ri)))
|
||||
return;
|
||||
if(delay)
|
||||
if(!ssl_printf(ssl, ", probedelay %d", delay))
|
||||
return;
|
||||
if(infra_host(worker->env.infra_cache, &a->addr, a->addrlen,
|
||||
*worker->env.now, &edns_vs, &edns_lame_known, &to)) {
|
||||
if(edns_vs == -1) {
|
||||
if(!ssl_printf(ssl, "noEDNS%s.",
|
||||
edns_lame_known?" probed":""))
|
||||
if(!ssl_printf(ssl, ", noEDNS%s.",
|
||||
edns_lame_known?" probed":" assumed"))
|
||||
return;
|
||||
} else {
|
||||
if(!ssl_printf(ssl, "EDNS %d%s.",
|
||||
edns_vs, edns_lame_known?" probed":""))
|
||||
if(!ssl_printf(ssl, ", EDNS %d%s.", edns_vs,
|
||||
edns_lame_known?" probed":" assumed"))
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
+15
-8
@@ -131,7 +131,7 @@ static RETSIGTYPE record_sigh(int sig)
|
||||
* Stores signals to replay later.
|
||||
*/
|
||||
static void
|
||||
signal_handling_record()
|
||||
signal_handling_record(void)
|
||||
{
|
||||
if( signal(SIGTERM, record_sigh) == SIG_ERR ||
|
||||
#ifdef SIGQUIT
|
||||
@@ -169,7 +169,7 @@ signal_handling_playback(struct worker* wrk)
|
||||
}
|
||||
|
||||
struct daemon*
|
||||
daemon_init()
|
||||
daemon_init(void)
|
||||
{
|
||||
struct daemon* daemon = (struct daemon*)calloc(1,
|
||||
sizeof(struct daemon));
|
||||
@@ -276,7 +276,7 @@ static void daemon_setup_modules(struct daemon* daemon)
|
||||
* @param shufport: the portlist output.
|
||||
* @return number of ports available.
|
||||
*/
|
||||
int daemon_get_shufport(struct daemon* daemon, int* shufport)
|
||||
static int daemon_get_shufport(struct daemon* daemon, int* shufport)
|
||||
{
|
||||
int i, n, k, temp;
|
||||
int avail = 0;
|
||||
@@ -339,12 +339,13 @@ daemon_create_workers(struct daemon* daemon)
|
||||
free(shufport);
|
||||
}
|
||||
|
||||
#ifdef THREADS_DISABLED
|
||||
/**
|
||||
* Close all pipes except for the numbered thread.
|
||||
* @param daemon: daemon to close pipes in.
|
||||
* @param thr: thread number 0..num-1 of thread to skip.
|
||||
*/
|
||||
void close_other_pipes(struct daemon* daemon, int thr)
|
||||
static void close_other_pipes(struct daemon* daemon, int thr)
|
||||
{
|
||||
int i;
|
||||
for(i=0; i<daemon->num; i++)
|
||||
@@ -359,6 +360,7 @@ void close_other_pipes(struct daemon* daemon, int thr)
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif /* THREADS_DISABLED */
|
||||
|
||||
/**
|
||||
* Function to start one thread.
|
||||
@@ -447,7 +449,7 @@ daemon_fork(struct daemon* daemon)
|
||||
*/
|
||||
daemon_create_workers(daemon);
|
||||
|
||||
#ifdef HAVE_EV_LOOP
|
||||
#if defined(HAVE_EV_LOOP) || defined(HAVE_EV_DEFAULT_LOOP)
|
||||
/* in libev the first inited base gets signals */
|
||||
if(!worker_init(daemon->workers[0], daemon->cfg, daemon->ports, 1))
|
||||
fatal_exit("Could not initialize main thread");
|
||||
@@ -461,7 +463,7 @@ daemon_fork(struct daemon* daemon)
|
||||
/* Special handling for the main thread. This is the thread
|
||||
* that handles signals and remote control.
|
||||
*/
|
||||
#ifndef HAVE_EV_LOOP
|
||||
#if !(defined(HAVE_EV_LOOP) || defined(HAVE_EV_DEFAULT_LOOP))
|
||||
/* libevent has the last inited base get signals (or any base) */
|
||||
if(!worker_init(daemon->workers[0], daemon->cfg, daemon->ports, 1))
|
||||
fatal_exit("Could not initialize main thread");
|
||||
@@ -532,8 +534,13 @@ daemon_delete(struct daemon* daemon)
|
||||
ub_c_lex_destroy();
|
||||
#endif
|
||||
/* libcrypto cleanup */
|
||||
#if HAVE_DECL_SSL_COMP_GET_COMPRESSION_METHODS
|
||||
sk_SSL_COMP_free(comp_meth);
|
||||
#if defined(USE_GOST) && defined(HAVE_LDNS_KEY_EVP_UNLOAD_GOST)
|
||||
ldns_key_EVP_unload_gost();
|
||||
#endif
|
||||
#if HAVE_DECL_SSL_COMP_GET_COMPRESSION_METHODS && HAVE_DECL_SK_SSL_COMP_POP_FREE
|
||||
#ifndef S_SPLINT_S
|
||||
sk_SSL_COMP_pop_free(comp_meth, (void(*)())CRYPTO_free);
|
||||
#endif
|
||||
#endif
|
||||
#ifdef HAVE_OPENSSL_CONFIG
|
||||
EVP_cleanup();
|
||||
|
||||
+1
-1
@@ -108,7 +108,7 @@ struct daemon {
|
||||
* Initialize daemon structure.
|
||||
* @return: The daemon structure, or NULL on error.
|
||||
*/
|
||||
struct daemon* daemon_init();
|
||||
struct daemon* daemon_init(void);
|
||||
|
||||
/**
|
||||
* Open shared listening ports (if needed).
|
||||
|
||||
+171
-40
@@ -59,6 +59,7 @@
|
||||
#include "util/module.h"
|
||||
#include "services/listen_dnsport.h"
|
||||
#include "services/cache/rrset.h"
|
||||
#include "services/cache/infra.h"
|
||||
#include "services/mesh.h"
|
||||
#include "services/localzone.h"
|
||||
#include "util/storage/slabhash.h"
|
||||
@@ -701,13 +702,14 @@ print_mem(SSL* ssl, struct worker* worker, struct daemon* daemon)
|
||||
|
||||
/** print uptime stats */
|
||||
static int
|
||||
print_uptime(SSL* ssl, struct worker* worker)
|
||||
print_uptime(SSL* ssl, struct worker* worker, int reset)
|
||||
{
|
||||
struct timeval now = *worker->env.now_tv;
|
||||
struct timeval up, dt;
|
||||
timeval_subtract(&up, &now, &worker->daemon->time_boot);
|
||||
timeval_subtract(&dt, &now, &worker->daemon->time_last_stat);
|
||||
worker->daemon->time_last_stat = now;
|
||||
if(reset)
|
||||
worker->daemon->time_last_stat = now;
|
||||
if(!ssl_printf(ssl, "time.now"SQ"%d.%6.6d\n",
|
||||
(unsigned)now.tv_sec, (unsigned)now.tv_usec)) return 0;
|
||||
if(!ssl_printf(ssl, "time.up"SQ"%d.%6.6d\n",
|
||||
@@ -891,7 +893,7 @@ do_stats(SSL* ssl, struct daemon_remote* rc, int reset)
|
||||
total.mesh_time_median /= (double)daemon->num;
|
||||
if(!print_stats(ssl, "total", &total))
|
||||
return;
|
||||
if(!print_uptime(ssl, rc->worker))
|
||||
if(!print_uptime(ssl, rc->worker, reset))
|
||||
return;
|
||||
if(daemon->cfg->stat_extended) {
|
||||
if(!print_mem(ssl, rc->worker, daemon))
|
||||
@@ -1061,6 +1063,9 @@ do_cache_remove(struct worker* worker, uint8_t* nm, size_t nmlen,
|
||||
hashvalue_t h;
|
||||
struct query_info k;
|
||||
rrset_cache_remove(worker->env.rrset_cache, nm, nmlen, t, c, 0);
|
||||
if(t == LDNS_RR_TYPE_SOA)
|
||||
rrset_cache_remove(worker->env.rrset_cache, nm, nmlen, t, c,
|
||||
PACKED_RRSET_SOA_NEG);
|
||||
k.qname = nm;
|
||||
k.qname_len = nmlen;
|
||||
k.qtype = t;
|
||||
@@ -1097,6 +1102,25 @@ do_flush_stats(SSL* ssl, struct worker* worker)
|
||||
send_ok(ssl);
|
||||
}
|
||||
|
||||
/** flush infra cache */
|
||||
static void
|
||||
do_flush_infra(SSL* ssl, struct worker* worker, char* arg)
|
||||
{
|
||||
struct sockaddr_storage addr;
|
||||
socklen_t len;
|
||||
if(strcmp(arg, "all") == 0) {
|
||||
slabhash_clear(worker->env.infra_cache->hosts);
|
||||
send_ok(ssl);
|
||||
return;
|
||||
}
|
||||
if(!ipstrtoaddr(arg, UNBOUND_DNS_PORT, &addr, &len)) {
|
||||
(void)ssl_printf(ssl, "error parsing ip addr: '%s'\n", arg);
|
||||
return;
|
||||
}
|
||||
infra_remove_host(worker->env.infra_cache, &addr, len);
|
||||
send_ok(ssl);
|
||||
}
|
||||
|
||||
/** flush requestlist */
|
||||
static void
|
||||
do_flush_requestlist(SSL* ssl, struct worker* worker)
|
||||
@@ -1317,7 +1341,7 @@ parse_delegpt(SSL* ssl, struct regional* region, char* args, uint8_t* root)
|
||||
return NULL;
|
||||
}
|
||||
/* add address */
|
||||
if(!delegpt_add_addr(dp, region, &addr, addrlen, 0, 0, 1)) {
|
||||
if(!delegpt_add_addr(dp, region, &addr, addrlen, 0, 0)) {
|
||||
(void)ssl_printf(ssl, "error out of memory\n");
|
||||
return NULL;
|
||||
}
|
||||
@@ -1494,6 +1518,89 @@ do_dump_requestlist(SSL* ssl, struct worker* worker)
|
||||
}
|
||||
}
|
||||
|
||||
/** structure for argument data for dump infra host */
|
||||
struct infra_arg {
|
||||
/** the infra cache */
|
||||
struct infra_cache* infra;
|
||||
/** the SSL connection */
|
||||
SSL* ssl;
|
||||
/** the time now */
|
||||
uint32_t now;
|
||||
/** ipstr */
|
||||
char* ipstr;
|
||||
};
|
||||
|
||||
/** callback for every lame element in the infra cache */
|
||||
static void
|
||||
dump_infra_lame(struct lruhash_entry* e, void* arg)
|
||||
{
|
||||
struct infra_arg* a = (struct infra_arg*)arg;
|
||||
struct infra_lame_key* k = (struct infra_lame_key*)e->key;
|
||||
struct infra_lame_data* d = (struct infra_lame_data*)e->data;
|
||||
ldns_rdf* rdf;
|
||||
size_t pos = 0;
|
||||
char* nm;
|
||||
/* skip expired */
|
||||
if(d->ttl < a->now) {
|
||||
return;
|
||||
}
|
||||
/* use ldns print for domain name */
|
||||
if(ldns_wire2dname(&rdf, k->zonename, k->namelen, &pos)
|
||||
!= LDNS_STATUS_OK)
|
||||
return;
|
||||
nm = ldns_rdf2str(rdf);
|
||||
ldns_rdf_deep_free(rdf);
|
||||
if(!ssl_printf(a->ssl, "%s lame %s ttl %d dnssec %d rec %d "
|
||||
"A %d other %d\n", a->ipstr, nm, (int)(d->ttl - a->now),
|
||||
d->isdnsseclame, d->rec_lame, d->lame_type_A, d->lame_other)) {
|
||||
free(nm);
|
||||
return;
|
||||
}
|
||||
free(nm);
|
||||
}
|
||||
|
||||
/** callback for every host element in the infra cache */
|
||||
static void
|
||||
dump_infra_host(struct lruhash_entry* e, void* arg)
|
||||
{
|
||||
struct infra_arg* a = (struct infra_arg*)arg;
|
||||
struct infra_host_key* k = (struct infra_host_key*)e->key;
|
||||
struct infra_host_data* d = (struct infra_host_data*)e->data;
|
||||
char ip_str[1024];
|
||||
addr_to_str(&k->addr, k->addrlen, ip_str, sizeof(ip_str));
|
||||
a->ipstr = ip_str;
|
||||
/* skip expired stuff (only backed off) */
|
||||
if(d->ttl < a->now) {
|
||||
if(d->rtt.rto >= USEFUL_SERVER_TOP_TIMEOUT) {
|
||||
if(!ssl_printf(a->ssl, "%s expired rto %d\n", ip_str,
|
||||
d->rtt.rto)) return;
|
||||
}
|
||||
if(d->lameness)
|
||||
lruhash_traverse(d->lameness, 0, &dump_infra_lame, arg);
|
||||
return;
|
||||
}
|
||||
if(!ssl_printf(a->ssl, "%s ttl %d ping %d var %d rtt %d rto %d "
|
||||
"ednsknown %d edns %d delay %d\n",
|
||||
ip_str, (int)(d->ttl - a->now),
|
||||
d->rtt.srtt, d->rtt.rttvar, rtt_notimeout(&d->rtt), d->rtt.rto,
|
||||
(int)d->edns_lame_known, (int)d->edns_version,
|
||||
(int)(a->now<d->probedelay?d->probedelay-a->now:0)))
|
||||
return;
|
||||
if(d->lameness)
|
||||
lruhash_traverse(d->lameness, 0, &dump_infra_lame, arg);
|
||||
}
|
||||
|
||||
/** do the dump_infra command */
|
||||
static void
|
||||
do_dump_infra(SSL* ssl, struct worker* worker)
|
||||
{
|
||||
struct infra_arg arg;
|
||||
arg.infra = worker->env.infra_cache;
|
||||
arg.ssl = ssl;
|
||||
arg.now = *worker->env.now;
|
||||
slabhash_traverse(arg.infra->hosts, 0, &dump_infra_host, (void*)&arg);
|
||||
}
|
||||
|
||||
/** do the log_reopen command */
|
||||
static void
|
||||
do_log_reopen(SSL* ssl, struct worker* worker)
|
||||
@@ -1618,7 +1725,7 @@ do_list_local_data(SSL* ssl, struct worker* worker)
|
||||
}
|
||||
|
||||
/** tell other processes to execute the command */
|
||||
void
|
||||
static void
|
||||
distribute_cmd(struct daemon_remote* rc, SSL* ssl, char* cmd)
|
||||
{
|
||||
int i;
|
||||
@@ -1636,62 +1743,69 @@ distribute_cmd(struct daemon_remote* rc, SSL* ssl, char* cmd)
|
||||
}
|
||||
}
|
||||
|
||||
/** check for name with end-of-string, space or tab after it */
|
||||
static int
|
||||
cmdcmp(char* p, const char* cmd, size_t len)
|
||||
{
|
||||
return strncmp(p,cmd,len)==0 && (p[len]==0||p[len]==' '||p[len]=='\t');
|
||||
}
|
||||
|
||||
/** execute a remote control command */
|
||||
static void
|
||||
execute_cmd(struct daemon_remote* rc, SSL* ssl, char* cmd,
|
||||
struct worker* worker)
|
||||
{
|
||||
char* p = skipwhite(cmd);
|
||||
/* compare command - check longer strings first in case of substrings*/
|
||||
if(strncmp(p, "stop", 4) == 0) {
|
||||
/* compare command */
|
||||
if(cmdcmp(p, "stop", 4)) {
|
||||
do_stop(ssl, rc);
|
||||
return;
|
||||
} else if(strncmp(p, "reload", 6) == 0) {
|
||||
} else if(cmdcmp(p, "reload", 6)) {
|
||||
do_reload(ssl, rc);
|
||||
return;
|
||||
} else if(strncmp(p, "stats_noreset", 13) == 0) {
|
||||
} else if(cmdcmp(p, "stats_noreset", 13)) {
|
||||
do_stats(ssl, rc, 0);
|
||||
return;
|
||||
} else if(strncmp(p, "stats", 5) == 0) {
|
||||
} else if(cmdcmp(p, "stats", 5)) {
|
||||
do_stats(ssl, rc, 1);
|
||||
return;
|
||||
} else if(strncmp(p, "status", 6) == 0) {
|
||||
} else if(cmdcmp(p, "status", 6)) {
|
||||
do_status(ssl, worker);
|
||||
return;
|
||||
} else if(strncmp(p, "dump_cache", 10) == 0) {
|
||||
} else if(cmdcmp(p, "dump_cache", 10)) {
|
||||
(void)dump_cache(ssl, worker);
|
||||
return;
|
||||
} else if(strncmp(p, "load_cache", 10) == 0) {
|
||||
} else if(cmdcmp(p, "load_cache", 10)) {
|
||||
if(load_cache(ssl, worker)) send_ok(ssl);
|
||||
return;
|
||||
} else if(strncmp(p, "list_forwards", 13) == 0) {
|
||||
} else if(cmdcmp(p, "list_forwards", 13)) {
|
||||
do_list_forwards(ssl, worker);
|
||||
return;
|
||||
} else if(strncmp(p, "list_stubs", 10) == 0) {
|
||||
} else if(cmdcmp(p, "list_stubs", 10)) {
|
||||
do_list_stubs(ssl, worker);
|
||||
return;
|
||||
} else if(strncmp(p, "list_local_zones", 16) == 0) {
|
||||
} else if(cmdcmp(p, "list_local_zones", 16)) {
|
||||
do_list_local_zones(ssl, worker);
|
||||
return;
|
||||
} else if(strncmp(p, "list_local_data", 15) == 0) {
|
||||
} else if(cmdcmp(p, "list_local_data", 15)) {
|
||||
do_list_local_data(ssl, worker);
|
||||
return;
|
||||
} else if(strncmp(p, "forward", 7) == 0) {
|
||||
} else if(cmdcmp(p, "forward", 7)) {
|
||||
/* must always distribute this cmd */
|
||||
if(rc) distribute_cmd(rc, ssl, cmd);
|
||||
do_forward(ssl, worker, skipwhite(p+7));
|
||||
return;
|
||||
} else if(strncmp(p, "flush_stats", 11) == 0) {
|
||||
} else if(cmdcmp(p, "flush_stats", 11)) {
|
||||
/* must always distribute this cmd */
|
||||
if(rc) distribute_cmd(rc, ssl, cmd);
|
||||
do_flush_stats(ssl, worker);
|
||||
return;
|
||||
} else if(strncmp(p, "flush_requestlist", 17) == 0) {
|
||||
} else if(cmdcmp(p, "flush_requestlist", 17)) {
|
||||
/* must always distribute this cmd */
|
||||
if(rc) distribute_cmd(rc, ssl, cmd);
|
||||
do_flush_requestlist(ssl, worker);
|
||||
return;
|
||||
} else if(strncmp(p, "lookup", 6) == 0) {
|
||||
} else if(cmdcmp(p, "lookup", 6)) {
|
||||
do_lookup(ssl, worker, skipwhite(p+6));
|
||||
return;
|
||||
}
|
||||
@@ -1704,29 +1818,33 @@ execute_cmd(struct daemon_remote* rc, SSL* ssl, char* cmd,
|
||||
distribute_cmd(rc, ssl, cmd);
|
||||
}
|
||||
#endif
|
||||
if(strncmp(p, "verbosity", 9) == 0) {
|
||||
if(cmdcmp(p, "verbosity", 9)) {
|
||||
do_verbosity(ssl, skipwhite(p+9));
|
||||
} else if(strncmp(p, "local_zone_remove", 17) == 0) {
|
||||
} else if(cmdcmp(p, "local_zone_remove", 17)) {
|
||||
do_zone_remove(ssl, worker, skipwhite(p+17));
|
||||
} else if(strncmp(p, "local_zone", 10) == 0) {
|
||||
} else if(cmdcmp(p, "local_zone", 10)) {
|
||||
do_zone_add(ssl, worker, skipwhite(p+10));
|
||||
} else if(strncmp(p, "local_data_remove", 17) == 0) {
|
||||
} else if(cmdcmp(p, "local_data_remove", 17)) {
|
||||
do_data_remove(ssl, worker, skipwhite(p+17));
|
||||
} else if(strncmp(p, "local_data", 10) == 0) {
|
||||
} else if(cmdcmp(p, "local_data", 10)) {
|
||||
do_data_add(ssl, worker, skipwhite(p+10));
|
||||
} else if(strncmp(p, "flush_zone", 10) == 0) {
|
||||
} else if(cmdcmp(p, "flush_zone", 10)) {
|
||||
do_flush_zone(ssl, worker, skipwhite(p+10));
|
||||
} else if(strncmp(p, "flush_type", 10) == 0) {
|
||||
} else if(cmdcmp(p, "flush_type", 10)) {
|
||||
do_flush_type(ssl, worker, skipwhite(p+10));
|
||||
} else if(strncmp(p, "flush", 5) == 0) {
|
||||
} else if(cmdcmp(p, "flush_infra", 11)) {
|
||||
do_flush_infra(ssl, worker, skipwhite(p+11));
|
||||
} else if(cmdcmp(p, "flush", 5)) {
|
||||
do_flush_name(ssl, worker, skipwhite(p+5));
|
||||
} else if(strncmp(p, "dump_requestlist", 16) == 0) {
|
||||
} else if(cmdcmp(p, "dump_requestlist", 16)) {
|
||||
do_dump_requestlist(ssl, worker);
|
||||
} else if(strncmp(p, "log_reopen", 10) == 0) {
|
||||
} else if(cmdcmp(p, "dump_infra", 10)) {
|
||||
do_dump_infra(ssl, worker);
|
||||
} else if(cmdcmp(p, "log_reopen", 10)) {
|
||||
do_log_reopen(ssl, worker);
|
||||
} else if(strncmp(p, "set_option", 10) == 0) {
|
||||
} else if(cmdcmp(p, "set_option", 10)) {
|
||||
do_set_option(ssl, worker, skipwhite(p+10));
|
||||
} else if(strncmp(p, "get_option", 10) == 0) {
|
||||
} else if(cmdcmp(p, "get_option", 10)) {
|
||||
do_get_option(ssl, worker, skipwhite(p+10));
|
||||
} else {
|
||||
(void)ssl_printf(ssl, "error unknown command '%s'\n", p);
|
||||
@@ -1753,7 +1871,8 @@ static void
|
||||
handle_req(struct daemon_remote* rc, struct rc_state* s, SSL* ssl)
|
||||
{
|
||||
int r;
|
||||
char magic[5];
|
||||
char pre[10];
|
||||
char magic[7];
|
||||
char buf[1024];
|
||||
#ifdef USE_WINSOCK
|
||||
/* makes it possible to set the socket blocking again. */
|
||||
@@ -1762,7 +1881,7 @@ handle_req(struct daemon_remote* rc, struct rc_state* s, SSL* ssl)
|
||||
#endif
|
||||
fd_set_block(s->c->fd);
|
||||
|
||||
/* try to read magic UBCT string */
|
||||
/* try to read magic UBCT[version]_space_ string */
|
||||
ERR_clear_error();
|
||||
if((r=SSL_read(ssl, magic, (int)sizeof(magic)-1)) <= 0) {
|
||||
if(SSL_get_error(ssl, r) == SSL_ERROR_ZERO_RETURN)
|
||||
@@ -1770,9 +1889,10 @@ handle_req(struct daemon_remote* rc, struct rc_state* s, SSL* ssl)
|
||||
log_crypto_err("could not SSL_read");
|
||||
return;
|
||||
}
|
||||
magic[4] = 0;
|
||||
if( r != 4 || strcmp(magic, "UBCT") != 0) {
|
||||
magic[6] = 0;
|
||||
if( r != 6 || strncmp(magic, "UBCT", 4) != 0) {
|
||||
verbose(VERB_QUERY, "control connection has bad magic string");
|
||||
/* probably wrong tool connected, ignore it completely */
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1780,6 +1900,13 @@ handle_req(struct daemon_remote* rc, struct rc_state* s, SSL* ssl)
|
||||
if(!ssl_read_line(ssl, buf, sizeof(buf))) {
|
||||
return;
|
||||
}
|
||||
snprintf(pre, sizeof(pre), "UBCT%d ", UNBOUND_CONTROL_VERSION);
|
||||
if(strcmp(magic, pre) != 0) {
|
||||
verbose(VERB_QUERY, "control connection had bad "
|
||||
"version %s, cmd: %s", magic, buf);
|
||||
ssl_printf(ssl, "error version mismatch\n");
|
||||
return;
|
||||
}
|
||||
verbose(VERB_DETAIL, "control cmd: %s", buf);
|
||||
|
||||
/* figure out what to do */
|
||||
@@ -1802,8 +1929,8 @@ int remote_control_callback(struct comm_point* c, void* arg, int err,
|
||||
ERR_clear_error();
|
||||
r = SSL_do_handshake(s->ssl);
|
||||
if(r != 1) {
|
||||
r = SSL_get_error(s->ssl, r);
|
||||
if(r == SSL_ERROR_WANT_READ) {
|
||||
int r2 = SSL_get_error(s->ssl, r);
|
||||
if(r2 == SSL_ERROR_WANT_READ) {
|
||||
if(s->shake_state == rc_hs_read) {
|
||||
/* try again later */
|
||||
return 0;
|
||||
@@ -1811,7 +1938,7 @@ int remote_control_callback(struct comm_point* c, void* arg, int err,
|
||||
s->shake_state = rc_hs_read;
|
||||
comm_point_listen_for_rw(c, 1, 0);
|
||||
return 0;
|
||||
} else if(r == SSL_ERROR_WANT_WRITE) {
|
||||
} else if(r2 == SSL_ERROR_WANT_WRITE) {
|
||||
if(s->shake_state == rc_hs_write) {
|
||||
/* try again later */
|
||||
return 0;
|
||||
@@ -1820,6 +1947,10 @@ int remote_control_callback(struct comm_point* c, void* arg, int err,
|
||||
comm_point_listen_for_rw(c, 0, 1);
|
||||
return 0;
|
||||
} else {
|
||||
if(r == 0)
|
||||
log_err("remote control connection closed prematurely");
|
||||
log_addr(1, "failed connection from",
|
||||
&s->c->repinfo.addr, s->c->repinfo.addrlen);
|
||||
log_crypto_err("remote control failed ssl");
|
||||
clean_point(rc, s);
|
||||
return 0;
|
||||
|
||||
+4
-2
@@ -100,12 +100,14 @@ void server_stats_log(struct server_stats* stats, struct worker* worker,
|
||||
(unsigned)stats->num_queries_missed_cache,
|
||||
(unsigned)stats->num_queries_prefetch);
|
||||
log_info("server stats for thread %d: requestlist max %u avg %g "
|
||||
"exceeded %u", threadnum, (unsigned)stats->max_query_list_size,
|
||||
"exceeded %u jostled %u", threadnum,
|
||||
(unsigned)stats->max_query_list_size,
|
||||
(stats->num_queries_missed_cache+stats->num_queries_prefetch)?
|
||||
(double)stats->sum_query_list_size/
|
||||
(stats->num_queries_missed_cache+
|
||||
stats->num_queries_prefetch) : 0.0,
|
||||
(unsigned)worker->env.mesh->stats_dropped);
|
||||
(unsigned)worker->env.mesh->stats_dropped,
|
||||
(unsigned)worker->env.mesh->stats_jostled);
|
||||
}
|
||||
|
||||
/** get rrsets bogus number from validator */
|
||||
|
||||
+91
-26
@@ -44,6 +44,7 @@
|
||||
#ifdef HAVE_GETOPT_H
|
||||
#include <getopt.h>
|
||||
#endif
|
||||
#include <sys/time.h>
|
||||
#include "util/log.h"
|
||||
#include "daemon/daemon.h"
|
||||
#include "daemon/remote.h"
|
||||
@@ -88,10 +89,59 @@
|
||||
/** global debug value to keep track of heap memory allocation */
|
||||
void* unbound_start_brk = 0;
|
||||
|
||||
#if !defined(HAVE_EVENT_BASE_GET_METHOD) && (defined(HAVE_EV_LOOP) || defined(HAVE_EV_DEFAULT_LOOP))
|
||||
static const char* ev_backend2str(int b)
|
||||
{
|
||||
switch(b) {
|
||||
case EVBACKEND_SELECT: return "select";
|
||||
case EVBACKEND_POLL: return "poll";
|
||||
case EVBACKEND_EPOLL: return "epoll";
|
||||
case EVBACKEND_KQUEUE: return "kqueue";
|
||||
case EVBACKEND_DEVPOLL: return "devpoll";
|
||||
case EVBACKEND_PORT: return "evport";
|
||||
}
|
||||
return "unknown";
|
||||
}
|
||||
#endif
|
||||
|
||||
/** get the event system in use */
|
||||
static void get_event_sys(const char** n, const char** s, const char** m)
|
||||
{
|
||||
#ifdef USE_WINSOCK
|
||||
*n = "event";
|
||||
*s = "winsock";
|
||||
*m = "WSAWaitForMultipleEvents";
|
||||
#elif defined(USE_MINI_EVENT)
|
||||
*n = "mini-event";
|
||||
*s = "internal";
|
||||
*m = "select";
|
||||
#else
|
||||
struct event_base* b;
|
||||
*s = event_get_version();
|
||||
# ifdef HAVE_EVENT_BASE_GET_METHOD
|
||||
*n = "libevent";
|
||||
b = event_base_new();
|
||||
*m = event_base_get_method(b);
|
||||
# elif defined(HAVE_EV_LOOP) || defined(HAVE_EV_DEFAULT_LOOP)
|
||||
*n = "libev";
|
||||
b = (struct event_base*)ev_default_loop(EVFLAG_AUTO);
|
||||
*m = ev_backend2str(ev_backend((struct ev_loop*)b));
|
||||
# else
|
||||
*n = "unknown";
|
||||
*m = "not obtainable";
|
||||
b = NULL;
|
||||
# endif
|
||||
# ifdef HAVE_EVENT_BASE_FREE
|
||||
event_base_free(b);
|
||||
# endif
|
||||
#endif
|
||||
}
|
||||
|
||||
/** print usage. */
|
||||
static void usage()
|
||||
{
|
||||
const char** m;
|
||||
const char *evnm="event", *evsys="", *evmethod="";
|
||||
printf("usage: unbound [options]\n");
|
||||
printf(" start unbound daemon DNS resolver.\n");
|
||||
printf("-h this help\n");
|
||||
@@ -105,20 +155,16 @@ static void usage()
|
||||
printf(" service - used to start from services control panel\n");
|
||||
#endif
|
||||
printf("Version %s\n", PACKAGE_VERSION);
|
||||
printf("linked libs: event %s, ldns %s, %s\n",
|
||||
#ifdef USE_WINSOCK
|
||||
"winsock",
|
||||
#elif defined(USE_MINI_EVENT)
|
||||
"internal",
|
||||
#else
|
||||
event_get_version(),
|
||||
#endif
|
||||
ldns_version(),
|
||||
get_event_sys(&evnm, &evsys, &evmethod);
|
||||
printf("linked libs: %s %s (it uses %s), ldns %s, %s\n",
|
||||
evnm, evsys, evmethod, ldns_version(),
|
||||
SSLeay_version(SSLEAY_VERSION));
|
||||
printf("linked modules:");
|
||||
for(m = module_list_avail(); *m; m++)
|
||||
printf(" %s", *m);
|
||||
printf("\n");
|
||||
printf("configured for %s on %s with options:%s\n",
|
||||
CONFIGURE_TARGET, CONFIGURE_DATE, CONFIGURE_BUILD_WITH);
|
||||
printf("BSD licensed, see LICENSE in source package for details.\n");
|
||||
printf("Report bugs to %s\n", PACKAGE_BUGREPORT);
|
||||
}
|
||||
@@ -159,6 +205,35 @@ checkrlimits(struct config_file* cfg)
|
||||
size_t avail;
|
||||
struct rlimit rlim;
|
||||
|
||||
if(total > 1024 &&
|
||||
strncmp(event_get_version(), "mini-event", 10) == 0) {
|
||||
log_warn("too many file descriptors requested. The builtin"
|
||||
"mini-event cannot handle more than 1024. Config "
|
||||
"for less fds or compile with libevent");
|
||||
if(numthread*perthread_noudp+15 > 1024)
|
||||
fatal_exit("too much tcp. not enough fds.");
|
||||
cfg->outgoing_num_ports = (int)((1024
|
||||
- numthread*perthread_noudp
|
||||
- 10 /* safety margin */) /numthread);
|
||||
log_warn("continuing with less udp ports: %u",
|
||||
cfg->outgoing_num_ports);
|
||||
total = 1024;
|
||||
}
|
||||
if(perthread > 64 &&
|
||||
strncmp(event_get_version(), "winsock-event", 13) == 0) {
|
||||
log_err("too many file descriptors requested. The winsock"
|
||||
" event handler cannot handle more than 64 per "
|
||||
" thread. Config for less fds");
|
||||
if(perthread_noudp+2 > 64)
|
||||
fatal_exit("too much tcp. not enough fds.");
|
||||
cfg->outgoing_num_ports = (int)((64
|
||||
- perthread_noudp
|
||||
- 2/* safety margin */));
|
||||
log_warn("continuing with less udp ports: %u",
|
||||
cfg->outgoing_num_ports);
|
||||
total = numthread*(perthread_noudp+
|
||||
(size_t)cfg->outgoing_num_ports)+misc;
|
||||
}
|
||||
if(getrlimit(RLIMIT_NOFILE, &rlim) < 0) {
|
||||
log_warn("getrlimit: %s", strerror(errno));
|
||||
return;
|
||||
@@ -169,8 +244,12 @@ checkrlimits(struct config_file* cfg)
|
||||
avail = (size_t)rlim.rlim_cur;
|
||||
rlim.rlim_cur = (rlim_t)(total + 10);
|
||||
rlim.rlim_max = (rlim_t)(total + 10);
|
||||
#ifdef HAVE_SETRLIMIT
|
||||
if(setrlimit(RLIMIT_NOFILE, &rlim) < 0) {
|
||||
log_warn("setrlimit: %s", strerror(errno));
|
||||
#else
|
||||
if(1) {
|
||||
#endif
|
||||
log_warn("cannot increase max open fds from %u to %u",
|
||||
(unsigned)avail, (unsigned)total+10);
|
||||
/* check that calculation below does not underflow,
|
||||
@@ -182,27 +261,13 @@ checkrlimits(struct config_file* cfg)
|
||||
- 10 /* safety margin */) /numthread);
|
||||
log_warn("continuing with less udp ports: %u",
|
||||
cfg->outgoing_num_ports);
|
||||
log_warn("increase ulimit or decrease threads, ports in config to remove this warning");
|
||||
log_warn("increase ulimit or decrease threads, "
|
||||
"ports in config to remove this warning");
|
||||
return;
|
||||
}
|
||||
log_warn("increased limit(open files) from %u to %u",
|
||||
(unsigned)avail, (unsigned)total+10);
|
||||
}
|
||||
if(total > 1024 &&
|
||||
strncmp(event_get_version(), "mini-event", 10) == 0) {
|
||||
log_err("too many file descriptors requested. The builtin"
|
||||
"mini-event cannot handle more than 1024. Config "
|
||||
"for less fds or compile with libevent");
|
||||
fatal_exit("configuration needs too many file descriptors");
|
||||
}
|
||||
if(perthread > 64 &&
|
||||
strncmp(event_get_version(), "winsock-event", 13) == 0) {
|
||||
log_err("too many file descriptors requested. The winsock"
|
||||
" event handler cannot handle more than 64 per "
|
||||
" thread. Config for less fds or compile with "
|
||||
" libevent");
|
||||
fatal_exit("configuration needs too many file descriptors");
|
||||
}
|
||||
#else
|
||||
(void)cfg;
|
||||
#endif /* HAVE_GETRLIMIT */
|
||||
@@ -418,7 +483,7 @@ perform_setup(struct daemon* daemon, struct config_file* cfg, int debug_mode,
|
||||
* chown to get permissions */
|
||||
if(cfg->username && cfg->username[0]) {
|
||||
if(chown(daemon->pidfile, uid, gid) == -1) {
|
||||
fatal_exit("cannot chown %u.%u %s: %s",
|
||||
log_err("cannot chown %u.%u %s: %s",
|
||||
(unsigned)uid, (unsigned)gid,
|
||||
daemon->pidfile, strerror(errno));
|
||||
}
|
||||
|
||||
+29
-47
@@ -141,7 +141,7 @@ debug_total_mem(size_t calctotal)
|
||||
#endif /* UNBOUND_ALLOC_STATS */
|
||||
|
||||
/** Report on memory usage by this thread and global */
|
||||
void
|
||||
static void
|
||||
worker_mem_report(struct worker* ATTR_UNUSED(worker),
|
||||
struct serviced_query* ATTR_UNUSED(cur_serv))
|
||||
{
|
||||
@@ -178,6 +178,8 @@ worker_mem_report(struct worker* ATTR_UNUSED(worker),
|
||||
+ sizeof(*worker->env.scratch_buffer)
|
||||
+ ldns_buffer_capacity(worker->env.scratch_buffer)
|
||||
+ forwards_get_mem(worker->env.fwds);
|
||||
if(worker->thread_num == 0)
|
||||
me += acl_list_get_mem(worker->daemon->acl);
|
||||
if(cur_serv) {
|
||||
me += serviced_get_mem(cur_serv);
|
||||
}
|
||||
@@ -283,9 +285,10 @@ worker_handle_service_reply(struct comm_point* c, void* arg, int error,
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** check request sanity. Returns error code, 0 OK, or -1 discard.
|
||||
/** check request sanity.
|
||||
* @param pkt: the wire packet to examine for sanity.
|
||||
* @param worker: parameters for checking.
|
||||
* @return error code, 0 OK, or -1 discard.
|
||||
*/
|
||||
static int
|
||||
worker_check_request(ldns_buffer* pkt, struct worker* worker)
|
||||
@@ -443,7 +446,8 @@ answer_norec_from_cache(struct worker* worker, struct query_info* qinfo,
|
||||
uint16_t udpsize = edns->udp_size;
|
||||
int secure = 0;
|
||||
uint32_t timenow = *worker->env.now;
|
||||
int must_validate = !(flags&BIT_CD) && worker->env.need_to_validate;
|
||||
int must_validate = (!(flags&BIT_CD) || worker->env.cfg->ignore_cd)
|
||||
&& worker->env.need_to_validate;
|
||||
struct dns_msg *msg = NULL;
|
||||
struct delegpt *dp;
|
||||
|
||||
@@ -519,7 +523,8 @@ answer_from_cache(struct worker* worker, struct query_info* qinfo,
|
||||
uint32_t timenow = *worker->env.now;
|
||||
uint16_t udpsize = edns->udp_size;
|
||||
int secure;
|
||||
int must_validate = !(flags&BIT_CD) && worker->env.need_to_validate;
|
||||
int must_validate = (!(flags&BIT_CD) || worker->env.cfg->ignore_cd)
|
||||
&& worker->env.need_to_validate;
|
||||
/* see if it is possible */
|
||||
if(rep->ttl < timenow) {
|
||||
/* the rrsets may have been updated in the meantime.
|
||||
@@ -770,10 +775,16 @@ worker_handle_request(struct comm_point* c, void* arg, int error,
|
||||
server_stats_insrcode(&worker->stats, c->buffer);
|
||||
return 1;
|
||||
}
|
||||
if(worker->env.cfg->log_queries) {
|
||||
char ip[128];
|
||||
addr_to_str(&repinfo->addr, repinfo->addrlen, ip, sizeof(ip));
|
||||
log_nametypeclass(0, ip, qinfo.qname, qinfo.qtype, qinfo.qclass);
|
||||
}
|
||||
if(qinfo.qtype == LDNS_RR_TYPE_AXFR ||
|
||||
qinfo.qtype == LDNS_RR_TYPE_IXFR) {
|
||||
verbose(VERB_ALGO, "worker request: refused zone transfer.");
|
||||
log_addr(VERB_CLIENT,"from",&repinfo->addr, repinfo->addrlen);
|
||||
ldns_buffer_rewind(c->buffer);
|
||||
LDNS_QR_SET(ldns_buffer_begin(c->buffer));
|
||||
LDNS_RCODE_SET(ldns_buffer_begin(c->buffer),
|
||||
LDNS_RCODE_REFUSED);
|
||||
@@ -906,14 +917,6 @@ worker_handle_request(struct comm_point* c, void* arg, int error,
|
||||
}
|
||||
|
||||
/* grab a work request structure for this new request */
|
||||
if(worker->env.mesh->num_reply_addrs>worker->request_size*16) {
|
||||
/* protect our memory usage from storing reply addresses */
|
||||
verbose(VERB_ALGO, "Too many requests queued. "
|
||||
"dropping incoming query.");
|
||||
worker->env.mesh->stats_dropped++;
|
||||
comm_point_drop_reply(repinfo);
|
||||
return 0;
|
||||
}
|
||||
mesh_new_client(worker->env.mesh, &qinfo,
|
||||
ldns_buffer_read_u16_at(c->buffer, 2),
|
||||
&edns, repinfo, *(uint16_t*)ldns_buffer_begin(c->buffer));
|
||||
@@ -1001,6 +1004,7 @@ void worker_probe_timer_cb(void* arg)
|
||||
struct worker*
|
||||
worker_create(struct daemon* daemon, int id, int* ports, int n)
|
||||
{
|
||||
unsigned int seed;
|
||||
struct worker* worker = (struct worker*)calloc(1,
|
||||
sizeof(struct worker));
|
||||
if(!worker)
|
||||
@@ -1018,6 +1022,19 @@ worker_create(struct daemon* daemon, int id, int* ports, int n)
|
||||
free(worker);
|
||||
return NULL;
|
||||
}
|
||||
/* create random state here to avoid locking trouble in RAND_bytes */
|
||||
seed = (unsigned int)time(NULL) ^ (unsigned int)getpid() ^
|
||||
(((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;
|
||||
log_err("could not init random numbers.");
|
||||
tube_delete(worker->cmd);
|
||||
free(worker->ports);
|
||||
free(worker);
|
||||
return NULL;
|
||||
}
|
||||
seed = 0;
|
||||
return worker;
|
||||
}
|
||||
|
||||
@@ -1025,7 +1042,6 @@ int
|
||||
worker_init(struct worker* worker, struct config_file *cfg,
|
||||
struct listen_port* ports, int do_sigs)
|
||||
{
|
||||
unsigned int seed;
|
||||
worker->need_to_exit = 0;
|
||||
worker->base = comm_base_create(do_sigs);
|
||||
if(!worker->base) {
|
||||
@@ -1070,16 +1086,6 @@ worker_init(struct worker* worker, struct config_file *cfg,
|
||||
} else { /* !do_sigs */
|
||||
worker->comsig = NULL;
|
||||
}
|
||||
seed = (unsigned int)time(NULL) ^ (unsigned int)getpid() ^
|
||||
(((unsigned int)worker->thread_num)<<17);
|
||||
/* shift thread_num so it does not match out pid bits */
|
||||
if(!(worker->rndstate = ub_initstate(seed, NULL))) {
|
||||
seed = 0;
|
||||
log_err("could not init random numbers.");
|
||||
worker_delete(worker);
|
||||
return 0;
|
||||
}
|
||||
seed = 0;
|
||||
worker->front = listen_create(worker->base, ports,
|
||||
cfg->msg_buffer_size, (int)cfg->incoming_num_tcp,
|
||||
worker_handle_request, worker);
|
||||
@@ -1122,7 +1128,6 @@ worker_init(struct worker* worker, struct config_file *cfg,
|
||||
worker_delete(worker);
|
||||
return 0;
|
||||
}
|
||||
worker->request_size = cfg->num_queries_per_thread;
|
||||
|
||||
server_stats_init(&worker->stats, cfg);
|
||||
alloc_init(&worker->alloc, &worker->daemon->superalloc,
|
||||
@@ -1133,7 +1138,6 @@ worker_init(struct worker* worker, struct config_file *cfg,
|
||||
if(worker->thread_num == 0)
|
||||
log_set_time(worker->env.now);
|
||||
worker->env.worker = worker;
|
||||
worker->env.send_packet = &worker_send_packet;
|
||||
worker->env.send_query = &worker_send_query;
|
||||
worker->env.alloc = &worker->alloc;
|
||||
worker->env.rnd = worker->rndstate;
|
||||
@@ -1222,19 +1226,6 @@ worker_delete(struct worker* worker)
|
||||
free(worker);
|
||||
}
|
||||
|
||||
int
|
||||
worker_send_packet(ldns_buffer* pkt, struct sockaddr_storage* addr,
|
||||
socklen_t addrlen, int timeout, struct module_qstate* q, int use_tcp)
|
||||
{
|
||||
struct worker* worker = q->env->worker;
|
||||
if(use_tcp) {
|
||||
return pending_tcp_query(worker->back, pkt, addr, addrlen,
|
||||
timeout, worker_handle_reply, q) != 0;
|
||||
}
|
||||
return pending_udp_query(worker->back, pkt, addr, addrlen,
|
||||
timeout*1000, worker_handle_reply, q) != 0;
|
||||
}
|
||||
|
||||
/** compare outbound entry qstates */
|
||||
static int
|
||||
outbound_entry_compare(void* a, void* b)
|
||||
@@ -1284,15 +1275,6 @@ void worker_stats_clear(struct worker* worker)
|
||||
}
|
||||
|
||||
/* --- fake callbacks for fptr_wlist to work --- */
|
||||
int libworker_send_packet(ldns_buffer* ATTR_UNUSED(pkt),
|
||||
struct sockaddr_storage* ATTR_UNUSED(addr),
|
||||
socklen_t ATTR_UNUSED(addrlen), int ATTR_UNUSED(timeout),
|
||||
struct module_qstate* ATTR_UNUSED(q), int ATTR_UNUSED(use_tcp))
|
||||
{
|
||||
log_assert(0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct outbound_entry* libworker_send_query(uint8_t* ATTR_UNUSED(qname),
|
||||
size_t ATTR_UNUSED(qnamelen), uint16_t ATTR_UNUSED(qtype),
|
||||
uint16_t ATTR_UNUSED(qclass), uint16_t ATTR_UNUSED(flags),
|
||||
|
||||
@@ -102,9 +102,6 @@ struct worker {
|
||||
/** timer for statistics */
|
||||
struct comm_timer* stat_timer;
|
||||
|
||||
/** number of requests that can be handled by this worker */
|
||||
size_t request_size;
|
||||
|
||||
/** random() table for this worker. */
|
||||
struct ub_randstate* rndstate;
|
||||
/** do we need to restart or quit (on signal) */
|
||||
@@ -167,20 +164,6 @@ void worker_send_cmd(struct worker* worker, enum worker_commands cmd);
|
||||
*/
|
||||
void worker_sighandler(int sig, void* arg);
|
||||
|
||||
/**
|
||||
* Worker service routine to send udp messages for modules.
|
||||
* @param pkt: packet to send.
|
||||
* @param addr: where to.
|
||||
* @param addrlen: length of addr.
|
||||
* @param timeout: seconds to wait until timeout.
|
||||
* @param q: wich query state to reactivate upon return.
|
||||
* @param use_tcp: true to use TCP, false for UDP.
|
||||
* @return: false on failure (memory or socket related). no query was
|
||||
* sent.
|
||||
*/
|
||||
int worker_send_packet(ldns_buffer* pkt, struct sockaddr_storage* addr,
|
||||
socklen_t addrlen, int timeout, struct module_qstate* q, int use_tcp);
|
||||
|
||||
/**
|
||||
* Worker service routine to send serviced queries to authoritative servers.
|
||||
* @param qname: query name. (host order)
|
||||
|
||||
+457
@@ -1,3 +1,460 @@
|
||||
16 June 2011: Wouter
|
||||
- log-queries: yesno option, default is no, prints querylog.
|
||||
- version is 1.4.11.
|
||||
|
||||
14 June 2011: Wouter
|
||||
- Use -flto compiler flag for link time optimization, if supported.
|
||||
- iana portlist updated.
|
||||
|
||||
12 June 2011: Wouter
|
||||
- IPv6 service address for d.root-servers.net (2001:500:2D::D).
|
||||
|
||||
10 June 2011: Wouter
|
||||
- unbound-control has version number in the header,
|
||||
UBCT[version]_space_ is the header sent by the client now.
|
||||
- Unbound control port number is registered with IANA:
|
||||
ub-dns-control 8953/tcp unbound dns nameserver control
|
||||
This is the new default for the control-port config setting.
|
||||
- statistics-interval prints the number of jostled queries to log.
|
||||
|
||||
30 May 2011: Wouter
|
||||
- Fix Makefile for U in environment, since wrong U is more common than
|
||||
deansification necessity.
|
||||
- iana portlist updated.
|
||||
- updated ldns tarball to 1.6.10rc2 snapshot of today.
|
||||
|
||||
25 May 2011: Wouter
|
||||
- Fix assertion failure when unbound generates an empty error reply
|
||||
in response to a query, CVE-2011-1922 VU#531342.
|
||||
- This fix is in tag 1.4.10.
|
||||
- defense in depth against the above bug, an error is printed to log
|
||||
instead of an assertion failure.
|
||||
|
||||
10 May 2011: Wouter
|
||||
- bug#386: --enable-allsymbols option links all binaries to libunbound
|
||||
and reduces install size significantly.
|
||||
- feature, ignore-cd-flag: yesno to provide dnssec to legacy servers.
|
||||
- iana portlist updated.
|
||||
- Fix TTL of SOA so negative TTL is separately cached from normal TTL.
|
||||
|
||||
14 April 2011: Wouter
|
||||
- configure created with newer autoconf 2.66.
|
||||
|
||||
12 April 2011: Wouter
|
||||
- bug#378: Fix that configure checks for ldns_get_random presence.
|
||||
|
||||
8 April 2011: Wouter
|
||||
- iana portlist updated.
|
||||
- queries with CD flag set cause DNSSEC validation, but the answer is
|
||||
not withheld if it is bogus. Thus, unbound will retry if it is bad
|
||||
and curb the TTL if it is bad, thus protecting the cache for use by
|
||||
downstream validators.
|
||||
- val-override-date: -1 ignores dates entirely, for NTP usage.
|
||||
|
||||
29 March 2011: Wouter
|
||||
- harden-below-nxdomain: changed so that it activates when the
|
||||
cached nxdomain is dnssec secure. This avoids backwards
|
||||
incompatibility because those old servers do not have dnssec.
|
||||
|
||||
24 March 2011: Wouter
|
||||
- iana portlist updated.
|
||||
- release 1.4.9.
|
||||
- trunk is 1.5.0
|
||||
|
||||
17 March 2011: Wouter
|
||||
- bug#370: new unbound.spec for CentOS 5.x from Harold Jones.
|
||||
Applied but did not do the --disable-gost.
|
||||
|
||||
10 March 2011: Wouter
|
||||
- tag 1.4.9 release candidate 1 created.
|
||||
|
||||
3 March 2011: Wouter
|
||||
- updated ldns to today.
|
||||
|
||||
1 March 2011: Wouter
|
||||
- Fix no ADflag for NXDOMAIN in NSEC3 optout. And wildcard in optout.
|
||||
- give config parse error for multiple names on a stub or forward zone.
|
||||
- updated ldns tarball to 1.6.9(todays snapshot).
|
||||
|
||||
24 February 2011: Wouter
|
||||
- bug #361: Fix, time.elapsed variable not reset with stats_noreset.
|
||||
|
||||
23 February 2011: Wouter
|
||||
- iana portlist updated.
|
||||
- common.sh to version 3.
|
||||
|
||||
18 February 2011: Wouter
|
||||
- common.sh in testdata updated to version 2.
|
||||
|
||||
15 February 2011: Wouter
|
||||
- Added explicit note on unbound-anchor usage:
|
||||
Please note usage of unbound-anchor root anchor is at your own risk
|
||||
and under the terms of our LICENSE (see that file in the source).
|
||||
|
||||
11 February 2011: Wouter
|
||||
- iana portlist updated.
|
||||
- tpkg updated with common.sh for common functionality.
|
||||
|
||||
7 February 2011: Wouter
|
||||
- Added regression test for addition of a .net DS to the root, and
|
||||
cache effects with different TTL for glue and DNSKEY.
|
||||
- iana portlist updated.
|
||||
|
||||
28 January 2011: Wouter
|
||||
- Fix remove private address does not throw away entire response.
|
||||
|
||||
24 January 2011: Wouter
|
||||
- release 1.4.8
|
||||
|
||||
19 January 2011: Wouter
|
||||
- fix bug#349: no -L/usr for ldns.
|
||||
|
||||
18 January 2011: Wouter
|
||||
- ldns 1.6.8 tarball included.
|
||||
- release 1.4.8rc1.
|
||||
|
||||
17 January 2011: Wouter
|
||||
- add get and set option for harden-below-nxdomain feature.
|
||||
- iana portlist updated.
|
||||
|
||||
14 January 2011: Wouter
|
||||
- Fix so a changed NS RRset does not get moved name stuck on old
|
||||
server, for type NS the TTL is not increased.
|
||||
|
||||
13 January 2011: Wouter
|
||||
- Fix prefetch so it does not get stuck on old server for moved names.
|
||||
|
||||
12 January 2011: Wouter
|
||||
- iana portlist updated.
|
||||
|
||||
11 January 2011: Wouter
|
||||
- Fix insecure CNAME sequence marked as secure, reported by Bert
|
||||
Hubert.
|
||||
|
||||
10 January 2011: Wouter
|
||||
- faster lruhash get_mem routine.
|
||||
|
||||
4 January 2011: Wouter
|
||||
- bug#346: remove ITAR scripts from contrib, the service is discontinued, use the root.
|
||||
- iana portlist updated.
|
||||
|
||||
23 December 2010: Wouter
|
||||
- Fix in infra cache that could cause rto larger than TOP_TIMEOUT kept.
|
||||
|
||||
21 December 2010: Wouter
|
||||
- algorithm compromise protection using the algorithms signalled in
|
||||
the DS record. Also, trust anchors, DLV, and RFC5011 receive this,
|
||||
and thus, if you have multiple algorithms in your trust-anchor-file
|
||||
then it will now behave different than before. Also, 5011 rollover
|
||||
for algorithms needs to be double-signature until the old algorithm
|
||||
is revoked.
|
||||
It is not an option, because I see no use to turn the security off.
|
||||
- iana portlist updated.
|
||||
|
||||
17 December 2010: Wouter
|
||||
- squelch 'tcp connect: bla' in logfile, (set verbosity 2 to see them).
|
||||
- fix validation in this case: CNAME to nodata for co-hosted opt-in
|
||||
NSEC3 insecure delegation, was bogus, fixed to be insecure.
|
||||
|
||||
16 December 2010: Wouter
|
||||
- Fix our 'BDS' license (typo reported by Xavier Belanger).
|
||||
|
||||
10 December 2010: Wouter
|
||||
- iana portlist updated.
|
||||
- review changes for unbound-anchor.
|
||||
|
||||
2 December 2010: Wouter
|
||||
- feature typetransparent localzone, does not block other RR types.
|
||||
|
||||
1 December 2010: Wouter
|
||||
- Fix bug#338: print address when socket creation fails.
|
||||
|
||||
30 November 2010: Wouter
|
||||
- Fix storage of EDNS failures in the infra cache.
|
||||
- iana portlist updated.
|
||||
|
||||
18 November 2010: Wouter
|
||||
- harden-below-nxdomain option, default off (because very old
|
||||
software may be incompatible). We could enable it by default in
|
||||
the future.
|
||||
|
||||
17 November 2010: Wouter
|
||||
- implement draft-vixie-dnsext-resimprove-00, we stop on NXDOMAIN.
|
||||
- make test output nicer.
|
||||
|
||||
15 November 2010: Wouter
|
||||
- silence 'tcp connect: broken pipe' and 'net down' at low verbosity.
|
||||
- iana portlist updated.
|
||||
- so-sndbuf option for very busy servers, a bit like so-rcvbuf.
|
||||
|
||||
9 November 2010: Wouter
|
||||
- unbound-anchor compiles with openssl 0.9.7.
|
||||
|
||||
8 November 2010: Wouter
|
||||
- release tag 1.4.7.
|
||||
- trunk is version 1.4.8.
|
||||
- Be lenient and accept imgw.pl malformed packet (like BIND).
|
||||
|
||||
5 November 2010: Wouter
|
||||
- do not synthesize a CNAME message from cache for qtype DS.
|
||||
|
||||
4 November 2010: Wouter
|
||||
- Use central entropy to seed threads.
|
||||
|
||||
3 November 2010: Wouter
|
||||
- Change the rtt used to probe EDNS-timeout hosts to 1000 msec.
|
||||
|
||||
2 November 2010: Wouter
|
||||
- tag 1.4.7rc1.
|
||||
- code review.
|
||||
|
||||
1 November 2010: Wouter
|
||||
- GOST code enabled by default (RFC 5933).
|
||||
|
||||
27 October 2010: Wouter
|
||||
- Fix uninit value in dump_infra print.
|
||||
- Fix validation failure for parent and child on same server with an
|
||||
insecure childzone and a CNAME from parent to child.
|
||||
- Configure detects libev-4.00.
|
||||
|
||||
26 October 2010: Wouter
|
||||
- dump_infra and flush_infra commands for unbound-control.
|
||||
- no timeout backoff if meanwhile a query succeeded.
|
||||
- Change of timeout code. No more lost and backoff in blockage.
|
||||
At 12sec timeout (and at least 2x lost before) one probe per IP
|
||||
is allowed only. At 120sec, the IP is blocked. After 15min, a
|
||||
120sec entry has a single retry packet.
|
||||
|
||||
25 October 2010: Wouter
|
||||
- Configure errors if ldns is not found.
|
||||
|
||||
22 October 2010: Wouter
|
||||
- Windows 7 fix for the installer.
|
||||
|
||||
21 October 2010: Wouter
|
||||
- Fix bug where fallback_tcp causes wrong roundtrip and edns
|
||||
observation to be noted in cache. Fix bug where EDNSprobe halted
|
||||
exponential backoff if EDNS status unknown.
|
||||
- new unresponsive host method, exponentially increasing block backoff.
|
||||
- iana portlist updated.
|
||||
|
||||
20 October 2010: Wouter
|
||||
- interface automatic works for some people with ip6 disabled.
|
||||
Therefore the error check is removed, so they can use the option.
|
||||
|
||||
19 October 2010: Wouter
|
||||
- Fix for request list growth, if a server has long timeout but the
|
||||
lost counter is low, then its effective rtt is the one without
|
||||
exponential backoff applied. Because the backoff is not working.
|
||||
The lost counter can then increase and the server is blacklisted,
|
||||
or the lost counter does not increase and the server is working
|
||||
for some queries.
|
||||
|
||||
18 October 2010: Wouter
|
||||
- iana portlist updated.
|
||||
|
||||
13 October 2010: Wouter
|
||||
- Fix TCP so it uses a random outgoing-interface.
|
||||
- unbound-anchor handles ADDPEND keystate.
|
||||
|
||||
11 October 2010: Wouter
|
||||
- Fix bug when DLV below a trust-anchor that uses NSEC3 optout where
|
||||
the zone has a secure delegation hosted on the same server did not
|
||||
verify as secure (it was insecure by mistake).
|
||||
- iana portlist updated.
|
||||
- ldns tarball updated (for reading cachedumps with bad RR data).
|
||||
|
||||
1 October 2010: Wouter
|
||||
- test for unbound-anchor. fix for reading certs.
|
||||
- Fix alloc_reg_release for longer uptime in out of memory conditions.
|
||||
|
||||
28 September 2010: Wouter
|
||||
- unbound-anchor working, it creates or updates a root.key file.
|
||||
Use it before you start the validator (e.g. at system boot time).
|
||||
|
||||
27 September 2010: Wouter
|
||||
- iana portlist updated.
|
||||
|
||||
24 September 2010: Wouter
|
||||
- bug#329: in example.conf show correct ipv4 link-local 169.254/16.
|
||||
|
||||
23 September 2010: Wouter
|
||||
- unbound-anchor app, unbound requires libexpat (xml parser library).
|
||||
|
||||
22 September 2010: Wouter
|
||||
- compliance with draft-ietf-dnsop-default-local-zones-14, removed
|
||||
reverse ipv6 orchid prefix from builtin list.
|
||||
- iana portlist updated.
|
||||
|
||||
17 September 2010: Wouter
|
||||
- DLV has downgrade protection again, because the RFC says so.
|
||||
- iana portlist updated.
|
||||
|
||||
16 September 2010: Wouter
|
||||
- Algorithm rollover operational reality intrudes, for trust-anchor,
|
||||
5011-store, and DLV-anchor if one key matches it's good enough.
|
||||
- iana portlist updated.
|
||||
- Fix reported validation error in out of memory condition.
|
||||
|
||||
15 September 2010: Wouter
|
||||
- Abide RFC5155 section 9.2: no AD flag for replies with NSEC3 optout.
|
||||
|
||||
14 September 2010: Wouter
|
||||
- increased mesh-max-activation from 1000 to 3000 for crazy domains
|
||||
like _tcp.slb.com with 262 servers.
|
||||
- iana portlist updated.
|
||||
|
||||
13 September 2010: Wouter
|
||||
- bug#327: Fix for cannot access stub zones until the root is primed.
|
||||
|
||||
9 September 2010: Wouter
|
||||
- unresponsive servers are not completely blacklisted (because of
|
||||
firewalls), but also not probed all the time (because of the request
|
||||
list size it generates). The probe rate is 1%.
|
||||
- iana portlist updated.
|
||||
|
||||
20 August 2010: Wouter
|
||||
- openbsd-lint fixes: acl_list_get_mem used if debug-alloc enabled.
|
||||
iterator get_mem includes priv_get_mem. delegpt nodup removed.
|
||||
listen_pushback, query_info_allocqname, write_socket, send_packet,
|
||||
comm_point_set_cb_arg and listen_resume removed.
|
||||
|
||||
19 August 2010: Wouter
|
||||
- Fix bug#321: resolution of rs.ripe.net artifacts with 0x20.
|
||||
Delegpt structures checked for duplicates always.
|
||||
No more nameserver lookups generated when depth is full anyway.
|
||||
- example.conf notes how to do DNSSEC validation and track the root.
|
||||
- iana portlist updated.
|
||||
|
||||
18 August 2010: Wouter
|
||||
- Fix bug#322: configure does not respect CFLAGS on Solaris.
|
||||
Pass CFLAGS="-xO4 -xtarget=generic" on the configure command line
|
||||
if use sun-cc, but some systems need different flags.
|
||||
|
||||
16 August 2010: Wouter
|
||||
- Fix acx_nlnetlabs.m4 configure output for autoconf-2.66 AS_TR_CPP
|
||||
changes, uses m4_bpatsubst now.
|
||||
- make test (or make check) should be more portable and run the unit
|
||||
test and testbound scripts. (make longtest has special requirements).
|
||||
|
||||
13 August 2010: Wouter
|
||||
- More pleasant remote control command parsing.
|
||||
- documentation added for return values reported by doxygen 1.7.1.
|
||||
- iana portlist updated.
|
||||
|
||||
9 August 2010: Wouter
|
||||
- Fix name of rrset printed that failed validation.
|
||||
|
||||
5 August 2010: Wouter
|
||||
- Return NXDOMAIN after chain of CNAMEs ends at name-not-found.
|
||||
|
||||
4 August 2010: Wouter
|
||||
- Fix validation in case a trust anchor enters into a zone with
|
||||
unsupported algorithms.
|
||||
|
||||
3 August 2010: Wouter
|
||||
- updated ldns tarball with bugfixes.
|
||||
- release tag 1.4.6.
|
||||
- trunk becomes 1.4.7 develop.
|
||||
- iana portlist updated.
|
||||
|
||||
22 July 2010: Wouter
|
||||
- more error details on failed remote control connection.
|
||||
|
||||
15 July 2010: Wouter
|
||||
- rlimit adjustments for select and ulimit can happen at the same time.
|
||||
|
||||
14 July 2010: Wouter
|
||||
- Donation text added to README.
|
||||
- Fix integer underflow in prefetch ttl creation from cache. This
|
||||
fixes a potential negative prefetch ttl.
|
||||
|
||||
12 July 2010: Wouter
|
||||
- Changed the defaults for num-queries-per-thread/outgoing-range.
|
||||
For builtin-select: 512/960, for libevent 1024/4096 and for
|
||||
windows 24/48 (because of win api). This makes the ratio this way
|
||||
to improve resilience under heavy load. For high performance, use
|
||||
libevent and possibly higher numbers.
|
||||
|
||||
10 July 2010: Wouter
|
||||
- GOST enabled if SSL is recent and ldns has GOST enabled too.
|
||||
- ldns tarball updated.
|
||||
|
||||
9 July 2010: Wouter
|
||||
- iana portlist updated.
|
||||
- Fix validation of qtype DNSKEY when a key-cache entry exists but
|
||||
no rr-cache entry is used (it expired or prefetch), it then goes
|
||||
back up to the DS or trust-anchor to validate the DNSKEY.
|
||||
|
||||
7 July 2010: Wouter
|
||||
- Neat function prototypes, unshadowed local declarations.
|
||||
|
||||
6 July 2010: Wouter
|
||||
- failure to chown the pidfile is not fatal any more.
|
||||
- testbound uses UTC timezone.
|
||||
- ldns tarball updated (ports and works on Minix 3.1.7). On Minix, add
|
||||
/usr/gnu/bin to PATH, use ./configure AR=/usr/gnu/bin/gar and gmake.
|
||||
|
||||
5 July 2010: Wouter
|
||||
- log if a server is skipped because it is on the donotquery list,
|
||||
at verbosity 4, to enable diagnosis why no queries to 127.0.0.1.
|
||||
- added feature to print configure date, target and options with -h.
|
||||
- added feature to print event backend system details with -h.
|
||||
- wdiff is not actually required by make test, updated requirements.
|
||||
|
||||
1 July 2010: Wouter
|
||||
- Fix RFC4035 compliance with 2.2 statement that the DNSKEY at apex
|
||||
must be signed with all algorithms from the DS rrset at the parent.
|
||||
This is now checked and becomes bogus if not.
|
||||
|
||||
28 June 2010: Wouter
|
||||
- Fix jostle list bug found by Vince (luoce@cnnic), it caused the qps
|
||||
in overload situations to be about 5 qps for the class of shortly
|
||||
serviced queries.
|
||||
The capacity of the resolver is then about (numqueriesperthread / 2)
|
||||
/ (average time for such long queries) qps for long queries.
|
||||
And about (numqueriesperthread / 2)/(jostletimeout in whole seconds)
|
||||
qps for short queries, per thread.
|
||||
- Fix the max number of reply-address count to be applied for duplicate
|
||||
queries, and not for new query list entries. This raises the memory
|
||||
usage to a max of (16+1)*numqueriesperthread reply addresses.
|
||||
|
||||
25 June 2010: Wouter
|
||||
- Fix handling of corner case reply from lame server, follows rfc2308.
|
||||
It could lead to a nodata reply getting into the cache if the search
|
||||
for a non-lame server turned up other misconfigured servers.
|
||||
- unbound.h has extern "C" statement for easier include in c++.
|
||||
|
||||
23 June 2010: Wouter
|
||||
- iana portlist updated.
|
||||
- makedist upgraded cross compile openssl option, like this:
|
||||
./makedist.sh -s -wssl openssl-1.0.0a.tar.gz -w --enable-gost
|
||||
|
||||
22 June 2010: Wouter
|
||||
- Unbound reports libev or libevent correctly in logs in verbose mode.
|
||||
- Fix to unload gost dynamic library module for leak testing.
|
||||
|
||||
18 June 2010: Wouter
|
||||
- iana portlist updated.
|
||||
|
||||
17 June 2010: Wouter
|
||||
- Add AAAA to root hints for I.ROOT-SERVERS.NET.
|
||||
|
||||
16 June 2010: Wouter
|
||||
- Fix assertion failure reported by Kai Storbeck from XS4ALL, the
|
||||
assertion was wrong.
|
||||
- updated ldns tarball.
|
||||
|
||||
15 June 2010: Wouter
|
||||
- tag 1.4.5 created.
|
||||
- trunk contains 1.4.6 in development.
|
||||
- Fix TCPreply on systems with no writev, if just 1 byte could be sent.
|
||||
- Fix to use one pointer less for iterator query state store_parent_NS.
|
||||
- makedist crosscompile to windows uses builtin ldns not host ldns.
|
||||
- Max referral count from 30 to 130, because 128 one character domains
|
||||
is valid DNS.
|
||||
- added documentation for the histogram printout to syslog.
|
||||
|
||||
11 June 2010: Wouter
|
||||
- When retry to parent the retrycount is not wiped, so failed
|
||||
nameservers are not tried again.
|
||||
|
||||
+39
-4
@@ -28,6 +28,8 @@ This software is under BSD license, see LICENSE for details.
|
||||
of outgoing ports. This improves randomization and spoof
|
||||
resistance. For the default of 16 ports the builtin alternative
|
||||
works well and is a little faster.
|
||||
* --with-libexpat=/path/to/libexpat
|
||||
Can be set to the install directory of libexpat.
|
||||
* --without-pthreads
|
||||
This disables pthreads. Without this option the pthreads library
|
||||
is detected automatically. Use this option to disable threading
|
||||
@@ -59,6 +61,13 @@ This software is under BSD license, see LICENSE for details.
|
||||
* --with-chroot-dir=path
|
||||
Set default chroot directory,
|
||||
the default is /usr/local/etc/unbound.
|
||||
* --with-rootkey-file=path
|
||||
Set the default root.key path. This file is read and written.
|
||||
the default is /usr/local/etc/unbound/root.key
|
||||
* --with-rootcert-file=path
|
||||
Set the default root update certificate path. A builtin certificate
|
||||
is used if this file is empty or does not exist.
|
||||
the default is /usr/local/etc/unbound/icannbundle.pem
|
||||
* --with-username=user
|
||||
Set default user name to change to,
|
||||
the default is the "unbound" user.
|
||||
@@ -69,11 +78,10 @@ This software is under BSD license, see LICENSE for details.
|
||||
Compile the python module that processes responses in the server.
|
||||
* --disable-sha2
|
||||
Disable support for RSASHA256 and RSASHA512 crypto.
|
||||
* --enable-gost
|
||||
Enable draft support for GOST crypto.
|
||||
* --disable-gost
|
||||
Disable support for GOST crypto, RFC 5933.
|
||||
|
||||
* 'make test' attempts to run a series of tests, depending on the support
|
||||
programs that are installed.
|
||||
* 'make test' runs a series of self checks.
|
||||
|
||||
Known issues
|
||||
------------
|
||||
@@ -97,6 +105,7 @@ o The warning 'openssl has no entropy, seeding with time', with chroot
|
||||
o On Solaris 5.10 some libtool packages from repositories do not work with
|
||||
gcc, showing errors gcc: unrecognized option `-KPIC'
|
||||
To solve this do ./configure libtool=./libtool [your options...].
|
||||
On Solaris you may pass CFLAGS="-xO4 -xtarget=generic" if you use sun-cc.
|
||||
o If unbound-control (or munin graphs) do not work, this can often be because
|
||||
the unbound-control-setup script creates the keys with restricted
|
||||
permissions, and the files need to be made readable or ownered by both the
|
||||
@@ -115,4 +124,30 @@ o Other code origins are from the NSD (NLnet Labs) and LDNS (NLnet Labs)
|
||||
projects. Such as buffer, region-allocator and red-black tree code.
|
||||
o See Credits file for contributors.
|
||||
|
||||
|
||||
Your Support
|
||||
------------
|
||||
NLnet Labs offers all of its software products as open source, most are
|
||||
published under a BSD license. You can download them, not only from the
|
||||
NLnet Labs website but also through the various OS distributions for
|
||||
which NSD, ldns, and Unbound are packaged. We therefore have little idea
|
||||
who uses our software in production environments and have no direct ties
|
||||
with 'our customers'.
|
||||
|
||||
Therefore, we ask you to contact us at users@NLnetLabs.nl and tell us
|
||||
whether you use one of our products in your production environment,
|
||||
what that environment looks like, and maybe even share some praise.
|
||||
We would like to refer to the fact that your organization is using our
|
||||
products. We will only do that if you explicitly allow us. In all other
|
||||
cases we will keep the information you share with us to ourselves.
|
||||
|
||||
In addition to the moral support you can also support us
|
||||
financially. NLnet Labs is a recognized not-for-profit charity foundation
|
||||
that is chartered to develop open-source software and open-standards
|
||||
for the Internet. If you use our software to satisfaction please express
|
||||
that by giving us a donation. For small donations PayPal can be used. For
|
||||
larger and regular donations please contact us at users@NLnetLabs.nl. Also
|
||||
see http://www.nlnetlabs.nl/labs/contributors/.
|
||||
|
||||
|
||||
* mailto:unbound-bugs@nlnetlabs.nl
|
||||
|
||||
+6
-8
@@ -1,22 +1,20 @@
|
||||
README unbound tests
|
||||
|
||||
There is a test setup for unbound. Use
|
||||
For a quick test that runs unit tests and state machine tests, use
|
||||
make test
|
||||
To make and run the tests. The results are summarized at the end.
|
||||
|
||||
There is a long test setup for unbound that needs tools installed. Use
|
||||
make longtest
|
||||
To make and run the long tests. The results are summarized at the end.
|
||||
|
||||
You need to have the following programs installed and in your PATH.
|
||||
* dig - from the bind-tools package. Used to send DNS queries.
|
||||
* wdiff - used for word-by-word comparisons.
|
||||
* splint (optional) - for lint test
|
||||
* doxygen (optional) - for doc completeness test
|
||||
* ldns-testns (optional) - from ldns examples. Used as DNS auth server.
|
||||
* ldns-testns - from ldns examples. Used as DNS auth server.
|
||||
* xxd and nc (optional) - for (malformed) packet transmission.
|
||||
The optional programs are detected and can be omitted.
|
||||
|
||||
Without any support programs, unittest and testbound can still be used.
|
||||
(cd testdata; ../testcode/mini_tpkg.sh exe 02-unittest.tpkg)
|
||||
(cd testdata; ../testcode/mini_tpkg.sh exe 03-testbound.tpkg)
|
||||
|
||||
testdata/ contains the data for tests.
|
||||
testcode/ contains scripts and c code for the tests.
|
||||
|
||||
|
||||
@@ -1,16 +1,21 @@
|
||||
|
||||
Specification for the unbound-control protocol.
|
||||
|
||||
Server listens on 953 TCP (localhost by default). Client connects,
|
||||
Server listens on 8953 TCP (localhost by default). Client connects,
|
||||
SSLv3 or TLSv1 connection setup (server selfsigned certificate,
|
||||
client has cert signed by server certificate).
|
||||
|
||||
Port 8953 is registered with IANA as:
|
||||
ub-dns-control 8953/tcp unbound dns nameserver control
|
||||
# Wouter Wijngaards <wouter&nlnetlabs.nl> 10 May 2011
|
||||
On may 11 2011, ticket [IANA #442315].
|
||||
|
||||
Query and Response
|
||||
------------------
|
||||
Client sends
|
||||
UBCT [commandline] \n
|
||||
fixed string UBCT, then an ascii text line, with a command,
|
||||
some whitespace allowed. Line ends with '\n'.
|
||||
UBCT[version] [commandline] \n
|
||||
fixed string UBCT1 (for version 1), then an ascii text line,
|
||||
with a command, some whitespace allowed. Line ends with '\n'.
|
||||
|
||||
Server executes command. And sends reply in ascii text over channel,
|
||||
closes the channel when done.
|
||||
|
||||
+35
-10
@@ -54,8 +54,9 @@ server:
|
||||
# outgoing-interface: 2001:DB8::6
|
||||
|
||||
# number of ports to allocate per thread, determines the size of the
|
||||
# port range that can be open simultaneously.
|
||||
# outgoing-range: 256
|
||||
# port range that can be open simultaneously. About double the
|
||||
# num-queries-per-thread, or, use as many as the OS will allow you.
|
||||
# outgoing-range: 4096
|
||||
|
||||
# permit unbound to use this port number or port range for
|
||||
# making outgoing queries, using an outgoing interface.
|
||||
@@ -78,6 +79,10 @@ server:
|
||||
# 0 is system default. Use 4m to catch query spikes for busy servers.
|
||||
# so-rcvbuf: 0
|
||||
|
||||
# buffer size for UDP port 53 outgoing (SO_SNDBUF socket option).
|
||||
# 0 is system default. Use 4m to handle spikes on very busy servers.
|
||||
# so-sndbuf: 0
|
||||
|
||||
# EDNS reassembly buffer to advertise to UDP peers (the actual buffer
|
||||
# is set with msg-buffer-size). 1480 can solve fragmentation (timeouts).
|
||||
# edns-buffer-size: 4096
|
||||
@@ -207,6 +212,9 @@ server:
|
||||
|
||||
# print UTC timestamp in ascii to logfile, default is epoch in seconds.
|
||||
# log-time-ascii: no
|
||||
|
||||
# print one line with time, IP, name, type, class for every query.
|
||||
# log-queries: no
|
||||
|
||||
# the pid file. Can be an absolute path outside of chroot/work dir.
|
||||
# pidfile: "@UNBOUND_PIDFILE@"
|
||||
@@ -252,6 +260,9 @@ server:
|
||||
# Default on, which insists on dnssec data for trust-anchored zones.
|
||||
# harden-dnssec-stripped: yes
|
||||
|
||||
# Harden against queries that fall under dnssec-signed nxdomain names.
|
||||
# harden-below-nxdomain: no
|
||||
|
||||
# Harden the referral path by performing additional queries for
|
||||
# infrastructure data. Validates the replies (if possible).
|
||||
# Default off, because the lookups burden the server. Experimental
|
||||
@@ -270,7 +281,7 @@ server:
|
||||
# private-address: 10.0.0.0/8
|
||||
# private-address: 172.16.0.0/12
|
||||
# private-address: 192.168.0.0/16
|
||||
# private-address: 192.254.0.0/16
|
||||
# private-address: 169.254.0.0/16
|
||||
# private-address: fd00::/8
|
||||
# private-address: fe80::/10
|
||||
|
||||
@@ -304,6 +315,16 @@ server:
|
||||
# separated by spaces. "iterator" or "validator iterator"
|
||||
# module-config: "validator iterator"
|
||||
|
||||
# File with trusted keys, kept uptodate using RFC5011 probes,
|
||||
# initial file like trust-anchor-file, then it stores metadata.
|
||||
# Use several entries, one per domain name, to track multiple zones.
|
||||
#
|
||||
# If you want to perform DNSSEC validation, run unbound-anchor before
|
||||
# you start unbound (i.e. in the system boot scripts). And enable:
|
||||
# Please note usage of unbound-anchor root anchor is at your own risk
|
||||
# and under the terms of our LICENSE (see that file in the source).
|
||||
# auto-trust-anchor-file: "@UNBOUND_ROOTKEY_FILE@"
|
||||
|
||||
# File with DLV trusted keys. Same format as trust-anchor-file.
|
||||
# There can be only one DLV configured, it is trusted from root down.
|
||||
# Download http://ftp.isc.org/www/dlv/dlv.isc.org.key
|
||||
@@ -312,15 +333,12 @@ server:
|
||||
# File with trusted keys for validation. Specify more than one file
|
||||
# with several entries, one file per entry.
|
||||
# Zone file format, with DS and DNSKEY entries.
|
||||
# Note this gets out of date, use auto-trust-anchor-file please.
|
||||
# trust-anchor-file: ""
|
||||
|
||||
# File with trusted keys, kept uptodate using RFC5011 probes,
|
||||
# initial file like trust-anchor-file, then it stores metadata.
|
||||
# Use several entries, one per domain name, to track multiple zones.
|
||||
# auto-trust-anchor-file: ""
|
||||
|
||||
# Trusted key for validation. DS or DNSKEY. specify the RR on a
|
||||
# single line, surrounded by "". TTL is ignored. class is IN default.
|
||||
# Note this gets out of date, use auto-trust-anchor-file please.
|
||||
# (These examples are from August 2007 and may not be valid anymore).
|
||||
# trust-anchor: "nlnetlabs.nl. DNSKEY 257 3 5 AQPzzTWMz8qSWIQlfRnPckx2BiVmkVN6LPupO3mbz7FhLSnm26n6iG9N Lby97Ji453aWZY3M5/xJBSOS2vWtco2t8C0+xeO1bc/d6ZTy32DHchpW 6rDH1vp86Ll+ha0tmwyy9QP7y2bVw5zSbFCrefk8qCUBgfHm9bHzMG1U BYtEIQ=="
|
||||
# trust-anchor: "jelte.nlnetlabs.nl. DS 42860 5 1 14D739EB566D2B1A5E216A0BA4D17FA9B038BE4A"
|
||||
@@ -329,6 +347,7 @@ server:
|
||||
# with several entries, one file per entry. Like trust-anchor-file
|
||||
# but has a different file format. Format is BIND-9 style format,
|
||||
# the trusted-keys { name flag proto algo "key"; }; clauses are read.
|
||||
# you need external update procedures to track changes in keys.
|
||||
# trusted-keys-file: ""
|
||||
|
||||
# Ignore chain of trust. Domain is treated as insecure.
|
||||
@@ -336,7 +355,7 @@ server:
|
||||
|
||||
# Override the date for validation with a specific fixed date.
|
||||
# Do not set this unless you are debugging signature inception
|
||||
# and expiration. "" or "0" turns the feature off.
|
||||
# and expiration. "" or "0" turns the feature off. -1 ignores date.
|
||||
# val-override-date: ""
|
||||
|
||||
# The time to live for bogus data, rrsets and messages. This avoids
|
||||
@@ -362,6 +381,11 @@ server:
|
||||
# replies if the message is found secure. The default is off.
|
||||
# val-permissive-mode: no
|
||||
|
||||
# Ignore the CD flag in incoming queries and refuse them bogus data.
|
||||
# Enable it if the only clients of unbound are legacy servers (w2008)
|
||||
# that set CD but cannot validate themselves.
|
||||
# ignore-cd-flag: 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.
|
||||
# val-log-level: 0
|
||||
@@ -404,6 +428,7 @@ server:
|
||||
# o transparent gives local data, but resolves normally for other names
|
||||
# o redirect serves the zone data for any subdomain in the zone.
|
||||
# o nodefault can be used to normally resolve AS112 zones.
|
||||
# o typetransparent resolves normally for other types and other names
|
||||
#
|
||||
# defaults are localhost address, reverse for 127.0.0.1 and ::1
|
||||
# and nxdomain for AS112 zones. If you configure one of these zones
|
||||
@@ -450,7 +475,7 @@ remote-control:
|
||||
# control-interface: ::1
|
||||
|
||||
# port number for remote control operations.
|
||||
# control-port: 953
|
||||
# control-port: 8953
|
||||
|
||||
# unbound server key file.
|
||||
# server-key-file: "@UNBOUND_RUN_DIR@/unbound_server.key"
|
||||
|
||||
@@ -0,0 +1,174 @@
|
||||
.TH "unbound-anchor" "8" "@date@" "NLnet Labs" "unbound @version@"
|
||||
.\"
|
||||
.\" unbound-anchor.8 -- unbound anchor maintenance utility manual
|
||||
.\"
|
||||
.\" Copyright (c) 2008, NLnet Labs. All rights reserved.
|
||||
.\"
|
||||
.\" See LICENSE for the license.
|
||||
.\"
|
||||
.\"
|
||||
.SH "NAME"
|
||||
.LP
|
||||
.B unbound\-anchor
|
||||
\- Unbound anchor utility.
|
||||
.SH "SYNOPSIS"
|
||||
.B unbound\-anchor
|
||||
.RB [ opts ]
|
||||
.SH "DESCRIPTION"
|
||||
.B Unbound\-anchor
|
||||
performs setup or update of the root trust anchor for DNSSEC validation.
|
||||
It can be run (as root) from the commandline, or run as part of startup
|
||||
scripts. Before you start the \fIunbound\fR(8) DNS server.
|
||||
.P
|
||||
Suggested usage:
|
||||
.P
|
||||
.nf
|
||||
# in the init scripts.
|
||||
# provide or update the root anchor (if necessary)
|
||||
unbound-anchor -a "@UNBOUND_ROOTKEY_FILE@"
|
||||
# Please note usage of this root anchor is at your own risk
|
||||
# and under the terms of our LICENSE (see source).
|
||||
#
|
||||
# start validating resolver
|
||||
# the unbound.conf contains:
|
||||
# auto-trust-anchor-file: "@UNBOUND_ROOTKEY_FILE@"
|
||||
unbound -c unbound.conf
|
||||
.fi
|
||||
.P
|
||||
This tool provides builtin default contents for the root anchor and root
|
||||
update certificate files.
|
||||
.P
|
||||
It tests if the root anchor file works, and if not, and an update is possible,
|
||||
attempts to update the root anchor using the root update certificate.
|
||||
It performs a https fetch of root-anchors.xml and checks the results, if
|
||||
all checks are successful, it updates the root anchor file. Otherwise
|
||||
the root anchor file is unchanged. It performs RFC5011 tracking if the
|
||||
DNSSEC information available via the DNS makes that possible.
|
||||
.P
|
||||
If does not perform an update if the certificate is expired, if the network
|
||||
is down or other errors occur.
|
||||
.P
|
||||
The available options are:
|
||||
.TP
|
||||
.B \-a \fIfile
|
||||
The root anchor key file, that is read in and written out.
|
||||
Default is @UNBOUND_ROOTKEY_FILE@.
|
||||
If the file does not exist, or is empty, a builtin root key is written to it.
|
||||
.TP
|
||||
.B \-c \fIfile
|
||||
The root update certificate file, that is read in.
|
||||
Default is @UNBOUND_ROOTCERT_FILE@.
|
||||
If the file does not exist, or is empty, a builtin certificate is used.
|
||||
.TP
|
||||
.B \-l
|
||||
List the builtin root key and builtin root update certificate on stdout.
|
||||
.TP
|
||||
.B \-u \fIname
|
||||
The server name, it connects to https://name. Specify without https:// prefix.
|
||||
The default is "data.iana.org". It connects to the port specified with \-P.
|
||||
You can pass an IPv4 addres or IPv6 address (no brackets) if you want.
|
||||
.TP
|
||||
.B \-x \fIpath
|
||||
The pathname to the root\-anchors.xml file on the server. (forms URL with \-u).
|
||||
The default is /root\-anchors/root\-anchors.xml.
|
||||
.TP
|
||||
.B \-s \fIpath
|
||||
The pathname to the root\-anchors.p7s file on the server. (forms URL with \-u).
|
||||
The default is /root\-anchors/root\-anchors.p7s. This file has to be a PKCS7
|
||||
signature over the xml file, using the pem file (\-c) as trust anchor.
|
||||
.TP
|
||||
.B \-4
|
||||
Use IPv4 for domain resolution and contacting the server on https. Default is
|
||||
to use IPv4 and IPv6 where appropriate.
|
||||
.TP
|
||||
.B \-6
|
||||
Use IPv6 for domain resolution and contacting the server on https. Default is
|
||||
to use IPv4 and IPv6 where appropriate.
|
||||
.TP
|
||||
.B \-f \fIresolv.conf
|
||||
Use the given resolv.conf file. Not enabled by default, but you could try to
|
||||
pass /etc/resolv.conf on some systems. It contains the IP addresses of the
|
||||
recursive nameservers to use. However, since this tool could be used to
|
||||
bootstrap that very recursive nameserver, it would not be useful (since
|
||||
that server is not up yet, since we are bootstrapping it). It could be
|
||||
useful in a situation where you know an upstream cache is deployed (and
|
||||
running) and in captive portal situations.
|
||||
.TP
|
||||
.B \-r \fIroot.hints
|
||||
Use the given root.hints file (same syntax as the BIND and Unbound root hints
|
||||
file) to bootstrap domain resolution. By default a list of builtin root
|
||||
hints is used. Unbound\-anchor goes to the network itself for these roots,
|
||||
to resolve the server (\-u option) and to check the root DNSKEY records.
|
||||
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 \-v
|
||||
More verbose. Once prints informational messages, multiple times may enable
|
||||
large debug amounts (such as full certificates or byte\-dumps of downloaded
|
||||
files). By default it prints almost nothing. It also prints nothing on
|
||||
errors by default; in that case the original root anchor file is simply
|
||||
left undisturbed, so that a recursive server can start right after it.
|
||||
.TP
|
||||
.B \-C \fIunbound.conf
|
||||
Debug option to read unbound.conf into the resolver process used.
|
||||
.TP
|
||||
.B \-P \fIport
|
||||
Set the port number to use for the https connection. The default is 443.
|
||||
.TP
|
||||
.B \-F
|
||||
Debug option to force update of the root anchor through downloading the xml
|
||||
file and verifying it with the certificate. By default it first tries to
|
||||
update by contacting the DNS, which uses much less bandwidth, is much
|
||||
faster (200 msec not 2 sec), and is nicer to the deployed infrastructure.
|
||||
With this option, it still attempts to do so (and may verbosely tell you),
|
||||
but then ignores the result and goes on to use the xml fallback method.
|
||||
.TP
|
||||
.B \-h
|
||||
Show the version and commandline option help.
|
||||
.TP
|
||||
.B \-v
|
||||
More verbose. Prints output detailing what happens.
|
||||
.SH "EXIT CODE"
|
||||
This tool exits with value 1 if the root anchor was updated using the
|
||||
certificate or if the builtin root-anchor was used. It exits with code
|
||||
0 if no update was necessary, if the update was possible with RFC5011
|
||||
tracking, or if an error occurred.
|
||||
.P
|
||||
You can check the exit value in this manner:
|
||||
.nf
|
||||
unbound-anchor -a "root.key" || logger "Please check root.key"
|
||||
.fi
|
||||
Or something more suitable for your operational environment.
|
||||
.SH "TRUST"
|
||||
The root keys and update certificate included in this tool
|
||||
are provided for convenience and under the terms of our
|
||||
license (see the LICENSE file in the source distribution or
|
||||
http://unbound.nlnetlabs.nl/svn/trunk/LICENSE) and might be stale or
|
||||
not suitable to your purpose.
|
||||
.P
|
||||
By running "unbound\-anchor \-l" the keys and certificate that are
|
||||
configured in the code are printed for your convenience.
|
||||
.P
|
||||
The build\-in configuration can be overridden by providing a root\-cert
|
||||
file and a rootkey file.
|
||||
.SH "FILES"
|
||||
.TP
|
||||
.I @UNBOUND_ROOTKEY_FILE@
|
||||
The root anchor file, updated with 5011 tracking, and read and written to.
|
||||
The file is created if it does not exist.
|
||||
.TP
|
||||
.I @UNBOUND_ROOTCERT_FILE@
|
||||
The trusted self\-signed certificate that is used to verify the downloaded
|
||||
DNSSEC root trust anchor. You can update it by fetching it from
|
||||
https://data.iana.org/root\-anchors/icannbundle.pem (and validate it).
|
||||
If the file does not exist or is empty, a builtin version is used.
|
||||
.TP
|
||||
.I https://data.iana.org/root\-anchors/root\-anchors.xml
|
||||
Source for the root key information.
|
||||
.TP
|
||||
.I https://data.iana.org/root\-anchors/root\-anchors.p7s
|
||||
Signature on the root key information.
|
||||
.SH "SEE ALSO"
|
||||
\fIunbound.conf\fR(5),
|
||||
\fIunbound\fR(8).
|
||||
@@ -142,6 +142,14 @@ Show what is worked on. Prints all queries that the server is currently
|
||||
working on. Prints the time that users have been waiting. For internal
|
||||
requests, no time is printed. And then prints out the module status.
|
||||
.TP
|
||||
.B flush_infra \fIall|IP
|
||||
If all then entire infra cache is emptied. If a specific IP address, the
|
||||
entry for that address is removed from the cache. It contains EDNS, ping
|
||||
and lameness data.
|
||||
.TP
|
||||
.B dump_infra
|
||||
Show the contents of the infra cache.
|
||||
.TP
|
||||
.B set_option \fIopt: val
|
||||
Set the option to the given value without a reload. The cache is therefore
|
||||
not flushed. The option must end with a ':' and whitespace must be between the
|
||||
|
||||
+67
-19
@@ -92,7 +92,10 @@ The verbosity can also be increased from the commandline, see \fIunbound\fR(8).
|
||||
.TP
|
||||
.B statistics\-interval: \fI<seconds>
|
||||
The number of seconds between printing statistics to the log for every thread.
|
||||
Disable with value 0 or "". Default is disabled.
|
||||
Disable with value 0 or "". Default is disabled. The histogram statistics
|
||||
are only printed if replies were sent during the statistics interval,
|
||||
requestlist statistics are printed for every interval (but can be 0).
|
||||
This is because the median calculation requires data to be present.
|
||||
.TP
|
||||
.B statistics\-cumulative: \fI<yes or no>
|
||||
If enabled, statistics are cumulative since starting unbound, without clearing
|
||||
@@ -121,9 +124,8 @@ interface and port number), if not specified the default port (from
|
||||
.TP
|
||||
.B interface\-automatic: \fI<yes or no>
|
||||
Detect source interface on UDP queries and copy them to replies. This
|
||||
feature is experimental, and needs support in your OS for IPv6
|
||||
(and its socket options) and IPv4 (and have source\-interface socket options).
|
||||
Default value is no.
|
||||
feature is experimental, and needs support in your OS for particular socket
|
||||
options. Default value is no.
|
||||
.TP
|
||||
.B outgoing\-interface: \fI<ip address>
|
||||
Interface to use to connect to the network. This interface is used to send
|
||||
@@ -138,8 +140,9 @@ sent via a random outgoing interface to counter spoofing.
|
||||
.TP
|
||||
.B outgoing\-range: \fI<number>
|
||||
Number of ports to open. This number of file descriptors can be opened per
|
||||
thread. Must be at least 1. Default is 256. Larger numbers need extra
|
||||
resources from the operating system.
|
||||
thread. Must be at least 1. Default depends on compile options. Larger
|
||||
numbers need extra resources from the operating system. For performance a
|
||||
a very large value is best, use libevent to make this possible.
|
||||
.TP
|
||||
.B outgoing\-port\-permit: \fI<port number or range>
|
||||
Permit unbound to open this port or range of ports for use to send queries.
|
||||
@@ -202,7 +205,7 @@ The number of queries that every thread will service simultaneously.
|
||||
If more queries arrive that need servicing, and no queries can be jostled out
|
||||
(see \fIjostle\-timeout\fR), then the queries are dropped. This forces
|
||||
the client to resend after a timeout; allowing the server time to work on
|
||||
the existing queries. Default 1024.
|
||||
the existing queries. Default depends on compile options, 512 or 1024.
|
||||
.TP
|
||||
.B jostle\-timeout: \fI<msec>
|
||||
Timeout used when the server is very busy. Set to a value that usually
|
||||
@@ -211,6 +214,11 @@ arrive, then 50% of the queries are allowed to run to completion, and
|
||||
the other 50% are replaced with the new incoming query if they have already
|
||||
spent more than their allowed time. This protects against denial of
|
||||
service by slow queries or high query rates. Default 200 milliseconds.
|
||||
The effect is that the qps for long-lasting queries is about
|
||||
(numqueriesperthread / 2) / (average time for such long queries) qps.
|
||||
The qps for short queries can be about (numqueriesperthread / 2)
|
||||
/ (jostletimeout in whole seconds) qps per thread, about (1024/2)*5 = 2560
|
||||
qps by default.
|
||||
.TP
|
||||
.B so\-rcvbuf: \fI<number>
|
||||
If not 0, then set the SO_RCVBUF socket option to get more buffer
|
||||
@@ -223,6 +231,17 @@ net.core.rmem_max. On BSD change kern.ipc.maxsockbuf in /etc/sysctl.conf.
|
||||
On OpenBSD change header and recompile kernel. On Solaris ndd \-set
|
||||
/dev/udp udp_max_buf 8388608.
|
||||
.TP
|
||||
.B so\-sndbuf: \fI<number>
|
||||
If not 0, then set the SO_SNDBUF socket option to get more buffer space on
|
||||
UDP port 53 outgoing queries. This for very busy servers handles spikes
|
||||
in answer traffic, otherwise 'send: resource temporarily unavailable'
|
||||
can get logged, the buffer overrun is also visible by netstat \-su.
|
||||
Default is 0 (use system value). Specify the number of bytes to ask
|
||||
for, try "4m" on a very busy server. The OS caps it at a maximum, on
|
||||
linux unbound needs root permission to bypass the limit, or the admin
|
||||
can use sysctl net.core.wmem_max. On BSD, Solaris changes are similar
|
||||
to so\-rcvbuf.
|
||||
.TP
|
||||
.B rrset\-cache\-size: \fI<number>
|
||||
Number of bytes size of the RRset cache. Default is 4 megabytes.
|
||||
A plain number is in bytes, append 'k', 'm' or 'g' for kilobytes, megabytes
|
||||
@@ -376,6 +395,12 @@ Sets logfile lines to use a timestamp in UTC ascii. Default is no, which
|
||||
prints the seconds since 1970 in brackets. No effect if using syslog, in
|
||||
that case syslog formats the timestamp printed into the log files.
|
||||
.TP
|
||||
.B log\-queries: \fI<yes or no>
|
||||
Prints one line per query to the log, with the log timestamp and IP address,
|
||||
name, type and class. 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 pidfile: \fI<filename>
|
||||
The process id is written to the file. Default is "@UNBOUND_PIDFILE@".
|
||||
So,
|
||||
@@ -447,6 +472,15 @@ removes DNSSEC data from packets, or a zone changes from signed to
|
||||
unsigned to badly signed often. If turned off you run the risk of a
|
||||
downgrade attack that disables security for a zone. Default is on.
|
||||
.TP
|
||||
.B harden\-below\-nxdomain: \fI<yes or no>
|
||||
From draft-vixie-dnsext-resimprove, returns nxdomain to queries for a name
|
||||
below another name that is already known to be nxdomain. DNSSEC mandates
|
||||
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.
|
||||
.TP
|
||||
.B harden\-referral\-path: \fI<yes or no>
|
||||
Harden the referral path by performing additional queries for
|
||||
infrastructure data. Validates the replies if trust anchors are configured
|
||||
@@ -479,7 +513,7 @@ that you configured is allowed to, and you can specify additional
|
||||
names using \fBprivate\-domain\fR. No private addresses are enabled
|
||||
by default. We consider to enable this for the RFC1918 private IP
|
||||
address space by default in later releases. That would enable private
|
||||
addresses for 10.0.0.0/8 172.16.0.0/12 192.168.0.0/16 192.254.0.0/16
|
||||
addresses for 10.0.0.0/8 172.16.0.0/12 192.168.0.0/16 169.254.0.0/16
|
||||
fd00::/8 and fe80::/10, since the RFC standards say these addresses
|
||||
should not be visible on the public internet. Turning on 127.0.0.0/8
|
||||
would hinder many spamblocklists as they use that.
|
||||
@@ -580,7 +614,8 @@ externally can create validation failures for that internal domain.
|
||||
Default is "" or "0", which disables this debugging feature. If enabled by
|
||||
giving a RRSIG style date, that date is used for verifying RRSIG inception
|
||||
and expiration dates, instead of the current date. Do not set this unless
|
||||
you are debugging signature inception and expiration.
|
||||
you are debugging signature inception and expiration. The value \-1 ignores
|
||||
the date altogether, useful for some special applications.
|
||||
.TP
|
||||
.B val\-sig\-skew\-min: \fI<seconds>
|
||||
Minimum number of seconds of clock skew to apply to validated signatures.
|
||||
@@ -628,6 +663,14 @@ receives the bogus data. For messages that are found to be secure the AD bit
|
||||
is set in replies. Also logging is performed as for full validation.
|
||||
The default value is "no".
|
||||
.TP
|
||||
.B ignore\-cd\-flag: \fI<yes or no>
|
||||
Instruct unbound to ignore the CD flag from clients and refuse to
|
||||
return bogus answers to them. Thus, the CD (Checking Disabled) flag
|
||||
does not disable checking any more. This is useful if legacy (w2008)
|
||||
servers that set the CD flag but cannot validate DNSSEC themselves are
|
||||
the clients, and then unbound provides them with DNSSEC protection.
|
||||
The default value 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
|
||||
@@ -673,11 +716,12 @@ A plain number is in bytes, append 'k', 'm' or 'g' for kilobytes, megabytes
|
||||
or gigabytes (1024*1024 bytes in a megabyte).
|
||||
.TP
|
||||
.B local\-zone: \fI<zone> <type>
|
||||
Configure a local zone. The type determines the answer to give if there is
|
||||
no match from local\-data. The types are deny, refuse, static, transparent,
|
||||
redirect, nodefault, and are explained below. After that the default settings
|
||||
are listed. Use local\-data: to enter data into the local zone. Answers for
|
||||
local zones are authoritative DNS answers. By default the zones are class IN.
|
||||
Configure a local zone. The type determines the answer to give if
|
||||
there is no match from local\-data. The types are deny, refuse, static,
|
||||
transparent, redirect, nodefault, typetransparent, and are explained
|
||||
below. After that the default settings are listed. Use local\-data: to
|
||||
enter data into the local zone. Answers for local zones are authoritative
|
||||
DNS answers. By default the zones are class IN.
|
||||
.IP
|
||||
If you need more complicated authoritative data, with referrals, wildcards,
|
||||
CNAME/DNAME support, or DNSSEC authoritative service, setup a stub\-zone for
|
||||
@@ -705,6 +749,13 @@ given in localdata, then a noerror nodata answer is returned.
|
||||
If no local\-zone is given local\-data causes a transparent zone
|
||||
to be created by default.
|
||||
.TP 10
|
||||
\h'5'\fItypetransparent\fR
|
||||
If there is a match from local data, the query is answered. If the query
|
||||
is for a different name, or for the same name but for a different type,
|
||||
the query is resolved normally. So, similar to transparent but types
|
||||
that are not listed in local data are resolved normally, so if an A record
|
||||
is in the local data that does not cause a nodata reply for AAAA queries.
|
||||
.TP 10
|
||||
\h'5'\fIredirect\fR
|
||||
The query is answered from the local data for the zone name.
|
||||
There may be no local data beneath the zone name.
|
||||
@@ -794,9 +845,6 @@ Reverse data for zone D.F.ip6.arpa.
|
||||
\h'5'\fIreverse RFC4291 IPv6 Link Local Addresses\fR
|
||||
Reverse data for zones 8.E.F.ip6.arpa to B.E.F.ip6.arpa.
|
||||
.TP 10
|
||||
\h'5'\fIreverse RFC4843 Orchid Prefix\fR
|
||||
Reverse data for zone 0.1.1.0.0.2.ip6.arpa.
|
||||
.TP 10
|
||||
\h'5'\fIreverse IPv6 Example Prefix\fR
|
||||
Reverse data for zone 8.B.D.0.1.0.0.2.ip6.arpa. This zone is used for
|
||||
tutorials and examples. You can remove the block on this zone with:
|
||||
@@ -846,7 +894,7 @@ By default localhost (127.0.0.1 and ::1) is listened to.
|
||||
Use 0.0.0.0 and ::0 to listen to all interfaces.
|
||||
.TP 5
|
||||
.B control\-port: <port number>
|
||||
The port number to listen on for control commands, default is 953
|
||||
The port number to listen on for control commands, default is 8953
|
||||
(that is the same port number named uses to listen to rndc).
|
||||
If you change this port number, and permissions have been dropped, a
|
||||
reload is not sufficient to open the port again, you must then restart.
|
||||
@@ -964,7 +1012,7 @@ server:
|
||||
num\-threads: 1
|
||||
outgoing\-num\-tcp: 1 # this limits TCP service, uses less buffers.
|
||||
incoming\-num\-tcp: 1
|
||||
outgoing\-range: 16 # uses less memory, but less performance.
|
||||
outgoing\-range: 60 # uses less memory, but less performance.
|
||||
msg\-buffer\-size: 8192 # note this limits service, 'no huge stuff'.
|
||||
msg\-cache\-size: 100k
|
||||
msg\-cache\-slabs: 1
|
||||
|
||||
+929
-550
File diff suppressed because it is too large
Load Diff
+19
-20
@@ -81,7 +81,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, 0))
|
||||
a->bogus, a->lame))
|
||||
return NULL;
|
||||
}
|
||||
return copy;
|
||||
@@ -154,7 +154,7 @@ delegpt_find_addr(struct delegpt* dp, struct sockaddr_storage* addr,
|
||||
int
|
||||
delegpt_add_target(struct delegpt* dp, struct regional* region,
|
||||
uint8_t* name, size_t namelen, struct sockaddr_storage* addr,
|
||||
socklen_t addrlen, int bogus, int lame, int nodup)
|
||||
socklen_t addrlen, int bogus, int lame)
|
||||
{
|
||||
struct delegpt_ns* ns = delegpt_find_ns(dp, name, namelen);
|
||||
if(!ns) {
|
||||
@@ -168,23 +168,22 @@ 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, nodup);
|
||||
return delegpt_add_addr(dp, region, addr, addrlen, bogus, lame);
|
||||
}
|
||||
|
||||
int
|
||||
delegpt_add_addr(struct delegpt* dp, struct regional* region,
|
||||
struct sockaddr_storage* addr, socklen_t addrlen, int bogus,
|
||||
int lame, int nodup)
|
||||
int lame)
|
||||
{
|
||||
struct delegpt_addr* a;
|
||||
if(nodup) {
|
||||
if((a = delegpt_find_addr(dp, addr, addrlen))) {
|
||||
if(bogus)
|
||||
a->bogus = bogus;
|
||||
if(!lame)
|
||||
a->lame = 0;
|
||||
return 1;
|
||||
}
|
||||
/* check for duplicates */
|
||||
if((a = delegpt_find_addr(dp, addr, addrlen))) {
|
||||
if(bogus)
|
||||
a->bogus = bogus;
|
||||
if(!lame)
|
||||
a->lame = 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
a = (struct delegpt_addr*)regional_alloc(region,
|
||||
@@ -361,10 +360,10 @@ delegpt_from_message(struct dns_msg* msg, struct regional* region)
|
||||
continue;
|
||||
|
||||
if(ntohs(s->rk.type) == LDNS_RR_TYPE_A) {
|
||||
if(!delegpt_add_rrset_A(dp, region, s, 0, 0))
|
||||
if(!delegpt_add_rrset_A(dp, region, s, 0))
|
||||
return NULL;
|
||||
} else if(ntohs(s->rk.type) == LDNS_RR_TYPE_AAAA) {
|
||||
if(!delegpt_add_rrset_AAAA(dp, region, s, 0, 0))
|
||||
if(!delegpt_add_rrset_AAAA(dp, region, s, 0))
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
@@ -394,7 +393,7 @@ delegpt_rrset_add_ns(struct delegpt* dp, struct regional* region,
|
||||
|
||||
int
|
||||
delegpt_add_rrset_A(struct delegpt* dp, struct regional* region,
|
||||
struct ub_packed_rrset_key* ak, int lame, int nodup)
|
||||
struct ub_packed_rrset_key* ak, int lame)
|
||||
{
|
||||
struct packed_rrset_data* d=(struct packed_rrset_data*)ak->entry.data;
|
||||
size_t i;
|
||||
@@ -409,7 +408,7 @@ delegpt_add_rrset_A(struct delegpt* dp, struct regional* region,
|
||||
memmove(&sa.sin_addr, d->rr_data[i]+2, INET_SIZE);
|
||||
if(!delegpt_add_target(dp, region, ak->rk.dname,
|
||||
ak->rk.dname_len, (struct sockaddr_storage*)&sa,
|
||||
len, (d->security==sec_status_bogus), lame, nodup))
|
||||
len, (d->security==sec_status_bogus), lame))
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
@@ -417,7 +416,7 @@ delegpt_add_rrset_A(struct delegpt* dp, struct regional* region,
|
||||
|
||||
int
|
||||
delegpt_add_rrset_AAAA(struct delegpt* dp, struct regional* region,
|
||||
struct ub_packed_rrset_key* ak, int lame, int nodup)
|
||||
struct ub_packed_rrset_key* ak, int lame)
|
||||
{
|
||||
struct packed_rrset_data* d=(struct packed_rrset_data*)ak->entry.data;
|
||||
size_t i;
|
||||
@@ -432,7 +431,7 @@ delegpt_add_rrset_AAAA(struct delegpt* dp, struct regional* region,
|
||||
memmove(&sa.sin6_addr, d->rr_data[i]+2, INET6_SIZE);
|
||||
if(!delegpt_add_target(dp, region, ak->rk.dname,
|
||||
ak->rk.dname_len, (struct sockaddr_storage*)&sa,
|
||||
len, (d->security==sec_status_bogus), lame, nodup))
|
||||
len, (d->security==sec_status_bogus), lame))
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
@@ -447,9 +446,9 @@ delegpt_add_rrset(struct delegpt* dp, struct regional* region,
|
||||
if(ntohs(rrset->rk.type) == LDNS_RR_TYPE_NS)
|
||||
return delegpt_rrset_add_ns(dp, region, rrset, lame);
|
||||
else if(ntohs(rrset->rk.type) == LDNS_RR_TYPE_A)
|
||||
return delegpt_add_rrset_A(dp, region, rrset, lame, 1);
|
||||
return delegpt_add_rrset_A(dp, region, rrset, lame);
|
||||
else if(ntohs(rrset->rk.type) == LDNS_RR_TYPE_AAAA)
|
||||
return delegpt_add_rrset_AAAA(dp, region, rrset, lame, 1);
|
||||
return delegpt_add_rrset_AAAA(dp, region, rrset, lame);
|
||||
log_warn("Unknown rrset type added to delegpt");
|
||||
return 1;
|
||||
}
|
||||
|
||||
+5
-11
@@ -185,7 +185,7 @@ int delegpt_add_ns(struct delegpt* dp, struct regional* regional,
|
||||
* @param regional: where to allocate the info.
|
||||
* @param ns_rrset: NS rrset.
|
||||
* @param lame: rrset is lame, disprefer it.
|
||||
* return 0 on alloc error.
|
||||
* @return 0 on alloc error.
|
||||
*/
|
||||
int delegpt_rrset_add_ns(struct delegpt* dp, struct regional* regional,
|
||||
struct ub_packed_rrset_key* ns_rrset, int lame);
|
||||
@@ -201,13 +201,11 @@ int delegpt_rrset_add_ns(struct delegpt* dp, struct regional* regional,
|
||||
* @param addrlen: the length of addr.
|
||||
* @param bogus: security status for the address, pass true if bogus.
|
||||
* @param lame: address is lame.
|
||||
* @param nodup: if true, no address duplicates are made by this add.
|
||||
* name duplicates are always filtered.
|
||||
* @return false on error.
|
||||
*/
|
||||
int delegpt_add_target(struct delegpt* dp, struct regional* regional,
|
||||
uint8_t* name, size_t namelen, struct sockaddr_storage* addr,
|
||||
socklen_t addrlen, int bogus, int lame, int nodup);
|
||||
socklen_t addrlen, int bogus, int lame);
|
||||
|
||||
/**
|
||||
* Add A RRset to delegpt.
|
||||
@@ -215,11 +213,10 @@ int delegpt_add_target(struct delegpt* dp, struct regional* regional,
|
||||
* @param regional: where to allocate the info.
|
||||
* @param rrset: RRset A to add.
|
||||
* @param lame: rrset is lame, disprefer it.
|
||||
* @param nodup: if true, no duplicates are made by this add. takes time.
|
||||
* @return 0 on alloc error.
|
||||
*/
|
||||
int delegpt_add_rrset_A(struct delegpt* dp, struct regional* regional,
|
||||
struct ub_packed_rrset_key* rrset, int lame, int nodup);
|
||||
struct ub_packed_rrset_key* rrset, int lame);
|
||||
|
||||
/**
|
||||
* Add AAAA RRset to delegpt.
|
||||
@@ -227,11 +224,10 @@ int delegpt_add_rrset_A(struct delegpt* dp, struct regional* regional,
|
||||
* @param regional: where to allocate the info.
|
||||
* @param rrset: RRset AAAA to add.
|
||||
* @param lame: rrset is lame, disprefer it.
|
||||
* @param nodup: if true, no duplicates are made by this add. takes time.
|
||||
* @return 0 on alloc error.
|
||||
*/
|
||||
int delegpt_add_rrset_AAAA(struct delegpt* dp, struct regional* regional,
|
||||
struct ub_packed_rrset_key* rrset, int lame, int nodup);
|
||||
struct ub_packed_rrset_key* rrset, int lame);
|
||||
|
||||
/**
|
||||
* Add any RRset to delegpt.
|
||||
@@ -253,12 +249,10 @@ 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 nodup: if true, no duplicates are made by this add. takes time.
|
||||
* @return false on error.
|
||||
*/
|
||||
int delegpt_add_addr(struct delegpt* dp, struct regional* regional,
|
||||
struct sockaddr_storage* addr, socklen_t addrlen, int bogus,
|
||||
int lame, int nodup);
|
||||
struct sockaddr_storage* addr, socklen_t addrlen, int bogus, int lame);
|
||||
|
||||
/**
|
||||
* Find NS record in name list of delegation point.
|
||||
|
||||
@@ -49,7 +49,7 @@
|
||||
#include "util/net_help.h"
|
||||
|
||||
struct iter_donotq*
|
||||
donotq_create()
|
||||
donotq_create(void)
|
||||
{
|
||||
struct iter_donotq* dq = (struct iter_donotq*)calloc(1,
|
||||
sizeof(struct iter_donotq));
|
||||
|
||||
@@ -65,7 +65,7 @@ struct iter_donotq {
|
||||
* Create donotqueryaddresses structure
|
||||
* @return new structure or NULL on error.
|
||||
*/
|
||||
struct iter_donotq* donotq_create();
|
||||
struct iter_donotq* donotq_create(void);
|
||||
|
||||
/**
|
||||
* Delete donotqueryaddresses structure.
|
||||
|
||||
+2
-3
@@ -67,7 +67,7 @@ fwd_cmp(const void* k1, const void* k2)
|
||||
}
|
||||
|
||||
struct iter_forwards*
|
||||
forwards_create()
|
||||
forwards_create(void)
|
||||
{
|
||||
struct iter_forwards* fwd = (struct iter_forwards*)calloc(1,
|
||||
sizeof(struct iter_forwards));
|
||||
@@ -215,8 +215,7 @@ read_fwds_addr(struct iter_forwards* fwd, struct config_stub* s,
|
||||
s->name, p->str);
|
||||
return 0;
|
||||
}
|
||||
if(!delegpt_add_addr(dp, fwd->region, &addr, addrlen,
|
||||
0, 0, 1)) {
|
||||
if(!delegpt_add_addr(dp, fwd->region, &addr, addrlen, 0, 0)) {
|
||||
log_err("out of memory");
|
||||
return 0;
|
||||
}
|
||||
|
||||
+1
-1
@@ -89,7 +89,7 @@ struct iter_forward_zone {
|
||||
* Create forwards
|
||||
* @return new forwards or NULL on error.
|
||||
*/
|
||||
struct iter_forwards* forwards_create();
|
||||
struct iter_forwards* forwards_create(void);
|
||||
|
||||
/**
|
||||
* Delete forwards.
|
||||
|
||||
+15
-7
@@ -51,7 +51,7 @@
|
||||
#include "util/data/dname.h"
|
||||
|
||||
struct iter_hints*
|
||||
hints_create()
|
||||
hints_create(void)
|
||||
{
|
||||
struct iter_hints* hints = (struct iter_hints*)calloc(1,
|
||||
sizeof(struct iter_hints));
|
||||
@@ -88,7 +88,7 @@ ah(struct delegpt* dp, struct regional* r, const char* sv, const char* ip)
|
||||
if(!delegpt_add_ns(dp, r, ldns_rdf_data(rdf), 0) ||
|
||||
!extstrtoaddr(ip, &addr, &addrlen) ||
|
||||
!delegpt_add_target(dp, r, ldns_rdf_data(rdf), ldns_rdf_size(rdf),
|
||||
&addr, addrlen, 0, 0, 1)) {
|
||||
&addr, addrlen, 0, 0)) {
|
||||
ldns_rdf_deep_free(rdf);
|
||||
return 0;
|
||||
}
|
||||
@@ -107,7 +107,7 @@ compile_time_root_prime(struct regional* r, int do_ip4, int do_ip6)
|
||||
; on server FTP.INTERNIC.NET
|
||||
; -OR- RS.INTERNIC.NET
|
||||
;
|
||||
; related version of root zone: 2008051300
|
||||
; related version of root zone: 2010061700
|
||||
*/
|
||||
struct delegpt* dp = delegpt_create(r);
|
||||
if(!dp)
|
||||
@@ -132,8 +132,10 @@ compile_time_root_prime(struct regional* r, int do_ip4, int do_ip6)
|
||||
}
|
||||
if(do_ip6) {
|
||||
if(!ah(dp, r, "A.ROOT-SERVERS.NET.", "2001:503:ba3e::2:30")) return 0;
|
||||
if(!ah(dp, r, "D.ROOT-SERVERS.NET.", "2001:500:2d::d")) return 0;
|
||||
if(!ah(dp, r, "F.ROOT-SERVERS.NET.", "2001:500:2f::f")) return 0;
|
||||
if(!ah(dp, r, "H.ROOT-SERVERS.NET.", "2001:500:1::803f:235")) return 0;
|
||||
if(!ah(dp, r, "I.ROOT-SERVERS.NET.", "2001:7fe::53")) return 0;
|
||||
if(!ah(dp, r, "J.ROOT-SERVERS.NET.", "2001:503:c27::2:30")) return 0;
|
||||
if(!ah(dp, r, "K.ROOT-SERVERS.NET.", "2001:7fd::1")) return 0;
|
||||
if(!ah(dp, r, "L.ROOT-SERVERS.NET.", "2001:500:3::42")) return 0;
|
||||
@@ -228,8 +230,7 @@ read_stubs_addr(struct iter_hints* hints, struct config_stub* s,
|
||||
s->name, p->str);
|
||||
return 0;
|
||||
}
|
||||
if(!delegpt_add_addr(dp, hints->region, &addr, addrlen,
|
||||
0, 0, 1)) {
|
||||
if(!delegpt_add_addr(dp, hints->region, &addr, addrlen, 0, 0)) {
|
||||
log_err("out of memory");
|
||||
return 0;
|
||||
}
|
||||
@@ -324,7 +325,7 @@ read_root_hints(struct iter_hints* hints, char* fname)
|
||||
ldns_rdf_data(ldns_rr_owner(rr)),
|
||||
ldns_rdf_size(ldns_rr_owner(rr)),
|
||||
(struct sockaddr_storage*)&sa, len,
|
||||
0, 0, 1)) {
|
||||
0, 0)) {
|
||||
log_err("out of memory reading root hints");
|
||||
goto stop_read;
|
||||
}
|
||||
@@ -340,7 +341,7 @@ read_root_hints(struct iter_hints* hints, char* fname)
|
||||
ldns_rdf_data(ldns_rr_owner(rr)),
|
||||
ldns_rdf_size(ldns_rr_owner(rr)),
|
||||
(struct sockaddr_storage*)&sa, len,
|
||||
0, 0, 1)) {
|
||||
0, 0)) {
|
||||
log_err("out of memory reading root hints");
|
||||
goto stop_read;
|
||||
}
|
||||
@@ -451,6 +452,13 @@ hints_lookup_stub(struct iter_hints* hints, uint8_t* qname,
|
||||
len, labs, qclass);
|
||||
if(!r) return NULL;
|
||||
|
||||
/* If there is no cache (root prime situation) */
|
||||
if(cache_dp == NULL) {
|
||||
if(r->dp->namelabs != 1)
|
||||
return r; /* no cache dp, use any non-root stub */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* If the stub is same as the delegation we got
|
||||
* And has noprime set, we need to 'prime' to use this stub instead.
|
||||
|
||||
@@ -81,7 +81,7 @@ struct iter_hints_stub {
|
||||
* Create hints
|
||||
* @return new hints or NULL on error.
|
||||
*/
|
||||
struct iter_hints* hints_create();
|
||||
struct iter_hints* hints_create(void);
|
||||
|
||||
/**
|
||||
* Delete hints.
|
||||
|
||||
@@ -51,7 +51,7 @@
|
||||
#include "util/net_help.h"
|
||||
#include "util/storage/dnstree.h"
|
||||
|
||||
struct iter_priv* priv_create()
|
||||
struct iter_priv* priv_create(void)
|
||||
{
|
||||
struct iter_priv* priv = (struct iter_priv*)calloc(1, sizeof(*priv));
|
||||
if(!priv)
|
||||
|
||||
@@ -74,7 +74,7 @@ struct iter_priv {
|
||||
* Create priv structure
|
||||
* @return new structure or NULL on error.
|
||||
*/
|
||||
struct iter_priv* priv_create();
|
||||
struct iter_priv* priv_create(void);
|
||||
|
||||
/**
|
||||
* Delete priv structure.
|
||||
|
||||
@@ -141,7 +141,7 @@ response_type_from_server(int rdset,
|
||||
* answer is there directly, our answer is there after
|
||||
* a cname, or there is just a cname. */
|
||||
for(i=0; i<msg->rep->an_numrrsets; i++) {
|
||||
struct ub_packed_rrset_key* s = msg->rep->rrsets[i];
|
||||
s = msg->rep->rrsets[i];
|
||||
|
||||
/* if the answer section has NS rrset, and qtype ANY
|
||||
* and the delegation is lower, and no CNAMEs followed,
|
||||
@@ -225,9 +225,14 @@ response_type_from_server(int rdset,
|
||||
/* Or if a lame server is deployed,
|
||||
* which gives ns==zone delegation from cache
|
||||
* without AA bit as well, with nodata nosoa*/
|
||||
/* real answer must be +AA and SOA RFC(2308),
|
||||
* so this is wrong, and we SERVFAIL it if
|
||||
* this is the only possible reply, if it
|
||||
* is misdeployed the THROWAWAY makes us pick
|
||||
* the next server from the selection */
|
||||
if(msg->rep->an_numrrsets==0 &&
|
||||
!(msg->rep->flags&BIT_AA) && !rdset)
|
||||
return RESPONSE_TYPE_REC_LAME;
|
||||
return RESPONSE_TYPE_THROWAWAY;
|
||||
return RESPONSE_TYPE_ANSWER;
|
||||
}
|
||||
/* If we are getting a referral upwards (or to
|
||||
|
||||
@@ -643,9 +643,9 @@ scrub_sanitize(ldns_buffer* pkt, struct msg_parse* msg,
|
||||
if( (rrset->type == LDNS_RR_TYPE_A ||
|
||||
rrset->type == LDNS_RR_TYPE_AAAA) &&
|
||||
priv_rrset_bad(ie->priv, pkt, rrset)) {
|
||||
/* set servfail, so the classification becomes
|
||||
* THROWAWAY, instead of LAME or other unwanted */
|
||||
FLAGS_SET_RCODE(msg->flags, LDNS_RCODE_SERVFAIL);
|
||||
|
||||
/* do not set servfail since this leads to too
|
||||
* many drops of other people using rfc1918 space */
|
||||
remove_rrset("sanitize: removing public name with "
|
||||
"private address", pkt, msg, prev, &rrset);
|
||||
continue;
|
||||
|
||||
+10
-11
@@ -183,10 +183,12 @@ iter_filter_unsuitable(struct iter_env* iter_env, struct module_env* env,
|
||||
uint8_t* name, size_t namelen, uint16_t qtype, uint32_t now,
|
||||
struct delegpt_addr* a)
|
||||
{
|
||||
int rtt, lame, reclame, dnsseclame, lost;
|
||||
int rtt, lame, reclame, dnsseclame;
|
||||
if(a->bogus)
|
||||
return -1; /* address of server is bogus */
|
||||
if(donotq_lookup(iter_env->donotq, &a->addr, a->addrlen)) {
|
||||
log_addr(VERB_ALGO, "skip addr on the donotquery list",
|
||||
&a->addr, a->addrlen);
|
||||
return -1; /* server is on the donotquery list */
|
||||
}
|
||||
if(!iter_env->supports_ipv6 && addr_is_ip6(&a->addr, a->addrlen)) {
|
||||
@@ -195,19 +197,18 @@ iter_filter_unsuitable(struct iter_env* iter_env, struct module_env* env,
|
||||
/* check lameness - need zone , class info */
|
||||
if(infra_get_lame_rtt(env->infra_cache, &a->addr, a->addrlen,
|
||||
name, namelen, qtype, &lame, &dnsseclame, &reclame,
|
||||
&rtt, &lost, now)) {
|
||||
&rtt, now)) {
|
||||
log_addr(VERB_ALGO, "servselect", &a->addr, a->addrlen);
|
||||
verbose(VERB_ALGO, " rtt=%d lost=%d%s%s%s%s", rtt, lost,
|
||||
verbose(VERB_ALGO, " rtt=%d%s%s%s%s", rtt,
|
||||
lame?" LAME":"",
|
||||
dnsseclame?" DNSSEC_LAME":"",
|
||||
reclame?" REC_LAME":"",
|
||||
a->lame?" ADDR_LAME":"");
|
||||
if(lame)
|
||||
return -1; /* server is lame */
|
||||
else if(rtt >= USEFUL_SERVER_TOP_TIMEOUT &&
|
||||
lost >= USEFUL_SERVER_MAX_LOST)
|
||||
/* server is unresponsive, but keep trying slowly */
|
||||
return USEFUL_SERVER_TOP_TIMEOUT+1;
|
||||
else if(rtt >= USEFUL_SERVER_TOP_TIMEOUT)
|
||||
/* server is unresponsive */
|
||||
return USEFUL_SERVER_TOP_TIMEOUT;
|
||||
/* select remainder from worst to best */
|
||||
else if(reclame)
|
||||
return rtt+USEFUL_SERVER_TOP_TIMEOUT*3; /* nonpref */
|
||||
@@ -215,8 +216,6 @@ iter_filter_unsuitable(struct iter_env* iter_env, struct module_env* env,
|
||||
return rtt+USEFUL_SERVER_TOP_TIMEOUT*2; /* nonpref */
|
||||
else if(a->lame)
|
||||
return rtt+USEFUL_SERVER_TOP_TIMEOUT+1; /* nonpref */
|
||||
else if(rtt >= USEFUL_SERVER_TOP_TIMEOUT) /* not blacklisted*/
|
||||
return USEFUL_SERVER_TOP_TIMEOUT+1;
|
||||
else return rtt;
|
||||
}
|
||||
/* no server information present */
|
||||
@@ -850,7 +849,7 @@ int iter_lookup_parent_glue_from_cache(struct module_env* env,
|
||||
log_rrset_key(VERB_ALGO, "found parent-side", akey);
|
||||
ns->done_pside4 = 1;
|
||||
/* a negative-cache-element has no addresses it adds */
|
||||
if(!delegpt_add_rrset_A(dp, region, akey, 1, 1))
|
||||
if(!delegpt_add_rrset_A(dp, region, akey, 1))
|
||||
log_err("malloc failure in lookup_parent_glue");
|
||||
lock_rw_unlock(&akey->entry.lock);
|
||||
}
|
||||
@@ -862,7 +861,7 @@ int iter_lookup_parent_glue_from_cache(struct module_env* env,
|
||||
log_rrset_key(VERB_ALGO, "found parent-side", akey);
|
||||
ns->done_pside6 = 1;
|
||||
/* a negative-cache-element has no addresses it adds */
|
||||
if(!delegpt_add_rrset_AAAA(dp, region, akey, 1, 1))
|
||||
if(!delegpt_add_rrset_AAAA(dp, region, akey, 1))
|
||||
log_err("malloc failure in lookup_parent_glue");
|
||||
lock_rw_unlock(&akey->entry.lock);
|
||||
}
|
||||
|
||||
@@ -159,6 +159,7 @@ void iter_mark_pside_cycle_targets(struct module_qstate* qstate,
|
||||
* @param qinfo: query name and type
|
||||
* @param qflags: query flags with RD flag
|
||||
* @param dp: delegpt to check.
|
||||
* @return true if dp is useless.
|
||||
*/
|
||||
int iter_dp_is_useless(struct query_info* qinfo, uint16_t qflags,
|
||||
struct delegpt* dp);
|
||||
|
||||
+47
-20
@@ -323,11 +323,8 @@ iter_prepend(struct iter_qstate* iq, struct dns_msg* msg,
|
||||
(msg->rep->ns_numrrsets + msg->rep->ar_numrrsets) *
|
||||
sizeof(struct ub_packed_rrset_key*));
|
||||
|
||||
/* if the rcode was NXDOMAIN, and we prepended DNAME/CNAMEs, then
|
||||
* it should now be NOERROR. */
|
||||
if(FLAGS_GET_RCODE(msg->rep->flags) == LDNS_RCODE_NXDOMAIN) {
|
||||
FLAGS_SET_RCODE(msg->rep->flags, LDNS_RCODE_NOERROR);
|
||||
}
|
||||
/* NXDOMAIN rcode can stay if we prepended DNAME/CNAMEs, because
|
||||
* this is what recursors should give. */
|
||||
msg->rep->rrset_count += num_an + num_ns;
|
||||
msg->rep->an_numrrsets += num_an;
|
||||
msg->rep->ns_numrrsets += num_ns;
|
||||
@@ -463,8 +460,7 @@ handle_cname_response(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||
* @param initial_state The initial response state (normally this
|
||||
* is QUERY_RESP_STATE, unless it is known that the request won't
|
||||
* need iterative processing
|
||||
* @param final_state The final state for the response to this
|
||||
* request.
|
||||
* @param finalstate The final state for the response to this request.
|
||||
* @param subq_ret: if newly allocated, the subquerystate, or NULL if it does
|
||||
* not need initialisation.
|
||||
* @param v: if true, validation is done on the subquery.
|
||||
@@ -474,13 +470,13 @@ static int
|
||||
generate_sub_request(uint8_t* qname, size_t qnamelen, uint16_t qtype,
|
||||
uint16_t qclass, struct module_qstate* qstate, int id,
|
||||
struct iter_qstate* iq, enum iter_state initial_state,
|
||||
enum iter_state final_state, struct module_qstate** subq_ret, int v)
|
||||
enum iter_state finalstate, struct module_qstate** subq_ret, int v)
|
||||
{
|
||||
struct module_qstate* subq = NULL;
|
||||
struct iter_qstate* subiq = NULL;
|
||||
uint16_t qflags = 0; /* OPCODE QUERY, no flags */
|
||||
struct query_info qinf;
|
||||
int prime = (final_state == PRIME_RESP_STATE)?1:0;
|
||||
int prime = (finalstate == PRIME_RESP_STATE)?1:0;
|
||||
qinf.qname = qname;
|
||||
qinf.qname_len = qnamelen;
|
||||
qinf.qtype = qtype;
|
||||
@@ -523,7 +519,7 @@ generate_sub_request(uint8_t* qname, size_t qnamelen, uint16_t qtype,
|
||||
subiq->depth = iq->depth+1;
|
||||
outbound_list_init(&subiq->outlist);
|
||||
subiq->state = initial_state;
|
||||
subiq->final_state = final_state;
|
||||
subiq->final_state = finalstate;
|
||||
subiq->qchase = subq->qinfo;
|
||||
subiq->chase_flags = subq->query_flags;
|
||||
subiq->refetch_glue = 0;
|
||||
@@ -538,6 +534,7 @@ generate_sub_request(uint8_t* qname, size_t qnamelen, uint16_t qtype,
|
||||
* @param ie: iterator global state.
|
||||
* @param id: module id.
|
||||
* @param qclass: the class to prime.
|
||||
* @return 0 on failure
|
||||
*/
|
||||
static int
|
||||
prime_root(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||
@@ -597,6 +594,8 @@ prime_root(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||
* @param q: request name.
|
||||
* @return true if a priming subrequest was made, false if not. The will only
|
||||
* issue a priming request if it detects an unprimed stub.
|
||||
* Uses value of 2 to signal during stub-prime in root-prime situation
|
||||
* that a noprime-stub is available and resolution can continue.
|
||||
*/
|
||||
static int
|
||||
prime_stub(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||
@@ -622,6 +621,8 @@ prime_stub(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||
|
||||
/* is it a noprime stub (always use) */
|
||||
if(stub->noprime) {
|
||||
int r = 0;
|
||||
if(iq->dp == NULL) r = 2;
|
||||
/* copy the dp out of the fixed hints structure, so that
|
||||
* it can be changed when servicing this query */
|
||||
iq->dp = delegpt_copy(stub_dp, qstate->region);
|
||||
@@ -632,7 +633,7 @@ prime_stub(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||
}
|
||||
log_nametypeclass(VERB_DETAIL, "use stub", stub_dp->name,
|
||||
LDNS_RR_TYPE_NS, q->qclass);
|
||||
return 0;
|
||||
return r;
|
||||
}
|
||||
|
||||
/* Otherwise, we need to (re)prime the stub. */
|
||||
@@ -937,8 +938,13 @@ processInitRequest(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||
msg = val_neg_getmsg(qstate->env->neg_cache, &iq->qchase,
|
||||
qstate->region, qstate->env->rrset_cache,
|
||||
qstate->env->scratch_buffer,
|
||||
*qstate->env->now, 1/*add SOA*/);
|
||||
*qstate->env->now, 1/*add SOA*/, NULL);
|
||||
}
|
||||
/* item taken from cache does not match our query name, thus
|
||||
* security needs to be re-examined later */
|
||||
if(msg && query_dname_compare(qstate->qinfo.qname,
|
||||
iq->qchase.qname) != 0)
|
||||
msg->rep->security = sec_status_unchecked;
|
||||
}
|
||||
if(msg) {
|
||||
/* handle positive cache response */
|
||||
@@ -1012,10 +1018,16 @@ processInitRequest(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||
delname = iq->qchase.qname;
|
||||
delnamelen = iq->qchase.qname_len;
|
||||
}
|
||||
if(iq->qchase.qtype == LDNS_RR_TYPE_DS || iq->refetch_glue) {
|
||||
if(iq->qchase.qtype == LDNS_RR_TYPE_DS || iq->refetch_glue ||
|
||||
(iq->qchase.qtype == LDNS_RR_TYPE_NS && qstate->prefetch_leeway)) {
|
||||
/* remove first label from delname, root goes to hints,
|
||||
* but only to fetch glue, not for qtype=DS. */
|
||||
if(dname_is_root(delname) && iq->refetch_glue)
|
||||
/* also when prefetching an NS record, fetch it again from
|
||||
* its parent, just as if it expired, so that you do not
|
||||
* get stuck on an older nameserver that gives old NSrecords */
|
||||
if(dname_is_root(delname) && (iq->refetch_glue ||
|
||||
(iq->qchase.qtype == LDNS_RR_TYPE_NS &&
|
||||
qstate->prefetch_leeway)))
|
||||
delname = NULL; /* go to root priming */
|
||||
else dname_remove_label(&delname, &delnamelen);
|
||||
iq->refetch_glue = 0; /* if CNAME causes restart, no refetch */
|
||||
@@ -1034,6 +1046,12 @@ processInitRequest(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||
/* If the cache has returned nothing, then we have a
|
||||
* root priming situation. */
|
||||
if(iq->dp == NULL) {
|
||||
/* if there is a stub, then no root prime needed */
|
||||
int r = prime_stub(qstate, iq, ie, id, &iq->qchase);
|
||||
if(r == 2)
|
||||
break; /* got noprime-stub-zone, continue */
|
||||
else if(r)
|
||||
return 0; /* stub prime request made */
|
||||
if(forwards_lookup_root(qstate->env->fwds,
|
||||
iq->qchase.qclass)) {
|
||||
/* forward zone root, no root prime needed */
|
||||
@@ -1303,6 +1321,9 @@ query_for_targets(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||
int missing;
|
||||
int toget = 0;
|
||||
|
||||
if(iq->depth == ie->max_dependency_depth)
|
||||
return 0;
|
||||
|
||||
iter_mark_cycle_targets(qstate, iq->dp);
|
||||
missing = (int)delegpt_count_missing_targets(iq->dp);
|
||||
log_assert(maxtargets != 0); /* that would not be useful */
|
||||
@@ -1400,8 +1421,7 @@ processLastResort(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||
/* if: malloc failure in lookup go up to try */
|
||||
/* if: no parent NS in cache - go up one level */
|
||||
verbose(VERB_ALGO, "try to grab parent NS");
|
||||
iq->store_parent_NS = 1;
|
||||
iq->parent_NS_old_dp = iq->dp;
|
||||
iq->store_parent_NS = iq->dp;
|
||||
iq->deleg_msg = NULL;
|
||||
iq->refetch_glue = 1;
|
||||
iq->query_restart_count++;
|
||||
@@ -1436,6 +1456,10 @@ processLastResort(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||
return 0; /* and wait for them */
|
||||
}
|
||||
}
|
||||
if(iq->depth == ie->max_dependency_depth) {
|
||||
verbose(VERB_QUERY, "maxdepth and need more nameservers, fail");
|
||||
return error_response_cache(qstate, id, LDNS_RCODE_SERVFAIL);
|
||||
}
|
||||
/* mark cycle targets for parent-side lookups */
|
||||
iter_mark_pside_cycle_targets(qstate, iq->dp);
|
||||
/* see if we can issue queries to get nameserver addresses */
|
||||
@@ -1865,8 +1889,8 @@ processQueryResponse(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||
qstate->region, iq->dp))
|
||||
return error_response(qstate, id, LDNS_RCODE_SERVFAIL);
|
||||
if(iq->store_parent_NS && query_dname_compare(iq->dp->name,
|
||||
iq->parent_NS_old_dp->name) == 0)
|
||||
iter_merge_retry_counts(iq->dp, iq->parent_NS_old_dp);
|
||||
iq->store_parent_NS->name) == 0)
|
||||
iter_merge_retry_counts(iq->dp, iq->store_parent_NS);
|
||||
delegpt_log(VERB_ALGO, iq->dp);
|
||||
/* Count this as a referral. */
|
||||
iq->referral_count++;
|
||||
@@ -2385,6 +2409,8 @@ processFinished(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||
}
|
||||
/* reset the query name back */
|
||||
iq->response->qinfo = qstate->qinfo;
|
||||
/* the security state depends on the combination */
|
||||
iq->response->rep->security = sec_status_unchecked;
|
||||
/* store message with the finished prepended items,
|
||||
* but only if we did recursion. The nonrecursion referral
|
||||
* from cache does not need to be stored in the msg cache. */
|
||||
@@ -2660,7 +2686,8 @@ iter_get_mem(struct module_env* env, int id)
|
||||
if(!ie)
|
||||
return 0;
|
||||
return sizeof(*ie) + sizeof(int)*((size_t)ie->max_dependency_depth+1)
|
||||
+ hints_get_mem(ie->hints) + donotq_get_mem(ie->donotq);
|
||||
+ hints_get_mem(ie->hints) + donotq_get_mem(ie->donotq)
|
||||
+ priv_get_mem(ie->priv);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2673,7 +2700,7 @@ static struct module_func_block iter_block = {
|
||||
};
|
||||
|
||||
struct module_func_block*
|
||||
iter_get_funcblock()
|
||||
iter_get_funcblock(void)
|
||||
{
|
||||
return &iter_block;
|
||||
}
|
||||
|
||||
+7
-5
@@ -55,7 +55,7 @@ struct iter_priv;
|
||||
/** max number of query restarts. Determines max number of CNAME chain. */
|
||||
#define MAX_RESTART_COUNT 8
|
||||
/** max number of referrals. Makes sure resolver does not run away */
|
||||
#define MAX_REFERRAL_COUNT 30
|
||||
#define MAX_REFERRAL_COUNT 130
|
||||
/** how nice is a server without further information, in msec
|
||||
* Equals rtt initial timeout value.
|
||||
*/
|
||||
@@ -75,6 +75,8 @@ struct iter_priv;
|
||||
* Chosen so that the UNKNOWN_SERVER_NICENESS falls within the band of a
|
||||
* fast server, this causes server exploration as a side benefit. msec. */
|
||||
#define RTT_BAND 400
|
||||
/** Start value for blacklisting a host, 2*USEFUL_SERVER_TOP_TIMEOUT in sec */
|
||||
#define INFRA_BACKOFF_INITIAL 240
|
||||
|
||||
/**
|
||||
* Global state for the iterator.
|
||||
@@ -250,10 +252,10 @@ struct iter_qstate {
|
||||
/**
|
||||
* The query must store NS records from referrals as parentside RRs
|
||||
* Enabled once it hits resolution problems, to throttle retries.
|
||||
* If enabled it is the pointer to the old delegation point with
|
||||
* the old retry counts for bad-nameserver-addresses.
|
||||
*/
|
||||
int store_parent_NS;
|
||||
/** the old delegation point with retry counts */
|
||||
struct delegpt* parent_NS_old_dp;
|
||||
struct delegpt* store_parent_NS;
|
||||
|
||||
/**
|
||||
* The query is for parent-side glue(A or AAAA) for a nameserver.
|
||||
@@ -314,7 +316,7 @@ struct iter_prep_list {
|
||||
* Get the iterator function block.
|
||||
* @return: function block with function pointers to iterator methods.
|
||||
*/
|
||||
struct module_func_block* iter_get_funcblock();
|
||||
struct module_func_block* iter_get_funcblock(void);
|
||||
|
||||
/**
|
||||
* Get iterator state as a string
|
||||
|
||||
Binary file not shown.
@@ -67,7 +67,7 @@
|
||||
#endif /* UB_ON_WINDOWS */
|
||||
|
||||
struct ub_ctx*
|
||||
ub_ctx_create()
|
||||
ub_ctx_create(void)
|
||||
{
|
||||
struct ub_ctx* ctx;
|
||||
unsigned int seed;
|
||||
|
||||
@@ -185,7 +185,6 @@ libworker_setup(struct ub_ctx* ctx, int is_bg)
|
||||
libworker_delete(w);
|
||||
return NULL;
|
||||
}
|
||||
w->env->send_packet = &libworker_send_packet;
|
||||
w->env->send_query = &libworker_send_query;
|
||||
w->env->detach_subs = &mesh_detach_subs;
|
||||
w->env->attach_sub = &mesh_attach_sub;
|
||||
@@ -671,18 +670,6 @@ void libworker_alloc_cleanup(void* arg)
|
||||
slabhash_clear(w->env->msg_cache);
|
||||
}
|
||||
|
||||
int libworker_send_packet(ldns_buffer* pkt, struct sockaddr_storage* addr,
|
||||
socklen_t addrlen, int timeout, struct module_qstate* q, int use_tcp)
|
||||
{
|
||||
struct libworker* w = (struct libworker*)q->env->worker;
|
||||
if(use_tcp) {
|
||||
return pending_tcp_query(w->back, pkt, addr, addrlen,
|
||||
timeout, libworker_handle_reply, q) != 0;
|
||||
}
|
||||
return pending_udp_query(w->back, pkt, addr, addrlen,
|
||||
timeout*1000, libworker_handle_reply, q) != 0;
|
||||
}
|
||||
|
||||
/** compare outbound entry qstates */
|
||||
static int
|
||||
outbound_entry_compare(void* a, void* b)
|
||||
@@ -823,15 +810,6 @@ void worker_sighandler(int ATTR_UNUSED(sig), void* ATTR_UNUSED(arg))
|
||||
log_assert(0);
|
||||
}
|
||||
|
||||
int worker_send_packet(ldns_buffer* ATTR_UNUSED(pkt),
|
||||
struct sockaddr_storage* ATTR_UNUSED(addr),
|
||||
socklen_t ATTR_UNUSED(addrlen), int ATTR_UNUSED(timeout),
|
||||
struct module_qstate* ATTR_UNUSED(q), int ATTR_UNUSED(use_tcp))
|
||||
{
|
||||
log_assert(0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct outbound_entry* worker_send_query(uint8_t* ATTR_UNUSED(qname),
|
||||
size_t ATTR_UNUSED(qnamelen), uint16_t ATTR_UNUSED(qtype),
|
||||
uint16_t ATTR_UNUSED(qclass), uint16_t ATTR_UNUSED(flags),
|
||||
|
||||
@@ -107,20 +107,6 @@ int libworker_fg(struct ub_ctx* ctx, struct ctx_query* q);
|
||||
/** cleanup the cache to remove all rrset IDs from it, arg is libworker */
|
||||
void libworker_alloc_cleanup(void* arg);
|
||||
|
||||
/**
|
||||
* Worker service routine to send udp messages for modules.
|
||||
* @param pkt: packet to send.
|
||||
* @param addr: where to.
|
||||
* @param addrlen: length of addr.
|
||||
* @param timeout: seconds to wait until timeout.
|
||||
* @param q: wich query state to reactivate upon return.
|
||||
* @param use_tcp: true to use TCP, false for UDP.
|
||||
* @return: false on failure (memory or socket related). no query was
|
||||
* sent.
|
||||
*/
|
||||
int libworker_send_packet(ldns_buffer* pkt, struct sockaddr_storage* addr,
|
||||
socklen_t addrlen, int timeout, struct module_qstate* q, int use_tcp);
|
||||
|
||||
/**
|
||||
* Worker service routine to send serviced queries to authoritative servers.
|
||||
* @param qname: query name. (host order)
|
||||
|
||||
@@ -93,6 +93,10 @@
|
||||
#ifndef _UB_UNBOUND_H
|
||||
#define _UB_UNBOUND_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* The validation context is created to hold the resolver status,
|
||||
* validation keys and a small cache (containing messages, rrsets,
|
||||
@@ -539,4 +543,8 @@ int ub_ctx_data_add(struct ub_ctx* ctx, char *data);
|
||||
*/
|
||||
int ub_ctx_data_remove(struct ub_ctx* ctx, char *data);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _UB_UNBOUND_H */
|
||||
|
||||
+60
-5
@@ -54,6 +54,8 @@ Generate a distribution tar file for unbound.
|
||||
-d SVN_root Retrieve the unbound source from the specified repository.
|
||||
Detected from svn working copy if not specified.
|
||||
-l ldnsdir Directory where ldns resides. Detected from Makefile.
|
||||
-wssl openssl.xx.tar.gz Also build openssl from tarball for windows dist.
|
||||
-wxp expat.xx.tar.gz Also build expat from tarball for windows dist.
|
||||
-w ... Build windows binary dist. last args passed to configure.
|
||||
EOF
|
||||
exit 1
|
||||
@@ -133,6 +135,8 @@ SNAPSHOT="no"
|
||||
RC="no"
|
||||
LDNSDIR=""
|
||||
DOWIN="no"
|
||||
WINSSL=""
|
||||
WINEXPAT=""
|
||||
|
||||
# Parse the command line arguments.
|
||||
while [ "$1" ]; do
|
||||
@@ -147,6 +151,14 @@ while [ "$1" ]; do
|
||||
"-s")
|
||||
SNAPSHOT="yes"
|
||||
;;
|
||||
"-wssl")
|
||||
WINSSL="$2"
|
||||
shift
|
||||
;;
|
||||
"-wxp")
|
||||
WINEXPAT="$2"
|
||||
shift
|
||||
;;
|
||||
"-w")
|
||||
DOWIN="yes"
|
||||
shift
|
||||
@@ -168,16 +180,56 @@ while [ "$1" ]; do
|
||||
done
|
||||
|
||||
if [ "$DOWIN" = "yes" ]; then
|
||||
# detect crosscompile, from Fedora11 at this point.
|
||||
# detect crosscompile, from Fedora13 at this point.
|
||||
if test "`uname`" = "Linux"; then
|
||||
info "Crosscompile windows dist"
|
||||
cross="yes"
|
||||
configure="mingw32-configure"
|
||||
strip="i686-pc-mingw32-strip"
|
||||
makensis="makensis" # from mingw32-nsis package
|
||||
# in crosscompile no installed ldns, use builtin (not linux-ldns)
|
||||
cross_flag="--with-ldns-builtin"
|
||||
|
||||
check_svn_root
|
||||
create_temp_dir
|
||||
|
||||
# crosscompile openssl for windows.
|
||||
if test -n "$WINSSL"; then
|
||||
info "Cross compile $WINSSL"
|
||||
info "winssl tar unpack"
|
||||
(cd ..; gzip -cd $WINSSL) | tar xf - || error_cleanup "tar unpack of $WINSSL failed"
|
||||
sslinstall="`pwd`/sslinstall"
|
||||
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
|
||||
sslflags="no-asm --cross-compile-prefix=i686-pc-mingw32- -DOPENSSL_NO_CAPIENG mingw"
|
||||
info "winssl: Configure $sslflags"
|
||||
./Configure --prefix="$sslinstall" $sslflags || error_cleanup "OpenSSL Configure failed"
|
||||
info "winssl: make"
|
||||
make || 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 ..
|
||||
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"
|
||||
wxpinstall="`pwd`/wxpinstall"
|
||||
cd expat-* || error_cleanup "no expat-X dir in tarball"
|
||||
info "wxp: configure"
|
||||
mingw32-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 installlib"
|
||||
make installlib || error_cleanup "libexpat install failed"
|
||||
cross_flag="$cross_flag --with-libexpat=$wxpinstall"
|
||||
cd ..
|
||||
fi
|
||||
|
||||
info "Exporting source from SVN."
|
||||
svn export "$SVNROOT" unbound || error_cleanup "SVN command failed"
|
||||
cd unbound || error_cleanup "Unbound not exported correctly from SVN"
|
||||
@@ -186,6 +238,7 @@ if [ "$DOWIN" = "yes" ]; then
|
||||
if test -f mingw32-config.cache; then rm mingw32-config.cache; fi
|
||||
else
|
||||
cross="no" # mingw and msys
|
||||
cross_flag=""
|
||||
configure="./configure"
|
||||
strip="strip"
|
||||
makensis="c:/Program Files/NSIS/makensis.exe" # http://nsis.sf.net
|
||||
@@ -213,8 +266,8 @@ if [ "$DOWIN" = "yes" ]; then
|
||||
# procedure for making unbound installer on mingw.
|
||||
info "Creating windows dist unbound $version"
|
||||
info "Calling configure"
|
||||
echo "$configure"' --enable-debug --enable-static-exe '"$*"
|
||||
$configure --enable-debug --enable-static-exe $* \
|
||||
echo "$configure"' --enable-debug --enable-static-exe '"$* $cross_flag"
|
||||
$configure --enable-debug --enable-static-exe $* $cross_flag \
|
||||
|| error_cleanup "Could not configure"
|
||||
info "Calling make"
|
||||
make || error_cleanup "Could not make"
|
||||
@@ -229,14 +282,15 @@ if [ "$DOWIN" = "yes" ]; then
|
||||
$strip anchor-update.exe
|
||||
$strip unbound-control.exe
|
||||
$strip unbound-host.exe
|
||||
$strip unbound-anchor.exe
|
||||
$strip unbound-checkconf.exe
|
||||
$strip unbound-service-install.exe
|
||||
$strip unbound-service-remove.exe
|
||||
cd tmp.$$
|
||||
cp ../doc/example.conf example.conf
|
||||
cp ../unbound.exe ../unbound-host.exe ../unbound-control.exe ../unbound-checkconf.exe ../unbound-service-install.exe ../unbound-service-remove.exe ../LICENSE ../winrc/unbound-website.url ../winrc/service.conf ../winrc/README.txt .
|
||||
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-website.url ../winrc/service.conf ../winrc/README.txt .
|
||||
# zipfile
|
||||
zip ../$file LICENSE README.txt unbound.exe unbound-host.exe unbound-control.exe unbound-checkconf.exe unbound-service-install.exe unbound-service-remove.exe example.conf service.conf unbound-website.url
|
||||
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 example.conf service.conf unbound-website.url
|
||||
info "Testing $file"
|
||||
(cd .. ; zip -T $file )
|
||||
# installer
|
||||
@@ -354,6 +408,7 @@ replace_all doc/unbound.8.in
|
||||
replace_all doc/unbound.conf.5.in
|
||||
replace_all doc/unbound-checkconf.8.in
|
||||
replace_all doc/unbound-control.8.in
|
||||
replace_all doc/unbound-anchor.8.in
|
||||
replace_all doc/unbound-host.1
|
||||
replace_all doc/libunbound.3.in
|
||||
|
||||
|
||||
@@ -375,7 +375,7 @@ static struct module_func_block pythonmod_block = {
|
||||
&pythonmod_clear, &pythonmod_get_mem
|
||||
};
|
||||
|
||||
struct module_func_block* pythonmod_get_funcblock()
|
||||
struct module_func_block* pythonmod_get_funcblock(void)
|
||||
{
|
||||
return &pythonmod_block;
|
||||
}
|
||||
|
||||
@@ -46,7 +46,7 @@
|
||||
* Get the module function block.
|
||||
* @return: function block with function pointers to module methods.
|
||||
*/
|
||||
struct module_func_block* pythonmod_get_funcblock();
|
||||
struct module_func_block* pythonmod_get_funcblock(void);
|
||||
|
||||
/** python module init */
|
||||
int pythonmod_init(struct module_env* env, int id);
|
||||
|
||||
@@ -74,6 +74,7 @@ void invalidateQueryInCache(struct module_qstate* qstate, struct query_info* qin
|
||||
*
|
||||
* @param qstate: module environment
|
||||
* @param pkt: a ldns_buffer which contains ldns_packet data
|
||||
* @return 0 on failure, out of memory or parse error.
|
||||
*/
|
||||
int createResponse(struct module_qstate* qstate, ldns_buffer* pkt);
|
||||
|
||||
|
||||
Vendored
+41
-11
@@ -49,6 +49,7 @@
|
||||
#include "util/module.h"
|
||||
#include "util/net_help.h"
|
||||
#include "util/regional.h"
|
||||
#include "util/config_file.h"
|
||||
|
||||
/** store rrsets in the rrset cache.
|
||||
* @param env: module environment with caches.
|
||||
@@ -180,7 +181,7 @@ find_add_addrs(struct module_env* env, uint16_t qclass,
|
||||
akey = rrset_cache_lookup(env->rrset_cache, ns->name,
|
||||
ns->namelen, LDNS_RR_TYPE_A, qclass, 0, now, 0);
|
||||
if(akey) {
|
||||
if(!delegpt_add_rrset_A(dp, region, akey, 0, 0)) {
|
||||
if(!delegpt_add_rrset_A(dp, region, akey, 0)) {
|
||||
lock_rw_unlock(&akey->entry.lock);
|
||||
return 0;
|
||||
}
|
||||
@@ -198,7 +199,7 @@ find_add_addrs(struct module_env* env, uint16_t qclass,
|
||||
akey = rrset_cache_lookup(env->rrset_cache, ns->name,
|
||||
ns->namelen, LDNS_RR_TYPE_AAAA, qclass, 0, now, 0);
|
||||
if(akey) {
|
||||
if(!delegpt_add_rrset_AAAA(dp, region, akey, 0, 0)) {
|
||||
if(!delegpt_add_rrset_AAAA(dp, region, akey, 0)) {
|
||||
lock_rw_unlock(&akey->entry.lock);
|
||||
return 0;
|
||||
}
|
||||
@@ -230,7 +231,7 @@ cache_fill_missing(struct module_env* env, uint16_t qclass,
|
||||
akey = rrset_cache_lookup(env->rrset_cache, ns->name,
|
||||
ns->namelen, LDNS_RR_TYPE_A, qclass, 0, now, 0);
|
||||
if(akey) {
|
||||
if(!delegpt_add_rrset_A(dp, region, akey, (int)ns->lame, 1)) {
|
||||
if(!delegpt_add_rrset_A(dp, region, akey, (int)ns->lame)) {
|
||||
lock_rw_unlock(&akey->entry.lock);
|
||||
return 0;
|
||||
}
|
||||
@@ -248,7 +249,7 @@ cache_fill_missing(struct module_env* env, uint16_t qclass,
|
||||
akey = rrset_cache_lookup(env->rrset_cache, ns->name,
|
||||
ns->namelen, LDNS_RR_TYPE_AAAA, qclass, 0, now, 0);
|
||||
if(akey) {
|
||||
if(!delegpt_add_rrset_AAAA(dp, region, akey, (int)ns->lame, 1)) {
|
||||
if(!delegpt_add_rrset_AAAA(dp, region, akey, (int)ns->lame)) {
|
||||
lock_rw_unlock(&akey->entry.lock);
|
||||
return 0;
|
||||
}
|
||||
@@ -417,22 +418,22 @@ gen_dns_msg(struct regional* region, struct query_info* q, size_t num)
|
||||
|
||||
/** generate dns_msg from cached message */
|
||||
static struct dns_msg*
|
||||
tomsg(struct module_env* env, struct msgreply_entry* e, struct reply_info* r,
|
||||
tomsg(struct module_env* env, struct query_info* q, struct reply_info* r,
|
||||
struct regional* region, uint32_t now, struct regional* scratch)
|
||||
{
|
||||
struct dns_msg* msg;
|
||||
size_t i;
|
||||
if(now > r->ttl)
|
||||
return NULL;
|
||||
msg = gen_dns_msg(region, &e->key, r->rrset_count);
|
||||
msg = gen_dns_msg(region, q, r->rrset_count);
|
||||
if(!msg)
|
||||
return NULL;
|
||||
msg->rep->flags = r->flags;
|
||||
msg->rep->qdcount = r->qdcount;
|
||||
msg->rep->ttl = r->ttl - now;
|
||||
if(r->prefetch_ttl - now > 0)
|
||||
if(r->prefetch_ttl > now)
|
||||
msg->rep->prefetch_ttl = r->prefetch_ttl - now;
|
||||
else msg->rep->prefetch_ttl = PREFETCH_TTL_CALC(r->prefetch_ttl);
|
||||
else msg->rep->prefetch_ttl = PREFETCH_TTL_CALC(msg->rep->ttl);
|
||||
msg->rep->security = r->security;
|
||||
msg->rep->an_numrrsets = r->an_numrrsets;
|
||||
msg->rep->ns_numrrsets = r->ns_numrrsets;
|
||||
@@ -606,7 +607,7 @@ dns_cache_lookup(struct module_env* env,
|
||||
if(e) {
|
||||
struct msgreply_entry* key = (struct msgreply_entry*)e->key;
|
||||
struct reply_info* data = (struct reply_info*)e->data;
|
||||
struct dns_msg* msg = tomsg(env, key, data, region, now,
|
||||
struct dns_msg* msg = tomsg(env, &key->key, data, region, now,
|
||||
scratch);
|
||||
if(msg) {
|
||||
lock_rw_unlock(&e->lock);
|
||||
@@ -630,8 +631,10 @@ dns_cache_lookup(struct module_env* env,
|
||||
lock_rw_unlock(&rrset->entry.lock);
|
||||
}
|
||||
|
||||
/* see if we have CNAME for this domain */
|
||||
if( (rrset=rrset_cache_lookup(env->rrset_cache, qname, qnamelen,
|
||||
/* see if we have CNAME for this domain,
|
||||
* but not for DS records (which are part of the parent) */
|
||||
if( qtype != LDNS_RR_TYPE_DS &&
|
||||
(rrset=rrset_cache_lookup(env->rrset_cache, qname, qnamelen,
|
||||
LDNS_RR_TYPE_CNAME, qclass, 0, now, 0))) {
|
||||
struct dns_msg* msg = rrset_msg(rrset, region, now, &k);
|
||||
if(msg) {
|
||||
@@ -668,6 +671,33 @@ dns_cache_lookup(struct module_env* env,
|
||||
}
|
||||
lock_rw_unlock(&rrset->entry.lock);
|
||||
}
|
||||
|
||||
/* stop downwards cache search on NXDOMAIN.
|
||||
* Empty nonterminals are NOERROR, so an NXDOMAIN for foo
|
||||
* means bla.foo also does not exist. The DNSSEC proofs are
|
||||
* the same. We search upwards for NXDOMAINs. */
|
||||
if(env->cfg->harden_below_nxdomain)
|
||||
while(!dname_is_root(k.qname)) {
|
||||
dname_remove_label(&k.qname, &k.qname_len);
|
||||
h = query_info_hash(&k);
|
||||
e = slabhash_lookup(env->msg_cache, h, &k, 0);
|
||||
if(e) {
|
||||
struct reply_info* data = (struct reply_info*)e->data;
|
||||
struct dns_msg* msg;
|
||||
if(FLAGS_GET_RCODE(data->flags) == LDNS_RCODE_NXDOMAIN
|
||||
&& data->security == sec_status_secure
|
||||
&& (msg=tomsg(env, &k, data, region, now, scratch))){
|
||||
lock_rw_unlock(&e->lock);
|
||||
msg->qinfo.qname=qname;
|
||||
msg->qinfo.qname_len=qnamelen;
|
||||
/* check that DNSSEC really works out */
|
||||
msg->rep->security = sec_status_unchecked;
|
||||
return msg;
|
||||
}
|
||||
lock_rw_unlock(&e->lock);
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
Vendored
+82
-9
@@ -47,6 +47,10 @@
|
||||
#include "util/log.h"
|
||||
#include "util/net_help.h"
|
||||
#include "util/config_file.h"
|
||||
#include "iterator/iterator.h"
|
||||
|
||||
/** Timeout when only a single probe query per IP is allowed. */
|
||||
#define PROBE_MAXRTO 12000 /* in msec */
|
||||
|
||||
size_t
|
||||
infra_host_sizefunc(void* k, void* ATTR_UNUSED(d))
|
||||
@@ -101,6 +105,7 @@ infra_create(struct config_file* cfg)
|
||||
infra->host_ttl = cfg->host_ttl;
|
||||
infra->lame_ttl = cfg->lame_ttl;
|
||||
infra->max_lame_size = cfg->infra_cache_lame_size;
|
||||
infra->jostle = cfg->jostle_time;
|
||||
return infra;
|
||||
}
|
||||
|
||||
@@ -122,6 +127,7 @@ infra_adjust(struct infra_cache* infra, struct config_file* cfg)
|
||||
infra->host_ttl = cfg->host_ttl;
|
||||
infra->lame_ttl = cfg->lame_ttl;
|
||||
infra->max_lame_size = cfg->infra_cache_lame_size;
|
||||
infra->jostle = cfg->jostle_time;
|
||||
maxmem = cfg->infra_cache_numhosts *
|
||||
(sizeof(struct infra_host_key)+sizeof(struct infra_host_data));
|
||||
if(maxmem != slabhash_get_size(infra->hosts) ||
|
||||
@@ -152,6 +158,19 @@ hash_addr(struct sockaddr_storage* addr, socklen_t addrlen)
|
||||
return h;
|
||||
}
|
||||
|
||||
void
|
||||
infra_remove_host(struct infra_cache* infra,
|
||||
struct sockaddr_storage* addr, socklen_t addrlen)
|
||||
{
|
||||
struct infra_host_key k;
|
||||
k.addrlen = addrlen;
|
||||
memcpy(&k.addr, addr, addrlen);
|
||||
k.entry.hash = hash_addr(addr, addrlen);
|
||||
k.entry.key = (void*)&k;
|
||||
k.entry.data = NULL;
|
||||
slabhash_remove(infra->hosts, k.entry.hash, &k);
|
||||
}
|
||||
|
||||
/** lookup version that does not check host ttl (you check it) */
|
||||
static struct lruhash_entry*
|
||||
infra_lookup_host_nottl(struct infra_cache* infra,
|
||||
@@ -197,7 +216,7 @@ host_entry_init(struct infra_cache* infra, struct lruhash_entry* e,
|
||||
rtt_init(&data->rtt);
|
||||
data->edns_version = 0;
|
||||
data->edns_lame_known = 0;
|
||||
data->num_timeouts = 0;
|
||||
data->probedelay = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -242,8 +261,10 @@ infra_host(struct infra_cache* infra, struct sockaddr_storage* addr,
|
||||
struct lruhash_entry* e = infra_lookup_host_nottl(infra, addr,
|
||||
addrlen, 0);
|
||||
struct infra_host_data* data;
|
||||
int wr = 0;
|
||||
if(e && ((struct infra_host_data*)e->data)->ttl < timenow) {
|
||||
/* it expired, try to reuse existing entry */
|
||||
int old = ((struct infra_host_data*)e->data)->rtt.rto;
|
||||
lock_rw_unlock(&e->lock);
|
||||
e = infra_lookup_host_nottl(infra, addr, addrlen, 1);
|
||||
if(e) {
|
||||
@@ -251,6 +272,11 @@ infra_host(struct infra_cache* infra, struct sockaddr_storage* addr,
|
||||
/* re-initialise */
|
||||
/* do not touch lameness, it may be valid still */
|
||||
host_entry_init(infra, e, timenow);
|
||||
wr = 1;
|
||||
/* TOP_TIMEOUT remains on reuse */
|
||||
if(old >= USEFUL_SERVER_TOP_TIMEOUT)
|
||||
((struct infra_host_data*)e->data)->rtt.rto
|
||||
= USEFUL_SERVER_TOP_TIMEOUT;
|
||||
}
|
||||
}
|
||||
if(!e) {
|
||||
@@ -269,6 +295,22 @@ infra_host(struct infra_cache* infra, struct sockaddr_storage* addr,
|
||||
*to = rtt_timeout(&data->rtt);
|
||||
*edns_vs = data->edns_version;
|
||||
*edns_lame_known = data->edns_lame_known;
|
||||
if(*to >= PROBE_MAXRTO && rtt_notimeout(&data->rtt)*4 <= *to) {
|
||||
/* delay other queries, this is the probe query */
|
||||
if(!wr) {
|
||||
lock_rw_unlock(&e->lock);
|
||||
e = infra_lookup_host_nottl(infra, addr, addrlen, 1);
|
||||
if(!e) { /* flushed from cache real fast, no use to
|
||||
allocate just for the probedelay */
|
||||
return 1;
|
||||
}
|
||||
data = (struct infra_host_data*)e->data;
|
||||
}
|
||||
/* add 999 to round up the timeout value from msec to sec,
|
||||
* then add a whole second so it is certain that this probe
|
||||
* has timed out before the next is allowed */
|
||||
data->probedelay = timenow + ((*to)+1999)/1000;
|
||||
}
|
||||
lock_rw_unlock(&e->lock);
|
||||
return 1;
|
||||
}
|
||||
@@ -456,7 +498,7 @@ infra_update_tcp_works(struct infra_cache* infra,
|
||||
if(data->rtt.rto >= RTT_MAX_TIMEOUT)
|
||||
/* do not disqualify this server altogether, it is better
|
||||
* than nothing */
|
||||
data->rtt.rto = RTT_MAX_TIMEOUT-1;
|
||||
data->rtt.rto = RTT_MAX_TIMEOUT-1000;
|
||||
lock_rw_unlock(&e->lock);
|
||||
}
|
||||
|
||||
@@ -481,11 +523,9 @@ infra_rtt_update(struct infra_cache* infra,
|
||||
data = (struct infra_host_data*)e->data;
|
||||
if(roundtrip == -1) {
|
||||
rtt_lost(&data->rtt, orig_rtt);
|
||||
if(data->num_timeouts<255)
|
||||
data->num_timeouts++;
|
||||
} else {
|
||||
rtt_update(&data->rtt, roundtrip);
|
||||
data->num_timeouts = 0;
|
||||
data->probedelay = 0;
|
||||
}
|
||||
if(data->rtt.rto > 0)
|
||||
rto = data->rtt.rto;
|
||||
@@ -496,6 +536,27 @@ infra_rtt_update(struct infra_cache* infra,
|
||||
return rto;
|
||||
}
|
||||
|
||||
int infra_get_host_rto(struct infra_cache* infra,
|
||||
struct sockaddr_storage* addr, socklen_t addrlen,
|
||||
struct rtt_info* rtt, int* delay, uint32_t timenow)
|
||||
{
|
||||
struct lruhash_entry* e = infra_lookup_host_nottl(infra, addr,
|
||||
addrlen, 0);
|
||||
struct infra_host_data* data;
|
||||
int ttl = -2;
|
||||
if(!e) return -1;
|
||||
data = (struct infra_host_data*)e->data;
|
||||
if(data->ttl >= timenow) {
|
||||
ttl = (int)(data->ttl - timenow);
|
||||
memmove(rtt, &data->rtt, sizeof(*rtt));
|
||||
if(timenow < data->probedelay)
|
||||
*delay = (int)(data->probedelay - timenow);
|
||||
else *delay = 0;
|
||||
}
|
||||
lock_rw_unlock(&e->lock);
|
||||
return ttl;
|
||||
}
|
||||
|
||||
int
|
||||
infra_edns_update(struct infra_cache* infra,
|
||||
struct sockaddr_storage* addr, socklen_t addrlen,
|
||||
@@ -515,7 +576,8 @@ infra_edns_update(struct infra_cache* infra,
|
||||
/* have an entry, update the rtt, and the ttl */
|
||||
data = (struct infra_host_data*)e->data;
|
||||
/* do not update if noEDNS and stored is yesEDNS */
|
||||
if(!(edns_version == -1 && data->edns_version != -1)) {
|
||||
if(!(edns_version == -1 && (data->edns_version != -1 &&
|
||||
data->edns_lame_known))) {
|
||||
data->edns_version = edns_version;
|
||||
data->edns_lame_known = 1;
|
||||
}
|
||||
@@ -530,8 +592,7 @@ int
|
||||
infra_get_lame_rtt(struct infra_cache* infra,
|
||||
struct sockaddr_storage* addr, socklen_t addrlen,
|
||||
uint8_t* name, size_t namelen, uint16_t qtype,
|
||||
int* lame, int* dnsseclame, int* reclame, int* rtt, int* lost,
|
||||
uint32_t timenow)
|
||||
int* lame, int* dnsseclame, int* reclame, int* rtt, uint32_t timenow)
|
||||
{
|
||||
struct infra_host_data* host;
|
||||
struct lruhash_entry* e = infra_lookup_host_nottl(infra, addr,
|
||||
@@ -541,7 +602,10 @@ infra_get_lame_rtt(struct infra_cache* infra,
|
||||
return 0;
|
||||
host = (struct infra_host_data*)e->data;
|
||||
*rtt = rtt_unclamped(&host->rtt);
|
||||
*lost = (int)host->num_timeouts;
|
||||
if(host->rtt.rto >= PROBE_MAXRTO && timenow < host->probedelay
|
||||
&& rtt_notimeout(&host->rtt)*4 <= host->rtt.rto)
|
||||
/* single probe for this domain, and we are not probing */
|
||||
*rtt = USEFUL_SERVER_TOP_TIMEOUT;
|
||||
/* check lameness first, if so, ttl on host does not matter anymore */
|
||||
if(infra_lookup_lame(host, name, namelen, timenow,
|
||||
&dlm, &rlm, &alm, &olm)) {
|
||||
@@ -576,6 +640,15 @@ infra_get_lame_rtt(struct infra_cache* infra,
|
||||
*dnsseclame = 0;
|
||||
*reclame = 0;
|
||||
if(timenow > host->ttl) {
|
||||
/* expired entry */
|
||||
/* see if this can be a re-probe of an unresponsive server */
|
||||
/* minus 1000 because that is outside of the RTTBAND, so
|
||||
* blacklisted servers stay blacklisted if this is chosen */
|
||||
if(host->rtt.rto >= USEFUL_SERVER_TOP_TIMEOUT) {
|
||||
*rtt = USEFUL_SERVER_TOP_TIMEOUT-1000;
|
||||
lock_rw_unlock(&e->lock);
|
||||
return 1;
|
||||
}
|
||||
lock_rw_unlock(&e->lock);
|
||||
return 0;
|
||||
}
|
||||
|
||||
Vendored
+27
-6
@@ -64,6 +64,8 @@ struct infra_host_key {
|
||||
struct infra_host_data {
|
||||
/** TTL value for this entry. absolute time. */
|
||||
uint32_t ttl;
|
||||
/** time in seconds (absolute) when probing re-commences, 0 disabled */
|
||||
uint32_t probedelay;
|
||||
/** round trip times for timeout calculation */
|
||||
struct rtt_info rtt;
|
||||
/** Names of the zones that are lame. NULL=no lame zones. */
|
||||
@@ -74,8 +76,6 @@ struct infra_host_data {
|
||||
* EDNS lame is when EDNS queries or replies are dropped,
|
||||
* and cause a timeout */
|
||||
uint8_t edns_lame_known;
|
||||
/** Number of consequtive timeouts; reset when reply arrives OK. */
|
||||
uint8_t num_timeouts;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -120,6 +120,8 @@ struct infra_cache {
|
||||
int lame_ttl;
|
||||
/** infra lame cache max memory per host, in bytes */
|
||||
size_t max_lame_size;
|
||||
/** jostle timeout in msec */
|
||||
size_t jostle;
|
||||
};
|
||||
|
||||
/** infra host cache default hash lookup size */
|
||||
@@ -140,6 +142,10 @@ struct infra_cache* infra_create(struct config_file* cfg);
|
||||
*/
|
||||
void infra_delete(struct infra_cache* infra);
|
||||
|
||||
/** explicitly delete an infra host element */
|
||||
void infra_remove_host(struct infra_cache* infra,
|
||||
struct sockaddr_storage* addr, socklen_t addrlen);
|
||||
|
||||
/**
|
||||
* Adjust infra cache to use updated configuration settings.
|
||||
* This may clean the cache. Operates a bit like realloc.
|
||||
@@ -169,6 +175,8 @@ struct infra_host_data* infra_lookup_host(struct infra_cache* infra,
|
||||
* Find host information to send a packet. Creates new entry if not found.
|
||||
* Lameness is empty. EDNS is 0 (try with first), and rtt is returned for
|
||||
* the first message to it.
|
||||
* Use this to send a packet only, because it also locks out others when
|
||||
* probing is restricted.
|
||||
* @param infra: infrastructure cache.
|
||||
* @param addr: host address.
|
||||
* @param addrlen: length of addr.
|
||||
@@ -261,6 +269,7 @@ int infra_edns_update(struct infra_cache* infra,
|
||||
|
||||
/**
|
||||
* Get Lameness information and average RTT if host is in the cache.
|
||||
* This information is to be used for server selection.
|
||||
* @param infra: infrastructure cache.
|
||||
* @param addr: host address.
|
||||
* @param addrlen: length of addr.
|
||||
@@ -273,16 +282,28 @@ int infra_edns_update(struct infra_cache* infra,
|
||||
* @param reclame: if function returns true, this is if it is recursion lame.
|
||||
* @param rtt: if function returns true, this returns avg rtt of the server.
|
||||
* The rtt value is unclamped and reflects recent timeouts.
|
||||
* @param lost: number of queries lost in a row. Reset to 0 when an answer
|
||||
* gets back. Gives a connectivity number.
|
||||
* @param timenow: what time it is now.
|
||||
* @return if found in cache, or false if not (or TTL bad).
|
||||
*/
|
||||
int infra_get_lame_rtt(struct infra_cache* infra,
|
||||
struct sockaddr_storage* addr, socklen_t addrlen,
|
||||
uint8_t* name, size_t namelen, uint16_t qtype,
|
||||
int* lame, int* dnsseclame, int* reclame, int* rtt, int* lost,
|
||||
uint32_t timenow);
|
||||
int* lame, int* dnsseclame, int* reclame, int* rtt, uint32_t timenow);
|
||||
|
||||
/**
|
||||
* Get additional (debug) info on timing.
|
||||
* @param infra: infra cache.
|
||||
* @param addr: host address.
|
||||
* @param addrlen: length of addr.
|
||||
* @param rtt: the rtt_info is copied into here (caller alloced return struct).
|
||||
* @param delay: probe delay (if any).
|
||||
* @param timenow: what time it is now.
|
||||
* @return TTL the infra host element is valid for. If -1: not found in cache.
|
||||
* TTL -2: found but expired.
|
||||
*/
|
||||
int infra_get_host_rto(struct infra_cache* infra,
|
||||
struct sockaddr_storage* addr, socklen_t addrlen,
|
||||
struct rtt_info* rtt, int* delay, uint32_t timenow);
|
||||
|
||||
/**
|
||||
* Get memory used by the infra cache.
|
||||
|
||||
Vendored
+27
-9
@@ -120,7 +120,7 @@ rrset_cache_touch(struct rrset_cache* r, struct ub_packed_rrset_key* key,
|
||||
|
||||
/** see if rrset needs to be updated in the cache */
|
||||
static int
|
||||
need_to_update_rrset(void* nd, void* cd, uint32_t timenow, int equal)
|
||||
need_to_update_rrset(void* nd, void* cd, uint32_t timenow, int equal, int ns)
|
||||
{
|
||||
struct packed_rrset_data* newd = (struct packed_rrset_data*)nd;
|
||||
struct packed_rrset_data* cached = (struct packed_rrset_data*)cd;
|
||||
@@ -145,10 +145,22 @@ need_to_update_rrset(void* nd, void* cd, uint32_t timenow, int equal)
|
||||
/* o item in cache has expired */
|
||||
if( cached->ttl < timenow )
|
||||
return 1;
|
||||
/* o same trust, but different in data - insert it */
|
||||
if( newd->trust == cached->trust && !equal )
|
||||
return 1;
|
||||
return 0;
|
||||
/* o same trust, but different in data - insert it */
|
||||
if( newd->trust == cached->trust && !equal ) {
|
||||
/* if this is type NS, do not 'stick' to owner that changes
|
||||
* the NS RRset, but use the old TTL for the new data, and
|
||||
* update to fetch the latest data. ttl is not expired, because
|
||||
* that check was before this one. */
|
||||
if(ns) {
|
||||
size_t i;
|
||||
newd->ttl = cached->ttl;
|
||||
for(i=0; i<(newd->count+newd->rrsig_count); i++)
|
||||
if(newd->rr_ttl[i] > newd->ttl)
|
||||
newd->rr_ttl[i] = newd->ttl;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** Update RRSet special key ID */
|
||||
@@ -191,7 +203,7 @@ rrset_cache_update(struct rrset_cache* r, struct rrset_ref* ref,
|
||||
equal = rrsetdata_equal((struct packed_rrset_data*)k->entry.
|
||||
data, (struct packed_rrset_data*)e->data);
|
||||
if(!need_to_update_rrset(k->entry.data, e->data, timenow,
|
||||
equal)) {
|
||||
equal, (rrset_type==LDNS_RR_TYPE_NS))) {
|
||||
/* cache is superior, return that value */
|
||||
lock_rw_unlock(&e->lock);
|
||||
ub_packed_rrset_parsedelete(k, alloc);
|
||||
@@ -338,9 +350,15 @@ rrset_update_sec_status(struct rrset_cache* r,
|
||||
if(updata->trust > cachedata->trust)
|
||||
cachedata->trust = updata->trust;
|
||||
cachedata->security = updata->security;
|
||||
cachedata->ttl = updata->ttl + now;
|
||||
for(i=0; i<cachedata->count+cachedata->rrsig_count; i++)
|
||||
cachedata->rr_ttl[i] = updata->rr_ttl[i]+now;
|
||||
/* for NS records only shorter TTLs, other types: update it */
|
||||
if(ntohs(rrset->rk.type) != LDNS_RR_TYPE_NS ||
|
||||
updata->ttl+now < cachedata->ttl ||
|
||||
cachedata->ttl < now ||
|
||||
updata->security == sec_status_bogus) {
|
||||
cachedata->ttl = updata->ttl + now;
|
||||
for(i=0; i<cachedata->count+cachedata->rrsig_count; i++)
|
||||
cachedata->rr_ttl[i] = updata->rr_ttl[i]+now;
|
||||
}
|
||||
}
|
||||
lock_rw_unlock(&e->lock);
|
||||
}
|
||||
|
||||
+99
-48
@@ -90,7 +90,8 @@ verbose_print_addr(struct addrinfo *addr)
|
||||
|
||||
int
|
||||
create_udp_sock(int family, int socktype, struct sockaddr* addr,
|
||||
socklen_t addrlen, int v6only, int* inuse, int* noproto, int rcv)
|
||||
socklen_t addrlen, int v6only, int* inuse, int* noproto,
|
||||
int rcv, int snd)
|
||||
{
|
||||
int s;
|
||||
#if defined(IPV6_USE_MIN_MTU)
|
||||
@@ -102,6 +103,9 @@ create_udp_sock(int family, int socktype, struct sockaddr* addr,
|
||||
#if !defined(SO_RCVBUFFORCE) && !defined(SO_RCVBUF)
|
||||
(void)rcv;
|
||||
#endif
|
||||
#if !defined(SO_SNDBUFFORCE) && !defined(SO_SNDBUF)
|
||||
(void)snd;
|
||||
#endif
|
||||
#ifndef IPV6_V6ONLY
|
||||
(void)v6only;
|
||||
#endif
|
||||
@@ -182,6 +186,65 @@ create_udp_sock(int family, int socktype, struct sockaddr* addr,
|
||||
}
|
||||
# endif
|
||||
#endif /* SO_RCVBUF */
|
||||
}
|
||||
/* first do RCVBUF as the receive buffer is more important */
|
||||
if(snd) {
|
||||
#ifdef SO_SNDBUF
|
||||
int got;
|
||||
socklen_t slen = (socklen_t)sizeof(got);
|
||||
# ifdef SO_SNDBUFFORCE
|
||||
/* Linux specific: try to use root permission to override
|
||||
* system limits on sndbuf. The limit is stored in
|
||||
* /proc/sys/net/core/wmem_max or sysctl net.core.wmem_max */
|
||||
if(setsockopt(s, SOL_SOCKET, SO_SNDBUFFORCE, (void*)&snd,
|
||||
(socklen_t)sizeof(snd)) < 0) {
|
||||
if(errno != EPERM) {
|
||||
# ifndef USE_WINSOCK
|
||||
log_err("setsockopt(..., SO_SNDBUFFORCE, "
|
||||
"...) failed: %s", strerror(errno));
|
||||
close(s);
|
||||
# else
|
||||
log_err("setsockopt(..., SO_SNDBUFFORCE, "
|
||||
"...) failed: %s",
|
||||
wsa_strerror(WSAGetLastError()));
|
||||
closesocket(s);
|
||||
# endif
|
||||
*noproto = 0;
|
||||
*inuse = 0;
|
||||
return -1;
|
||||
}
|
||||
# endif /* SO_SNDBUFFORCE */
|
||||
if(setsockopt(s, SOL_SOCKET, SO_SNDBUF, (void*)&snd,
|
||||
(socklen_t)sizeof(snd)) < 0) {
|
||||
# ifndef USE_WINSOCK
|
||||
log_err("setsockopt(..., SO_SNDBUF, "
|
||||
"...) failed: %s", strerror(errno));
|
||||
close(s);
|
||||
# else
|
||||
log_err("setsockopt(..., SO_SNDBUF, "
|
||||
"...) failed: %s",
|
||||
wsa_strerror(WSAGetLastError()));
|
||||
closesocket(s);
|
||||
# endif
|
||||
*noproto = 0;
|
||||
*inuse = 0;
|
||||
return -1;
|
||||
}
|
||||
/* check if we got the right thing or if system
|
||||
* reduced to some system max. Warn if so */
|
||||
if(getsockopt(s, SOL_SOCKET, SO_SNDBUF, (void*)&got,
|
||||
&slen) >= 0 && got < snd/2) {
|
||||
log_warn("so-sndbuf %u was not granted. "
|
||||
"Got %u. To fix: start with "
|
||||
"root permissions(linux) or sysctl "
|
||||
"bigger net.core.wmem_max(linux) or "
|
||||
"kern.ipc.maxsockbuf(bsd) values.",
|
||||
(unsigned)snd, (unsigned)got);
|
||||
}
|
||||
# ifdef SO_SNDBUFFORCE
|
||||
}
|
||||
# endif
|
||||
#endif /* SO_SNDBUF */
|
||||
}
|
||||
if(family == AF_INET6) {
|
||||
# if defined(IPV6_V6ONLY)
|
||||
@@ -280,15 +343,21 @@ 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) {
|
||||
log_err("can't bind socket: %s", strerror(errno));
|
||||
log_addr(0, "failed address",
|
||||
(struct sockaddr_storage*)addr, addrlen);
|
||||
}
|
||||
#endif /* EADDRINUSE */
|
||||
close(s);
|
||||
#else /* USE_WINSOCK */
|
||||
if(WSAGetLastError() != WSAEADDRINUSE &&
|
||||
WSAGetLastError() != WSAEADDRNOTAVAIL)
|
||||
WSAGetLastError() != WSAEADDRNOTAVAIL) {
|
||||
log_err("can't bind socket: %s",
|
||||
wsa_strerror(WSAGetLastError()));
|
||||
log_addr(0, "failed address",
|
||||
(struct sockaddr_storage*)addr, addrlen);
|
||||
}
|
||||
closesocket(s);
|
||||
#endif
|
||||
return -1;
|
||||
@@ -368,10 +437,18 @@ create_tcp_accept_sock(struct addrinfo *addr, int v6only, int* noproto)
|
||||
/* detect freebsd jail with no ipv6 permission */
|
||||
if(addr->ai_family==AF_INET6 && errno==EINVAL)
|
||||
*noproto = 1;
|
||||
else log_err("can't bind socket: %s", strerror(errno));
|
||||
else {
|
||||
log_err("can't bind socket: %s", strerror(errno));
|
||||
log_addr(0, "failed address",
|
||||
(struct sockaddr_storage*)addr->ai_addr,
|
||||
addr->ai_addrlen);
|
||||
}
|
||||
#else
|
||||
log_err("can't bind socket: %s",
|
||||
wsa_strerror(WSAGetLastError()));
|
||||
log_addr(0, "failed address",
|
||||
(struct sockaddr_storage*)addr->ai_addr,
|
||||
addr->ai_addrlen);
|
||||
#endif
|
||||
return -1;
|
||||
}
|
||||
@@ -394,7 +471,7 @@ create_tcp_accept_sock(struct addrinfo *addr, int v6only, int* noproto)
|
||||
*/
|
||||
static int
|
||||
make_sock(int stype, const char* ifname, const char* port,
|
||||
struct addrinfo *hints, int v6only, int* noip6, size_t rcv)
|
||||
struct addrinfo *hints, int v6only, int* noip6, size_t rcv, size_t snd)
|
||||
{
|
||||
struct addrinfo *res = NULL;
|
||||
int r, s, inuse, noproto;
|
||||
@@ -420,8 +497,8 @@ make_sock(int stype, const char* ifname, const char* port,
|
||||
if(stype == SOCK_DGRAM) {
|
||||
verbose_print_addr(res);
|
||||
s = create_udp_sock(res->ai_family, res->ai_socktype,
|
||||
(struct sockaddr*)res->ai_addr,
|
||||
res->ai_addrlen, v6only, &inuse, &noproto, (int)rcv);
|
||||
(struct sockaddr*)res->ai_addr, res->ai_addrlen,
|
||||
v6only, &inuse, &noproto, (int)rcv, (int)snd);
|
||||
if(s == -1 && inuse) {
|
||||
log_err("bind: address already in use");
|
||||
} else if(s == -1 && noproto && hints->ai_family == AF_INET6){
|
||||
@@ -440,7 +517,7 @@ make_sock(int stype, const char* ifname, const char* port,
|
||||
/** make socket and first see if ifname contains port override info */
|
||||
static int
|
||||
make_sock_port(int stype, const char* ifname, const char* port,
|
||||
struct addrinfo *hints, int v6only, int* noip6, size_t rcv)
|
||||
struct addrinfo *hints, int v6only, int* noip6, size_t rcv, size_t snd)
|
||||
{
|
||||
char* s = strchr(ifname, '@');
|
||||
if(s) {
|
||||
@@ -461,9 +538,10 @@ make_sock_port(int stype, const char* ifname, const char* port,
|
||||
newif[s-ifname] = 0;
|
||||
strncpy(p, s+1, sizeof(p));
|
||||
p[strlen(s+1)]=0;
|
||||
return make_sock(stype, newif, p, hints, v6only, noip6, rcv);
|
||||
return make_sock(stype, newif, p, hints, v6only, noip6,
|
||||
rcv, snd);
|
||||
}
|
||||
return make_sock(stype, ifname, port, hints, v6only, noip6, rcv);
|
||||
return make_sock(stype, ifname, port, hints, v6only, noip6, rcv, snd);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -553,19 +631,20 @@ set_recvpktinfo(int s, int family)
|
||||
* @param port: Port number to use (as string).
|
||||
* @param list: list of open ports, appended to, changed to point to list head.
|
||||
* @param rcv: receive buffer size for UDP
|
||||
* @param snd: send buffer size for UDP
|
||||
* @return: returns false on error.
|
||||
*/
|
||||
static int
|
||||
ports_create_if(const char* ifname, int do_auto, int do_udp, int do_tcp,
|
||||
struct addrinfo *hints, const char* port, struct listen_port** list,
|
||||
size_t rcv)
|
||||
size_t rcv, size_t snd)
|
||||
{
|
||||
int s, noip6=0;
|
||||
if(!do_udp && !do_tcp)
|
||||
return 0;
|
||||
if(do_auto) {
|
||||
if((s = make_sock_port(SOCK_DGRAM, ifname, port, hints, 1,
|
||||
&noip6, rcv)) == -1) {
|
||||
&noip6, rcv, snd)) == -1) {
|
||||
if(noip6) {
|
||||
log_warn("IPv6 protocol not available");
|
||||
return 1;
|
||||
@@ -586,7 +665,7 @@ ports_create_if(const char* ifname, int do_auto, int do_udp, int do_tcp,
|
||||
} else if(do_udp) {
|
||||
/* regular udp socket */
|
||||
if((s = make_sock_port(SOCK_DGRAM, ifname, port, hints, 1,
|
||||
&noip6, rcv)) == -1) {
|
||||
&noip6, rcv, snd)) == -1) {
|
||||
if(noip6) {
|
||||
log_warn("IPv6 protocol not available");
|
||||
return 1;
|
||||
@@ -604,7 +683,7 @@ ports_create_if(const char* ifname, int do_auto, int do_udp, int do_tcp,
|
||||
}
|
||||
if(do_tcp) {
|
||||
if((s = make_sock_port(SOCK_STREAM, ifname, port, hints, 1,
|
||||
&noip6, 0)) == -1) {
|
||||
&noip6, 0, 0)) == -1) {
|
||||
if(noip6) {
|
||||
/*log_warn("IPv6 protocol not available");*/
|
||||
return 1;
|
||||
@@ -715,32 +794,6 @@ listen_delete(struct listen_dnsport* front)
|
||||
free(front);
|
||||
}
|
||||
|
||||
void listen_pushback(struct listen_dnsport* listen)
|
||||
{
|
||||
struct listen_list *p;
|
||||
log_assert(listen);
|
||||
for(p = listen->cps; p; p = p->next)
|
||||
{
|
||||
if(p->com->type != comm_udp &&
|
||||
p->com->type != comm_tcp_accept)
|
||||
continue;
|
||||
comm_point_stop_listening(p->com);
|
||||
}
|
||||
}
|
||||
|
||||
void listen_resume(struct listen_dnsport* listen)
|
||||
{
|
||||
struct listen_list *p;
|
||||
log_assert(listen);
|
||||
for(p = listen->cps; p; p = p->next)
|
||||
{
|
||||
if(p->com->type != comm_udp &&
|
||||
p->com->type != comm_tcp_accept)
|
||||
continue;
|
||||
comm_point_start_listening(p->com, -1, -1);
|
||||
}
|
||||
}
|
||||
|
||||
struct listen_port*
|
||||
listening_ports_open(struct config_file* cfg)
|
||||
{
|
||||
@@ -770,17 +823,14 @@ listening_ports_open(struct config_file* cfg)
|
||||
if(!do_ip4 && !do_ip6) {
|
||||
return NULL;
|
||||
}
|
||||
if(do_auto && (!do_ip4 || !do_ip6)) {
|
||||
log_warn("interface_automatic option does not work when either do-ip4 or do-ip6 is not enabled. Disabling option.");
|
||||
do_auto = 0;
|
||||
}
|
||||
/* create ip4 and ip6 ports so that return addresses are nice. */
|
||||
if(do_auto || cfg->num_ifs == 0) {
|
||||
if(do_ip6) {
|
||||
hints.ai_family = AF_INET6;
|
||||
if(!ports_create_if(do_auto?"::0":"::1",
|
||||
do_auto, cfg->do_udp, do_tcp,
|
||||
&hints, portbuf, &list, cfg->socket_rcvbuf)) {
|
||||
&hints, portbuf, &list,
|
||||
cfg->so_rcvbuf, cfg->so_sndbuf)) {
|
||||
listening_ports_free(list);
|
||||
return NULL;
|
||||
}
|
||||
@@ -789,7 +839,8 @@ listening_ports_open(struct config_file* cfg)
|
||||
hints.ai_family = AF_INET;
|
||||
if(!ports_create_if(do_auto?"0.0.0.0":"127.0.0.1",
|
||||
do_auto, cfg->do_udp, do_tcp,
|
||||
&hints, portbuf, &list, cfg->socket_rcvbuf)) {
|
||||
&hints, portbuf, &list,
|
||||
cfg->so_rcvbuf, cfg->so_sndbuf)) {
|
||||
listening_ports_free(list);
|
||||
return NULL;
|
||||
}
|
||||
@@ -801,7 +852,7 @@ listening_ports_open(struct config_file* cfg)
|
||||
hints.ai_family = AF_INET6;
|
||||
if(!ports_create_if(cfg->ifs[i], 0, cfg->do_udp,
|
||||
do_tcp, &hints, portbuf, &list,
|
||||
cfg->socket_rcvbuf)) {
|
||||
cfg->so_rcvbuf, cfg->so_sndbuf)) {
|
||||
listening_ports_free(list);
|
||||
return NULL;
|
||||
}
|
||||
@@ -811,7 +862,7 @@ listening_ports_open(struct config_file* cfg)
|
||||
hints.ai_family = AF_INET;
|
||||
if(!ports_create_if(cfg->ifs[i], 0, cfg->do_udp,
|
||||
do_tcp, &hints, portbuf, &list,
|
||||
cfg->socket_rcvbuf)) {
|
||||
cfg->so_rcvbuf, cfg->so_sndbuf)) {
|
||||
listening_ports_free(list);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -130,25 +130,6 @@ struct listen_dnsport* listen_create(struct comm_base* base,
|
||||
struct listen_port* ports, size_t bufsize, int tcp_accept_count,
|
||||
comm_point_callback_t* cb, void* cb_arg);
|
||||
|
||||
/**
|
||||
* Stop listening to the dnsports. Ports are still open but not checked
|
||||
* for readability - performs pushback of the load.
|
||||
* @param listen: the listening structs to stop listening on. Note that
|
||||
* udp and tcp-accept handlers stop, but ongoing tcp-handlers are kept
|
||||
* going, since its rude to 'reset connection by peer' them, instead,
|
||||
* we keep them and the callback will be called when its ready. It can
|
||||
* be dropped at that time. New tcp and udp queries can be served by
|
||||
* other threads.
|
||||
*/
|
||||
void listen_pushback(struct listen_dnsport* listen);
|
||||
|
||||
/**
|
||||
* Start listening again to the dnsports.
|
||||
* Call after the listen_pushback has been called.
|
||||
* @param listen: the listening structs to stop listening on.
|
||||
*/
|
||||
void listen_resume(struct listen_dnsport* listen);
|
||||
|
||||
/**
|
||||
* delete the listening structure
|
||||
* @param listen: listening structure.
|
||||
@@ -181,10 +162,12 @@ size_t listen_get_mem(struct listen_dnsport* listen);
|
||||
* @param noproto: on error, this is set true if cause is that the
|
||||
IPv6 proto (family) is not available.
|
||||
* @param rcv: set size on rcvbuf with socket option, if 0 it is not set.
|
||||
* @param snd: set size on sndbuf with socket option, if 0 it is not set.
|
||||
* @return: the socket. -1 on error.
|
||||
*/
|
||||
int create_udp_sock(int family, int socktype, struct sockaddr* addr,
|
||||
socklen_t addrlen, int v6only, int* inuse, int* noproto, int rcv);
|
||||
socklen_t addrlen, int v6only, int* inuse, int* noproto, int rcv,
|
||||
int snd);
|
||||
|
||||
/**
|
||||
* Create and bind TCP listening socket
|
||||
|
||||
+13
-4
@@ -52,7 +52,7 @@
|
||||
#include "util/data/msgparse.h"
|
||||
|
||||
struct local_zones*
|
||||
local_zones_create()
|
||||
local_zones_create(void)
|
||||
{
|
||||
struct local_zones* zones = (struct local_zones*)calloc(1,
|
||||
sizeof(*zones));
|
||||
@@ -290,7 +290,7 @@ get_rr_nameclass(const char* str, uint8_t** nm, uint16_t* dclass)
|
||||
* @param type: type to look for (host order).
|
||||
* @return rrset pointer or NULL if not found.
|
||||
*/
|
||||
struct local_rrset*
|
||||
static struct local_rrset*
|
||||
local_data_find_type(struct local_data* data, uint16_t type)
|
||||
{
|
||||
struct local_rrset* p;
|
||||
@@ -698,7 +698,6 @@ lz_enter_defaults(struct local_zones* zones, struct config_file* cfg,
|
||||
!add_as112_default(zones, cfg, buf, "9.e.f.ip6.arpa.") ||
|
||||
!add_as112_default(zones, cfg, buf, "a.e.f.ip6.arpa.") ||
|
||||
!add_as112_default(zones, cfg, buf, "b.e.f.ip6.arpa.") ||
|
||||
!add_as112_default(zones, cfg, buf, "0.1.1.0.0.2.ip6.arpa.") ||
|
||||
!add_as112_default(zones, cfg, buf, "8.b.d.0.1.0.0.2.ip6.arpa.")) {
|
||||
log_err("out of memory adding default zone");
|
||||
return 0;
|
||||
@@ -968,6 +967,10 @@ void local_zones_print(struct local_zones* zones)
|
||||
log_nametypeclass(0, "transparent zone",
|
||||
z->name, 0, z->dclass);
|
||||
break;
|
||||
case local_zone_typetransparent:
|
||||
log_nametypeclass(0, "typetransparent zone",
|
||||
z->name, 0, z->dclass);
|
||||
break;
|
||||
case local_zone_static:
|
||||
log_nametypeclass(0, "static zone",
|
||||
z->name, 0, z->dclass);
|
||||
@@ -1096,7 +1099,10 @@ lz_zone_answer(struct local_zone* z, struct query_info* qinfo,
|
||||
*(uint16_t*)ldns_buffer_begin(buf),
|
||||
ldns_buffer_read_u16_at(buf, 2), edns);
|
||||
return 1;
|
||||
}
|
||||
} else if(z->type == local_zone_typetransparent) {
|
||||
/* no NODATA or NXDOMAINS for this zone type */
|
||||
return 0;
|
||||
}
|
||||
/* else z->type == local_zone_transparent */
|
||||
|
||||
/* if the zone is transparent and the name exists, but the type
|
||||
@@ -1153,6 +1159,7 @@ const char* local_zone_type2str(enum localzone_type t)
|
||||
case local_zone_refuse: return "refuse";
|
||||
case local_zone_redirect: return "redirect";
|
||||
case local_zone_transparent: return "transparent";
|
||||
case local_zone_typetransparent: return "typetransparent";
|
||||
case local_zone_static: return "static";
|
||||
case local_zone_nodefault: return "nodefault";
|
||||
}
|
||||
@@ -1169,6 +1176,8 @@ int local_zone_str2type(const char* type, enum localzone_type* t)
|
||||
*t = local_zone_static;
|
||||
else if(strcmp(type, "transparent") == 0)
|
||||
*t = local_zone_transparent;
|
||||
else if(strcmp(type, "typetransparent") == 0)
|
||||
*t = local_zone_typetransparent;
|
||||
else if(strcmp(type, "redirect") == 0)
|
||||
*t = local_zone_redirect;
|
||||
else return 0;
|
||||
|
||||
@@ -63,6 +63,8 @@ enum localzone_type {
|
||||
local_zone_static,
|
||||
/** resolve normally */
|
||||
local_zone_transparent,
|
||||
/** do not block types at localdata names */
|
||||
local_zone_typetransparent,
|
||||
/** answer with data at zone apex */
|
||||
local_zone_redirect,
|
||||
/** remove default AS112 blocking contents for zone
|
||||
@@ -149,7 +151,7 @@ struct local_rrset {
|
||||
* Create local zones storage
|
||||
* @return new struct or NULL on error.
|
||||
*/
|
||||
struct local_zones* local_zones_create();
|
||||
struct local_zones* local_zones_create(void);
|
||||
|
||||
/**
|
||||
* Delete local zones storage
|
||||
|
||||
+24
-8
@@ -234,7 +234,7 @@ mesh_delete_all(struct mesh_area* mesh)
|
||||
|
||||
int mesh_make_new_space(struct mesh_area* mesh)
|
||||
{
|
||||
struct mesh_state* m = mesh->jostle_last;
|
||||
struct mesh_state* m = mesh->jostle_first;
|
||||
/* free space is available */
|
||||
if(mesh->num_reply_states < mesh->max_reply_states)
|
||||
return 1;
|
||||
@@ -270,7 +270,11 @@ void mesh_new_client(struct mesh_area* mesh, struct query_info* qinfo,
|
||||
uint16_t qflags, struct edns_data* edns, struct comm_reply* rep,
|
||||
uint16_t qid)
|
||||
{
|
||||
struct mesh_state* s = mesh_area_find(mesh, qinfo, qflags, 0);
|
||||
/* do not use CD flag from user for mesh state, we want the CD-query
|
||||
* to receive validation anyway, to protect out cache contents and
|
||||
* avoid bad-data in this cache that a downstream validator cannot
|
||||
* remove from this cache */
|
||||
struct mesh_state* s = mesh_area_find(mesh, qinfo, qflags&BIT_RD, 0);
|
||||
int was_detached = 0;
|
||||
int was_noreply = 0;
|
||||
int added = 0;
|
||||
@@ -283,11 +287,22 @@ void mesh_new_client(struct mesh_area* mesh, struct query_info* qinfo,
|
||||
mesh->stats_dropped ++;
|
||||
return;
|
||||
}
|
||||
/* for this new reply state, the reply address is free,
|
||||
* so the limit of reply addresses does not stop reply states*/
|
||||
} else {
|
||||
/* protect our memory usage from storing reply addresses */
|
||||
if(mesh->num_reply_addrs > mesh->max_reply_states*16) {
|
||||
verbose(VERB_ALGO, "Too many requests queued. "
|
||||
"dropping incoming query.");
|
||||
mesh->stats_dropped++;
|
||||
comm_point_drop_reply(rep);
|
||||
return;
|
||||
}
|
||||
}
|
||||
/* see if it already exists, if not, create one */
|
||||
if(!s) {
|
||||
struct rbnode_t* n;
|
||||
s = mesh_state_create(mesh->env, qinfo, qflags, 0);
|
||||
s = mesh_state_create(mesh->env, qinfo, qflags&BIT_RD, 0);
|
||||
if(!s) {
|
||||
log_err("mesh_state_create: out of memory; SERVFAIL");
|
||||
error_encode(rep->c->buffer, LDNS_RCODE_SERVFAIL,
|
||||
@@ -346,7 +361,7 @@ mesh_new_callback(struct mesh_area* mesh, struct query_info* qinfo,
|
||||
uint16_t qflags, struct edns_data* edns, ldns_buffer* buf,
|
||||
uint16_t qid, mesh_cb_func_t cb, void* cb_arg)
|
||||
{
|
||||
struct mesh_state* s = mesh_area_find(mesh, qinfo, qflags, 0);
|
||||
struct mesh_state* s = mesh_area_find(mesh, qinfo, qflags&BIT_RD, 0);
|
||||
int was_detached = 0;
|
||||
int was_noreply = 0;
|
||||
int added = 0;
|
||||
@@ -355,7 +370,7 @@ mesh_new_callback(struct mesh_area* mesh, struct query_info* qinfo,
|
||||
/* see if it already exists, if not, create one */
|
||||
if(!s) {
|
||||
struct rbnode_t* n;
|
||||
s = mesh_state_create(mesh->env, qinfo, qflags, 0);
|
||||
s = mesh_state_create(mesh->env, qinfo, qflags&BIT_RD, 0);
|
||||
if(!s) {
|
||||
return 0;
|
||||
}
|
||||
@@ -392,7 +407,7 @@ mesh_new_callback(struct mesh_area* mesh, struct query_info* qinfo,
|
||||
void mesh_new_prefetch(struct mesh_area* mesh, struct query_info* qinfo,
|
||||
uint16_t qflags, uint32_t leeway)
|
||||
{
|
||||
struct mesh_state* s = mesh_area_find(mesh, qinfo, qflags, 0);
|
||||
struct mesh_state* s = mesh_area_find(mesh, qinfo, qflags&BIT_RD, 0);
|
||||
struct rbnode_t* n;
|
||||
/* already exists, and for a different purpose perhaps.
|
||||
* if mesh_no_list, keep it that way. */
|
||||
@@ -409,7 +424,7 @@ void mesh_new_prefetch(struct mesh_area* mesh, struct query_info* qinfo,
|
||||
mesh->stats_dropped ++;
|
||||
return;
|
||||
}
|
||||
s = mesh_state_create(mesh->env, qinfo, qflags, 0);
|
||||
s = mesh_state_create(mesh->env, qinfo, qflags&BIT_RD, 0);
|
||||
if(!s) {
|
||||
log_err("prefetch mesh_state_create: out of memory");
|
||||
return;
|
||||
@@ -757,7 +772,8 @@ mesh_send_reply(struct mesh_state* m, int rcode, struct reply_info* rep,
|
||||
struct timeval duration;
|
||||
int secure;
|
||||
/* examine security status */
|
||||
if(m->s.env->need_to_validate && !(r->qflags&BIT_CD) && rep &&
|
||||
if(m->s.env->need_to_validate && (!(r->qflags&BIT_CD) ||
|
||||
m->s.env->cfg->ignore_cd) && rep &&
|
||||
rep->security <= sec_status_bogus) {
|
||||
rcode = LDNS_RCODE_SERVFAIL;
|
||||
if(m->s.env->cfg->stat_extended)
|
||||
|
||||
+1
-1
@@ -63,7 +63,7 @@ struct timehist;
|
||||
* Maximum number of mesh state activations. Any more is likely an
|
||||
* infinite loop in the module. It is then terminated.
|
||||
*/
|
||||
#define MESH_MAX_ACTIVATION 1000
|
||||
#define MESH_MAX_ACTIVATION 3000
|
||||
|
||||
/**
|
||||
* Max number of references-to-references-to-references.. search size.
|
||||
|
||||
+90
-12
@@ -130,6 +130,65 @@ waiting_tcp_delete(struct waiting_tcp* w)
|
||||
free(w);
|
||||
}
|
||||
|
||||
/**
|
||||
* Pick random outgoing-interface of that family, and bind it.
|
||||
* port set to 0 so OS picks a port number for us.
|
||||
* if it is the ANY address, do not bind.
|
||||
* @param w: tcp structure with destination address.
|
||||
* @param s: socket fd.
|
||||
* @return false on error, socket closed.
|
||||
*/
|
||||
static int
|
||||
pick_outgoing_tcp(struct waiting_tcp* w, int s)
|
||||
{
|
||||
struct port_if* pi = NULL;
|
||||
int num;
|
||||
#ifdef INET6
|
||||
if(addr_is_ip6(&w->addr, w->addrlen))
|
||||
num = w->outnet->num_ip6;
|
||||
else
|
||||
#endif
|
||||
num = w->outnet->num_ip4;
|
||||
if(num == 0) {
|
||||
log_err("no TCP outgoing interfaces of family");
|
||||
log_addr(VERB_OPS, "for addr", &w->addr, w->addrlen);
|
||||
#ifndef USE_WINSOCK
|
||||
close(s);
|
||||
#else
|
||||
closesocket(s);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
#ifdef INET6
|
||||
if(addr_is_ip6(&w->addr, w->addrlen))
|
||||
pi = &w->outnet->ip6_ifs[ub_random_max(w->outnet->rnd, num)];
|
||||
else
|
||||
#endif
|
||||
pi = &w->outnet->ip4_ifs[ub_random_max(w->outnet->rnd, num)];
|
||||
log_assert(pi);
|
||||
if(addr_is_any(&pi->addr, pi->addrlen)) {
|
||||
/* binding to the ANY interface is for listening sockets */
|
||||
return 1;
|
||||
}
|
||||
/* set port to 0 */
|
||||
if(addr_is_ip6(&pi->addr, pi->addrlen))
|
||||
((struct sockaddr_in6*)&pi->addr)->sin6_port = 0;
|
||||
else ((struct sockaddr_in*)&pi->addr)->sin_port = 0;
|
||||
if(bind(s, (struct sockaddr*)&pi->addr, pi->addrlen) != 0) {
|
||||
#ifndef USE_WINSOCK
|
||||
log_err("outgoing tcp: bind: %s", strerror(errno));
|
||||
close(s);
|
||||
#else
|
||||
log_err("outgoing tcp: bind: %s",
|
||||
wsa_strerror(WSAGetLastError()));
|
||||
closesocket(s);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
log_addr(VERB_ALGO, "tcp bound to src", &pi->addr, pi->addrlen);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/** use next free buffer to service a tcp query */
|
||||
static int
|
||||
outnet_tcp_take_into_use(struct waiting_tcp* w, uint8_t* pkt, size_t pkt_len)
|
||||
@@ -156,6 +215,9 @@ outnet_tcp_take_into_use(struct waiting_tcp* w, uint8_t* pkt, size_t pkt_len)
|
||||
log_addr(0, "failed address", &w->addr, w->addrlen);
|
||||
return 0;
|
||||
}
|
||||
if(!pick_outgoing_tcp(w, s))
|
||||
return 0;
|
||||
|
||||
fd_set_nonblock(s);
|
||||
if(connect(s, (struct sockaddr*)&w->addr, w->addrlen) == -1) {
|
||||
#ifndef USE_WINSOCK
|
||||
@@ -758,12 +820,14 @@ udp_sockport(struct sockaddr_storage* addr, socklen_t addrlen, int port,
|
||||
struct sockaddr_in6* sa = (struct sockaddr_in6*)addr;
|
||||
sa->sin6_port = (in_port_t)htons((uint16_t)port);
|
||||
fd = create_udp_sock(AF_INET6, SOCK_DGRAM,
|
||||
(struct sockaddr*)addr, addrlen, 1, inuse, &noproto, 0);
|
||||
(struct sockaddr*)addr, addrlen, 1, inuse, &noproto,
|
||||
0, 0);
|
||||
} else {
|
||||
struct sockaddr_in* sa = (struct sockaddr_in*)addr;
|
||||
sa->sin_port = (in_port_t)htons((uint16_t)port);
|
||||
fd = create_udp_sock(AF_INET, SOCK_DGRAM,
|
||||
(struct sockaddr*)addr, addrlen, 1, inuse, &noproto, 0);
|
||||
(struct sockaddr*)addr, addrlen, 1, inuse, &noproto,
|
||||
0, 0);
|
||||
}
|
||||
return fd;
|
||||
}
|
||||
@@ -1243,13 +1307,16 @@ serviced_udp_send(struct serviced_query* sq, ldns_buffer* buff)
|
||||
if(!infra_host(sq->outnet->infra, &sq->addr, sq->addrlen, now, &vs,
|
||||
&edns_lame_known, &rtt))
|
||||
return 0;
|
||||
sq->last_rtt = rtt;
|
||||
verbose(VERB_ALGO, "EDNS lookup known=%d vs=%d", edns_lame_known, vs);
|
||||
if(sq->status == serviced_initial) {
|
||||
if(edns_lame_known == 0 && rtt > 5000 && rtt < 10001) {
|
||||
/* perform EDNS lame probe - check if server is
|
||||
* EDNS lame (EDNS queries to it are dropped) */
|
||||
verbose(VERB_ALGO, "serviced query: send probe to see "
|
||||
" if use of EDNS causes timeouts");
|
||||
rtt /= 10;
|
||||
/* even 700 msec may be too small */
|
||||
rtt = 1000;
|
||||
sq->status = serviced_query_PROBE_EDNS;
|
||||
} else if(vs != -1) {
|
||||
sq->status = serviced_query_UDP_EDNS;
|
||||
@@ -1259,7 +1326,6 @@ serviced_udp_send(struct serviced_query* sq, ldns_buffer* buff)
|
||||
}
|
||||
serviced_encode(sq, buff, sq->status == serviced_query_UDP_EDNS);
|
||||
sq->last_sent_time = *sq->outnet->now_tv;
|
||||
sq->last_rtt = rtt;
|
||||
sq->edns_lame_known = (int)edns_lame_known;
|
||||
verbose(VERB_ALGO, "serviced query UDP timeout=%d msec", rtt);
|
||||
sq->pending = pending_udp_query(sq->outnet, buff, &sq->addr,
|
||||
@@ -1522,18 +1588,20 @@ serviced_udp_callback(struct comm_point* c, void* arg, int error,
|
||||
serviced_callbacks(sq, error, c, rep);
|
||||
return 0;
|
||||
}
|
||||
if(sq->status == serviced_query_UDP_EDNS
|
||||
if(!fallback_tcp) {
|
||||
if(sq->status == serviced_query_UDP_EDNS
|
||||
&& (LDNS_RCODE_WIRE(ldns_buffer_begin(c->buffer))
|
||||
== LDNS_RCODE_FORMERR || LDNS_RCODE_WIRE(
|
||||
ldns_buffer_begin(c->buffer)) == LDNS_RCODE_NOTIMPL)) {
|
||||
/* try to get an answer by falling back without EDNS */
|
||||
verbose(VERB_ALGO, "serviced query: attempt without EDNS");
|
||||
sq->status = serviced_query_UDP_EDNS_fallback;
|
||||
sq->retry = 0;
|
||||
if(!serviced_udp_send(sq, c->buffer)) {
|
||||
serviced_callbacks(sq, NETEVENT_CLOSED, c, rep);
|
||||
}
|
||||
return 0;
|
||||
} else if(sq->status == serviced_query_PROBE_EDNS) {
|
||||
} else if(sq->status == serviced_query_PROBE_EDNS) {
|
||||
/* probe without EDNS succeeds, so we conclude that this
|
||||
* host likely has EDNS packets dropped */
|
||||
log_addr(VERB_DETAIL, "timeouts, concluded that connection to "
|
||||
@@ -1545,15 +1613,17 @@ serviced_udp_callback(struct comm_point* c, void* arg, int error,
|
||||
log_err("Out of memory caching no edns for host");
|
||||
}
|
||||
sq->status = serviced_query_UDP;
|
||||
} else if(sq->status == serviced_query_UDP_EDNS &&
|
||||
} else if(sq->status == serviced_query_UDP_EDNS &&
|
||||
!sq->edns_lame_known) {
|
||||
/* now we know that edns queries received answers store that */
|
||||
log_addr(VERB_ALGO, "serviced query: EDNS works for",
|
||||
&sq->addr, sq->addrlen);
|
||||
if(!infra_edns_update(outnet->infra, &sq->addr, sq->addrlen,
|
||||
0, (uint32_t)now.tv_sec)) {
|
||||
log_err("Out of memory caching edns works");
|
||||
}
|
||||
sq->edns_lame_known = 1;
|
||||
} else if(sq->status == serviced_query_UDP_EDNS_fallback &&
|
||||
} else if(sq->status == serviced_query_UDP_EDNS_fallback &&
|
||||
!sq->edns_lame_known && (LDNS_RCODE_WIRE(
|
||||
ldns_buffer_begin(c->buffer)) == LDNS_RCODE_NOERROR ||
|
||||
LDNS_RCODE_WIRE(ldns_buffer_begin(c->buffer)) ==
|
||||
@@ -1562,14 +1632,21 @@ serviced_udp_callback(struct comm_point* c, void* arg, int error,
|
||||
/* the fallback produced a result that looks promising, note
|
||||
* that this server should be approached without EDNS */
|
||||
/* only store noEDNS in cache if domain is noDNSSEC */
|
||||
if(!sq->want_dnssec)
|
||||
if(!sq->want_dnssec) {
|
||||
log_addr(VERB_ALGO, "serviced query: EDNS fails for",
|
||||
&sq->addr, sq->addrlen);
|
||||
if(!infra_edns_update(outnet->infra, &sq->addr, sq->addrlen,
|
||||
-1, (uint32_t)now.tv_sec)) {
|
||||
log_err("Out of memory caching no edns for host");
|
||||
}
|
||||
} else {
|
||||
log_addr(VERB_ALGO, "serviced query: EDNS fails, but "
|
||||
"not stored because need DNSSEC for", &sq->addr,
|
||||
sq->addrlen);
|
||||
}
|
||||
sq->status = serviced_query_UDP;
|
||||
}
|
||||
if(now.tv_sec > sq->last_sent_time.tv_sec ||
|
||||
}
|
||||
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 */
|
||||
@@ -1580,7 +1657,8 @@ serviced_udp_callback(struct comm_point* c, void* arg, int error,
|
||||
if(!infra_rtt_update(outnet->infra, &sq->addr, sq->addrlen,
|
||||
roundtime, sq->last_rtt, (uint32_t)now.tv_sec))
|
||||
log_err("out of memory noting rtt.");
|
||||
}
|
||||
}
|
||||
} /* end of if_!fallback_tcp */
|
||||
/* perform TC flag check and TCP fallback after updating our
|
||||
* cache entries for EDNS status and RTT times */
|
||||
if(LDNS_TC_WIRE(ldns_buffer_begin(c->buffer)) || fallback_tcp) {
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -96,6 +96,8 @@ usage()
|
||||
printf(" flush_stats flush statistics, make zero\n");
|
||||
printf(" flush_requestlist drop queries that are worked on\n");
|
||||
printf(" dump_requestlist show what is worked on\n");
|
||||
printf(" flush_infra [all | ip] remove ping, edns for one IP or all\n");
|
||||
printf(" dump_infra show ping and edns entries\n");
|
||||
printf(" set_option opt: val set option to value, no reload\n");
|
||||
printf(" get_option opt get option value\n");
|
||||
printf(" list_stubs list stub-zones and root hints in use\n");
|
||||
@@ -256,12 +258,13 @@ send_file(SSL* ssl, FILE* in, char* buf, size_t sz)
|
||||
static int
|
||||
go_cmd(SSL* ssl, int argc, char* argv[])
|
||||
{
|
||||
const char* pre="UBCT";
|
||||
char pre[10];
|
||||
const char* space=" ";
|
||||
const char* newline="\n";
|
||||
int was_error = 0, first_line = 1;
|
||||
int r, 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");
|
||||
for(i=0; i<argc; i++) {
|
||||
|
||||
@@ -100,15 +100,6 @@ void worker_sighandler(int ATTR_UNUSED(sig), void* ATTR_UNUSED(arg))
|
||||
log_assert(0);
|
||||
}
|
||||
|
||||
int worker_send_packet(ldns_buffer* ATTR_UNUSED(pkt),
|
||||
struct sockaddr_storage* ATTR_UNUSED(addr),
|
||||
socklen_t ATTR_UNUSED(addrlen), int ATTR_UNUSED(timeout),
|
||||
struct module_qstate* ATTR_UNUSED(q), int ATTR_UNUSED(use_tcp))
|
||||
{
|
||||
log_assert(0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct outbound_entry* worker_send_query(uint8_t* ATTR_UNUSED(qname),
|
||||
size_t ATTR_UNUSED(qnamelen), uint16_t ATTR_UNUSED(qtype),
|
||||
uint16_t ATTR_UNUSED(qclass), uint16_t ATTR_UNUSED(flags),
|
||||
@@ -140,15 +131,6 @@ worker_alloc_cleanup(void* ATTR_UNUSED(arg))
|
||||
log_assert(0);
|
||||
}
|
||||
|
||||
int libworker_send_packet(ldns_buffer* ATTR_UNUSED(pkt),
|
||||
struct sockaddr_storage* ATTR_UNUSED(addr),
|
||||
socklen_t ATTR_UNUSED(addrlen), int ATTR_UNUSED(timeout),
|
||||
struct module_qstate* ATTR_UNUSED(q), int ATTR_UNUSED(use_tcp))
|
||||
{
|
||||
log_assert(0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct outbound_entry* libworker_send_query(uint8_t* ATTR_UNUSED(qname),
|
||||
size_t ATTR_UNUSED(qnamelen), uint16_t ATTR_UNUSED(qtype),
|
||||
uint16_t ATTR_UNUSED(qclass), uint16_t ATTR_UNUSED(flags),
|
||||
|
||||
@@ -84,7 +84,7 @@ struct lookinfo {
|
||||
static int num_wait = 0;
|
||||
|
||||
/** usage information for asynclook */
|
||||
void usage(char* argv[])
|
||||
static void usage(char* argv[])
|
||||
{
|
||||
printf("usage: %s [options] name ...\n", argv[0]);
|
||||
printf("names are looked up at the same time, asynchronously.\n");
|
||||
|
||||
@@ -52,7 +52,7 @@
|
||||
#ifdef USE_THREAD_DEBUG
|
||||
|
||||
/** How long to wait before lock attempt is a failure. */
|
||||
#define CHECK_LOCK_TIMEOUT 30 /* seconds */
|
||||
#define CHECK_LOCK_TIMEOUT 120 /* seconds */
|
||||
/** How long to wait before join attempt is a failure. */
|
||||
#define CHECK_JOIN_TIMEOUT 120 /* seconds */
|
||||
|
||||
@@ -68,7 +68,7 @@ int check_locking_order = 1;
|
||||
static pid_t check_lock_pid;
|
||||
|
||||
/** print all possible debug info on the state of the system */
|
||||
static void total_debug_info();
|
||||
static void total_debug_info(void);
|
||||
|
||||
/** print pretty lock error and exit */
|
||||
static void lock_error(struct checked_lock* lock,
|
||||
@@ -674,7 +674,7 @@ static void* checklock_main(void* arg)
|
||||
}
|
||||
|
||||
/** init the main thread */
|
||||
void checklock_start()
|
||||
void checklock_start(void)
|
||||
{
|
||||
if(!key_created) {
|
||||
struct thr_check* thisthr = (struct thr_check*)calloc(1,
|
||||
@@ -692,7 +692,7 @@ void checklock_start()
|
||||
}
|
||||
|
||||
/** stop checklocks */
|
||||
void checklock_stop()
|
||||
void checklock_stop(void)
|
||||
{
|
||||
if(key_created) {
|
||||
int i;
|
||||
@@ -726,7 +726,7 @@ checklock_thrcreate(pthread_t* id, void* (*func)(void*), void* arg)
|
||||
|
||||
/** count number of thread infos */
|
||||
static int
|
||||
count_thread_infos()
|
||||
count_thread_infos(void)
|
||||
{
|
||||
int cnt = 0;
|
||||
int i;
|
||||
@@ -795,7 +795,7 @@ thread_debug_info(struct thr_check* thr)
|
||||
}
|
||||
|
||||
static void
|
||||
total_debug_info()
|
||||
total_debug_info(void)
|
||||
{
|
||||
int i;
|
||||
log_info("checklocks: supervising %d threads.",
|
||||
|
||||
@@ -206,12 +206,12 @@ size_t lock_get_mem(void* lock);
|
||||
/**
|
||||
* Initialise checklock. Sets up internal debug structures.
|
||||
*/
|
||||
void checklock_start();
|
||||
void checklock_start(void);
|
||||
|
||||
/**
|
||||
* Cleanup internal debug state.
|
||||
*/
|
||||
void checklock_stop();
|
||||
void checklock_stop(void);
|
||||
|
||||
/**
|
||||
* Init locks.
|
||||
|
||||
+1
-1
@@ -139,7 +139,7 @@ struct tcp_proxy {
|
||||
};
|
||||
|
||||
/** usage information for delayer */
|
||||
void usage(char* argv[])
|
||||
static void usage(char* argv[])
|
||||
{
|
||||
printf("usage: %s [options]\n", argv[0]);
|
||||
printf(" -f addr : use addr, forward to that server, @port.\n");
|
||||
|
||||
+13
-42
@@ -1,19 +1,18 @@
|
||||
#!/usr/bin/env bash
|
||||
. testdata/common.sh
|
||||
|
||||
NEED_SPLINT='00-lint.tpkg'
|
||||
NEED_DOXYGEN='01-doc.tpkg'
|
||||
NEED_LDNS_TESTNS='fwd_no_edns.tpkg fwd_tcp_tc.tpkg fwd_tcp.tpkg fwd_three_service.tpkg fwd_three.tpkg fwd_ttlexpire.tpkg fwd_udp.tpkg fwd_tcp_tc6.tpkg fwd_compress_c00c.tpkg fwd_ancil.tpkg stat_timer.tpkg 05-asynclook.tpkg stream_tcp.tpkg speed_cache.tpkg fwd_oneport.tpkg fwd_udptmout.tpkg fwd_waitudp.tpkg tcp_sigpipe.tpkg hostsfileosx.tpkg local_nodefault.tpkg fwd_zero.tpkg'
|
||||
NEED_XXD='fwd_compress_c00c.tpkg fwd_zero.tpkg'
|
||||
NEED_NC='fwd_compress_c00c.tpkg fwd_zero.tpkg'
|
||||
NEED_CURL='06-ianaports.tpkg'
|
||||
NEED_CURL='06-ianaports.tpkg root_anchor.tpkg'
|
||||
NEED_WHOAMI='07-confroot.tpkg'
|
||||
NEED_IPV6='fwd_ancil.tpkg fwd_tcp_tc6.tpkg stub_udp6.tpkg'
|
||||
NEED_IPV6='fwd_ancil.tpkg fwd_tcp_tc6.tpkg stub_udp6.tpkg edns_cache.tpkg'
|
||||
NEED_NOMINGW='tcp_sigpipe.tpkg 07-confroot.tpkg 08-host-lib.tpkg fwd_ancil.tpkg'
|
||||
|
||||
# test if dig, wdiff and ldns-testns are available.
|
||||
if test ! -x "`which dig 2>&1`"; then echo No 'dig' in path; exit 1; fi
|
||||
if test ! -x "`which wdiff 2>&1`"; then echo No 'wdiff' in path; exit 1; fi
|
||||
if test ! -x "`which ldns-testns 2>&1`"; then echo No 'ldns-testns' in path; exit 1; fi
|
||||
# test if dig and ldns-testns are available.
|
||||
test_tool_avail "dig"
|
||||
test_tool_avail "ldns-testns"
|
||||
|
||||
# test for ipv6, uses streamptcp peculiarity.
|
||||
if ./streamtcp -f ::1 2>&1 | grep "not supported" >/dev/null 2>&1; then
|
||||
@@ -34,41 +33,13 @@ sh ../testcode/mini_tpkg.sh clean
|
||||
rm -f .perfstats.txt
|
||||
for test in `ls *.tpkg`; do
|
||||
SKIP=0
|
||||
if echo $NEED_SPLINT | grep $test >/dev/null; then
|
||||
if test ! -x "`which splint`"; then
|
||||
SKIP=1;
|
||||
fi
|
||||
fi
|
||||
if echo $NEED_DOXYGEN | grep $test >/dev/null; then
|
||||
if test ! -x "`which doxygen`"; then
|
||||
SKIP=1;
|
||||
fi
|
||||
fi
|
||||
if echo $NEED_CURL | grep $test >/dev/null; then
|
||||
if test ! -x "`which curl`"; then
|
||||
SKIP=1;
|
||||
fi
|
||||
fi
|
||||
if echo $NEED_LDNS_TESTNS | grep $test >/dev/null; then
|
||||
if test ! -x "`which ldns-testns`"; then
|
||||
SKIP=1;
|
||||
fi
|
||||
fi
|
||||
if echo $NEED_XXD | grep $test >/dev/null; then
|
||||
if test ! -x "`which xxd`"; then
|
||||
SKIP=1;
|
||||
fi
|
||||
fi
|
||||
if echo $NEED_NC | grep $test >/dev/null; then
|
||||
if test ! -x "`which nc`"; then
|
||||
SKIP=1;
|
||||
fi
|
||||
fi
|
||||
if echo $NEED_WHOAMI | grep $test >/dev/null; then
|
||||
if test ! -x "`which whoami`"; then
|
||||
SKIP=1;
|
||||
fi
|
||||
fi
|
||||
skip_if_in_list $test "$NEED_SPLINT" "splint"
|
||||
skip_if_in_list $test "$NEED_DOXYGEN" "doxygen"
|
||||
skip_if_in_list $test "$NEED_CURL" "curl"
|
||||
skip_if_in_list $test "$NEED_XXD" "xxd"
|
||||
skip_if_in_list $test "$NEED_NC" "nc"
|
||||
skip_if_in_list $test "$NEED_WHOAMI" "whoami"
|
||||
|
||||
if echo $NEED_IPV6 | grep $test >/dev/null; then
|
||||
if test "$HAVE_IPV6" = no; then
|
||||
SKIP=1;
|
||||
|
||||
+23
-11
@@ -54,6 +54,7 @@
|
||||
#include "util/config_file.h"
|
||||
#include "services/listen_dnsport.h"
|
||||
#include "services/outside_network.h"
|
||||
#include "services/cache/infra.h"
|
||||
#include "testcode/replay.h"
|
||||
#include "testcode/ldns-testpkts.h"
|
||||
#include "util/log.h"
|
||||
@@ -97,7 +98,7 @@ fake_event_init(struct replay_scenario* scen)
|
||||
}
|
||||
|
||||
void
|
||||
fake_event_cleanup()
|
||||
fake_event_cleanup(void)
|
||||
{
|
||||
replay_scenario_delete(saved_scenario);
|
||||
saved_scenario = NULL;
|
||||
@@ -134,6 +135,7 @@ repevt_string(enum replay_event_type t)
|
||||
case repevt_error: return "ERROR";
|
||||
case repevt_assign: return "ASSIGN";
|
||||
case repevt_traffic: return "TRAFFIC";
|
||||
case repevt_infra_rtt: return "INFRA_RTT";
|
||||
default: return "UNKNOWN";
|
||||
}
|
||||
}
|
||||
@@ -226,7 +228,7 @@ pending_find_match(struct replay_runtime* runtime, struct entry** entry,
|
||||
* @param runtime: runtime.
|
||||
* @param entry: if true, the entry that matches is returned.
|
||||
* @param pend: if true, the outgoing message that matches is returned.
|
||||
* return: true if pending query matches the now event.
|
||||
* @return: true if pending query matches the now event.
|
||||
*/
|
||||
static int
|
||||
pending_matches_range(struct replay_runtime* runtime,
|
||||
@@ -541,6 +543,18 @@ autotrust_check(struct replay_runtime* runtime, struct replay_moment* mom)
|
||||
log_info("autotrust %s is OK", mom->autotrust_id);
|
||||
}
|
||||
|
||||
/** Store RTT in infra cache */
|
||||
static void
|
||||
do_infra_rtt(struct replay_runtime* runtime)
|
||||
{
|
||||
struct replay_moment* now = runtime->now;
|
||||
int rto = infra_rtt_update(runtime->infra, &now->addr,
|
||||
now->addrlen, atoi(now->string), -1, runtime->now_secs);
|
||||
log_addr(0, "INFRA_RTT for", &now->addr, now->addrlen);
|
||||
log_info("INFRA_RTT(roundtrip %d): rto of %d", atoi(now->string), rto);
|
||||
if(rto == 0) fatal_exit("infra_rtt_update failed");
|
||||
}
|
||||
|
||||
/**
|
||||
* Advance to the next moment.
|
||||
*/
|
||||
@@ -619,6 +633,10 @@ do_moment_and_advance(struct replay_runtime* runtime)
|
||||
case repevt_traffic:
|
||||
advance_moment(runtime);
|
||||
break;
|
||||
case repevt_infra_rtt:
|
||||
do_infra_rtt(runtime);
|
||||
advance_moment(runtime);
|
||||
break;
|
||||
default:
|
||||
fatal_exit("testbound: unknown event type %d",
|
||||
runtime->now->evt_type);
|
||||
@@ -847,18 +865,20 @@ outside_network_create(struct comm_base* base, size_t bufsize,
|
||||
size_t ATTR_UNUSED(num_ports), char** ATTR_UNUSED(ifs),
|
||||
int ATTR_UNUSED(num_ifs), int ATTR_UNUSED(do_ip4),
|
||||
int ATTR_UNUSED(do_ip6), size_t ATTR_UNUSED(num_tcp),
|
||||
struct infra_cache* ATTR_UNUSED(infra),
|
||||
struct infra_cache* infra,
|
||||
struct ub_randstate* ATTR_UNUSED(rnd),
|
||||
int ATTR_UNUSED(use_caps_for_id), int* ATTR_UNUSED(availports),
|
||||
int ATTR_UNUSED(numavailports), size_t ATTR_UNUSED(unwanted_threshold),
|
||||
void (*unwanted_action)(void*), void* ATTR_UNUSED(unwanted_param),
|
||||
int ATTR_UNUSED(do_udp))
|
||||
{
|
||||
struct replay_runtime* runtime = (struct replay_runtime*)base;
|
||||
struct outside_network* outnet = calloc(1,
|
||||
sizeof(struct outside_network));
|
||||
(void)unwanted_action;
|
||||
if(!outnet)
|
||||
return NULL;
|
||||
runtime->infra = infra;
|
||||
outnet->base = base;
|
||||
outnet->udp_buff = ldns_buffer_new(bufsize);
|
||||
if(!outnet->udp_buff)
|
||||
@@ -1099,14 +1119,6 @@ void listening_ports_free(struct listen_port* list)
|
||||
free(list);
|
||||
}
|
||||
|
||||
void listen_pushback(struct listen_dnsport* ATTR_UNUSED(listen))
|
||||
{
|
||||
}
|
||||
|
||||
void listen_resume(struct listen_dnsport* ATTR_UNUSED(listen))
|
||||
{
|
||||
}
|
||||
|
||||
struct comm_point* comm_point_create_local(struct comm_base* ATTR_UNUSED(base),
|
||||
int ATTR_UNUSED(fd), size_t ATTR_UNUSED(bufsize),
|
||||
comm_point_callback_t* ATTR_UNUSED(callback),
|
||||
|
||||
@@ -61,7 +61,7 @@ void fake_event_init(struct replay_scenario* scen);
|
||||
/**
|
||||
* Deinit fake event services.
|
||||
*/
|
||||
void fake_event_cleanup();
|
||||
void fake_event_cleanup(void);
|
||||
|
||||
/**
|
||||
* Get filename to store temporary config stuff. The pid is added. in /tmp.
|
||||
|
||||
@@ -258,8 +258,7 @@ static struct entry* new_entry()
|
||||
* @param buf: is the buffer to store the result in
|
||||
* @param offset: is the starting position in the result buffer
|
||||
* @param buf_len: is the length of buf.
|
||||
*
|
||||
* This function returns the length of the result
|
||||
* @return This function returns the length of the result
|
||||
*/
|
||||
static size_t
|
||||
hexstr2bin(char *hexstr, int len, uint8_t *buf, size_t offset, size_t buf_len)
|
||||
|
||||
@@ -80,8 +80,9 @@ cd $dir
|
||||
mv $name.dir/* .
|
||||
|
||||
# EXE
|
||||
echo "minitpkg exe $name"
|
||||
echo "minitpkg exe $name" > $result
|
||||
grep "Description:" $name.dsc >> $result 2>&1
|
||||
echo "DateRunStart: "`date "+%s" 2>/dev/null` >> $result
|
||||
if test -f $name.pre; then
|
||||
echo "minitpkg exe $name.pre"
|
||||
echo "minitpkg exe $name.pre" >> $result
|
||||
@@ -113,6 +114,7 @@ if test -f $name.post; then
|
||||
echo "Warning: $name.post did not exit successfully"
|
||||
fi
|
||||
fi
|
||||
echo "DateRunEnd: "`date "+%s" 2>/dev/null` >> $result
|
||||
|
||||
mv $result ..
|
||||
cd ..
|
||||
|
||||
+6
-6
@@ -492,13 +492,13 @@ qlist_parse_line(ldns_buffer* buf, char* p)
|
||||
ldns_buffer_write_u16_at(buf, 0, 0); /* zero ID */
|
||||
if(rec) LDNS_RD_SET(ldns_buffer_begin(buf));
|
||||
if(edns) {
|
||||
struct edns_data edns;
|
||||
memset(&edns, 0, sizeof(edns));
|
||||
edns.edns_present = 1;
|
||||
edns.udp_size = EDNS_ADVERTISED_SIZE;
|
||||
struct edns_data ed;
|
||||
memset(&ed, 0, sizeof(ed));
|
||||
ed.edns_present = 1;
|
||||
ed.udp_size = EDNS_ADVERTISED_SIZE;
|
||||
/* Set DO bit in all EDNS datagrams ... */
|
||||
edns.bits = EDNS_DO;
|
||||
attach_edns_record(buf, &edns);
|
||||
ed.bits = EDNS_DO;
|
||||
attach_edns_record(buf, &ed);
|
||||
}
|
||||
ldns_rdf_deep_free(rdf);
|
||||
return 1;
|
||||
|
||||
@@ -0,0 +1,618 @@
|
||||
/*
|
||||
* petal.c - https daemon that is small and beautiful.
|
||||
*
|
||||
* Copyright (c) 2010, 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 REGENTS 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
|
||||
*
|
||||
* HTTP1.1/SSL server.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#ifdef HAVE_GETOPT_H
|
||||
#include <getopt.h>
|
||||
#endif
|
||||
#ifdef HAVE_OPENSSL_SSL_H
|
||||
#include <openssl/ssl.h>
|
||||
#endif
|
||||
#ifdef HAVE_OPENSSL_ERR_H
|
||||
#include <openssl/err.h>
|
||||
#endif
|
||||
#ifdef HAVE_OPENSSL_RAND_H
|
||||
#include <openssl/rand.h>
|
||||
#endif
|
||||
#include <openssl/x509.h>
|
||||
#include <openssl/pem.h>
|
||||
#include <ctype.h>
|
||||
#include <signal.h>
|
||||
#if defined(UNBOUND_ALLOC_LITE) || defined(UNBOUND_ALLOC_STATS)
|
||||
#ifdef malloc
|
||||
#undef malloc
|
||||
#endif
|
||||
#ifdef free
|
||||
#undef free
|
||||
#endif
|
||||
#endif /* alloc lite or alloc stats */
|
||||
|
||||
/** verbosity for this application */
|
||||
static int verb = 0;
|
||||
|
||||
/** Give petal usage, and exit (1). */
|
||||
static void
|
||||
usage()
|
||||
{
|
||||
printf("Usage: petal [opts]\n");
|
||||
printf(" https daemon serves files from ./'host'/filename\n");
|
||||
printf(" (no hostname: from the 'default' directory)\n");
|
||||
printf("-a addr bind to this address, 127.0.0.1\n");
|
||||
printf("-p port port number, default 443\n");
|
||||
printf("-k keyfile SSL private key file (PEM), petal.key\n");
|
||||
printf("-c certfile SSL certificate file (PEM), petal.pem\n");
|
||||
printf("-v more verbose\n");
|
||||
printf("-h show this usage help\n");
|
||||
printf("Version %s\n", PACKAGE_VERSION);
|
||||
printf("BSD licensed, see LICENSE in source package for details.\n");
|
||||
printf("Report bugs to %s\n", PACKAGE_BUGREPORT);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/** fatal exit */
|
||||
static void print_exit(const char* str) {printf("error %s\n", str); exit(1);}
|
||||
/** print errno */
|
||||
static void log_errno(const char* str)
|
||||
{printf("error %s: %s\n", str, strerror(errno));}
|
||||
|
||||
/** parse a text IP address into a sockaddr */
|
||||
static int
|
||||
parse_ip_addr(char* str, int port, struct sockaddr_storage* ret, socklen_t* l)
|
||||
{
|
||||
socklen_t len = 0;
|
||||
struct sockaddr_storage* addr = NULL;
|
||||
struct sockaddr_in6 a6;
|
||||
struct sockaddr_in a;
|
||||
uint16_t p = (uint16_t)port;
|
||||
int fam = 0;
|
||||
memset(&a6, 0, sizeof(a6));
|
||||
memset(&a, 0, sizeof(a));
|
||||
|
||||
if(inet_pton(AF_INET6, str, &a6.sin6_addr) > 0) {
|
||||
/* it is an IPv6 */
|
||||
fam = AF_INET6;
|
||||
a6.sin6_family = AF_INET6;
|
||||
a6.sin6_port = (in_port_t)htons(p);
|
||||
addr = (struct sockaddr_storage*)&a6;
|
||||
len = (socklen_t)sizeof(struct sockaddr_in6);
|
||||
}
|
||||
if(inet_pton(AF_INET, str, &a.sin_addr) > 0) {
|
||||
/* it is an IPv4 */
|
||||
fam = AF_INET;
|
||||
a.sin_family = AF_INET;
|
||||
a.sin_port = (in_port_t)htons(p);
|
||||
addr = (struct sockaddr_storage*)&a;
|
||||
len = (socklen_t)sizeof(struct sockaddr_in);
|
||||
}
|
||||
if(!len) print_exit("cannot parse addr");
|
||||
*l = len;
|
||||
memmove(ret, addr, len);
|
||||
return fam;
|
||||
}
|
||||
|
||||
/** close the fd */
|
||||
static void
|
||||
fd_close(int fd)
|
||||
{
|
||||
#ifndef USE_WINSOCK
|
||||
close(fd);
|
||||
#else
|
||||
closesocket(fd);
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* Read one line from SSL
|
||||
* zero terminates.
|
||||
* skips "\r\n" (but not copied to buf).
|
||||
* @param ssl: the SSL connection to read from (blocking).
|
||||
* @param buf: buffer to return line in.
|
||||
* @param len: size of the buffer.
|
||||
* @return 0 on error, 1 on success.
|
||||
*/
|
||||
static int
|
||||
read_ssl_line(SSL* ssl, char* buf, size_t len)
|
||||
{
|
||||
size_t n = 0;
|
||||
int r;
|
||||
int endnl = 0;
|
||||
while(1) {
|
||||
if(n >= len) {
|
||||
if(verb) printf("line too long\n");
|
||||
return 0;
|
||||
}
|
||||
if((r = SSL_read(ssl, buf+n, 1)) <= 0) {
|
||||
if(SSL_get_error(ssl, r) == SSL_ERROR_ZERO_RETURN) {
|
||||
/* EOF */
|
||||
break;
|
||||
}
|
||||
if(verb) printf("could not SSL_read\n");
|
||||
return 0;
|
||||
}
|
||||
if(endnl && buf[n] == '\n') {
|
||||
break;
|
||||
} else if(endnl) {
|
||||
/* bad data */
|
||||
if(verb) printf("error: stray linefeeds\n");
|
||||
return 0;
|
||||
} else if(buf[n] == '\r') {
|
||||
/* skip \r, and also \n on the wire */
|
||||
endnl = 1;
|
||||
continue;
|
||||
} else if(buf[n] == '\n') {
|
||||
/* skip the \n, we are done */
|
||||
break;
|
||||
} else n++;
|
||||
}
|
||||
buf[n] = 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/** process one http header */
|
||||
static int
|
||||
process_one_header(char* buf, char* file, size_t flen, char* host, size_t hlen,
|
||||
int* vs)
|
||||
{
|
||||
if(strncasecmp(buf, "GET ", 4) == 0) {
|
||||
char* e = strstr(buf, " HTTP/1.1");
|
||||
if(!e) e = strstr(buf, " http/1.1");
|
||||
if(!e) {
|
||||
e = strstr(buf, " HTTP/1.0");
|
||||
if(!e) e = strstr(buf, " http/1.0");
|
||||
if(!e) e = strrchr(buf, ' ');
|
||||
if(!e) e = strrchr(buf, '\t');
|
||||
if(e) *vs = 10;
|
||||
}
|
||||
if(e) *e = 0;
|
||||
if(strlen(buf) < 4) return 0;
|
||||
(void)strlcpy(file, buf+4, flen);
|
||||
} else if(strncasecmp(buf, "Host: ", 6) == 0) {
|
||||
(void)strlcpy(host, buf+6, hlen);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/** read http headers and process them */
|
||||
static int
|
||||
read_http_headers(SSL* ssl, char* file, size_t flen, char* host, size_t hlen,
|
||||
int* vs)
|
||||
{
|
||||
char buf[1024];
|
||||
file[0] = 0;
|
||||
host[0] = 0;
|
||||
while(read_ssl_line(ssl, buf, sizeof(buf))) {
|
||||
if(verb>=2) printf("read: %s\n", buf);
|
||||
if(buf[0] == 0)
|
||||
return 1;
|
||||
if(!process_one_header(buf, file, flen, host, hlen, vs))
|
||||
return 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** setup SSL context */
|
||||
static SSL_CTX*
|
||||
setup_ctx(char* key, char* cert)
|
||||
{
|
||||
SSL_CTX* ctx = SSL_CTX_new(SSLv23_server_method());
|
||||
if(!ctx) print_exit("out of memory");
|
||||
(void)SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv2);
|
||||
if(!SSL_CTX_use_certificate_file(ctx, cert, SSL_FILETYPE_PEM))
|
||||
print_exit("cannot read cert");
|
||||
if(!SSL_CTX_use_PrivateKey_file(ctx, key, SSL_FILETYPE_PEM))
|
||||
print_exit("cannot read key");
|
||||
if(!SSL_CTX_check_private_key(ctx))
|
||||
print_exit("private key is not correct");
|
||||
if(!SSL_CTX_load_verify_locations(ctx, cert, NULL))
|
||||
print_exit("cannot load cert verify locations");
|
||||
return ctx;
|
||||
}
|
||||
|
||||
/** setup listening TCP */
|
||||
static int
|
||||
setup_fd(char* addr, int port)
|
||||
{
|
||||
struct sockaddr_storage ad;
|
||||
socklen_t len;
|
||||
int fd;
|
||||
int c = 1;
|
||||
int fam = parse_ip_addr(addr, port, &ad, &len);
|
||||
fd = socket(fam, SOCK_STREAM, 0);
|
||||
if(fd == -1) {
|
||||
log_errno("socket");
|
||||
return -1;
|
||||
}
|
||||
if(setsockopt(fd, SOL_SOCKET, SO_REUSEADDR,
|
||||
(void*)&c, (socklen_t) sizeof(int)) < 0) {
|
||||
log_errno("setsockopt(SOL_SOCKET, SO_REUSEADDR)");
|
||||
}
|
||||
if(bind(fd, (struct sockaddr*)&ad, len) == -1) {
|
||||
log_errno("bind");
|
||||
fd_close(fd);
|
||||
return -1;
|
||||
}
|
||||
if(listen(fd, 5) == -1) {
|
||||
log_errno("listen");
|
||||
fd_close(fd);
|
||||
return -1;
|
||||
}
|
||||
return fd;
|
||||
}
|
||||
|
||||
/** setup SSL connection to the client */
|
||||
static SSL*
|
||||
setup_ssl(int s, SSL_CTX* ctx)
|
||||
{
|
||||
SSL* ssl = SSL_new(ctx);
|
||||
if(!ssl) return NULL;
|
||||
SSL_set_accept_state(ssl);
|
||||
(void)SSL_set_mode(ssl, SSL_MODE_AUTO_RETRY);
|
||||
if(!SSL_set_fd(ssl, s)) {
|
||||
SSL_free(ssl);
|
||||
return NULL;
|
||||
}
|
||||
return ssl;
|
||||
}
|
||||
|
||||
/** check a file name for safety */
|
||||
static int
|
||||
file_name_is_safe(char* s)
|
||||
{
|
||||
size_t l = strlen(s);
|
||||
if(s[0] != '/')
|
||||
return 0; /* must start with / */
|
||||
if(strstr(s, "/../"))
|
||||
return 0; /* no updirs in URL */
|
||||
if(l>=3 && s[l-1]=='.' && s[l-2]=='.' && s[l-3]=='/')
|
||||
return 0; /* ends with /.. */
|
||||
return 1;
|
||||
}
|
||||
|
||||
/** adjust host and filename */
|
||||
static void
|
||||
adjust_host_file(char* host, char* file)
|
||||
{
|
||||
size_t i, len;
|
||||
/* remove a port number if present */
|
||||
if(strrchr(host, ':'))
|
||||
*strrchr(host, ':') = 0;
|
||||
/* lowercase */
|
||||
len = strlen(host);
|
||||
for(i=0; i<len; i++)
|
||||
host[i] = tolower((unsigned char)host[i]);
|
||||
len = strlen(file);
|
||||
for(i=0; i<len; i++)
|
||||
file[i] = tolower((unsigned char)file[i]);
|
||||
}
|
||||
|
||||
/** check a host name for safety */
|
||||
static int
|
||||
host_name_is_safe(char* s)
|
||||
{
|
||||
if(strchr(s, '/'))
|
||||
return 0;
|
||||
if(strcmp(s, "..") == 0)
|
||||
return 0;
|
||||
if(strcmp(s, ".") == 0)
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/** provide file in whole transfer */
|
||||
static void
|
||||
provide_file_10(SSL* ssl, char* fname)
|
||||
{
|
||||
char* buf, *at;
|
||||
size_t len, avail, header_reserve=1024;
|
||||
FILE* in = fopen(fname,
|
||||
#ifndef USE_WINSOCK
|
||||
"r"
|
||||
#else
|
||||
"rb"
|
||||
#endif
|
||||
);
|
||||
int r;
|
||||
const char* rcode = "200 OK";
|
||||
if(!in) {
|
||||
char hdr[1024];
|
||||
rcode = "404 File not found";
|
||||
r = snprintf(hdr, sizeof(hdr), "HTTP/1.1 %s\r\n\r\n", rcode);
|
||||
if(SSL_write(ssl, hdr, r) <= 0) {
|
||||
/* write failure */
|
||||
}
|
||||
return;
|
||||
}
|
||||
fseek(in, 0, SEEK_END);
|
||||
len = (size_t)ftell(in);
|
||||
fseek(in, 0, SEEK_SET);
|
||||
/* plus some space for the header */
|
||||
buf = (char*)malloc(len+header_reserve);
|
||||
if(!buf) {
|
||||
fclose(in);
|
||||
return;
|
||||
}
|
||||
avail = len+header_reserve;
|
||||
at = buf;
|
||||
r = snprintf(at, avail, "HTTP/1.1 %s\r\n", rcode);
|
||||
at += r;
|
||||
avail -= r;
|
||||
r = snprintf(at, avail, "Server: petal/%s\r\n", PACKAGE_VERSION);
|
||||
at += r;
|
||||
avail -= r;
|
||||
r = snprintf(at, avail, "Content-Length: %u\r\n", (unsigned)len);
|
||||
at += r;
|
||||
avail -= r;
|
||||
r = snprintf(at, avail, "\r\n");
|
||||
at += r;
|
||||
avail -= r;
|
||||
if(avail < len) { /* robust */
|
||||
free(buf);
|
||||
fclose(in);
|
||||
return;
|
||||
}
|
||||
if(fread(at, 1, len, in) != len) {
|
||||
free(buf);
|
||||
fclose(in);
|
||||
return;
|
||||
}
|
||||
fclose(in);
|
||||
at += len;
|
||||
avail -= len;
|
||||
if(SSL_write(ssl, buf, at-buf) <= 0) {
|
||||
/* write failure */
|
||||
}
|
||||
free(buf);
|
||||
}
|
||||
|
||||
/** provide file over SSL, chunked encoding */
|
||||
static void
|
||||
provide_file_chunked(SSL* ssl, char* fname)
|
||||
{
|
||||
char buf[16384];
|
||||
char* at = buf;
|
||||
size_t avail = sizeof(buf);
|
||||
int r;
|
||||
FILE* in = fopen(fname,
|
||||
#ifndef USE_WINSOCK
|
||||
"r"
|
||||
#else
|
||||
"rb"
|
||||
#endif
|
||||
);
|
||||
const char* rcode = "200 OK";
|
||||
if(!in) {
|
||||
rcode = "404 File not found";
|
||||
}
|
||||
|
||||
/* print headers */
|
||||
r = snprintf(at, avail, "HTTP/1.1 %s\r\n", rcode);
|
||||
at += r;
|
||||
avail -= r;
|
||||
r = snprintf(at, avail, "Server: petal/%s\r\n", PACKAGE_VERSION);
|
||||
at += r;
|
||||
avail -= r;
|
||||
r = snprintf(at, avail, "Transfer-Encoding: chunked\r\n");
|
||||
at += r;
|
||||
avail -= r;
|
||||
r = snprintf(at, avail, "Connection: close\r\n");
|
||||
at += r;
|
||||
avail -= r;
|
||||
r = snprintf(at, avail, "\r\n");
|
||||
at += r;
|
||||
avail -= r;
|
||||
if(avail < 16) { /* robust */
|
||||
if(in) fclose(in);
|
||||
return;
|
||||
}
|
||||
|
||||
do {
|
||||
char tmpbuf[sizeof(buf)];
|
||||
/* read chunk; space-16 for xxxxCRLF..CRLF0CRLFCRLF (3 spare)*/
|
||||
size_t red = in?fread(tmpbuf, 1, avail-16, in):0;
|
||||
/* prepare chunk */
|
||||
r = snprintf(at, avail, "%x\r\n", (unsigned)red);
|
||||
if(verb >= 3)
|
||||
{printf("chunk len %x\n", (unsigned)red); fflush(stdout);}
|
||||
at += r;
|
||||
avail -= r;
|
||||
if(red != 0) {
|
||||
if(red > avail) break; /* robust */
|
||||
memmove(at, tmpbuf, red);
|
||||
at += red;
|
||||
avail -= red;
|
||||
r = snprintf(at, avail, "\r\n");
|
||||
at += r;
|
||||
avail -= r;
|
||||
}
|
||||
if(in && feof(in) && red != 0) {
|
||||
r = snprintf(at, avail, "0\r\n");
|
||||
at += r;
|
||||
avail -= r;
|
||||
}
|
||||
if(!in || feof(in)) {
|
||||
r = snprintf(at, avail, "\r\n");
|
||||
at += r;
|
||||
avail -= r;
|
||||
}
|
||||
/* send chunk */
|
||||
if(SSL_write(ssl, buf, at-buf) <= 0) {
|
||||
/* SSL error */
|
||||
break;
|
||||
}
|
||||
|
||||
/* setup for next chunk */
|
||||
at = buf;
|
||||
avail = sizeof(buf);
|
||||
} while(in && !feof(in) && !ferror(in));
|
||||
|
||||
if(in) fclose(in);
|
||||
}
|
||||
|
||||
/** provide service to the ssl descriptor */
|
||||
static void
|
||||
service_ssl(SSL* ssl, struct sockaddr_storage* from, socklen_t falen)
|
||||
{
|
||||
char file[1024];
|
||||
char host[1024];
|
||||
char combined[2048];
|
||||
int vs = 11;
|
||||
if(!read_http_headers(ssl, file, sizeof(file), host, sizeof(host),
|
||||
&vs))
|
||||
return;
|
||||
adjust_host_file(host, file);
|
||||
if(host[0] == 0 || !host_name_is_safe(host))
|
||||
(void)strlcpy(host, "default", sizeof(host));
|
||||
if(!file_name_is_safe(file)) {
|
||||
return;
|
||||
}
|
||||
snprintf(combined, sizeof(combined), "%s%s", host, file);
|
||||
if(verb) {
|
||||
char out[100];
|
||||
void* a = &((struct sockaddr_in*)from)->sin_addr;
|
||||
if(falen != (socklen_t)sizeof(struct sockaddr_in))
|
||||
a = &((struct sockaddr_in6*)from)->sin6_addr;
|
||||
out[0]=0;
|
||||
(void)inet_ntop((int)((struct sockaddr_in*)from)->sin_family,
|
||||
a, out, (socklen_t)sizeof(out));
|
||||
printf("%s requests %s\n", out, combined);
|
||||
fflush(stdout);
|
||||
}
|
||||
if(vs == 10)
|
||||
provide_file_10(ssl, combined);
|
||||
else provide_file_chunked(ssl, combined);
|
||||
}
|
||||
|
||||
/** provide ssl service */
|
||||
static void
|
||||
do_service(char* addr, int port, char* key, char* cert)
|
||||
{
|
||||
SSL_CTX* sslctx = setup_ctx(key, cert);
|
||||
int fd = setup_fd(addr, port);
|
||||
int go = 1;
|
||||
if(fd == -1) print_exit("could not setup sockets");
|
||||
if(verb) {printf("petal start\n"); fflush(stdout);}
|
||||
while(go) {
|
||||
struct sockaddr_storage from;
|
||||
socklen_t flen = (socklen_t)sizeof(from);
|
||||
int s = accept(fd, (struct sockaddr*)&from, &flen);
|
||||
if(verb) fflush(stdout);
|
||||
if(s != -1) {
|
||||
SSL* ssl = setup_ssl(s, sslctx);
|
||||
if(verb) fflush(stdout);
|
||||
if(ssl) {
|
||||
service_ssl(ssl, &from, flen);
|
||||
if(verb) fflush(stdout);
|
||||
SSL_shutdown(ssl);
|
||||
SSL_free(ssl);
|
||||
}
|
||||
fd_close(s);
|
||||
} else if (verb >=2) log_errno("accept");
|
||||
if(verb) fflush(stdout);
|
||||
}
|
||||
/* if we get a kill signal, the process dies and the OS reaps us */
|
||||
if(verb) printf("petal end\n");
|
||||
fd_close(fd);
|
||||
SSL_CTX_free(sslctx);
|
||||
}
|
||||
|
||||
/** getopt global, in case header files fail to declare it. */
|
||||
extern int optind;
|
||||
/** getopt global, in case header files fail to declare it. */
|
||||
extern char* optarg;
|
||||
|
||||
/** Main routine for petal */
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
int c;
|
||||
int port = 443;
|
||||
char* addr = "127.0.0.1", *key = "petal.key", *cert = "petal.pem";
|
||||
#ifdef USE_WINSOCK
|
||||
WSADATA wsa_data;
|
||||
if((c=WSAStartup(MAKEWORD(2,2), &wsa_data)) != 0)
|
||||
{ printf("WSAStartup failed\n"); exit(1); }
|
||||
atexit((void (*)(void))WSACleanup);
|
||||
#endif
|
||||
|
||||
/* parse the options */
|
||||
while( (c=getopt(argc, argv, "a:c:k:hp:v")) != -1) {
|
||||
switch(c) {
|
||||
case 'a':
|
||||
addr = optarg;
|
||||
break;
|
||||
case 'c':
|
||||
cert = optarg;
|
||||
break;
|
||||
case 'k':
|
||||
key = optarg;
|
||||
break;
|
||||
case 'p':
|
||||
port = atoi(optarg);
|
||||
break;
|
||||
case 'v':
|
||||
verb++;
|
||||
break;
|
||||
case '?':
|
||||
case 'h':
|
||||
default:
|
||||
usage();
|
||||
}
|
||||
}
|
||||
argc -= optind;
|
||||
argv += optind;
|
||||
if(argc != 0)
|
||||
usage();
|
||||
|
||||
#ifdef SIGPIPE
|
||||
(void)signal(SIGPIPE, SIG_IGN);
|
||||
#endif
|
||||
ERR_load_crypto_strings();
|
||||
ERR_load_SSL_strings();
|
||||
OpenSSL_add_all_algorithms();
|
||||
(void)SSL_library_init();
|
||||
|
||||
do_service(addr, port, key, cert);
|
||||
|
||||
CRYPTO_cleanup_all_ex_data();
|
||||
ERR_remove_state(0);
|
||||
ERR_free_strings();
|
||||
RAND_cleanup();
|
||||
return 0;
|
||||
}
|
||||
+6
-6
@@ -48,7 +48,7 @@
|
||||
#include "testcode/readhex.h"
|
||||
|
||||
/** usage information for pktview */
|
||||
void usage(char* argv[])
|
||||
static void usage(char* argv[])
|
||||
{
|
||||
printf("usage: %s\n", argv[0]);
|
||||
printf("present hex packet on stdin.\n");
|
||||
@@ -56,7 +56,7 @@ void usage(char* argv[])
|
||||
}
|
||||
|
||||
/** read hex input */
|
||||
void read_input(ldns_buffer* pkt, FILE* in)
|
||||
static void read_input(ldns_buffer* pkt, FILE* in)
|
||||
{
|
||||
char buf[102400];
|
||||
char* np = buf;
|
||||
@@ -69,7 +69,7 @@ void read_input(ldns_buffer* pkt, FILE* in)
|
||||
}
|
||||
|
||||
/** analyze domain name in packet, possibly compressed */
|
||||
void analyze_dname(ldns_buffer* pkt)
|
||||
static void analyze_dname(ldns_buffer* pkt)
|
||||
{
|
||||
size_t oldpos = ldns_buffer_position(pkt);
|
||||
size_t len;
|
||||
@@ -84,7 +84,7 @@ void analyze_dname(ldns_buffer* pkt)
|
||||
}
|
||||
|
||||
/** analyze rdata in packet */
|
||||
void analyze_rdata(ldns_buffer*pkt, const ldns_rr_descriptor* desc,
|
||||
static void analyze_rdata(ldns_buffer*pkt, const ldns_rr_descriptor* desc,
|
||||
uint16_t rdlen)
|
||||
{
|
||||
int rdf = 0;
|
||||
@@ -124,7 +124,7 @@ void analyze_rdata(ldns_buffer*pkt, const ldns_rr_descriptor* desc,
|
||||
}
|
||||
|
||||
/** analyze rr in packet */
|
||||
void analyze_rr(ldns_buffer* pkt, int q)
|
||||
static void analyze_rr(ldns_buffer* pkt, int q)
|
||||
{
|
||||
uint16_t type, dclass, len;
|
||||
uint32_t ttl;
|
||||
@@ -150,7 +150,7 @@ void analyze_rr(ldns_buffer* pkt, int q)
|
||||
}
|
||||
|
||||
/** analyse pkt */
|
||||
void analyze(ldns_buffer* pkt)
|
||||
static void analyze(ldns_buffer* pkt)
|
||||
{
|
||||
uint16_t i, f, qd, an, ns, ar;
|
||||
int rrnum = 0;
|
||||
|
||||
+22
-4
@@ -330,6 +330,24 @@ replay_moment_read(char* remain, FILE* in, const char* name, int* lineno,
|
||||
} else if(parse_keyword(&remain, "ASSIGN")) {
|
||||
mom->evt_type = repevt_assign;
|
||||
read_assign_step(remain, mom);
|
||||
} else if(parse_keyword(&remain, "INFRA_RTT")) {
|
||||
char *s;
|
||||
mom->evt_type = repevt_infra_rtt;
|
||||
while(isspace((int)*remain))
|
||||
remain++;
|
||||
s = remain;
|
||||
remain = strchr(s, ' ');
|
||||
if(!remain) fatal_exit("expected two args for INFRA_RTT");
|
||||
remain[0] = 0;
|
||||
remain++;
|
||||
while(isspace((int)*remain))
|
||||
remain++;
|
||||
if(!extstrtoaddr(s, &mom->addr, &mom->addrlen))
|
||||
fatal_exit("bad infra_rtt address %s", s);
|
||||
if(strlen(remain)>0 && remain[strlen(remain)-1]=='\n')
|
||||
remain[strlen(remain)-1] = 0;
|
||||
mom->string = strdup(remain);
|
||||
if(!mom->string) fatal_exit("out of memory");
|
||||
} else {
|
||||
log_err("%d: unknown event type %s", *lineno, remain);
|
||||
free(mom);
|
||||
@@ -606,7 +624,7 @@ do_macro_recursion(rbtree_t* store, struct replay_runtime* runtime,
|
||||
}
|
||||
|
||||
/** get var from store */
|
||||
struct replay_var*
|
||||
static struct replay_var*
|
||||
macro_getvar(rbtree_t* store, char* name)
|
||||
{
|
||||
struct replay_var k;
|
||||
@@ -950,17 +968,17 @@ void testbound_selftest(void)
|
||||
free(v);
|
||||
|
||||
v = macro_process(store, NULL, "it is ${ctime 123456}");
|
||||
log_assert( v && strcmp(v, "it is Fri Jan 2 11:17:36 1970") == 0);
|
||||
log_assert( v && strcmp(v, "it is Fri Jan 2 10:17:36 1970") == 0);
|
||||
free(v);
|
||||
|
||||
r = macro_assign(store, "t1", "123456");
|
||||
log_assert(r);
|
||||
v = macro_process(store, NULL, "it is ${ctime ${$t1}}");
|
||||
log_assert( v && strcmp(v, "it is Fri Jan 2 11:17:36 1970") == 0);
|
||||
log_assert( v && strcmp(v, "it is Fri Jan 2 10:17:36 1970") == 0);
|
||||
free(v);
|
||||
|
||||
v = macro_process(store, NULL, "it is ${ctime $t1}");
|
||||
log_assert( v && strcmp(v, "it is Fri Jan 2 11:17:36 1970") == 0);
|
||||
log_assert( v && strcmp(v, "it is Fri Jan 2 10:17:36 1970") == 0);
|
||||
free(v);
|
||||
|
||||
r = macro_assign(store, "x", "1");
|
||||
|
||||
+8
-1
@@ -75,6 +75,7 @@
|
||||
* the step waits for traffic to stop.
|
||||
* o CHECK_AUTOTRUST [id] - followed by FILE_BEGIN [to match] FILE_END.
|
||||
* The file contents is macro expanded before match.
|
||||
* o INFRA_RTT [ip] [rtt] - update infra cache entry with rtt.
|
||||
* o ERROR
|
||||
* ; following entry starts on the next line, ENTRY_BEGIN.
|
||||
* ; more STEP items
|
||||
@@ -136,6 +137,7 @@ struct replay_range;
|
||||
struct fake_pending;
|
||||
struct fake_timer;
|
||||
struct replay_var;
|
||||
struct infra_cache;
|
||||
|
||||
/**
|
||||
* A replay scenario.
|
||||
@@ -196,9 +198,11 @@ struct replay_moment {
|
||||
repevt_error,
|
||||
/** assignment to a variable */
|
||||
repevt_assign,
|
||||
/** store infra rtt cache entry: addr and string (int) */
|
||||
repevt_infra_rtt,
|
||||
/** cause traffic to flow */
|
||||
repevt_traffic
|
||||
}
|
||||
}
|
||||
/** variable with what is to happen this moment */
|
||||
evt_type;
|
||||
|
||||
@@ -285,6 +289,9 @@ struct replay_runtime {
|
||||
/** user argument for incoming query callback */
|
||||
void *cb_arg;
|
||||
|
||||
/** ref the infra cache (was passed to outside_network_create) */
|
||||
struct infra_cache* infra;
|
||||
|
||||
/** the current time in seconds */
|
||||
uint32_t now_secs;
|
||||
/** the current time in microseconds */
|
||||
|
||||
@@ -58,7 +58,7 @@
|
||||
#endif
|
||||
|
||||
/** usage information for streamtcp */
|
||||
void usage(char* argv[])
|
||||
static void usage(char* argv[])
|
||||
{
|
||||
printf("usage: %s [options] name type class ...\n", argv[0]);
|
||||
printf(" sends the name-type-class queries over TCP.\n");
|
||||
|
||||
+14
-5
@@ -82,14 +82,14 @@ testbound_usage()
|
||||
|
||||
/**
|
||||
* Add options from string to passed argc. splits on whitespace.
|
||||
* @param optarg: the option argument, "-v -p 12345" or so.
|
||||
* @param args: the option argument, "-v -p 12345" or so.
|
||||
* @param pass_argc: ptr to the argc for unbound. Modified.
|
||||
* @param pass_argv: the argv to pass to unbound. Modified.
|
||||
*/
|
||||
static void
|
||||
add_opts(const char* optarg, int* pass_argc, char* pass_argv[])
|
||||
add_opts(const char* args, int* pass_argc, char* pass_argv[])
|
||||
{
|
||||
const char *p = optarg, *np;
|
||||
const char *p = args, *np;
|
||||
size_t len;
|
||||
while(p && isspace((int)*p))
|
||||
p++;
|
||||
@@ -251,6 +251,7 @@ void remove_configfile(void)
|
||||
* Main fake event test program. Setup, teardown and report errors.
|
||||
* @param argc: arg count.
|
||||
* @param argv: array of commandline arguments.
|
||||
* @return program failure if test fails.
|
||||
*/
|
||||
int
|
||||
main(int argc, char* argv[])
|
||||
@@ -263,8 +264,10 @@ main(int argc, char* argv[])
|
||||
char* init_optarg = optarg;
|
||||
struct replay_scenario* scen = NULL;
|
||||
|
||||
/* we do not want the test to depend on the timezone */
|
||||
(void)putenv("TZ=UTC");
|
||||
|
||||
log_init(NULL, 0, NULL);
|
||||
log_info("Start of %s testbound program.", PACKAGE_STRING);
|
||||
/* determine commandline options for the daemon */
|
||||
pass_argc = 1;
|
||||
pass_argv[0] = "unbound";
|
||||
@@ -318,6 +321,7 @@ main(int argc, char* argv[])
|
||||
testbound_usage();
|
||||
return 1;
|
||||
}
|
||||
log_info("Start of %s testbound program.", PACKAGE_STRING);
|
||||
if(atexit(&remove_configfile) != 0)
|
||||
fatal_exit("atexit() failed: %s", strerror(errno));
|
||||
|
||||
@@ -339,8 +343,13 @@ main(int argc, char* argv[])
|
||||
fake_event_cleanup();
|
||||
for(c=1; c<pass_argc; c++)
|
||||
free(pass_argv[c]);
|
||||
if(res == 0)
|
||||
if(res == 0) {
|
||||
log_info("Testbound Exit Success");
|
||||
#ifdef HAVE_PTHREAD
|
||||
/* dlopen frees its thread state (dlopen of gost engine) */
|
||||
pthread_exit(NULL);
|
||||
#endif
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
@@ -121,7 +121,7 @@ test_anchors(ldns_buffer* buff, struct val_anchors* a)
|
||||
unit_assert(anchors_lookup(a, (uint8_t*)"\002oo\000", 4, c) == NULL);
|
||||
}
|
||||
|
||||
void anchors_test()
|
||||
void anchors_test(void)
|
||||
{
|
||||
ldns_buffer* buff = ldns_buffer_new(65800);
|
||||
struct val_anchors* a;
|
||||
|
||||
+14
-14
@@ -100,7 +100,7 @@ dname_test_qdtl(ldns_buffer* buff)
|
||||
|
||||
/** test query_dname_compare */
|
||||
static void
|
||||
dname_test_query_dname_compare()
|
||||
dname_test_query_dname_compare(void)
|
||||
{
|
||||
unit_show_func("util/data/dname.c", "query_dname_compare");
|
||||
unit_assert(query_dname_compare((uint8_t*)"", (uint8_t*)"") == 0);
|
||||
@@ -130,7 +130,7 @@ dname_test_query_dname_compare()
|
||||
|
||||
/** test dname_count_labels */
|
||||
static void
|
||||
dname_test_count_labels()
|
||||
dname_test_count_labels(void)
|
||||
{
|
||||
unit_show_func("util/data/dname.c", "dname_count_labels");
|
||||
unit_assert(dname_count_labels((uint8_t*)"") == 1);
|
||||
@@ -143,7 +143,7 @@ dname_test_count_labels()
|
||||
|
||||
/** test dname_count_size_labels */
|
||||
static void
|
||||
dname_test_count_size_labels()
|
||||
dname_test_count_size_labels(void)
|
||||
{
|
||||
size_t sz = 0;
|
||||
unit_show_func("util/data/dname.c", "dname_count_size_labels");
|
||||
@@ -270,7 +270,7 @@ dname_test_pkt_dname_len(ldns_buffer* buff)
|
||||
|
||||
/** test dname_lab_cmp */
|
||||
static void
|
||||
dname_test_dname_lab_cmp()
|
||||
dname_test_dname_lab_cmp(void)
|
||||
{
|
||||
int ml = 0; /* number of labels that matched exactly */
|
||||
unit_show_func("util/data/dname.c", "dname_lab_cmp");
|
||||
@@ -372,7 +372,7 @@ dname_test_dname_lab_cmp()
|
||||
|
||||
/** test dname_subdomain_c */
|
||||
static void
|
||||
dname_test_subdomain()
|
||||
dname_test_subdomain(void)
|
||||
{
|
||||
unit_show_func("util/data/dname.c", "dname_subdomain");
|
||||
unit_assert(dname_subdomain_c(
|
||||
@@ -409,7 +409,7 @@ dname_test_subdomain()
|
||||
|
||||
/** test dname_strict_subdomain */
|
||||
static void
|
||||
dname_test_strict_subdomain()
|
||||
dname_test_strict_subdomain(void)
|
||||
{
|
||||
unit_show_func("util/data/dname.c", "dname_strict_subdomain");
|
||||
unit_assert(!dname_strict_subdomain(
|
||||
@@ -446,7 +446,7 @@ dname_test_strict_subdomain()
|
||||
|
||||
/** test dname_is_root */
|
||||
static void
|
||||
dname_test_isroot()
|
||||
dname_test_isroot(void)
|
||||
{
|
||||
unit_show_func("util/data/dname.c", "dname_isroot");
|
||||
unit_assert(dname_is_root((uint8_t*)"\000"));
|
||||
@@ -459,7 +459,7 @@ dname_test_isroot()
|
||||
|
||||
/** test dname_remove_label */
|
||||
static void
|
||||
dname_test_removelabel()
|
||||
dname_test_removelabel(void)
|
||||
{
|
||||
uint8_t* orig = (uint8_t*)"\007example\003com\000";
|
||||
uint8_t* n = orig;
|
||||
@@ -478,7 +478,7 @@ dname_test_removelabel()
|
||||
|
||||
/** test dname_signame_label_count */
|
||||
static void
|
||||
dname_test_sigcount()
|
||||
dname_test_sigcount(void)
|
||||
{
|
||||
unit_show_func("util/data/dname.c", "dname_signame_label_count");
|
||||
unit_assert(dname_signame_label_count((uint8_t*)"\000") == 0);
|
||||
@@ -498,7 +498,7 @@ dname_test_sigcount()
|
||||
|
||||
/** test dname_is_wild routine */
|
||||
static void
|
||||
dname_test_iswild()
|
||||
dname_test_iswild(void)
|
||||
{
|
||||
unit_show_func("util/data/dname.c", "dname_iswild");
|
||||
unit_assert( !dname_is_wild((uint8_t*)"\000") );
|
||||
@@ -509,7 +509,7 @@ dname_test_iswild()
|
||||
|
||||
/** test dname_canonical_compare */
|
||||
static void
|
||||
dname_test_canoncmp()
|
||||
dname_test_canoncmp(void)
|
||||
{
|
||||
unit_show_func("util/data/dname.c", "dname_canonical_compare");
|
||||
/* equality */
|
||||
@@ -729,7 +729,7 @@ dname_test_canoncmp()
|
||||
|
||||
/** Test dname_get_shared_topdomain */
|
||||
static void
|
||||
dname_test_topdomain()
|
||||
dname_test_topdomain(void)
|
||||
{
|
||||
unit_show_func("util/data/dname.c", "dname_get_shared_topdomain");
|
||||
unit_assert( query_dname_compare(
|
||||
@@ -751,7 +751,7 @@ dname_test_topdomain()
|
||||
|
||||
/** Test dname_valid */
|
||||
static void
|
||||
dname_test_valid()
|
||||
dname_test_valid(void)
|
||||
{
|
||||
unit_show_func("util/data/dname.c", "dname_valid");
|
||||
unit_assert( dname_valid(
|
||||
@@ -831,7 +831,7 @@ dname_setup_bufs(ldns_buffer* loopbuf, ldns_buffer* boundbuf)
|
||||
ldns_buffer_flip(boundbuf);
|
||||
}
|
||||
|
||||
void dname_test()
|
||||
void dname_test(void)
|
||||
{
|
||||
ldns_buffer* loopbuf = ldns_buffer_new(14);
|
||||
ldns_buffer* boundbuf = ldns_buffer_new(16);
|
||||
|
||||
@@ -477,7 +477,7 @@ test_threaded_table(struct lruhash* table)
|
||||
if(0) lruhash_status(table, "hashtest", 1);
|
||||
}
|
||||
|
||||
void lruhash_test()
|
||||
void lruhash_test(void)
|
||||
{
|
||||
/* start very very small array, so it can do lots of table_grow() */
|
||||
/* also small in size so that reclaim has to be done quickly. */
|
||||
|
||||
+59
-7
@@ -65,7 +65,7 @@ int testcount = 0;
|
||||
#include "util/alloc.h"
|
||||
/** test alloc code */
|
||||
static void
|
||||
alloc_test() {
|
||||
alloc_test(void) {
|
||||
alloc_special_t *t1, *t2;
|
||||
struct alloc_cache major, minor1, minor2;
|
||||
int i;
|
||||
@@ -104,7 +104,7 @@ alloc_test() {
|
||||
#include "util/net_help.h"
|
||||
/** test net code */
|
||||
static void
|
||||
net_test()
|
||||
net_test(void)
|
||||
{
|
||||
const char* t4[] = {"\000\000\000\000",
|
||||
"\200\000\000\000",
|
||||
@@ -304,12 +304,40 @@ net_test()
|
||||
unit_assert(ipstrtoaddr("2::ffff:192.168.0.2", 53, &a, &l));
|
||||
unit_assert(!addr_is_ip4mapped(&a, l));
|
||||
}
|
||||
/* test addr_is_any */
|
||||
unit_show_func("util/net_help.c", "addr_is_any");
|
||||
if(1) {
|
||||
struct sockaddr_storage a;
|
||||
socklen_t l = (socklen_t)sizeof(a);
|
||||
unit_assert(ipstrtoaddr("0.0.0.0", 53, &a, &l));
|
||||
unit_assert(addr_is_any(&a, l));
|
||||
unit_assert(ipstrtoaddr("0.0.0.0", 10053, &a, &l));
|
||||
unit_assert(addr_is_any(&a, l));
|
||||
unit_assert(ipstrtoaddr("0.0.0.0", 0, &a, &l));
|
||||
unit_assert(addr_is_any(&a, l));
|
||||
unit_assert(ipstrtoaddr("::0", 0, &a, &l));
|
||||
unit_assert(addr_is_any(&a, l));
|
||||
unit_assert(ipstrtoaddr("::0", 53, &a, &l));
|
||||
unit_assert(addr_is_any(&a, l));
|
||||
unit_assert(ipstrtoaddr("::1", 53, &a, &l));
|
||||
unit_assert(!addr_is_any(&a, l));
|
||||
unit_assert(ipstrtoaddr("2001:1667::1", 0, &a, &l));
|
||||
unit_assert(!addr_is_any(&a, l));
|
||||
unit_assert(ipstrtoaddr("2001::0", 0, &a, &l));
|
||||
unit_assert(!addr_is_any(&a, l));
|
||||
unit_assert(ipstrtoaddr("10.0.0.0", 0, &a, &l));
|
||||
unit_assert(!addr_is_any(&a, l));
|
||||
unit_assert(ipstrtoaddr("0.0.0.10", 0, &a, &l));
|
||||
unit_assert(!addr_is_any(&a, l));
|
||||
unit_assert(ipstrtoaddr("192.0.2.1", 0, &a, &l));
|
||||
unit_assert(!addr_is_any(&a, l));
|
||||
}
|
||||
}
|
||||
|
||||
#include "util/config_file.h"
|
||||
/** test config_file: cfg_parse_memsize */
|
||||
static void
|
||||
config_memsize_test()
|
||||
config_memsize_test(void)
|
||||
{
|
||||
size_t v = 0;
|
||||
unit_show_func("util/config_file.c", "cfg_parse_memsize");
|
||||
@@ -348,7 +376,7 @@ config_memsize_test()
|
||||
#include "util/rtt.h"
|
||||
/** test RTT code */
|
||||
static void
|
||||
rtt_test()
|
||||
rtt_test(void)
|
||||
{
|
||||
int init = 376;
|
||||
int i;
|
||||
@@ -375,7 +403,7 @@ rtt_test()
|
||||
#include "util/config_file.h"
|
||||
/** test host cache */
|
||||
static void
|
||||
infra_test()
|
||||
infra_test(void)
|
||||
{
|
||||
struct sockaddr_storage one;
|
||||
socklen_t onelen;
|
||||
@@ -407,7 +435,7 @@ infra_test()
|
||||
unit_assert( infra_edns_update(slab, &one, onelen, -1, now) );
|
||||
unit_assert( infra_host(slab, &one, onelen,
|
||||
now, &vs, &edns_lame, &to) );
|
||||
unit_assert( vs == 0 && to == init*2 && edns_lame == 0);
|
||||
unit_assert( vs == -1 && to == init*2 && edns_lame == 1);
|
||||
|
||||
now += cfg->host_ttl + 10;
|
||||
unit_assert( infra_host(slab, &one, onelen,
|
||||
@@ -437,6 +465,22 @@ infra_test()
|
||||
unit_assert(!dlame && !rlame && alame && olame);
|
||||
lock_rw_unlock(&k->entry.lock);
|
||||
|
||||
/* test that noEDNS cannot overwrite known-yesEDNS */
|
||||
now += cfg->host_ttl + 10;
|
||||
unit_assert( infra_host(slab, &one, onelen,
|
||||
now, &vs, &edns_lame, &to) );
|
||||
unit_assert( vs == 0 && to == init && edns_lame == 0 );
|
||||
|
||||
unit_assert( infra_edns_update(slab, &one, onelen, 0, now) );
|
||||
unit_assert( infra_host(slab, &one, onelen,
|
||||
now, &vs, &edns_lame, &to) );
|
||||
unit_assert( vs == 0 && to == init && edns_lame == 1 );
|
||||
|
||||
unit_assert( infra_edns_update(slab, &one, onelen, -1, now) );
|
||||
unit_assert( infra_host(slab, &one, onelen,
|
||||
now, &vs, &edns_lame, &to) );
|
||||
unit_assert( vs == 0 && to == init && edns_lame == 1 );
|
||||
|
||||
infra_delete(slab);
|
||||
config_delete(cfg);
|
||||
}
|
||||
@@ -444,7 +488,7 @@ infra_test()
|
||||
#include "util/random.h"
|
||||
/** test randomness */
|
||||
static void
|
||||
rnd_test()
|
||||
rnd_test(void)
|
||||
{
|
||||
struct ub_randstate* r;
|
||||
int num = 1000, i;
|
||||
@@ -487,6 +531,7 @@ void unit_show_feature(const char* feature)
|
||||
* Main unit test program. Setup, teardown and report errors.
|
||||
* @param argc: arg count.
|
||||
* @param argv: array of commandline arguments.
|
||||
* @return program failure if test fails.
|
||||
*/
|
||||
int
|
||||
main(int argc, char* argv[])
|
||||
@@ -522,6 +567,9 @@ main(int argc, char* argv[])
|
||||
msgparse_test();
|
||||
checklock_stop();
|
||||
printf("%d checks ok.\n", testcount);
|
||||
#if defined(USE_GOST) && defined(HAVE_LDNS_KEY_EVP_UNLOAD_GOST)
|
||||
ldns_key_EVP_unload_gost();
|
||||
#endif
|
||||
#ifdef HAVE_OPENSSL_CONFIG
|
||||
EVP_cleanup();
|
||||
ENGINE_cleanup();
|
||||
@@ -531,5 +579,9 @@ main(int argc, char* argv[])
|
||||
ERR_remove_state(0);
|
||||
ERR_free_strings();
|
||||
RAND_cleanup();
|
||||
#ifdef HAVE_PTHREAD
|
||||
/* dlopen frees its thread specific state */
|
||||
pthread_exit(NULL);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
+8
-8
@@ -57,20 +57,20 @@ void unit_show_func(const char* file, const char* func);
|
||||
void unit_show_feature(const char* feature);
|
||||
|
||||
/** unit test lruhashtable implementation */
|
||||
void lruhash_test();
|
||||
void lruhash_test(void);
|
||||
/** unit test slabhashtable implementation */
|
||||
void slabhash_test();
|
||||
void slabhash_test(void);
|
||||
/** unit test for msgreply and msgparse */
|
||||
void msgparse_test();
|
||||
void msgparse_test(void);
|
||||
/** unit test dname handling functions */
|
||||
void dname_test();
|
||||
void dname_test(void);
|
||||
/** unit test trust anchor storage functions */
|
||||
void anchors_test();
|
||||
void anchors_test(void);
|
||||
/** unit test for verification functions */
|
||||
void verify_test();
|
||||
void verify_test(void);
|
||||
/** unit test for negative cache functions */
|
||||
void neg_test();
|
||||
void neg_test(void);
|
||||
/** unit test for regional allocator functions */
|
||||
void regional_test();
|
||||
void regional_test(void);
|
||||
|
||||
#endif /* TESTCODE_UNITMAIN_H */
|
||||
|
||||
+11
-3
@@ -53,6 +53,8 @@
|
||||
|
||||
/** verbose message parse unit test */
|
||||
static int vbmp = 0;
|
||||
/** do not accept formerr */
|
||||
static int check_formerr_gone = 0;
|
||||
/** if matching within a section should disregard the order of RRs. */
|
||||
static int matches_nolocation = 0;
|
||||
/** see if RRSIGs are properly matched to RRsets. */
|
||||
@@ -415,10 +417,12 @@ testpkt(ldns_buffer* pkt, struct alloc_cache* alloc, ldns_buffer* out,
|
||||
if(ret != 0) {
|
||||
if(vbmp) printf("parse code %d: %s\n", ret,
|
||||
ldns_lookup_by_id(ldns_rcodes, ret)->name);
|
||||
if(ret == LDNS_RCODE_FORMERR)
|
||||
if(ret == LDNS_RCODE_FORMERR) {
|
||||
unit_assert(!check_formerr_gone);
|
||||
checkformerr(pkt);
|
||||
}
|
||||
unit_assert(ret != LDNS_RCODE_SERVFAIL);
|
||||
} else {
|
||||
} else if(!check_formerr_gone) {
|
||||
const size_t lim = 512;
|
||||
ret = reply_info_encode(&qi, rep, id, flags, out, timenow,
|
||||
region, 65535, (int)(edns.bits & EDNS_DO) );
|
||||
@@ -573,7 +577,7 @@ testfromdrillfile(ldns_buffer* pkt, struct alloc_cache* alloc,
|
||||
fclose(in);
|
||||
}
|
||||
|
||||
void msgparse_test()
|
||||
void msgparse_test(void)
|
||||
{
|
||||
ldns_buffer* pkt = ldns_buffer_new(65553);
|
||||
ldns_buffer* out = ldns_buffer_new(65553);
|
||||
@@ -599,6 +603,10 @@ void msgparse_test()
|
||||
check_rrsigs = 0;
|
||||
matches_nolocation = 0;
|
||||
|
||||
check_formerr_gone = 1;
|
||||
testfromdrillfile(pkt, &alloc, out, "testdata/test_packets.8");
|
||||
check_formerr_gone = 0;
|
||||
|
||||
/* cleanup */
|
||||
alloc_clear(&alloc);
|
||||
alloc_clear(&super_a);
|
||||
|
||||
+2
-2
@@ -91,7 +91,7 @@ static void print_neg_cache(struct val_neg_cache* neg)
|
||||
}
|
||||
|
||||
/** get static pointer to random zone name */
|
||||
static char* get_random_zone()
|
||||
static char* get_random_zone(void)
|
||||
{
|
||||
static char zname[256];
|
||||
int labels = random() % 3;
|
||||
@@ -526,7 +526,7 @@ static void stress_test(struct val_neg_cache* neg)
|
||||
}
|
||||
}
|
||||
|
||||
void neg_test()
|
||||
void neg_test(void)
|
||||
{
|
||||
struct val_neg_cache* neg;
|
||||
srandom(48);
|
||||
|
||||
@@ -195,7 +195,7 @@ corner_cases(struct regional* r)
|
||||
|
||||
/** test specific cases */
|
||||
static void
|
||||
specific_cases()
|
||||
specific_cases(void)
|
||||
{
|
||||
struct regional* r = regional_create();
|
||||
corner_cases(r);
|
||||
@@ -228,7 +228,7 @@ burden_test(size_t max)
|
||||
|
||||
/** randomly allocate stuff */
|
||||
static void
|
||||
random_burden()
|
||||
random_burden(void)
|
||||
{
|
||||
size_t max_alloc = 2048 + 128; /* small chance of LARGE */
|
||||
int i;
|
||||
@@ -236,7 +236,7 @@ random_burden()
|
||||
burden_test(max_alloc);
|
||||
}
|
||||
|
||||
void regional_test()
|
||||
void regional_test(void)
|
||||
{
|
||||
unit_show_feature("regional");
|
||||
specific_cases();
|
||||
|
||||
@@ -356,7 +356,7 @@ test_threaded_table(struct slabhash* table)
|
||||
if(0) slabhash_status(table, "hashtest", 1);
|
||||
}
|
||||
|
||||
void slabhash_test()
|
||||
void slabhash_test(void)
|
||||
{
|
||||
/* start very very small array, so it can do lots of table_grow() */
|
||||
/* also small in size so that reclaim has to be done quickly. */
|
||||
|
||||
+32
-3
@@ -148,6 +148,33 @@ should_be_bogus(struct ub_packed_rrset_key* rrset, struct query_info* qinfo)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** return number of rrs in an rrset */
|
||||
static size_t
|
||||
rrset_get_count(struct ub_packed_rrset_key* rrset)
|
||||
{
|
||||
struct packed_rrset_data* d = (struct packed_rrset_data*)
|
||||
rrset->entry.data;
|
||||
if(!d) return 0;
|
||||
return d->count;
|
||||
}
|
||||
|
||||
/** setup sig alg list from dnskey */
|
||||
static void
|
||||
setup_sigalg(struct ub_packed_rrset_key* dnskey, uint8_t* sigalg)
|
||||
{
|
||||
uint8_t a[ALGO_NEEDS_MAX];
|
||||
size_t i, n = 0;
|
||||
memset(a, 0, sizeof(a));
|
||||
for(i=0; i<rrset_get_count(dnskey); i++) {
|
||||
uint8_t algo = (uint8_t)dnskey_get_algo(dnskey, i);
|
||||
if(a[algo] == 0) {
|
||||
a[algo] = 1;
|
||||
sigalg[n++] = algo;
|
||||
}
|
||||
}
|
||||
sigalg[n] = 0;
|
||||
}
|
||||
|
||||
/** verify and test one rrset against the key rrset */
|
||||
static void
|
||||
verifytest_rrset(struct module_env* env, struct val_env* ve,
|
||||
@@ -156,12 +183,14 @@ verifytest_rrset(struct module_env* env, struct val_env* ve,
|
||||
{
|
||||
enum sec_status sec;
|
||||
char* reason = NULL;
|
||||
uint8_t sigalg[ALGO_NEEDS_MAX+1];
|
||||
if(vsig) {
|
||||
log_nametypeclass(VERB_QUERY, "verify of rrset",
|
||||
rrset->rk.dname, ntohs(rrset->rk.type),
|
||||
ntohs(rrset->rk.rrset_class));
|
||||
}
|
||||
sec = dnskeyset_verify_rrset(env, ve, rrset, dnskey, &reason);
|
||||
setup_sigalg(dnskey, sigalg); /* check all algorithms in the dnskey */
|
||||
sec = dnskeyset_verify_rrset(env, ve, rrset, dnskey, sigalg, &reason);
|
||||
if(vsig) {
|
||||
printf("verify outcome is: %s %s\n", sec_status_to_string(sec),
|
||||
reason?reason:"");
|
||||
@@ -343,7 +372,7 @@ unitest_nsec_has_type_rdata(char* bitmap, size_t len, uint16_t type)
|
||||
|
||||
/** Test NSEC type bitmap routine */
|
||||
static void
|
||||
nsectest()
|
||||
nsectest(void)
|
||||
{
|
||||
/* bitmap starts at type bitmap rdata field */
|
||||
/* from rfc 4034 example */
|
||||
@@ -465,7 +494,7 @@ nsec3_hash_test(const char* fname)
|
||||
}
|
||||
|
||||
void
|
||||
verify_test()
|
||||
verify_test(void)
|
||||
{
|
||||
unit_show_feature("signature verify");
|
||||
verifytest_file("testdata/test_signatures.1", "20070818005004");
|
||||
|
||||
Vendored
BIN
Binary file not shown.
Vendored
BIN
Binary file not shown.
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user