mirror of
https://github.com/NLnetLabs/unbound.git
synced 2026-08-17 21:25:50 +02:00
Compare commits
141
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3d7ad2de3c | ||
|
|
24cb32dc6b | ||
|
|
4263f2a692 | ||
|
|
8459b5f55f | ||
|
|
6acc20abf4 | ||
|
|
498039108b | ||
|
|
d165625c4d | ||
|
|
af6cbba475 | ||
|
|
14f657933c | ||
|
|
1808c93e15 | ||
|
|
8078891a28 | ||
|
|
9a102eed3e | ||
|
|
02c493bd2d | ||
|
|
e2f8a1cb82 | ||
|
|
78a3c4e93d | ||
|
|
5eb7ff35ca | ||
|
|
4e1eab891b | ||
|
|
31a3035c60 | ||
|
|
aaab8cb352 | ||
|
|
fc0dcf12c3 | ||
|
|
4664c66f06 | ||
|
|
56f3cd33ec | ||
|
|
a64adc395f | ||
|
|
66f896ddbf | ||
|
|
ee5ee20071 | ||
|
|
fc3fc7a1f3 | ||
|
|
7be0e5b814 | ||
|
|
d4cfee1f00 | ||
|
|
f7059107b3 | ||
|
|
7a528cdf53 | ||
|
|
f90f5a2583 | ||
|
|
76ee7a352a | ||
|
|
148e8a69c9 | ||
|
|
39e4ba0e78 | ||
|
|
afda1a8bcc | ||
|
|
092a325270 | ||
|
|
cc6322ac0f | ||
|
|
2487f435f6 | ||
|
|
423e1a95a8 | ||
|
|
8ffff3c0a3 | ||
|
|
39e01091e7 | ||
|
|
8527bd4aff | ||
|
|
1dec098624 | ||
|
|
283f2a5edb | ||
|
|
0db56d8a0d | ||
|
|
065d2ad96f | ||
|
|
d7f2306161 | ||
|
|
66c8bd4ad1 | ||
|
|
725929734e | ||
|
|
60f51c1197 | ||
|
|
85abd17e90 | ||
|
|
ef69508048 | ||
|
|
97854e6bc5 | ||
|
|
01af814844 | ||
|
|
6de373e04c | ||
|
|
4a6d702edf | ||
|
|
0bad5716d4 | ||
|
|
55fe583de8 | ||
|
|
55aefcad19 | ||
|
|
fa07056f79 | ||
|
|
5990dde29b | ||
|
|
f9074eb440 | ||
|
|
54318b8c35 | ||
|
|
3bbe7a2e0b | ||
|
|
0f56fd3042 | ||
|
|
0d3ecd25df | ||
|
|
96d4800692 | ||
|
|
d13686227c | ||
|
|
e60174a000 | ||
|
|
556b4efb8a | ||
|
|
cf3d92a7a7 | ||
|
|
cf19737ee6 | ||
|
|
3dca36a649 | ||
|
|
aab6da9362 | ||
|
|
8d472c8cf8 | ||
|
|
baf8056ba5 | ||
|
|
17631b6fd8 | ||
|
|
1b3eb34cd1 | ||
|
|
6d3f7cc4e0 | ||
|
|
3f94669a88 | ||
|
|
395f328d4a | ||
|
|
4ba9161e75 | ||
|
|
8638d6c019 | ||
|
|
95296a2528 | ||
|
|
9dd64e357f | ||
|
|
8ef2cb4705 | ||
|
|
9b55215eb6 | ||
|
|
9f104a42d0 | ||
|
|
21e851b0fb | ||
|
|
227ae5b7a4 | ||
|
|
9739014da1 | ||
|
|
c49eefba59 | ||
|
|
c6bbc4ea23 | ||
|
|
f7d8e3f4bd | ||
|
|
dd7404f467 | ||
|
|
30a1d557bd | ||
|
|
a377c6a9d5 | ||
|
|
f47e78c543 | ||
|
|
f9fd2676f9 | ||
|
|
c858743222 | ||
|
|
9ab79dc0dc | ||
|
|
ffed368bfc | ||
|
|
5abd6c8da1 | ||
|
|
d44b91ec12 | ||
|
|
399a165cc3 | ||
|
|
97ebee32d0 | ||
|
|
29f4a9ab78 | ||
|
|
b6a93eae31 | ||
|
|
3fced109b9 | ||
|
|
77e7e73a32 | ||
|
|
adb8eda081 | ||
|
|
0cc33e29e7 | ||
|
|
9e9d7ba0a7 | ||
|
|
74530fdb64 | ||
|
|
2f7bd77250 | ||
|
|
dccc665658 | ||
|
|
2139a8572c | ||
|
|
e65070ce6f | ||
|
|
b9bf0872c2 | ||
|
|
2904445bd2 | ||
|
|
f17580e460 | ||
|
|
0f80e5e78a | ||
|
|
a8bf62f962 | ||
|
|
234defa371 | ||
|
|
20ee8c10f5 | ||
|
|
06f41d9d84 | ||
|
|
f0cf79146c | ||
|
|
7eeb7cc78c | ||
|
|
46e703c989 | ||
|
|
d26b183ba6 | ||
|
|
ff8c2ed1bc | ||
|
|
8359474330 | ||
|
|
64627b1a63 | ||
|
|
87700fea40 | ||
|
|
bbe801da93 | ||
|
|
f35ae11ff4 | ||
|
|
677d67c29c | ||
|
|
6adf9e1459 | ||
|
|
85af59c734 | ||
|
|
30478d3e17 | ||
|
|
288f022dd6 |
+61
-53
@@ -34,6 +34,7 @@ libtool=@libtool@
|
||||
ldnsdir=@ldnsdir@
|
||||
staticexe=@staticexe@
|
||||
configfile=@ub_conf_file@
|
||||
CHECKLOCK_SRC=@CHECKLOCK_SRC@
|
||||
|
||||
YACC=@YACC@
|
||||
LEX=@LEX@
|
||||
@@ -62,63 +63,63 @@ COMMON_SRC=$(patsubst $(srcdir)/%,%, $(wildcard $(srcdir)/services/*.c \
|
||||
$(srcdir)/services/cache/*.c $(srcdir)/util/*.c \
|
||||
$(srcdir)/util/data/*.c $(srcdir)/util/storage/*.c \
|
||||
$(srcdir)/iterator/*.c $(srcdir)/validator/*.c)) \
|
||||
util/configparser.c util/configlexer.c testcode/checklocks.c
|
||||
COMMON_OBJ=$(addprefix $(BUILD),$(COMMON_SRC:.c=.o))
|
||||
COMPAT_OBJ=$(addprefix $(BUILD)compat/,$(LIBOBJS))
|
||||
util/configparser.c util/configlexer.c $(CHECKLOCK_SRC)
|
||||
COMMON_OBJ=$(addprefix $(BUILD),$(COMMON_SRC:.c=.lo))
|
||||
COMPAT_OBJ=$(addprefix $(BUILD)compat/,$(LIBOBJS:.o=.lo))
|
||||
UNITTEST_SRC=$(patsubst $(srcdir)/%,%, \
|
||||
$(wildcard $(srcdir)/testcode/unit*.c)) \
|
||||
testcode/readhex.c testcode/ldns-testpkts.c smallapp/worker_cb.c \
|
||||
$(COMMON_SRC)
|
||||
UNITTEST_OBJ=$(addprefix $(BUILD),$(UNITTEST_SRC:.c=.o)) $(COMPAT_OBJ)
|
||||
UNITTEST_OBJ=$(addprefix $(BUILD),$(UNITTEST_SRC:.c=.lo)) $(COMPAT_OBJ)
|
||||
DAEMON_SRC=$(patsubst $(srcdir)/%,%, $(wildcard $(srcdir)/daemon/*.c)) \
|
||||
$(COMMON_SRC)
|
||||
DAEMON_OBJ=$(addprefix $(BUILD),$(DAEMON_SRC:.c=.o)) $(COMPAT_OBJ)
|
||||
DAEMON_OBJ=$(addprefix $(BUILD),$(DAEMON_SRC:.c=.lo)) $(COMPAT_OBJ)
|
||||
CHECKCONF_SRC=smallapp/unbound-checkconf.c smallapp/worker_cb.c $(COMMON_SRC)
|
||||
CHECKCONF_OBJ=$(addprefix $(BUILD),$(CHECKCONF_SRC:.c=.o)) $(COMPAT_OBJ)
|
||||
CHECKCONF_OBJ=$(addprefix $(BUILD),$(CHECKCONF_SRC:.c=.lo)) $(COMPAT_OBJ)
|
||||
HOST_SRC=smallapp/unbound-host.c
|
||||
HOST_OBJ=$(addprefix $(BUILD),$(HOST_SRC:.c=.o)) $(COMPAT_OBJ)
|
||||
HOST_OBJ=$(addprefix $(BUILD),$(HOST_SRC:.c=.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 \
|
||||
services/listen_dnsport.c services/outside_network.c, $(COMMON_SRC))
|
||||
TESTBOUND_OBJ=$(addprefix $(BUILD),$(TESTBOUND_SRC:.c=.o)) $(COMPAT_OBJ)
|
||||
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=.o)) $(COMPAT_OBJ)
|
||||
LOCKVERIFY_OBJ=$(addprefix $(BUILD),$(LOCKVERIFY_SRC:.c=.lo)) $(COMPAT_OBJ)
|
||||
PKTVIEW_SRC=testcode/pktview.c testcode/readhex.c smallapp/worker_cb.c \
|
||||
$(COMMON_SRC)
|
||||
PKTVIEW_OBJ=$(addprefix $(BUILD),$(PKTVIEW_SRC:.c=.o)) $(COMPAT_OBJ)
|
||||
PKTVIEW_OBJ=$(addprefix $(BUILD),$(PKTVIEW_SRC:.c=.lo)) $(COMPAT_OBJ)
|
||||
SIGNIT_SRC=testcode/signit.c smallapp/worker_cb.c $(COMMON_SRC)
|
||||
SIGNIT_OBJ=$(addprefix $(BUILD),$(SIGNIT_SRC:.c=.o)) $(COMPAT_OBJ)
|
||||
SIGNIT_OBJ=$(addprefix $(BUILD),$(SIGNIT_SRC:.c=.lo)) $(COMPAT_OBJ)
|
||||
MEMSTATS_SRC=testcode/memstats.c smallapp/worker_cb.c $(COMMON_SRC)
|
||||
MEMSTATS_OBJ=$(addprefix $(BUILD),$(MEMSTATS_SRC:.c=.o)) $(COMPAT_OBJ)
|
||||
MEMSTATS_OBJ=$(addprefix $(BUILD),$(MEMSTATS_SRC:.c=.lo)) $(COMPAT_OBJ)
|
||||
ASYNCLOOK_SRC=testcode/asynclook.c
|
||||
ASYNCLOOK_OBJ=$(addprefix $(BUILD),$(ASYNCLOOK_SRC:.c=.o)) $(COMPAT_OBJ)
|
||||
ASYNCLOOK_OBJ=$(addprefix $(BUILD),$(ASYNCLOOK_SRC:.c=.lo)) $(COMPAT_OBJ)
|
||||
STREAMTCP_SRC=testcode/streamtcp.c smallapp/worker_cb.c $(COMMON_SRC)
|
||||
STREAMTCP_OBJ=$(addprefix $(BUILD),$(STREAMTCP_SRC:.c=.o)) $(COMPAT_OBJ)
|
||||
STREAMTCP_OBJ=$(addprefix $(BUILD),$(STREAMTCP_SRC:.c=.lo)) $(COMPAT_OBJ)
|
||||
PERF_SRC=testcode/perf.c smallapp/worker_cb.c $(COMMON_SRC)
|
||||
PERF_OBJ=$(addprefix $(BUILD),$(PERF_SRC:.c=.o)) $(COMPAT_OBJ)
|
||||
PERF_OBJ=$(addprefix $(BUILD),$(PERF_SRC:.c=.lo)) $(COMPAT_OBJ)
|
||||
DELAYER_SRC=testcode/delayer.c smallapp/worker_cb.c $(COMMON_SRC)
|
||||
DELAYER_OBJ=$(addprefix $(BUILD),$(DELAYER_SRC:.c=.o)) $(COMPAT_OBJ)
|
||||
DELAYER_OBJ=$(addprefix $(BUILD),$(DELAYER_SRC:.c=.lo)) $(COMPAT_OBJ)
|
||||
HARVEST_SRC=testcode/harvest.c
|
||||
HARVEST_OBJ=$(addprefix $(BUILD),$(HARVEST_SRC:.c=.o)) $(COMPAT_OBJ)
|
||||
HARVEST_OBJ=$(addprefix $(BUILD),$(HARVEST_SRC:.c=.lo)) $(COMPAT_OBJ)
|
||||
LIBUNBOUND_SRC=$(patsubst $(srcdir)/%,%, \
|
||||
$(wildcard $(srcdir)/libunbound/*.c) $(COMMON_SRC))
|
||||
LIBUNBOUND_OBJ=$(addprefix $(BUILD),$(LIBUNBOUND_SRC:.c=.o)) $(COMPAT_OBJ)
|
||||
LIBUNBOUND_OBJ=$(addprefix $(BUILD),$(LIBUNBOUND_SRC:.c=.lo)) $(COMPAT_OBJ)
|
||||
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) )
|
||||
ALL_OBJ=$(addprefix $(BUILD),$(ALL_SRC:.c=.o) \
|
||||
$(addprefix compat/,$(LIBOBJS))) $(COMPAT_OBJ)
|
||||
ALL_OBJ=$(addprefix $(BUILD),$(ALL_SRC:.c=.lo) \
|
||||
$(addprefix compat/,$(LIBOBJS:.o=.lo))) $(COMPAT_OBJ)
|
||||
|
||||
COMPILE=$(LIBTOOL) --tag=CC --mode=compile $(CC) $(CPPFLAGS) $(CFLAGS)
|
||||
LINK=$(LIBTOOL) --tag=CC --mode=link $(CC) $(staticexe) $(RUNTIME_PATH) $(CFLAGS) $(LDFLAGS)
|
||||
LINK_LIB=$(LIBTOOL) --tag=CC --mode=link $(CC) $(RUNTIME_PATH) $(CFLAGS) $(LDFLAGS) $(staticexe) -release $(VERSION) -no-undefined
|
||||
LINK_LIB=$(LIBTOOL) --tag=CC --mode=link $(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
|
||||
|
||||
$(BUILD)%.o: $(srcdir)/%.c
|
||||
$(BUILD)%.lo: $(srcdir)/%.c
|
||||
$(INFO) Build $<
|
||||
@if test ! -z "$(ldnsdir)" -a ! -e $(ldnsdir)/include/ldns/ldns.h; \
|
||||
then (cd $(ldnsdir); $(MAKE) copy-headers); fi
|
||||
@@ -131,13 +132,13 @@ tests: all unittest testbound lock-verify pktview signit memstats \
|
||||
asynclook streamtcp perf delayer harvest
|
||||
|
||||
test: tests
|
||||
bash testcode/do-tests.sh
|
||||
if test -x "`which bash`"; then bash testcode/do-tests.sh; else sh testcode/do-tests.sh; fi
|
||||
|
||||
lib: libunbound.la
|
||||
|
||||
libunbound.la: $(LIBUNBOUND_OBJ)
|
||||
$(INFO) Link $@
|
||||
$Q$(LINK_LIB) --export-symbols $(srcdir)/libunbound/ubsyms.def -o $@ $(sort $(LIBUNBOUND_OBJ:.o=.lo)) -rpath $(libdir) $(LIBS)
|
||||
$Q$(LINK_LIB) --export-symbols $(srcdir)/libunbound/ubsyms.def -o $@ $(sort $(LIBUNBOUND_OBJ)) -rpath $(libdir) $(LIBS)
|
||||
|
||||
ifeq ($(patsubst ldns-src%,ldns-src,$(ldnsdir)),ldns-src)
|
||||
ldnslib=$(ldnsdir)/lib/libldns.a
|
||||
@@ -227,6 +228,7 @@ util/configparser.c util/configparser.h: $(srcdir)/util/configparser.y
|
||||
|
||||
clean:
|
||||
rm -f *.o *.d *.lo *~ tags
|
||||
rm -f unbound unbound-checkconf unbound-host
|
||||
rm -rf autom4te.cache .libs build doc/html
|
||||
|
||||
realclean: clean
|
||||
@@ -257,42 +259,48 @@ strip:
|
||||
strip unbound-host
|
||||
|
||||
install:
|
||||
$(INSTALL) -m 755 -d $(sbindir)
|
||||
$(INSTALL) -m 755 -d $(mandir)
|
||||
$(INSTALL) -m 755 -d $(mandir)/man8
|
||||
$(INSTALL) -m 755 -d $(mandir)/man5
|
||||
$(INSTALL) -m 755 -d $(mandir)/man3
|
||||
$(INSTALL) -m 755 -d $(mandir)/man1
|
||||
$(INSTALL) -m 755 -d $(libdir)
|
||||
$(INSTALL) -m 755 -d $(includedir)
|
||||
$(LIBTOOL) --mode=install cp unbound $(sbindir)/unbound
|
||||
$(LIBTOOL) --mode=install cp unbound-checkconf $(sbindir)/unbound-checkconf
|
||||
$(LIBTOOL) --mode=install cp unbound-host $(sbindir)/unbound-host
|
||||
$(INSTALL) -c -m 644 $(srcdir)/doc/unbound.8 $(mandir)/man8
|
||||
$(INSTALL) -c -m 644 $(srcdir)/doc/unbound-checkconf.8 $(mandir)/man8
|
||||
$(INSTALL) -c -m 644 $(srcdir)/doc/unbound.conf.5 $(mandir)/man5
|
||||
$(INSTALL) -c -m 644 $(srcdir)/doc/unbound-host.1 $(mandir)/man1
|
||||
$(INSTALL) -c -m 644 $(srcdir)/doc/libunbound.3 $(mandir)/man3
|
||||
if test ! -e $(configfile); then $(INSTALL) -d `dirname $(configfile)`; $(INSTALL) -c -m 644 $(srcdir)/doc/example.conf $(configfile); fi
|
||||
$(LIBTOOL) --mode=install cp $(srcdir)/libunbound/unbound.h $(includedir)/unbound.h
|
||||
$(LIBTOOL) --mode=install cp libunbound.la $(libdir)
|
||||
$(LIBTOOL) --mode=finish $(libdir)
|
||||
$(INSTALL) -m 755 -d $(DESTDIR)$(sbindir)
|
||||
$(INSTALL) -m 755 -d $(DESTDIR)$(mandir)
|
||||
$(INSTALL) -m 755 -d $(DESTDIR)$(mandir)/man8
|
||||
$(INSTALL) -m 755 -d $(DESTDIR)$(mandir)/man5
|
||||
$(INSTALL) -m 755 -d $(DESTDIR)$(mandir)/man3
|
||||
$(INSTALL) -m 755 -d $(DESTDIR)$(mandir)/man1
|
||||
$(INSTALL) -m 755 -d $(DESTDIR)$(libdir)
|
||||
$(INSTALL) -m 755 -d $(DESTDIR)$(includedir)
|
||||
$(LIBTOOL) --mode=install cp unbound $(DESTDIR)$(sbindir)/unbound
|
||||
$(LIBTOOL) --mode=install cp unbound-checkconf $(DESTDIR)$(sbindir)/unbound-checkconf
|
||||
$(LIBTOOL) --mode=install cp unbound-host $(DESTDIR)$(sbindir)/unbound-host
|
||||
$(INSTALL) -c -m 644 $(srcdir)/doc/unbound.8 $(DESTDIR)$(mandir)/man8
|
||||
$(INSTALL) -c -m 644 $(srcdir)/doc/unbound-checkconf.8 $(DESTDIR)$(mandir)/man8
|
||||
$(INSTALL) -c -m 644 $(srcdir)/doc/unbound.conf.5 $(DESTDIR)$(mandir)/man5
|
||||
$(INSTALL) -c -m 644 $(srcdir)/doc/unbound-host.1 $(DESTDIR)$(mandir)/man1
|
||||
$(INSTALL) -c -m 644 $(srcdir)/doc/libunbound.3 $(DESTDIR)$(mandir)/man3
|
||||
if test ! -e $(DESTDIR)$(configfile); then $(INSTALL) -d `dirname $(DESTDIR)$(configfile)`; $(INSTALL) -c -m 644 $(srcdir)/doc/example.conf $(DESTDIR)$(configfile); fi
|
||||
$(LIBTOOL) --mode=install cp $(srcdir)/libunbound/unbound.h $(DESTDIR)$(includedir)/unbound.h
|
||||
$(LIBTOOL) --mode=install cp libunbound.la $(DESTDIR)$(libdir)
|
||||
$(LIBTOOL) --mode=finish $(DESTDIR)$(libdir)
|
||||
|
||||
uninstall:
|
||||
rm -f -- $(sbindir)/unbound $(sbindir)/unbound-checkconf $(sbindir)/unbound-host
|
||||
rm -f -- $(mandir)/man8/unbound.8 $(mandir)/man8/unbound-checkconf.8 $(mandir)/man5/unbound.conf.5
|
||||
rm -f -- $(mandir)/man1/unbound-host.1 $(mandir)/man3/libunbound.3
|
||||
rm -f -- $(includedir)/unbound.h
|
||||
$(LIBTOOL) --mode=uninstall rm -f $(libdir)/libunbound.la
|
||||
rm -f -- $(DESTDIR)$(sbindir)/unbound $(DESTDIR)$(sbindir)/unbound-checkconf $(DESTDIR)$(sbindir)/unbound-host
|
||||
rm -f -- $(DESTDIR)$(mandir)/man8/unbound.8 $(DESTDIR)$(mandir)/man8/unbound-checkconf.8 $(DESTDIR)$(mandir)/man5/unbound.conf.5
|
||||
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
|
||||
@echo
|
||||
@echo "You still need to remove `dirname $(configfile)` , $(configfile) by hand"
|
||||
@echo "You still need to remove "`dirname $(DESTDIR)$(configfile)`" , $(DESTDIR)$(configfile) by hand"
|
||||
|
||||
download_ldns:
|
||||
svn export https://www.nlnetlabs.nl/ldns/svn/trunk/makedist.sh ldns_makedist.sh
|
||||
./ldns_makedist.sh -s -d https://www.nlnetlabs.nl/ldns/svn/trunk
|
||||
svn export https://www.nlnetlabs.nl/svn/ldns/trunk/makedist.sh ldns_makedist.sh
|
||||
./ldns_makedist.sh -s -d https://www.nlnetlabs.nl/svn/ldns/trunk
|
||||
mv ldns-*_pre_*.tar.gz ldns-src.tar.gz
|
||||
rm ldns-*_pre_*.tar.gz.sha1 ldns_makedist.sh
|
||||
|
||||
iana_update:
|
||||
curl -o port-numbers.tmp http://www.iana.org/assignments/port-numbers
|
||||
egrep -v "Unassigned|Reserved" port-numbers.tmp | awk '{ match($$0, "[0-9]+/udp"); if (RLENGTH > 0) print substr($$0, RSTART, RLENGTH - 4) ","}' | sort -nu > portslist.tmp
|
||||
cat portslist.tmp > util/iana_ports.inc
|
||||
rm -f port-numbers.tmp portslist.tmp
|
||||
|
||||
# Automatic dependencies.
|
||||
$(BUILD)%.d: $(srcdir)/%.c
|
||||
$(INFO) Depend $<
|
||||
@@ -300,7 +308,7 @@ $(BUILD)%.d: $(srcdir)/%.c
|
||||
then (cd $(ldnsdir); $(MAKE) copy-headers); fi
|
||||
@-if test ! -d $(dir $@); then $(INSTALL) -d $(patsubst %/,%,$(dir $@)); fi
|
||||
$Q$(SHELL) -ec '$(CC) -MM $(CPPFLAGS) $(CFLAGS) $< \
|
||||
| sed '\''s!\(.*\)\.o[ :]*!$(dir $@)\1.o $@ : !g'\'' > $@; \
|
||||
| sed '\''s!\(.*\)\.o[ :]*!$(dir $@)\1.lo $@ : !g'\'' > $@; \
|
||||
[ -s $@ ] || rm -f $@'
|
||||
|
||||
ifneq ($(MAKECMDGOALS),clean)
|
||||
|
||||
Vendored
+370
-198
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,107 @@
|
||||
/*
|
||||
* Taken from FreeBSD src / lib / libc / stdtime / localtime.c 1.43 revision.
|
||||
* localtime.c 7.78.
|
||||
* tzfile.h 1.8
|
||||
* adapted to be replacement gmtime_r.
|
||||
*/
|
||||
#include "config.h"
|
||||
|
||||
#ifdef HAVE_TIME_H
|
||||
#include <time.h>
|
||||
#endif
|
||||
|
||||
#define MONSPERYEAR 12
|
||||
#define DAYSPERNYEAR 365
|
||||
#define DAYSPERLYEAR 366
|
||||
#define SECSPERMIN 60
|
||||
#define SECSPERHOUR (60*60)
|
||||
#define SECSPERDAY (24*60*60)
|
||||
#define DAYSPERWEEK 7
|
||||
#define TM_SUNDAY 0
|
||||
#define TM_MONDAY 1
|
||||
#define TM_TUESDAY 2
|
||||
#define TM_WEDNESDAY 3
|
||||
#define TM_THURSDAY 4
|
||||
#define TM_FRIDAY 5
|
||||
#define TM_SATURDAY 6
|
||||
|
||||
#define TM_YEAR_BASE 1900
|
||||
|
||||
#define EPOCH_YEAR 1970
|
||||
#define EPOCH_WDAY TM_THURSDAY
|
||||
|
||||
#define isleap(y) (((y) % 4) == 0 && (((y) % 100) != 0 || ((y) % 400) == 0))
|
||||
|
||||
static const int mon_lengths[2][MONSPERYEAR] = {
|
||||
{ 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 },
|
||||
{ 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }
|
||||
};
|
||||
|
||||
static const int year_lengths[2] = {
|
||||
DAYSPERNYEAR, DAYSPERLYEAR
|
||||
};
|
||||
|
||||
static void
|
||||
timesub(timep, offset, tmp)
|
||||
const time_t * const timep;
|
||||
const long offset;
|
||||
struct tm * const tmp;
|
||||
{
|
||||
long days;
|
||||
long rem;
|
||||
long y;
|
||||
int yleap;
|
||||
const int * ip;
|
||||
|
||||
days = *timep / SECSPERDAY;
|
||||
rem = *timep % SECSPERDAY;
|
||||
rem += (offset);
|
||||
while (rem < 0) {
|
||||
rem += SECSPERDAY;
|
||||
--days;
|
||||
}
|
||||
while (rem >= SECSPERDAY) {
|
||||
rem -= SECSPERDAY;
|
||||
++days;
|
||||
}
|
||||
tmp->tm_hour = (int) (rem / SECSPERHOUR);
|
||||
rem = rem % SECSPERHOUR;
|
||||
tmp->tm_min = (int) (rem / SECSPERMIN);
|
||||
/*
|
||||
** A positive leap second requires a special
|
||||
** representation. This uses "... ??:59:60" et seq.
|
||||
*/
|
||||
tmp->tm_sec = (int) (rem % SECSPERMIN) ;
|
||||
tmp->tm_wday = (int) ((EPOCH_WDAY + days) % DAYSPERWEEK);
|
||||
if (tmp->tm_wday < 0)
|
||||
tmp->tm_wday += DAYSPERWEEK;
|
||||
y = EPOCH_YEAR;
|
||||
#define LEAPS_THRU_END_OF(y) ((y) / 4 - (y) / 100 + (y) / 400)
|
||||
while (days < 0 || days >= (long) year_lengths[yleap = isleap(y)]) {
|
||||
long newy;
|
||||
|
||||
newy = y + days / DAYSPERNYEAR;
|
||||
if (days < 0)
|
||||
--newy;
|
||||
days -= (newy - y) * DAYSPERNYEAR +
|
||||
LEAPS_THRU_END_OF(newy - 1) -
|
||||
LEAPS_THRU_END_OF(y - 1);
|
||||
y = newy;
|
||||
}
|
||||
tmp->tm_year = y - TM_YEAR_BASE;
|
||||
tmp->tm_yday = (int) days;
|
||||
ip = mon_lengths[yleap];
|
||||
for (tmp->tm_mon = 0; days >= (long) ip[tmp->tm_mon]; ++(tmp->tm_mon))
|
||||
days = days - (long) ip[tmp->tm_mon];
|
||||
tmp->tm_mday = (int) (days + 1);
|
||||
tmp->tm_isdst = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Re-entrant version of gmtime.
|
||||
*/
|
||||
struct tm * gmtime_r(const time_t* timep, struct tm *tm)
|
||||
{
|
||||
timesub(timep, 0L, tm);
|
||||
return tm;
|
||||
}
|
||||
@@ -56,8 +56,12 @@
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/param.h>
|
||||
#ifdef HAVE_NETINET_IN_H
|
||||
#include <netinet/in.h>
|
||||
#endif
|
||||
#ifdef HAVE_ARPA_INET_H
|
||||
#include <arpa/inet.h>
|
||||
#endif
|
||||
#include <ctype.h>
|
||||
|
||||
#if 0
|
||||
|
||||
@@ -23,8 +23,12 @@
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/types.h>
|
||||
#ifdef HAVE_SYS_SOCKET_H
|
||||
#include <sys/socket.h>
|
||||
#endif
|
||||
#ifdef HAVE_NETINET_IN_H
|
||||
#include <netinet/in.h>
|
||||
#endif
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
@@ -62,7 +66,11 @@ inet_ntop(int af, const void *src, char *dst, size_t size)
|
||||
case AF_INET6:
|
||||
return (inet_ntop6(src, dst, size));
|
||||
default:
|
||||
#ifdef EAFNOSUPPORT
|
||||
errno = EAFNOSUPPORT;
|
||||
#else
|
||||
errno = ENOSYS;
|
||||
#endif
|
||||
return (NULL);
|
||||
}
|
||||
/* NOTREACHED */
|
||||
|
||||
@@ -70,7 +70,11 @@ inet_pton(af, src, dst)
|
||||
case AF_INET6:
|
||||
return (inet_pton6(src, dst));
|
||||
default:
|
||||
#ifdef EAFNOSUPPORT
|
||||
errno = EAFNOSUPPORT;
|
||||
#else
|
||||
errno = ENOSYS;
|
||||
#endif
|
||||
return (-1);
|
||||
}
|
||||
/* NOTREACHED */
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
/* socketpair.c - windows mingw32 replacement for socketpair.
|
||||
* creates a pipe that works like a socketpair a bit
|
||||
* Taken from libevent-1.4.3.stable WIN32-Code/misc.c
|
||||
* License: BSD.
|
||||
*/
|
||||
#include "config.h"
|
||||
#include <stdio.h>
|
||||
#include <windows.h>
|
||||
|
||||
int
|
||||
socketpair(int d, int type, int protocol, int *sv)
|
||||
{
|
||||
static int count;
|
||||
char buf[64];
|
||||
HANDLE fd;
|
||||
DWORD dwMode;
|
||||
(void)d; (void)type; (void)protocol;
|
||||
sprintf(buf, "\\\\.\\pipe\\levent-%d", count++);
|
||||
/* Create a duplex pipe which will behave like a socket pair */
|
||||
fd = CreateNamedPipe(buf, PIPE_ACCESS_DUPLEX, PIPE_TYPE_BYTE | PIPE_NOWAIT,
|
||||
PIPE_UNLIMITED_INSTANCES, 4096, 4096, 0, NULL);
|
||||
if (fd == INVALID_HANDLE_VALUE)
|
||||
return (-1);
|
||||
sv[0] = (int)fd;
|
||||
|
||||
fd = CreateFile(buf, GENERIC_READ|GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||
if (fd == INVALID_HANDLE_VALUE)
|
||||
return (-1);
|
||||
dwMode = PIPE_NOWAIT;
|
||||
SetNamedPipeHandleState(fd, &dwMode, NULL, NULL);
|
||||
sv[1] = (int)fd;
|
||||
|
||||
return (0);
|
||||
}
|
||||
Vendored
+25
-9
@@ -4,7 +4,7 @@
|
||||
# 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation,
|
||||
# Inc.
|
||||
|
||||
timestamp='2006-07-02'
|
||||
timestamp='2007-05-17'
|
||||
|
||||
# This file is free software; you can redistribute it and/or modify it
|
||||
# under the terms of the GNU General Public License as published by
|
||||
@@ -161,6 +161,7 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
|
||||
arm*) machine=arm-unknown ;;
|
||||
sh3el) machine=shl-unknown ;;
|
||||
sh3eb) machine=sh-unknown ;;
|
||||
sh5el) machine=sh5le-unknown ;;
|
||||
*) machine=${UNAME_MACHINE_ARCH}-unknown ;;
|
||||
esac
|
||||
# The Operating System including object format, if it has switched
|
||||
@@ -329,7 +330,7 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
|
||||
sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*)
|
||||
echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
|
||||
exit ;;
|
||||
i86pc:SunOS:5.*:*)
|
||||
i86pc:SunOS:5.*:* | ix86xen:SunOS:5.*:*)
|
||||
echo i386-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
|
||||
exit ;;
|
||||
sun4*:SunOS:6*:*)
|
||||
@@ -780,7 +781,7 @@ EOF
|
||||
i*:CYGWIN*:*)
|
||||
echo ${UNAME_MACHINE}-pc-cygwin
|
||||
exit ;;
|
||||
i*:MINGW*:*)
|
||||
*:MINGW*:*)
|
||||
echo ${UNAME_MACHINE}-pc-mingw32
|
||||
exit ;;
|
||||
i*:windows32*:*)
|
||||
@@ -790,12 +791,15 @@ EOF
|
||||
i*:PW*:*)
|
||||
echo ${UNAME_MACHINE}-pc-pw32
|
||||
exit ;;
|
||||
x86:Interix*:[3456]*)
|
||||
echo i586-pc-interix${UNAME_RELEASE}
|
||||
exit ;;
|
||||
EM64T:Interix*:[3456]*)
|
||||
echo x86_64-unknown-interix${UNAME_RELEASE}
|
||||
exit ;;
|
||||
*:Interix*:[3456]*)
|
||||
case ${UNAME_MACHINE} in
|
||||
x86)
|
||||
echo i586-pc-interix${UNAME_RELEASE}
|
||||
exit ;;
|
||||
EM64T | authenticamd)
|
||||
echo x86_64-unknown-interix${UNAME_RELEASE}
|
||||
exit ;;
|
||||
esac ;;
|
||||
[345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*)
|
||||
echo i${UNAME_MACHINE}-pc-mks
|
||||
exit ;;
|
||||
@@ -950,6 +954,9 @@ EOF
|
||||
x86_64:Linux:*:*)
|
||||
echo x86_64-unknown-linux-gnu
|
||||
exit ;;
|
||||
xtensa:Linux:*:*)
|
||||
echo xtensa-unknown-linux-gnu
|
||||
exit ;;
|
||||
i*86:Linux:*:*)
|
||||
# The BFD linker knows what the default object file format is, so
|
||||
# first see if it will tell us. cd to the root directory to prevent
|
||||
@@ -1208,6 +1215,15 @@ EOF
|
||||
SX-6:SUPER-UX:*:*)
|
||||
echo sx6-nec-superux${UNAME_RELEASE}
|
||||
exit ;;
|
||||
SX-7:SUPER-UX:*:*)
|
||||
echo sx7-nec-superux${UNAME_RELEASE}
|
||||
exit ;;
|
||||
SX-8:SUPER-UX:*:*)
|
||||
echo sx8-nec-superux${UNAME_RELEASE}
|
||||
exit ;;
|
||||
SX-8R:SUPER-UX:*:*)
|
||||
echo sx8r-nec-superux${UNAME_RELEASE}
|
||||
exit ;;
|
||||
Power*:Rhapsody:*:*)
|
||||
echo powerpc-apple-rhapsody${UNAME_RELEASE}
|
||||
exit ;;
|
||||
|
||||
+150
-4
@@ -21,30 +21,51 @@
|
||||
/* Define to 1 if your system has a working `chown' function. */
|
||||
#undef HAVE_CHOWN
|
||||
|
||||
/* Define to 1 if you have the `chroot' function. */
|
||||
#undef HAVE_CHROOT
|
||||
|
||||
/* Define to 1 if you have the <dlfcn.h> header file. */
|
||||
#undef HAVE_DLFCN_H
|
||||
|
||||
/* Define to 1 if you have the `event_base_free' function. */
|
||||
#undef HAVE_EVENT_BASE_FREE
|
||||
|
||||
/* Define to 1 if you have the `event_base_get_method' function. */
|
||||
#undef HAVE_EVENT_BASE_GET_METHOD
|
||||
|
||||
/* Define to 1 if you have the `event_base_once' function. */
|
||||
#undef HAVE_EVENT_BASE_ONCE
|
||||
|
||||
/* Define to 1 if you have the <event.h> header file. */
|
||||
#undef HAVE_EVENT_H
|
||||
|
||||
/* Define to 1 if you have the `fcntl' function. */
|
||||
#undef HAVE_FCNTL
|
||||
|
||||
/* Define to 1 if you have the `fork' function. */
|
||||
#undef HAVE_FORK
|
||||
|
||||
/* Define to 1 if fseeko (and presumably ftello) exists and is declared. */
|
||||
#undef HAVE_FSEEKO
|
||||
|
||||
/* Define to 1 if you have the `getaddrinfo' function. */
|
||||
/* Whether getaddrinfo is available */
|
||||
#undef HAVE_GETADDRINFO
|
||||
|
||||
/* Define to 1 if you have the <getopt.h> header file. */
|
||||
#undef HAVE_GETOPT_H
|
||||
|
||||
/* Define to 1 if you have the `getpwnam' function. */
|
||||
#undef HAVE_GETPWNAM
|
||||
|
||||
/* Define to 1 if you have the `getrlimit' function. */
|
||||
#undef HAVE_GETRLIMIT
|
||||
|
||||
/* Define to 1 if you have the `gmtime_r' function. */
|
||||
#undef HAVE_GMTIME_R
|
||||
|
||||
/* If you have HMAC_CTX_init */
|
||||
#undef HAVE_HMAC_CTX_INIT
|
||||
|
||||
/* Define to 1 if you have the `inet_aton' function. */
|
||||
#undef HAVE_INET_ATON
|
||||
|
||||
@@ -57,8 +78,11 @@
|
||||
/* Define to 1 if you have the <inttypes.h> header file. */
|
||||
#undef HAVE_INTTYPES_H
|
||||
|
||||
/* Define to 1 if you have the `crypto' library (-lcrypto). */
|
||||
#undef HAVE_LIBCRYPTO
|
||||
/* if the function 'ioctlsocket' is available */
|
||||
#undef HAVE_IOCTLSOCKET
|
||||
|
||||
/* Define to 1 if you have the `kill' function. */
|
||||
#undef HAVE_KILL
|
||||
|
||||
/* Define to 1 if you have the `ldns' library (-lldns). */
|
||||
#undef HAVE_LIBLDNS
|
||||
@@ -73,6 +97,9 @@
|
||||
/* Define to 1 if you have the <memory.h> header file. */
|
||||
#undef HAVE_MEMORY_H
|
||||
|
||||
/* Define to 1 if you have the <netdb.h> header file. */
|
||||
#undef HAVE_NETDB_H
|
||||
|
||||
/* Define to 1 if you have the <netinet/in.h> header file. */
|
||||
#undef HAVE_NETINET_IN_H
|
||||
|
||||
@@ -94,12 +121,42 @@
|
||||
/* Define to 1 if the system has the type `pthread_spinlock_t'. */
|
||||
#undef HAVE_PTHREAD_SPINLOCK_T
|
||||
|
||||
/* Define to 1 if you have the <pwd.h> header file. */
|
||||
#undef HAVE_PWD_H
|
||||
|
||||
/* Define to 1 if you have the `random' function. */
|
||||
#undef HAVE_RANDOM
|
||||
|
||||
/* Define to 1 if you have the `recvmsg' function. */
|
||||
#undef HAVE_RECVMSG
|
||||
|
||||
/* Define to 1 if you have the `sbrk' function. */
|
||||
#undef HAVE_SBRK
|
||||
|
||||
/* Define to 1 if you have the `sendmsg' function. */
|
||||
#undef HAVE_SENDMSG
|
||||
|
||||
/* Define to 1 if you have the `setsid' function. */
|
||||
#undef HAVE_SETSID
|
||||
|
||||
/* Define to 1 if you have the `sigprocmask' function. */
|
||||
#undef HAVE_SIGPROCMASK
|
||||
|
||||
/* Define to 1 if you have the `sleep' function. */
|
||||
#undef HAVE_SLEEP
|
||||
|
||||
/* 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
|
||||
|
||||
/* Define to 1 if you have the `srandom' function. */
|
||||
#undef HAVE_SRANDOM
|
||||
|
||||
/* Define if you have the SSL libraries installed. */
|
||||
#undef HAVE_SSL
|
||||
|
||||
@@ -130,6 +187,9 @@
|
||||
/* Define to 1 if you have the <sys/param.h> header file. */
|
||||
#undef HAVE_SYS_PARAM_H
|
||||
|
||||
/* Define to 1 if you have the <sys/resource.h> header file. */
|
||||
#undef HAVE_SYS_RESOURCE_H
|
||||
|
||||
/* Define to 1 if you have the <sys/socket.h> header file. */
|
||||
#undef HAVE_SYS_SOCKET_H
|
||||
|
||||
@@ -142,27 +202,54 @@
|
||||
/* Define to 1 if you have the <sys/uio.h> header file. */
|
||||
#undef HAVE_SYS_UIO_H
|
||||
|
||||
/* Define to 1 if you have the <sys/wait.h> header file. */
|
||||
#undef HAVE_SYS_WAIT_H
|
||||
|
||||
/* Define to 1 if you have the <time.h> header file. */
|
||||
#undef HAVE_TIME_H
|
||||
|
||||
/* Define to 1 if you have the `tzset' function. */
|
||||
#undef HAVE_TZSET
|
||||
|
||||
/* Define to 1 if you have the <unistd.h> header file. */
|
||||
#undef HAVE_UNISTD_H
|
||||
|
||||
/* Define to 1 if you have the `usleep' function. */
|
||||
#undef HAVE_USLEEP
|
||||
|
||||
/* Define to 1 if you have the `vfork' function. */
|
||||
#undef HAVE_VFORK
|
||||
|
||||
/* Define to 1 if you have the <vfork.h> header file. */
|
||||
#undef HAVE_VFORK_H
|
||||
|
||||
/* Define to 1 if you have the <windows.h> header file. */
|
||||
#undef HAVE_WINDOWS_H
|
||||
|
||||
/* Using Windows threads */
|
||||
#undef HAVE_WINDOWS_THREADS
|
||||
|
||||
/* Define to 1 if you have the <winsock2.h> header file. */
|
||||
#undef HAVE_WINSOCK2_H
|
||||
|
||||
/* Define to 1 if `fork' works. */
|
||||
#undef HAVE_WORKING_FORK
|
||||
|
||||
/* Define to 1 if `vfork' works. */
|
||||
#undef HAVE_WORKING_VFORK
|
||||
|
||||
/* Define to 1 if you have the `writev' function. */
|
||||
#undef HAVE_WRITEV
|
||||
|
||||
/* Define to 1 if you have the <ws2tcpip.h> header file. */
|
||||
#undef HAVE_WS2TCPIP_H
|
||||
|
||||
/* Define to the maximum message length to pass to syslog. */
|
||||
#undef MAXSYSLOGMSGLEN
|
||||
|
||||
/* Define if mkdir has one argument. */
|
||||
#undef MKDIR_HAS_ONE_ARG
|
||||
|
||||
/* Define to the address where bug reports for this package should be sent. */
|
||||
#undef PACKAGE_BUGREPORT
|
||||
|
||||
@@ -178,7 +265,7 @@
|
||||
/* Define to the version of this package. */
|
||||
#undef PACKAGE_VERSION
|
||||
|
||||
/* Pathname to unbound process id file */
|
||||
/* default pidfile location */
|
||||
#undef PIDFILE
|
||||
|
||||
/* Define to necessary symbol if this constant uses a non-standard name on
|
||||
@@ -203,6 +290,12 @@
|
||||
/* Define if you want to use internal select based events */
|
||||
#undef USE_MINI_EVENT
|
||||
|
||||
/* Whether the windows socket API is used */
|
||||
#undef USE_WINSOCK
|
||||
|
||||
/* the version of the windows API enabled */
|
||||
#undef WINVER
|
||||
|
||||
/* Define to 1 if `lex' declares `yytext' as a `char *' by default, not a
|
||||
`char[]'. */
|
||||
#undef YYTEXT_POINTER
|
||||
@@ -262,6 +355,9 @@
|
||||
/* Define to `int' if <sys/types.h> does not define. */
|
||||
#undef pid_t
|
||||
|
||||
/* Define to 'int' if not defined */
|
||||
#undef rlim_t
|
||||
|
||||
/* Define to `unsigned int' if <sys/types.h> does not define. */
|
||||
#undef size_t
|
||||
|
||||
@@ -333,6 +429,14 @@
|
||||
#include <arpa/inet.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_WINSOCK2_H
|
||||
#include <winsock2.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_WS2TCPIP_H
|
||||
#include <ws2tcpip.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_GETOPT_H
|
||||
#include <getopt.h>
|
||||
#endif
|
||||
@@ -373,6 +477,10 @@
|
||||
#define RAND_MAX 2147483647
|
||||
#endif
|
||||
|
||||
#ifndef MAXHOSTNAMELEN
|
||||
#define MAXHOSTNAMELEN 256
|
||||
#endif
|
||||
|
||||
#ifndef IPV6_MIN_MTU
|
||||
#define IPV6_MIN_MTU 1280
|
||||
#endif /* IPV6_MIN_MTU */
|
||||
@@ -390,30 +498,68 @@
|
||||
#define MAXINCLUDES 10
|
||||
|
||||
#ifndef HAVE_SNPRINTF
|
||||
#define snprintf snprintf_unbound
|
||||
#define vsnprintf vsnprintf_unbound
|
||||
#include <stdarg.h>
|
||||
int snprintf (char *str, size_t count, const char *fmt, ...);
|
||||
int vsnprintf (char *str, size_t count, const char *fmt, va_list arg);
|
||||
#endif /* HAVE_SNPRINTF */
|
||||
#ifndef HAVE_INET_PTON
|
||||
#define inet_pton inet_pton_unbound
|
||||
int inet_pton(int af, const char* src, void* dst);
|
||||
#endif /* HAVE_INET_PTON */
|
||||
#ifndef HAVE_INET_NTOP
|
||||
#define inet_ntop inet_ntop_unbound
|
||||
const char *inet_ntop(int af, const void *src, char *dst, size_t size);
|
||||
#endif
|
||||
#ifndef HAVE_INET_ATON
|
||||
#define inet_aton inet_aton_unbound
|
||||
int inet_aton(const char *cp, struct in_addr *addr);
|
||||
#endif
|
||||
#ifndef HAVE_MEMMOVE
|
||||
#define memmove memmove_unbound
|
||||
void *memmove(void *dest, const void *src, size_t n);
|
||||
#endif
|
||||
#ifndef HAVE_STRLCPY
|
||||
#define strlcpy strlcpy_unbound
|
||||
size_t strlcpy(char *dst, const char *src, size_t siz);
|
||||
#endif
|
||||
#ifndef HAVE_GMTIME_R
|
||||
#define gmtime_r gmtime_r_unbound
|
||||
struct tm *gmtime_r(const time_t *timep, struct tm *result);
|
||||
#endif
|
||||
#ifndef HAVE_GETADDRINFO
|
||||
#define getaddrinfo getaddrinfo_unbound
|
||||
#define gai_strerror gai_strerror_unbound
|
||||
#define freeaddrinfo freeaddrinfo_unbound
|
||||
#define getnameinfo getnameinfo_unbound
|
||||
struct sockaddr_storage;
|
||||
#include "compat/fake-rfc2553.h"
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_SLEEP
|
||||
#define sleep(x) Sleep((x)*1000) /* on win32 */
|
||||
#endif /* HAVE_SLEEP */
|
||||
#ifndef HAVE_USLEEP
|
||||
#define usleep(x) Sleep((x)/1000 + 1) /* on win32 */
|
||||
#endif /* HAVE_USLEEP */
|
||||
#ifndef HAVE_RANDOM
|
||||
#define random rand /* on win32, for tests only (bad random) */
|
||||
#endif /* HAVE_RANDOM */
|
||||
#ifndef HAVE_SRANDOM
|
||||
#define srandom(x) srand(x) /* on win32, for tests only (bad random) */
|
||||
#endif /* HAVE_SRANDOM */
|
||||
#ifndef HAVE_SOCKETPAIR
|
||||
int socketpair(int d, int type, int protocol, int *sv);
|
||||
#endif
|
||||
|
||||
/* detect if we need to cast to unsigned int for FD_SET to avoid warnings */
|
||||
#ifdef HAVE_WINSOCK2_H
|
||||
#define FD_SET_T (u_int)
|
||||
#else
|
||||
#define FD_SET_T
|
||||
#endif
|
||||
|
||||
#include "ldns/ldns.h"
|
||||
|
||||
#ifdef UNBOUND_ALLOC_STATS
|
||||
|
||||
Vendored
+15
-5
@@ -4,7 +4,7 @@
|
||||
# 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation,
|
||||
# Inc.
|
||||
|
||||
timestamp='2006-09-20'
|
||||
timestamp='2007-04-29'
|
||||
|
||||
# This file is (in principle) common to ALL GNU software.
|
||||
# The presence of a machine in this file suggests that SOME GNU software
|
||||
@@ -245,12 +245,12 @@ case $basic_machine in
|
||||
| bfin \
|
||||
| c4x | clipper \
|
||||
| d10v | d30v | dlx | dsp16xx \
|
||||
| fr30 | frv \
|
||||
| fido | fr30 | frv \
|
||||
| h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \
|
||||
| i370 | i860 | i960 | ia64 \
|
||||
| ip2k | iq2000 \
|
||||
| m32c | m32r | m32rle | m68000 | m68k | m88k \
|
||||
| maxq | mb | microblaze | mcore \
|
||||
| maxq | mb | microblaze | mcore | mep \
|
||||
| mips | mipsbe | mipseb | mipsel | mipsle \
|
||||
| mips16 \
|
||||
| mips64 | mips64el \
|
||||
@@ -324,7 +324,7 @@ case $basic_machine in
|
||||
| clipper-* | craynv-* | cydra-* \
|
||||
| d10v-* | d30v-* | dlx-* \
|
||||
| elxsi-* \
|
||||
| f30[01]-* | f700-* | fr30-* | frv-* | fx80-* \
|
||||
| f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \
|
||||
| h8300-* | h8500-* \
|
||||
| hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \
|
||||
| i*86-* | i860-* | i960-* | ia64-* \
|
||||
@@ -683,6 +683,10 @@ case $basic_machine in
|
||||
basic_machine=i386-pc
|
||||
os=-mingw32
|
||||
;;
|
||||
mingw32ce)
|
||||
basic_machine=arm-unknown
|
||||
os=-mingw32ce
|
||||
;;
|
||||
miniframe)
|
||||
basic_machine=m68000-convergent
|
||||
;;
|
||||
@@ -925,6 +929,9 @@ case $basic_machine in
|
||||
basic_machine=sh-hitachi
|
||||
os=-hms
|
||||
;;
|
||||
sh5el)
|
||||
basic_machine=sh5le-unknown
|
||||
;;
|
||||
sh64)
|
||||
basic_machine=sh64-unknown
|
||||
;;
|
||||
@@ -1219,7 +1226,7 @@ case $os in
|
||||
| -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \
|
||||
| -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \
|
||||
| -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \
|
||||
| -skyos* | -haiku* | -rdos* | -toppers*)
|
||||
| -skyos* | -haiku* | -rdos* | -toppers* | -drops*)
|
||||
# Remember, each alternative MUST END IN *, to match a version number.
|
||||
;;
|
||||
-qnx*)
|
||||
@@ -1414,6 +1421,9 @@ case $basic_machine in
|
||||
m68*-cisco)
|
||||
os=-aout
|
||||
;;
|
||||
mep-*)
|
||||
os=-elf
|
||||
;;
|
||||
mips*-cisco)
|
||||
os=-elf
|
||||
;;
|
||||
|
||||
+322
-83
@@ -1,47 +1,86 @@
|
||||
# -*- Autoconf -*-
|
||||
# Process this file with autoconf to produce a configure script.
|
||||
AC_PREREQ(2.57)
|
||||
AC_PREREQ(2.56)
|
||||
|
||||
AC_INIT(unbound, 0.10, unbound-bugs@nlnetlabs.nl, unbound)
|
||||
AC_INIT(unbound,1.0.1, unbound-bugs@nlnetlabs.nl, unbound)
|
||||
|
||||
LIBUNBOUND_CURRENT=0
|
||||
LIBUNBOUND_REVISION=13
|
||||
LIBUNBOUND_AGE=0
|
||||
# 1.0.0 had 0:12:0
|
||||
# 1.0.1 had 0:13:0
|
||||
|
||||
# Current -- the number of the binary API that we're implementing
|
||||
# Revision -- which iteration of the implementation of the binary
|
||||
# API are we supplying?
|
||||
# Age -- How many previous binary API versions do we also
|
||||
# support?
|
||||
#
|
||||
# If we release a new version that does not change the binary API,
|
||||
# increment Revision.
|
||||
#
|
||||
# If we release a new version that changes the binary API, but does
|
||||
# not break programs compiled against the old binary API, increment
|
||||
# Current and Age. Set Revision to 0, since this is the first
|
||||
# implementation of the new API.
|
||||
#
|
||||
# Otherwise, we're changing the binary API and breaking bakward
|
||||
# compatibility with old binaries. Increment Current. Set Age to 0,
|
||||
# since we're backward compatible with no previous APIs. Set Revision
|
||||
# to 0 too.
|
||||
AC_SUBST(LIBUNBOUND_CURRENT)
|
||||
AC_SUBST(LIBUNBOUND_REVISION)
|
||||
AC_SUBST(LIBUNBOUND_AGE)
|
||||
|
||||
CFLAGS=
|
||||
AC_AIX
|
||||
|
||||
dnl
|
||||
dnl By default set $sysconfdir to /etc and $localstatedir to /var
|
||||
dnl By default set prefix to /usr/local
|
||||
dnl
|
||||
case "$prefix" in
|
||||
NONE)
|
||||
case "$sysconfdir" in
|
||||
'${prefix}/etc')
|
||||
sysconfdir=/etc
|
||||
;;
|
||||
esac
|
||||
case "$localstatedir" in
|
||||
'${prefix}/var')
|
||||
localstatedir=/var
|
||||
;;
|
||||
esac
|
||||
prefix="/usr/local"
|
||||
;;
|
||||
esac
|
||||
|
||||
#
|
||||
# Determine configuration file
|
||||
ub_conf_file=${sysconfdir}/unbound/unbound.conf
|
||||
# the eval is to evaluate shell expansion twice
|
||||
ub_conf_file=`eval echo "${sysconfdir}/unbound/unbound.conf"`
|
||||
AC_ARG_WITH([conf_file],
|
||||
AC_HELP_STRING([--with-conf-file=path], [Pathname to the Unbound configuration file]),
|
||||
[ub_conf_file=$withval])
|
||||
AC_HELP_STRING([--with-conf-file=path],
|
||||
[Pathname to the Unbound configuration file]),
|
||||
[ub_conf_file="$withval"])
|
||||
AC_SUBST(ub_conf_file)
|
||||
# the eval is to evaluate shell expansion twice, once
|
||||
# for $nsd_conf_file and once for the ${prefix} within it.
|
||||
AC_DEFINE_UNQUOTED(CONFIGFILE, ["`eval echo $ub_conf_file`"], [Pathname to the Unbound configuration file])
|
||||
AC_DEFINE_UNQUOTED(CONFIGFILE, ["$ub_conf_file"], [Pathname to the Unbound configuration file])
|
||||
|
||||
# Determine run, chroot directory and pidfile locations
|
||||
ub_cfg=`eval echo $ub_conf_file`
|
||||
ub_dir=`dirname $ub_cfg`
|
||||
AC_DEFINE_UNQUOTED(RUN_DIR, ["$ub_dir"], [Directory to chdir to])
|
||||
AC_DEFINE_UNQUOTED(CHROOT_DIR, ["$ub_dir"], [Directory to chroot to])
|
||||
AC_DEFINE_UNQUOTED(PIDFILE, ["$ub_dir/unbound.pid"], [Pathname to unbound process id file])
|
||||
AC_ARG_WITH(run-dir,
|
||||
AC_HELP_STRING([--with-run-dir=path],
|
||||
[set default directory to chdir to (by default dir part of cfg file)]),
|
||||
UNBOUND_RUN_DIR="$withval",
|
||||
UNBOUND_RUN_DIR=`dirname "$ub_conf_file"`)
|
||||
AC_SUBST(UNBOUND_RUN_DIR)
|
||||
AC_DEFINE_UNQUOTED(RUN_DIR, ["$UNBOUND_RUN_DIR"], [Directory to chdir to])
|
||||
|
||||
AC_ARG_WITH(chroot-dir,
|
||||
AC_HELP_STRING([--with-chroot-dir=path],
|
||||
[set default directory to chroot to (by default same as run-dir)]),
|
||||
UNBOUND_CHROOT_DIR="$withval",
|
||||
UNBOUND_CHROOT_DIR="$UNBOUND_RUN_DIR")
|
||||
AC_SUBST(UNBOUND_CHROOT_DIR)
|
||||
AC_DEFINE_UNQUOTED(CHROOT_DIR, ["$UNBOUND_CHROOT_DIR"], [Directory to chroot to])
|
||||
|
||||
AC_ARG_WITH(pidfile,
|
||||
AC_HELP_STRING([--with-pidfile=filename],
|
||||
[set default pathname to unbound pidfile (default run-dir/unbound.pid)]),
|
||||
UNBOUND_PIDFILE="$withval",
|
||||
UNBOUND_PIDFILE="$UNBOUND_RUN_DIR/unbound.pid")
|
||||
AC_SUBST(UNBOUND_PIDFILE)
|
||||
AC_DEFINE_UNQUOTED(PIDFILE, ["$UNBOUND_PIDFILE"], [default pidfile location])
|
||||
|
||||
AC_DEFINE(WINVER, 0x0502, [the version of the windows API enabled])
|
||||
|
||||
dnl routine to help check for compiler flags.
|
||||
AC_DEFUN([CHECK_COMPILER_FLAG],
|
||||
@@ -126,6 +165,10 @@ CHECK_COMPILER_FLAG(O2, [CFLAGS="$CFLAGS -O2"])
|
||||
|
||||
AC_CHECK_HEADERS([getopt.h time.h],,, [AC_INCLUDES_DEFAULT])
|
||||
|
||||
# MinGW32 tests
|
||||
AC_CHECK_HEADERS([winsock2.h ws2tcpip.h],,, [AC_INCLUDES_DEFAULT])
|
||||
# end mingw32 tests
|
||||
|
||||
CHECK_COMPILER_FLAG_NEEDED(-std=c99 -D__EXTENSIONS__ -D_BSD_SOURCE -D_POSIX_C_SOURCE=200112 -D_XOPEN_SOURCE=600 -D_XOPEN_SOURCE_EXTENDED=1 -D_ALL_SOURCE,
|
||||
[
|
||||
#include "confdefs.h"
|
||||
@@ -213,6 +256,17 @@ int test() {
|
||||
}
|
||||
], [CFLAGS="$CFLAGS -D_BSD_SOURCE"])
|
||||
|
||||
CHECK_COMPILER_FLAG_NEEDED(-D_GNU_SOURCE,
|
||||
[
|
||||
#include <netinet/in.h>
|
||||
|
||||
int test() {
|
||||
struct in6_pktinfo inf;
|
||||
int a = (int)sizeof(inf);
|
||||
return a;
|
||||
}
|
||||
], [CFLAGS="$CFLAGS -D_GNU_SOURCE"])
|
||||
|
||||
CHECK_COMPILER_FLAG_NEEDED(-D_POSIX_C_SOURCE=200112,
|
||||
[
|
||||
#include "confdefs.h"
|
||||
@@ -340,8 +394,11 @@ AC_DEFUN([AC_PROG_OBJC], [:])
|
||||
AC_DEFUN([AC_PROG_OBJCCPP], [:])
|
||||
AC_DEFUN([AC_LIBTOOL_CXX], [:])
|
||||
AC_DEFUN([AC_LIBTOOL_F77], [:])
|
||||
# Use libtool
|
||||
AC_CHECK_PROGS(libtool, [glibtool libtool15 libtool], [./libtool])
|
||||
# always use ./libtool unless override from commandline (libtool=mylibtool)
|
||||
if test -z "$libtool"; then
|
||||
libtool="./libtool"
|
||||
fi
|
||||
AC_SUBST(libtool)
|
||||
AC_PATH_TOOL(AR, ar, [false])
|
||||
if test $AR = false; then
|
||||
AC_MSG_ERROR([Cannot find 'ar', please extend PATH to include it])
|
||||
@@ -358,7 +415,7 @@ AC_PROG_LIBTOOL
|
||||
|
||||
# Checks for header files.
|
||||
AC_HEADER_STDC
|
||||
AC_CHECK_HEADERS([stdarg.h stdbool.h netinet/in.h sys/param.h sys/socket.h sys/uio.h arpa/inet.h syslog.h],,, [AC_INCLUDES_DEFAULT])
|
||||
AC_CHECK_HEADERS([stdarg.h stdbool.h netinet/in.h sys/param.h sys/socket.h sys/uio.h sys/resource.h arpa/inet.h syslog.h netdb.h sys/wait.h pwd.h],,, [AC_INCLUDES_DEFAULT])
|
||||
|
||||
# check for types
|
||||
AC_CHECK_TYPE(int8_t, char)
|
||||
@@ -376,6 +433,13 @@ AC_TYPE_PID_T
|
||||
AC_TYPE_OFF_T
|
||||
AC_CHECK_TYPE(u_char, unsigned char)
|
||||
|
||||
AC_CHECK_TYPE(rlim_t, ,
|
||||
[AC_DEFINE([rlim_t], [unsigned long], [Define to 'int' if not defined])], [
|
||||
AC_INCLUDES_DEFAULT
|
||||
#if HAVE_SYS_RESOURCE_H
|
||||
# include <sys/resource.h>
|
||||
#endif
|
||||
])
|
||||
AC_CHECK_TYPE(socklen_t, ,
|
||||
[AC_DEFINE([socklen_t], [int], [Define to 'int' if not defined])], [
|
||||
AC_INCLUDES_DEFAULT
|
||||
@@ -402,31 +466,19 @@ AC_INCLUDES_DEFAULT
|
||||
#endif
|
||||
])
|
||||
|
||||
# Check for yyunput
|
||||
AC_DEFUN([CHECK_YYUNPUT],
|
||||
[AC_MSG_CHECKING(whether lex can not generate yyunput)
|
||||
AC_CACHE_VAL(ac_cv_c_yy_unput,
|
||||
[ac_cv_c_yy_unput=no
|
||||
if $LEX --nounput -h 2>&1 | grep "do not generate" 2>&1 >/dev/null; then
|
||||
ac_cv_c_yy_unput="yes"
|
||||
else
|
||||
ac_cv_c_yy_unput="no"
|
||||
fi
|
||||
])
|
||||
|
||||
AC_MSG_RESULT($ac_cv_c_yy_unput)
|
||||
if test $ac_cv_c_yy_unput = yes; then
|
||||
LEX="$LEX --nounput"
|
||||
fi
|
||||
])dnl
|
||||
|
||||
CHECK_YYUNPUT
|
||||
|
||||
# add option to disable the evil rpath
|
||||
dnl Check whether to use rpath or not
|
||||
AC_ARG_ENABLE(rpath,
|
||||
[ --disable-rpath disable hardcoded rpath (default=enabled)],
|
||||
enable_rpath=$enableval, enable_rpath=yes)
|
||||
if test "x$enable_rpath" = xno; then
|
||||
AC_MSG_RESULT([Fixing libtool for -rpath problems.])
|
||||
sed < libtool > libtool-2 \
|
||||
's/^hardcode_libdir_flag_spec.*$'/'hardcode_libdir_flag_spec=" -D__LIBTOOL_RPATH_SED__ "/'
|
||||
mv libtool-2 libtool
|
||||
chmod 755 libtool
|
||||
libtool="./libtool"
|
||||
fi
|
||||
|
||||
# Checks for libraries.
|
||||
AC_ARG_WITH(ssl, AC_HELP_STRING([--with-ssl=pathname],
|
||||
@@ -458,9 +510,34 @@ AC_ARG_WITH(ssl, AC_HELP_STRING([--with-ssl=pathname],
|
||||
if test "x$enable_rpath" = xyes; then
|
||||
RUNTIME_PATH="$RUNTIME_PATH -R$ssldir/lib"
|
||||
fi
|
||||
AC_CHECK_LIB(crypto, HMAC_CTX_init,, [
|
||||
|
||||
AC_MSG_CHECKING([for HMAC_CTX_init in -lcrypto])
|
||||
ORIGLIBS="$LIBS"
|
||||
LIBS="$LIBS -lcrypto"
|
||||
AC_TRY_LINK(, [
|
||||
int HMAC_CTX_init(void);
|
||||
(void)HMAC_CTX_init();
|
||||
], [
|
||||
AC_MSG_RESULT(yes)
|
||||
AC_DEFINE([HAVE_HMAC_CTX_INIT], 1,
|
||||
[If you have HMAC_CTX_init])
|
||||
], [
|
||||
AC_MSG_RESULT(no)
|
||||
# check if -lwsock32 or -lgdi32 are needed.
|
||||
LIBS="$LIBS -lgdi32"
|
||||
AC_MSG_CHECKING([if -lcrypto needs -lgdi32])
|
||||
AC_TRY_LINK([], [
|
||||
int HMAC_CTX_init(void);
|
||||
(void)HMAC_CTX_init();
|
||||
],[
|
||||
AC_DEFINE([HAVE_HMAC_CTX_INIT], 1,
|
||||
[If you have HMAC_CTX_init])
|
||||
AC_MSG_RESULT(yes)
|
||||
],[
|
||||
AC_MSG_RESULT(no)
|
||||
AC_MSG_ERROR([OpenSSL found in $ssldir, but version 0.9.7 or higher is required])
|
||||
])
|
||||
])
|
||||
])
|
||||
fi
|
||||
AC_SUBST(HAVE_SSL)
|
||||
AC_SUBST(RUNTIME_PATH)
|
||||
@@ -489,6 +566,7 @@ fi
|
||||
# check solaris thread library
|
||||
AC_ARG_WITH(solaris-threads, AC_HELP_STRING([--with-solaris-threads],
|
||||
[use solaris native thread library.]), [ ],[ withval="no" ])
|
||||
ub_have_sol_threads=no
|
||||
if test x_$withval != x_no; then
|
||||
if test x_$ub_have_pthreads != x_no; then
|
||||
AC_WARN([Have pthreads already, ignoring --with-solaris-threads])
|
||||
@@ -499,23 +577,40 @@ if test x_$withval != x_no; then
|
||||
|
||||
CHECK_COMPILER_FLAG(mt, [CFLAGS="$CFLAGS -mt"],
|
||||
[CFLAGS="$CFLAGS -D_REENTRANT"])
|
||||
ub_have_sol_threads=yes
|
||||
] , [
|
||||
AC_ERROR([no solaris threads found.])
|
||||
])
|
||||
fi
|
||||
fi
|
||||
|
||||
# check windows threads
|
||||
if test x_$ub_have_pthreads = x_no -a x_$ub_have_sol_threads = x_no; then
|
||||
AC_CHECK_HEADERS([windows.h],,, [AC_INCLUDES_DEFAULT])
|
||||
AC_MSG_CHECKING([for CreateThread])
|
||||
AC_TRY_COMPILE([
|
||||
#ifdef HAVE_WINDOWS_H
|
||||
#include <windows.h>
|
||||
#endif
|
||||
], [
|
||||
HANDLE t = CreateThread(NULL, 0, NULL, NULL, 0, NULL);
|
||||
],
|
||||
AC_MSG_RESULT(yes)
|
||||
AC_DEFINE(HAVE_WINDOWS_THREADS, 1, [Using Windows threads])
|
||||
,
|
||||
AC_MSG_RESULT(no)
|
||||
)
|
||||
fi
|
||||
|
||||
# check to see if libraries are needed for these functions.
|
||||
AC_SEARCH_LIBS([inet_pton], [nsl])
|
||||
AC_SEARCH_LIBS([socket], [socket])
|
||||
# check for library used by libevent after 1.3c
|
||||
AC_SEARCH_LIBS([clock_gettime], [rt])
|
||||
|
||||
# check for libevent
|
||||
AC_ARG_WITH(libevent, AC_HELP_STRING([--with-libevent=pathname],
|
||||
[use libevent (will check /usr/local /opt/local /usr/lib /usr/pkg /usr/sfw /usr or you can specify an explicit path). Slower, but allows use of large outgoing port ranges.]),
|
||||
[ ],[ withval="no" ])
|
||||
if test x_$withval == x_yes -o x_$withval != x_no; then
|
||||
if test x_$withval = x_yes -o x_$withval != x_no; then
|
||||
AC_MSG_CHECKING(for libevent)
|
||||
if test x_$withval = x_ -o x_$withval = x_yes; then
|
||||
withval="/usr/local /opt/local /usr/lib /usr/pkg /usr/sfw /usr"
|
||||
@@ -529,10 +624,10 @@ if test x_$withval == x_yes -o x_$withval != x_no; then
|
||||
fi
|
||||
done
|
||||
if test x_$found_libevent != x_yes; then
|
||||
if test -f "$dir/event.h" -a -f "$dir/libevent.la"; then
|
||||
if test -f "$dir/event.h" -a \( -f "$dir/libevent.la" -o -f "$dir/libev.la" \) ; then
|
||||
# libevent source directory
|
||||
AC_MSG_RESULT(found in $thedir)
|
||||
CPPFLAGS="$CPPFLAGS -I$thedir"
|
||||
CPPFLAGS="$CPPFLAGS -I$thedir -I$thedir/include"
|
||||
BAK_LDFLAGS="$LDFLAGS"
|
||||
# remove evdns from linking
|
||||
mkdir build >/dev/null 2>&1
|
||||
@@ -544,8 +639,8 @@ if test x_$withval == x_yes -o x_$withval != x_no; then
|
||||
cp $ev_files_o build/libevent
|
||||
cp $ev_files_lo build/libevent
|
||||
cp $ev_files_libso build/libevent/.libs
|
||||
LATE_LDFLAGS="build/libevent/*.lo"
|
||||
LDFLAGS="build/libevent/*.o $LDFLAGS"
|
||||
LATE_LDFLAGS="build/libevent/*.lo -lm"
|
||||
LDFLAGS="build/libevent/*.o $LDFLAGS -lm"
|
||||
else
|
||||
AC_MSG_ERROR([Cannot find the libevent library in $withval
|
||||
You can restart ./configure --with-libevent=no to use a builtin alternative.
|
||||
@@ -560,10 +655,14 @@ large outgoing port ranges. ])
|
||||
fi
|
||||
fi
|
||||
AC_SUBST(RUNTIME_PATH)
|
||||
# check for library used by libevent after 1.3c
|
||||
AC_SEARCH_LIBS([clock_gettime], [rt])
|
||||
|
||||
AC_SEARCH_LIBS(event_set, [event])
|
||||
AC_CHECK_HEADERS([event.h],,, [AC_INCLUDES_DEFAULT])
|
||||
AC_CHECK_FUNCS([event_base_free]) # only in libevent 1.2 and later
|
||||
AC_CHECK_FUNCS([event_base_once]) # only in libevent 1.4? and later
|
||||
AC_CHECK_FUNCS([event_base_get_method]) # only in libevent 1.4.3 and later
|
||||
if test -n "$BAK_LDFLAGS"; then
|
||||
LDFLAGS="$BAK_LDFLAGS"
|
||||
fi
|
||||
@@ -587,6 +686,8 @@ AC_ARG_ENABLE(lock_checks, AC_HELP_STRING([--enable-lock-checks],
|
||||
, )
|
||||
if test x_$enable_lock_checks = x_yes; then
|
||||
AC_DEFINE(ENABLE_LOCK_CHECKS, 1, [Define if you want to use debug lock checking (slow).])
|
||||
CHECKLOCK_SRC="testcode/checklocks.c"
|
||||
AC_SUBST(CHECKLOCK_SRC)
|
||||
fi
|
||||
|
||||
# set memory allocation checking if requested
|
||||
@@ -604,6 +705,116 @@ AC_FUNC_FORK
|
||||
AC_TYPE_SIGNAL
|
||||
AC_FUNC_FSEEKO
|
||||
AC_SYS_LARGEFILE
|
||||
dnl try to see if an additional _LARGEFILE_SOURCE 1 is needed to get fseeko
|
||||
CHECK_COMPILER_FLAG_NEEDED(-D_LARGEFILE_SOURCE=1,
|
||||
[
|
||||
#include <stdio.h>
|
||||
int test() {
|
||||
int a = fseeko(stdin, 0, 0);
|
||||
return a;
|
||||
}
|
||||
], [CFLAGS="$CFLAGS -D_LARGEFILE_SOURCE=1"])
|
||||
|
||||
AC_DEFUN([AC_CHECK_GETADDRINFO_WITH_INCLUDES],
|
||||
[AC_REQUIRE([AC_PROG_CC])
|
||||
AC_MSG_CHECKING(for getaddrinfo)
|
||||
ac_cv_func_getaddrinfo=no
|
||||
AC_LINK_IFELSE(
|
||||
[
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
char* getaddrinfo();
|
||||
char* (*f) () = getaddrinfo;
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
int main() {
|
||||
;
|
||||
return 0;
|
||||
}
|
||||
],
|
||||
dnl this case on linux, solaris, bsd
|
||||
[ac_cv_func_getaddrinfo="yes"],
|
||||
dnl no quick getaddrinfo, try mingw32 and winsock2 library.
|
||||
ORIGLIBS="$LIBS"
|
||||
LIBS="$LIBS -lws2_32"
|
||||
AC_LINK_IFELSE(
|
||||
AC_LANG_PROGRAM(
|
||||
[
|
||||
#ifdef HAVE_WS2TCPIP_H
|
||||
#include <ws2tcpip.h>
|
||||
#endif
|
||||
],
|
||||
[
|
||||
(void)getaddrinfo(NULL, NULL, NULL, NULL);
|
||||
]
|
||||
),
|
||||
[
|
||||
ac_cv_func_getaddrinfo="yes"
|
||||
dnl already: LIBS="$LIBS -lws2_32"
|
||||
AC_DEFINE(USE_WINSOCK, 1, [Whether the windows socket API is used])
|
||||
],
|
||||
[
|
||||
ac_cv_func_getaddrinfo="no"
|
||||
LIBS="$ORIGLIBS"
|
||||
])
|
||||
)
|
||||
|
||||
AC_MSG_RESULT($ac_cv_func_getaddrinfo)
|
||||
if test $ac_cv_func_getaddrinfo = yes; then
|
||||
AC_DEFINE(HAVE_GETADDRINFO, 1, [Whether getaddrinfo is available])
|
||||
fi
|
||||
])dnl
|
||||
|
||||
AC_CHECK_GETADDRINFO_WITH_INCLUDES
|
||||
if test $ac_cv_func_getaddrinfo = no; then
|
||||
AC_LIBOBJ([fake-rfc2553])
|
||||
fi
|
||||
AC_CHECK_FUNCS([tzset sigprocmask fcntl getpwnam getrlimit setsid sbrk chroot kill sleep usleep random srandom recvmsg sendmsg writev])
|
||||
|
||||
# check mkdir
|
||||
AC_MSG_CHECKING([whether mkdir has one arg])
|
||||
AC_TRY_COMPILE([
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#ifdef HAVE_WINSOCK2_H
|
||||
#include <winsock2.h>
|
||||
#endif
|
||||
#ifdef HAVE_SYS_STAT_H
|
||||
#include <sys/stat.h>
|
||||
#endif
|
||||
], [
|
||||
(void)mkdir("directory");
|
||||
],
|
||||
AC_MSG_RESULT(yes)
|
||||
AC_DEFINE(MKDIR_HAS_ONE_ARG, 1, [Define if mkdir has one argument.])
|
||||
,
|
||||
AC_MSG_RESULT(no)
|
||||
)
|
||||
|
||||
# check ioctlsocket
|
||||
AC_MSG_CHECKING(for ioctlsocket)
|
||||
AC_LINK_IFELSE(AC_LANG_PROGRAM([
|
||||
#ifdef HAVE_WINSOCK2_H
|
||||
#include <winsock2.h>
|
||||
#endif
|
||||
], [
|
||||
(void)ioctlsocket(0, 0, NULL);
|
||||
]), [
|
||||
AC_MSG_RESULT(yes)
|
||||
AC_DEFINE(HAVE_IOCTLSOCKET, 1, [if the function 'ioctlsocket' is available])
|
||||
],[AC_MSG_RESULT(no)])
|
||||
|
||||
AC_REPLACE_FUNCS(inet_aton)
|
||||
AC_REPLACE_FUNCS(inet_pton)
|
||||
AC_REPLACE_FUNCS(inet_ntop)
|
||||
AC_REPLACE_FUNCS(snprintf)
|
||||
AC_REPLACE_FUNCS(strlcpy)
|
||||
AC_REPLACE_FUNCS(memmove)
|
||||
AC_REPLACE_FUNCS(gmtime_r)
|
||||
AC_REPLACE_FUNCS(socketpair) dnl for mingw32
|
||||
|
||||
# check this after all other compilation checks, since the linking of the lib
|
||||
# may break checks after this.
|
||||
@@ -616,21 +827,9 @@ AC_ARG_WITH(ldns,
|
||||
AC_SUBST(ldnsdir)
|
||||
])
|
||||
|
||||
AC_CHECK_LIB(ldns, ldns_rr_new, [
|
||||
AC_CHECK_LIB(ldns, ldns_buffer_copy, [
|
||||
dnl ldns was found, check compat functions
|
||||
AC_CHECK_LIB(ldns, [ldns_rr_free])
|
||||
AC_REPLACE_FUNCS(inet_aton)
|
||||
AC_REPLACE_FUNCS(inet_pton)
|
||||
AC_REPLACE_FUNCS(inet_ntop)
|
||||
AC_REPLACE_FUNCS(snprintf)
|
||||
AC_REPLACE_FUNCS(strlcpy)
|
||||
AC_REPLACE_FUNCS(memmove)
|
||||
|
||||
AC_CHECK_FUNCS([getaddrinfo])
|
||||
if test $ac_cv_func_getaddrinfo = no; then
|
||||
AC_LIBOBJ([fake-rfc2553])
|
||||
fi
|
||||
|
||||
] , [
|
||||
dnl use the builtin ldns-src.tar.gz file to build ldns.
|
||||
if test ! -f $srcdir/ldns-src.tar.gz; then
|
||||
@@ -645,21 +844,11 @@ echo "****************************************************************"
|
||||
if test -d ldns-src; then rm -rf ldns-src; fi
|
||||
mkdir ldns-src; cp $srcdir/ldns-src.tar.gz ldns-src/ldns-src.tar.gz; (cd ldns-src; gzip -cd ldns-src.tar.gz | tar xf -); rm -f ldns-src/ldns-src.tar.gz
|
||||
ldnsdir=`ls -d ldns-src/ldns*`
|
||||
AC_MSG_NOTICE([Configure $ldnsdir])
|
||||
echo "(cd $ldnsdir && ./configure)"
|
||||
(cd $ldnsdir && ./configure)
|
||||
AC_MSG_NOTICE([Finished $ldnsdir configure])
|
||||
CPPFLAGS="$CPPFLAGS -I$ldnsdir/include"
|
||||
AC_MSG_NOTICE([Configure $ldnsdir scheduled after config.status])
|
||||
AC_CONFIG_SUBDIRS([ldns-src/ldns*])
|
||||
CPPFLAGS="-I$ldnsdir/include $CPPFLAGS"
|
||||
LDFLAGS="$LDFLAGS $ldnsdir/*.lo"
|
||||
AC_SUBST(ldnsdir)
|
||||
dnl use ldns compat functions
|
||||
AC_DEFINE(HAVE_INET_ATON)
|
||||
AC_DEFINE(HAVE_INET_PTON)
|
||||
AC_DEFINE(HAVE_INET_NTOP)
|
||||
AC_DEFINE(HAVE_SNPRINTF)
|
||||
AC_DEFINE(HAVE_STRLCPY)
|
||||
AC_DEFINE(HAVE_MEMMOVE)
|
||||
AC_DEFINE(HAVE_GETADDRINFO)
|
||||
])
|
||||
LDFLAGS="$LATE_LDFLAGS $LDFLAGS"
|
||||
|
||||
@@ -706,6 +895,14 @@ AH_BOTTOM([
|
||||
#include <arpa/inet.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_WINSOCK2_H
|
||||
#include <winsock2.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_WS2TCPIP_H
|
||||
#include <ws2tcpip.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_GETOPT_H
|
||||
#include <getopt.h>
|
||||
#endif
|
||||
@@ -746,6 +943,10 @@ AH_BOTTOM([
|
||||
#define RAND_MAX 2147483647
|
||||
#endif
|
||||
|
||||
#ifndef MAXHOSTNAMELEN
|
||||
#define MAXHOSTNAMELEN 256
|
||||
#endif
|
||||
|
||||
#ifndef IPV6_MIN_MTU
|
||||
#define IPV6_MIN_MTU 1280
|
||||
#endif /* IPV6_MIN_MTU */
|
||||
@@ -763,30 +964,68 @@ AH_BOTTOM([
|
||||
#define MAXINCLUDES 10
|
||||
|
||||
#ifndef HAVE_SNPRINTF
|
||||
#define snprintf snprintf_unbound
|
||||
#define vsnprintf vsnprintf_unbound
|
||||
#include <stdarg.h>
|
||||
int snprintf (char *str, size_t count, const char *fmt, ...);
|
||||
int vsnprintf (char *str, size_t count, const char *fmt, va_list arg);
|
||||
#endif /* HAVE_SNPRINTF */
|
||||
#ifndef HAVE_INET_PTON
|
||||
#define inet_pton inet_pton_unbound
|
||||
int inet_pton(int af, const char* src, void* dst);
|
||||
#endif /* HAVE_INET_PTON */
|
||||
#ifndef HAVE_INET_NTOP
|
||||
#define inet_ntop inet_ntop_unbound
|
||||
const char *inet_ntop(int af, const void *src, char *dst, size_t size);
|
||||
#endif
|
||||
#ifndef HAVE_INET_ATON
|
||||
#define inet_aton inet_aton_unbound
|
||||
int inet_aton(const char *cp, struct in_addr *addr);
|
||||
#endif
|
||||
#ifndef HAVE_MEMMOVE
|
||||
#define memmove memmove_unbound
|
||||
void *memmove(void *dest, const void *src, size_t n);
|
||||
#endif
|
||||
#ifndef HAVE_STRLCPY
|
||||
#define strlcpy strlcpy_unbound
|
||||
size_t strlcpy(char *dst, const char *src, size_t siz);
|
||||
#endif
|
||||
#ifndef HAVE_GMTIME_R
|
||||
#define gmtime_r gmtime_r_unbound
|
||||
struct tm *gmtime_r(const time_t *timep, struct tm *result);
|
||||
#endif
|
||||
#ifndef HAVE_GETADDRINFO
|
||||
#define getaddrinfo getaddrinfo_unbound
|
||||
#define gai_strerror gai_strerror_unbound
|
||||
#define freeaddrinfo freeaddrinfo_unbound
|
||||
#define getnameinfo getnameinfo_unbound
|
||||
struct sockaddr_storage;
|
||||
#include "compat/fake-rfc2553.h"
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_SLEEP
|
||||
#define sleep(x) Sleep((x)*1000) /* on win32 */
|
||||
#endif /* HAVE_SLEEP */
|
||||
#ifndef HAVE_USLEEP
|
||||
#define usleep(x) Sleep((x)/1000 + 1) /* on win32 */
|
||||
#endif /* HAVE_USLEEP */
|
||||
#ifndef HAVE_RANDOM
|
||||
#define random rand /* on win32, for tests only (bad random) */
|
||||
#endif /* HAVE_RANDOM */
|
||||
#ifndef HAVE_SRANDOM
|
||||
#define srandom(x) srand(x) /* on win32, for tests only (bad random) */
|
||||
#endif /* HAVE_SRANDOM */
|
||||
#ifndef HAVE_SOCKETPAIR
|
||||
int socketpair(int d, int type, int protocol, int *sv);
|
||||
#endif
|
||||
|
||||
/* detect if we need to cast to unsigned int for FD_SET to avoid warnings */
|
||||
#ifdef HAVE_WINSOCK2_H
|
||||
#define FD_SET_T (u_int)
|
||||
#else
|
||||
#define FD_SET_T
|
||||
#endif
|
||||
|
||||
#include "ldns/ldns.h"
|
||||
|
||||
#ifdef UNBOUND_ALLOC_STATS
|
||||
@@ -812,6 +1051,6 @@ void *unbound_stat_realloc_log(void *ptr, size_t size, const char* file,
|
||||
#define UNBOUND_DNS_PORT 53
|
||||
])
|
||||
|
||||
AC_CONFIG_FILES([Makefile])
|
||||
AC_CONFIG_FILES([Makefile doc/example.conf doc/libunbound.3 doc/unbound.8 doc/unbound-checkconf.8 doc/unbound.conf.5])
|
||||
AC_CONFIG_HEADER([config.h])
|
||||
AC_OUTPUT
|
||||
|
||||
@@ -2,3 +2,8 @@ These files are contributed to unbound, and are not part of the official
|
||||
distribution but may be helpful.
|
||||
|
||||
* rc_d_unbound: FreeBSD compatible /etc/rc.d script.
|
||||
* parseunbound.pl: perl script to run from cron that parses statistics from
|
||||
the log file and stores them.
|
||||
* 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.
|
||||
|
||||
@@ -0,0 +1,140 @@
|
||||
#!/usr/local/bin/perl -w
|
||||
#
|
||||
# Script to parse the output from the unbound namedaemon.
|
||||
# Unbound supports a threading model, and outputs a multiline log-blob for
|
||||
# every thread.
|
||||
#
|
||||
# This script should parse all threads of the once, and store it
|
||||
# in a local cached file for speedy results when queried lots.
|
||||
#
|
||||
use strict;
|
||||
use POSIX qw(SEEK_END);
|
||||
use Storable;
|
||||
use FileHandle;
|
||||
use Carp qw(croak carp);
|
||||
use constant UNBOUND_CACHE => "/var/tmp/unbound-cache.stor";
|
||||
|
||||
my $run_from_cron = @ARGV && $ARGV[0] eq "--cron" && shift;
|
||||
my $DEBUG = -t STDERR;
|
||||
|
||||
# NB. VERY IMPORTANTES: set this when running this script.
|
||||
my $numthreads = 4;
|
||||
|
||||
### if cache exists, read it in. and is newer than 3 minutes
|
||||
if ( -r UNBOUND_CACHE ) {
|
||||
my $result = retrieve(UNBOUND_CACHE);
|
||||
if (-M _ < 3/24/60 && !$run_from_cron ) {
|
||||
print STDERR "Cached results:\n" if $DEBUG;
|
||||
print join("\n", @$result), "\n";
|
||||
exit;
|
||||
}
|
||||
}
|
||||
my $logfile = shift or die "Usage: parseunbound.pl --cron unboundlogfile";
|
||||
my $in = new FileHandle $logfile or die "Cannot open $logfile: $!\n";
|
||||
|
||||
# there is a special key 'thread' that indicates the thread. its not used, but returned anyway.
|
||||
my @records = ('thread', 'queries', 'cachehits', 'recursions', 'recursionavg',
|
||||
'outstandingmax', 'outstandingavg', 'outstandingexc',
|
||||
'median25', 'median50', 'median75',
|
||||
'us_0', 'us_1', 'us_2', 'us_4', 'us_8', 'us_16', 'us_32',
|
||||
'us_64', 'us_128', 'us_256', 'us_512', 'us_1024', 'us_2048',
|
||||
'us_4096', 'us_8192', 'us_16384', 'us_32768', 'us_65536',
|
||||
'us_131072', 'us_262144', 'us_524288', 's_1', 's_2', 's_4',
|
||||
's_8', 's_16', 's_32', 's_64', 's_128', 's_256', 's_512');
|
||||
# Stats hash containing one or more keys. for every thread, 1 key.
|
||||
my %allstats = (); # key="$threadid", stats={key => value}
|
||||
my %startstats = (); # when we got a queries entry for this thread
|
||||
my %donestats = (); # same, but only when we got a histogram entry for it
|
||||
# stats hash contains name/value pairs of the actual numbers for that thread.
|
||||
my $offset = 0;
|
||||
my $inthread=0;
|
||||
my $inpid;
|
||||
|
||||
# We should continue looping untill we meet these conditions:
|
||||
# a) more total queries than the previous run (which defaults to 0) AND
|
||||
# b) parsed all $numthreads threads in the log.
|
||||
my $numqueries = $previousresult ? $previousresult->[1] : 0;
|
||||
|
||||
# Main loop
|
||||
while ( scalar keys %startstats < $numthreads || scalar keys %donestats < $numthreads) {
|
||||
$offset += 10000;
|
||||
if ( $offset > -s $logfile or $offset > 10_000_000 ) {
|
||||
die "Cannot find stats in $logfile\n";
|
||||
}
|
||||
$in->seek(-$offset, SEEK_END) or croak "cannot seek $logfile: $!\n";
|
||||
|
||||
for my $line ( <$in> ) {
|
||||
chomp($line);
|
||||
|
||||
#[1208777234] unbound[6705:0]
|
||||
if ($line =~ m/^\[\d+\] unbound\[\d+:(\d+)\]/) {
|
||||
$inthread = $1;
|
||||
if ($inthread + 1 > $numthreads) {
|
||||
die "Hey. lazy. change \$numthreads in this script to ($inthread)\n";
|
||||
}
|
||||
}
|
||||
# this line doesn't contain a pid:thread. skip.
|
||||
else {
|
||||
next;
|
||||
}
|
||||
|
||||
if ( $line =~ m/info: server stats for thread \d+: (\d+) queries, (\d+) answers from cache, (\d+) recursions/ ) {
|
||||
$startstats{$inthread} = 1;
|
||||
$allstats{$inthread}->{thread} = $inthread;
|
||||
$allstats{$inthread}->{queries} = $1;
|
||||
$allstats{$inthread}->{cachehits} = $2;
|
||||
$allstats{$inthread}->{recursions} = $3;
|
||||
}
|
||||
elsif ( $line =~ m/info: server stats for thread (\d+): requestlist max (\d+) avg ([0-9\.]+) exceeded (\d+)/ ) {
|
||||
$allstats{$inthread}->{outstandingmax} = $2;
|
||||
$allstats{$inthread}->{outstandingavg} = int($3); # This is a float; rrdtool only handles ints.
|
||||
$allstats{$inthread}->{outstandingexc} = $4;
|
||||
}
|
||||
elsif ( $line =~ m/info: average recursion processing time ([0-9\.]+) sec/ ) {
|
||||
$allstats{$inthread}->{recursionavg} = int($1 * 1000); # change sec to milisec.
|
||||
}
|
||||
elsif ( $line =~ m/info: histogram of recursion processing times/ ) {
|
||||
next;
|
||||
}
|
||||
elsif ( $line =~ m/info: \[25%\]=([0-9\.]+) median\[50%\]=([0-9\.]+) \[75%\]=([0-9\.]+)/ ) {
|
||||
$allstats{$inthread}->{median25} = int($1 * 1000000); # change seconds to usec
|
||||
$allstats{$inthread}->{median50} = int($2 * 1000000);
|
||||
$allstats{$inthread}->{median75} = int($3 * 1000000);
|
||||
}
|
||||
elsif ( $line =~ m/info: lower\(secs\) upper\(secs\) recursions/ ) {
|
||||
# since after this line we're unsure if we get these numbers
|
||||
# at all, we sould consider this marker as the end of the
|
||||
# block. Chances that we're parsing a file halfway written
|
||||
# at this stage are small. Bold statement.
|
||||
$donestats{$inthread} = 1;
|
||||
next;
|
||||
}
|
||||
elsif ( $line =~ m/info:\s+(\d+)\.(\d+)\s+(\d+)\.(\d+)\s+(\d+)/ ) {
|
||||
my ($froms, $fromus, $toms, $tous, $counter) = ($1, $2, $3, $4, $5);
|
||||
my $prefix = '';
|
||||
if ($froms > 0) {
|
||||
$allstats{$inthread}->{'s_' . int($froms)} = $counter;
|
||||
} else {
|
||||
$allstats{$inthread}->{'us_' . int($fromus)} = $counter;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
my @result;
|
||||
# loop on the records we want to store
|
||||
for my $key ( @records ) {
|
||||
my $sum = 0;
|
||||
# these are the different threads parsed
|
||||
foreach my $thread ( 0 .. $numthreads - 1 ) {
|
||||
$sum += ($allstats{$thread}->{$key} || 0);
|
||||
}
|
||||
print STDERR "$key = " . $sum . "\n" if $DEBUG;
|
||||
push @result, $sum;
|
||||
}
|
||||
print join("\n", @result), "\n";
|
||||
store \@result, UNBOUND_CACHE;
|
||||
|
||||
if ($DEBUG) {
|
||||
print STDERR "Threads: " . (scalar keys %allstats) . "\n";
|
||||
}
|
||||
@@ -16,7 +16,7 @@ name="unbound"
|
||||
rcvar=`set_rcvar`
|
||||
|
||||
command="/usr/local/sbin/unbound"
|
||||
pidfile="/etc/unbound/unbound.pid"
|
||||
pidfile="/usr/local/etc/unbound/unbound.pid"
|
||||
extra_commands="reload"
|
||||
|
||||
load_rc_config $name
|
||||
|
||||
@@ -0,0 +1,139 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# unbound This shell script takes care of starting and stopping
|
||||
# unbound (DNS server).
|
||||
#
|
||||
# chkconfig: - 14 86
|
||||
# description: unbound is a Domain Name Server (DNS) \
|
||||
# that is used to resolve host names to IP addresses.
|
||||
|
||||
### BEGIN INIT INFO
|
||||
# Provides: $named unbound
|
||||
# Required-Start: $network $local_fs
|
||||
# Required-Stop: $network $local_fs
|
||||
# Should-Start: $syslog
|
||||
# Should-Stop: $syslog
|
||||
# Short-Description: unbound recursive Domain Name Server.
|
||||
# Description: unbound is a Domain Name Server (DNS)
|
||||
# that is used to resolve host names to IP addresses.
|
||||
### END INIT INFO
|
||||
|
||||
# Source function library.
|
||||
. /etc/rc.d/init.d/functions
|
||||
|
||||
exec="/usr/sbin/unbound"
|
||||
prog="unbound"
|
||||
config="/var/unbound/unbound.conf"
|
||||
pidfile="/var/unbound/unbound.pid"
|
||||
rootdir="/var/unbound"
|
||||
|
||||
[ -e /etc/sysconfig/$prog ] && . /etc/sysconfig/$prog
|
||||
|
||||
lockfile=/var/lock/subsys/$prog
|
||||
|
||||
start() {
|
||||
[ -x $exec ] || exit 5
|
||||
[ -f $config ] || exit 6
|
||||
echo -n $"Starting $prog: "
|
||||
|
||||
# setup root jail
|
||||
if [ -s /etc/localtime ]; then
|
||||
[ -d ${rootdir}/etc ] || mkdir -p ${rootdir}/etc ;
|
||||
if [ ! -e ${rootdir}/etc/localtime ] || /usr/bin/cmp -s /etc/localtime ${rootdir}/etc/localtime; then
|
||||
cp -fp /etc/localtime ${rootdir}/etc/localtime
|
||||
fi;
|
||||
fi;
|
||||
if [ -s /etc/resolv.conf ]; then
|
||||
[ -d ${rootdir}/etc ] || mkdir -p ${rootdir}/etc ;
|
||||
if [ ! -e ${rootdir}/etc/resolv.conf ] || /usr/bin/cmp -s /etc/resolv.conf ${rootdir}/etc/resolv.conf; then
|
||||
cp -fp /etc/resolv.conf ${rootdir}/etc/resolv.conf
|
||||
fi;
|
||||
fi;
|
||||
if ! egrep -q '^/[^[:space:]]+[[:space:]]+'${rootdir}'/dev/log' /proc/mounts; then
|
||||
[ -d ${rootdir}/dev ] || mkdir -p ${rootdir}/dev ;
|
||||
[ -e ${rootdir}/dev/log ] || touch ${rootdir}/dev/log
|
||||
mount --bind -n /dev/log ${rootdir}/dev/log >/dev/null 2>&1;
|
||||
fi;
|
||||
if ! egrep -q '^/[^[:space:]]+[[:space:]]+'${rootdir}'/dev/random' /proc/mounts; then
|
||||
[ -d ${rootdir}/dev ] || mkdir -p ${rootdir}/dev ;
|
||||
[ -e ${rootdir}/dev/random ] || touch ${rootdir}/dev/random
|
||||
mount --bind -n /dev/random ${rootdir}/dev/random >/dev/null 2>&1;
|
||||
fi;
|
||||
|
||||
# if not running, start it up here
|
||||
daemon $exec
|
||||
retval=$?
|
||||
echo
|
||||
[ $retval -eq 0 ] && touch $lockfile
|
||||
return $retval
|
||||
}
|
||||
|
||||
stop() {
|
||||
echo -n $"Stopping $prog: "
|
||||
# stop it here, often "killproc $prog"
|
||||
killproc -p $pidfile $prog
|
||||
retval=$?
|
||||
echo
|
||||
[ $retval -eq 0 ] && rm -f $lockfile
|
||||
if egrep -q '^/[^[:space:]]+[[:space:]]+'${rootdir}'/dev/log' /proc/mounts; then
|
||||
umount ${rootdir}/dev/log >/dev/null 2>&1
|
||||
fi;
|
||||
if egrep -q '^/[^[:space:]]+[[:space:]]+'${rootdir}'/dev/random' /proc/mounts; then
|
||||
umount ${rootdir}/dev/random >/dev/null 2>&1
|
||||
fi;
|
||||
return $retval
|
||||
}
|
||||
|
||||
restart() {
|
||||
stop
|
||||
start
|
||||
}
|
||||
|
||||
reload() {
|
||||
kill -HUP `cat $pidfile`
|
||||
}
|
||||
|
||||
force_reload() {
|
||||
restart
|
||||
}
|
||||
|
||||
rh_status() {
|
||||
# run checks to determine if the service is running or use generic status
|
||||
status -p $pidfile $prog
|
||||
}
|
||||
|
||||
rh_status_q() {
|
||||
rh_status -p $pidfile >/dev/null 2>&1
|
||||
}
|
||||
|
||||
case "$1" in
|
||||
start)
|
||||
rh_status_q && exit 0
|
||||
$1
|
||||
;;
|
||||
stop)
|
||||
rh_status_q || exit 0
|
||||
$1
|
||||
;;
|
||||
restart)
|
||||
$1
|
||||
;;
|
||||
reload)
|
||||
rh_status_q || exit 7
|
||||
$1
|
||||
;;
|
||||
force-reload)
|
||||
force_reload
|
||||
;;
|
||||
status)
|
||||
rh_status
|
||||
;;
|
||||
condrestart|try-restart)
|
||||
rh_status_q || exit 0
|
||||
restart
|
||||
;;
|
||||
*)
|
||||
echo $"Usage: $0 {start|stop|status|restart|condrestart|try-restart|reload|force-reload}"
|
||||
exit 2
|
||||
esac
|
||||
exit $?
|
||||
@@ -0,0 +1,103 @@
|
||||
Summary: Validating, recursive, and caching DNS resolver
|
||||
Name: unbound
|
||||
Version: 1.0.1
|
||||
Release: 1%{?dist}
|
||||
License: BSD
|
||||
Url: http://www.nlnetlabs.nl/unbound/
|
||||
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
|
||||
|
||||
%description
|
||||
Unbound is a validating, recursive, and caching DNS resolver.
|
||||
|
||||
The C implementation of Unbound is developed and maintained by NLnet
|
||||
Labs. It is based on ideas and algorithms taken from a java prototype
|
||||
developed by Verisign labs, Nominet, Kirei and ep.net.
|
||||
|
||||
Unbound is designed as a set of modular components, so that also
|
||||
DNSSEC (secure DNS) validation and stub-resolvers (that do not run
|
||||
as a server, but are linked into an application) are easily possible.
|
||||
|
||||
The source code is under a BSD License.
|
||||
|
||||
%prep
|
||||
%setup -q
|
||||
|
||||
# configure with /var/unbound/unbound.conf so that all default chroot,
|
||||
# pidfile and config file are in /var/unbound, ready for chroot jail set up.
|
||||
#
|
||||
# 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
|
||||
|
||||
%build
|
||||
#%{__make} %{?_smp_mflags}
|
||||
make
|
||||
|
||||
%install
|
||||
rm -rf %{buildroot}
|
||||
%{__make} DESTDIR=%{buildroot} install
|
||||
install -d 0700 %{buildroot}%{_localstatedir}/%{name}
|
||||
install -d 0755 %{buildroot}%{_initrddir}
|
||||
install -m 0755 contrib/unbound.init %{buildroot}%{_initrddir}/unbound
|
||||
# add symbolic link from /etc/unbound.conf -> /var/unbound/unbound.conf
|
||||
ln -s %{_localstatedir}/unbound/unbound.conf %{buildroot}%{_sysconfdir}/unbound.conf
|
||||
# remove static library from install (fedora packaging guidelines)
|
||||
rm -f %{buildroot}%{_libdir}/libunbound.a %{buildroot}%{_libdir}/libunbound.la
|
||||
|
||||
%clean
|
||||
rm -rf ${RPM_BUILD_ROOT}
|
||||
|
||||
%files
|
||||
%defattr(-,root,root,-)
|
||||
%doc doc/README doc/CREDITS doc/LICENSE doc/FEATURES
|
||||
%attr(0755,root,root) %{_initrddir}/%{name}
|
||||
%attr(0700,%{name},%{name}) %dir %{_localstatedir}/%{name}
|
||||
%attr(0644,%{name},%{name}) %config(noreplace) %{_localstatedir}/%{name}/unbound.conf
|
||||
%attr(0644,%{name},%{name}) %config(noreplace) %{_sysconfdir}/unbound.conf
|
||||
%{_sbindir}/*
|
||||
%{_mandir}/*/*
|
||||
%{_includedir}/*
|
||||
%{_libdir}/libunbound*
|
||||
|
||||
%pre
|
||||
getent group unbound >/dev/null || groupadd -r unbound
|
||||
getent passwd unbound >/dev/null || \
|
||||
useradd -r -g unbound -d /var/unbound -s /sbin/nologin \
|
||||
-c "unbound name daemon" unbound
|
||||
exit 0
|
||||
|
||||
%post
|
||||
# This adds the proper /etc/rc*.d links for the script
|
||||
/sbin/chkconfig --add %{name}
|
||||
|
||||
%preun
|
||||
if [ $1 -eq 0 ]; then
|
||||
/sbin/service %{name} stop >/dev/null 2>&1
|
||||
/sbin/chkconfig --del %{name}
|
||||
# remove root jail
|
||||
rm -f /var/unbound/dev/log /var/unbound/dev/random /var/unbound/etc/localtime /var/unbound/etc/resolv.conf >/dev/null 2>&1
|
||||
rmdir /var/unbound/dev >/dev/null 2>&1 || :
|
||||
rmdir /var/unbound/etc >/dev/null 2>&1 || :
|
||||
rmdir /var/unbound >/dev/null 2>&1 || :
|
||||
fi
|
||||
|
||||
%postun
|
||||
if [ "$1" -ge "1" ]; then
|
||||
/sbin/service %{name} condrestart >/dev/null 2>&1 || :
|
||||
fi
|
||||
|
||||
%changelog
|
||||
* Thu May 22 2008 Wouter Wijngaards <wouter@nlnetlabs.nl> - 1.0.0
|
||||
- contrib changes from Patrick Vande Walle.
|
||||
|
||||
* Thu Apr 25 2008 Wouter Wijngaards <wouter@nlnetlabs.nl> - 0.12
|
||||
- Using parts from ports collection entry by Jaap Akkerhuis.
|
||||
- Using Fedoraproject wiki guidelines.
|
||||
|
||||
* Wed Apr 23 2008 Wouter Wijngaards <wouter@nlnetlabs.nl> - 0.11
|
||||
- Initial version.
|
||||
Executable
+134
@@ -0,0 +1,134 @@
|
||||
#!/bin/sh
|
||||
# update-anchor.sh, update a trust anchor.
|
||||
# this file is BSD licensed.
|
||||
|
||||
# which validating lookup to use.
|
||||
ubhost=unbound-host
|
||||
|
||||
function usage()
|
||||
{
|
||||
echo "usage: update-anchor [-b] <zone name> <trust anchor file>"
|
||||
echo " performs an update of trust anchor file"
|
||||
echo " the trust anchor file is overwritten with the latest keys"
|
||||
echo " the trust anchor file should contain only keys for one zone"
|
||||
echo " -b causes keyfile to be made in bind format."
|
||||
echo " without -b the file is made in unbound format."
|
||||
echo " "
|
||||
echo "alternate:"
|
||||
echo " update-anchor [-b] -d directory"
|
||||
echo " update all <zone>.anchor files in the directory."
|
||||
echo " "
|
||||
echo " name the files br.anchor se.anchor ..., and include them in"
|
||||
echo " the validating resolver config file."
|
||||
echo " put keys for the root in a file with the name root.anchor."
|
||||
exit 1
|
||||
}
|
||||
|
||||
if test $# -eq 0; then
|
||||
usage
|
||||
fi
|
||||
bindformat="no"
|
||||
filearg='-f'
|
||||
if test X"$1" = "X-b"; then
|
||||
shift
|
||||
bindformat="yes"
|
||||
filearg='-F'
|
||||
fi
|
||||
if test $# -ne 2; then
|
||||
echo "arguments wrong."
|
||||
usage
|
||||
fi
|
||||
|
||||
function do_update() {
|
||||
# arguments: <zonename> <keyfile>
|
||||
zonename="$1"
|
||||
keyfile="$2"
|
||||
|
||||
tmpfile="/tmp/update-anchor.$$"
|
||||
$ubhost -v $filearg "$keyfile" -t DNSKEY "$zonename" >$tmpfile
|
||||
if test $? -ne 0; then
|
||||
rm -f $tmpfile
|
||||
echo "Error: Could not update zone $zonename anchor file $keyfile"
|
||||
echo "Cause: $ubhost lookup failed"
|
||||
echo " (Is the domain decommissioned? Is connectivity lost?)"
|
||||
return 2
|
||||
fi
|
||||
|
||||
# has the lookup been DNSSEC validated?
|
||||
if grep '(secure)$' $tmpfile >/dev/null 2>&1; then
|
||||
:
|
||||
else
|
||||
rm -f $tmpfile
|
||||
echo "Error: Could not update zone $zonename anchor file $keyfile"
|
||||
echo "Cause: result of lookup was not secure"
|
||||
echo " (keys too far out of date? domain changed ownership?)"
|
||||
return 3
|
||||
fi
|
||||
|
||||
if test $bindformat = "yes"; then
|
||||
# are there any KSK keys on board?
|
||||
echo 'trusted-keys {' > "$keyfile"
|
||||
if grep ' has DNSKEY record 257' $tmpfile >/dev/null 2>&1; then
|
||||
# store KSK keys in anchor file
|
||||
grep '(secure)$' $tmpfile | \
|
||||
grep ' has DNSKEY record 257' | \
|
||||
sed -e 's/ (secure)$/";/' | \
|
||||
sed -e 's/ has DNSKEY record \([0-9]*\) \([0-9]*\) \([0-9]*\) /. \1 \2 \3 "/' | \
|
||||
sed -e 's/^\.\././' >> "$keyfile"
|
||||
else
|
||||
# store all keys in the anchor file
|
||||
grep '(secure)$' $tmpfile | \
|
||||
sed -e 's/ (secure)$/";/' | \
|
||||
sed -e 's/ has DNSKEY record \([0-9]*\) \([0-9]*\) \([0-9]*\) /. \1 \2 \3 "/' | \
|
||||
sed -e 's/^\.\././' >> "$keyfile"
|
||||
fi
|
||||
echo '};' >> "$keyfile"
|
||||
else #not bindformat
|
||||
# are there any KSK keys on board?
|
||||
if grep ' has DNSKEY record 257' $tmpfile >/dev/null 2>&1; then
|
||||
# store KSK keys in anchor file
|
||||
grep '(secure)$' $tmpfile | \
|
||||
grep ' has DNSKEY record 257' | \
|
||||
sed -e 's/ (secure)$//' | \
|
||||
sed -e 's/ has DNSKEY record /. IN DNSKEY /' | \
|
||||
sed -e 's/^\.\././' > "$keyfile"
|
||||
else
|
||||
# store all keys in the anchor file
|
||||
grep '(secure)$' $tmpfile | \
|
||||
sed -e 's/ (secure)$//' | \
|
||||
sed -e 's/ has DNSKEY record /. IN DNSKEY /' | \
|
||||
sed -e 's/^\.\././' > "$keyfile"
|
||||
fi
|
||||
fi # endif-bindformat
|
||||
|
||||
echo "$zonename key file $keyfile updated."
|
||||
|
||||
rm -f $tmpfile
|
||||
}
|
||||
|
||||
if test X"$1" = "X-d"; then
|
||||
tdir="$2"
|
||||
echo "start updating in $2"
|
||||
for x in $tdir/*.anchor; do
|
||||
if test `basename "$x"` = "root.anchor"; then
|
||||
zname="."
|
||||
else
|
||||
zname=`basename "$x" .anchor`
|
||||
fi
|
||||
do_update "$zname" "$x"
|
||||
done
|
||||
echo "done updating in $2"
|
||||
else
|
||||
# regular invocation
|
||||
if test X"$1" = "X."; then
|
||||
zname="$1"
|
||||
else
|
||||
# strip trailing dot from zone name
|
||||
zname="`echo $1 | sed -e 's/\.$//'`"
|
||||
fi
|
||||
kfile="$2"
|
||||
do_update $zname $kfile
|
||||
exit $?
|
||||
fi
|
||||
|
||||
exit 0
|
||||
+8
-6
@@ -194,14 +194,16 @@ acl_list_apply_cfg(struct acl_list* acl, struct config_file* cfg)
|
||||
/* insert defaults, with '0' to ignore them if they are duplicates */
|
||||
if(!acl_list_str_cfg(acl, "0.0.0.0/0", "refuse", 0))
|
||||
return 0;
|
||||
if(!acl_list_str_cfg(acl, "::0/0", "refuse", 0))
|
||||
return 0;
|
||||
if(!acl_list_str_cfg(acl, "127.0.0.0/8", "allow", 0))
|
||||
return 0;
|
||||
if(!acl_list_str_cfg(acl, "::1", "allow", 0))
|
||||
return 0;
|
||||
if(!acl_list_str_cfg(acl, "::ffff:127.0.0.1", "allow", 0))
|
||||
return 0;
|
||||
if(cfg->do_ip6) {
|
||||
if(!acl_list_str_cfg(acl, "::0/0", "refuse", 0))
|
||||
return 0;
|
||||
if(!acl_list_str_cfg(acl, "::1", "allow", 0))
|
||||
return 0;
|
||||
if(!acl_list_str_cfg(acl, "::ffff:127.0.0.1", "allow", 0))
|
||||
return 0;
|
||||
}
|
||||
acl_list_init_parents(acl);
|
||||
return 1;
|
||||
}
|
||||
|
||||
+104
-6
@@ -53,6 +53,7 @@
|
||||
#include "services/localzone.h"
|
||||
#include "services/modstack.h"
|
||||
#include "util/module.h"
|
||||
#include "util/random.h"
|
||||
#include <signal.h>
|
||||
|
||||
/** How many quit requests happened. */
|
||||
@@ -75,13 +76,24 @@ static RETSIGTYPE record_sigh(int sig)
|
||||
switch(sig)
|
||||
{
|
||||
case SIGTERM:
|
||||
#ifdef SIGQUIT
|
||||
case SIGQUIT:
|
||||
#endif
|
||||
#ifdef SIGBREAK
|
||||
case SIGBREAK:
|
||||
#endif
|
||||
case SIGINT:
|
||||
sig_record_quit++;
|
||||
break;
|
||||
#ifdef SIGHUP
|
||||
case SIGHUP:
|
||||
sig_record_reload++;
|
||||
break;
|
||||
#endif
|
||||
#ifdef SIGPIPE
|
||||
case SIGPIPE:
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
log_err("ignoring signal %d", sig);
|
||||
}
|
||||
@@ -95,9 +107,20 @@ static void
|
||||
signal_handling_record()
|
||||
{
|
||||
if( signal(SIGTERM, record_sigh) == SIG_ERR ||
|
||||
#ifdef SIGQUIT
|
||||
signal(SIGQUIT, record_sigh) == SIG_ERR ||
|
||||
signal(SIGINT, record_sigh) == SIG_ERR ||
|
||||
signal(SIGHUP, record_sigh) == SIG_ERR)
|
||||
#endif
|
||||
#ifdef SIGBREAK
|
||||
signal(SIGBREAK, record_sigh) == SIG_ERR ||
|
||||
#endif
|
||||
#ifdef SIGHUP
|
||||
signal(SIGHUP, record_sigh) == SIG_ERR ||
|
||||
#endif
|
||||
#ifdef SIGPIPE
|
||||
signal(SIGPIPE, SIG_IGN) == SIG_ERR ||
|
||||
#endif
|
||||
signal(SIGINT, record_sigh) == SIG_ERR
|
||||
)
|
||||
log_err("install sighandler: %s", strerror(errno));
|
||||
}
|
||||
|
||||
@@ -108,8 +131,10 @@ signal_handling_record()
|
||||
static void
|
||||
signal_handling_playback(struct worker* wrk)
|
||||
{
|
||||
#ifdef SIGHUP
|
||||
if(sig_record_reload)
|
||||
worker_sighandler(SIGHUP, wrk);
|
||||
#endif
|
||||
if(sig_record_quit)
|
||||
worker_sighandler(SIGTERM, wrk);
|
||||
sig_record_quit = 0;
|
||||
@@ -121,11 +146,26 @@ daemon_init()
|
||||
{
|
||||
struct daemon* daemon = (struct daemon*)calloc(1,
|
||||
sizeof(struct daemon));
|
||||
#ifdef USE_WINSOCK
|
||||
int r;
|
||||
WSADATA wsa_data;
|
||||
#endif
|
||||
if(!daemon)
|
||||
return NULL;
|
||||
#ifdef USE_WINSOCK
|
||||
r = WSAStartup(MAKEWORD(2,2), &wsa_data);
|
||||
if(r != 0) {
|
||||
fatal_exit("could not init winsock. WSAStartup: %s",
|
||||
wsa_strerror(r));
|
||||
}
|
||||
#endif /* USE_WINSOCK */
|
||||
signal_handling_record();
|
||||
checklock_start();
|
||||
ERR_load_crypto_strings();
|
||||
#ifdef HAVE_TZSET
|
||||
/* init timezone info while we are not chrooted yet */
|
||||
tzset();
|
||||
#endif
|
||||
daemon->need_to_exit = 0;
|
||||
modstack_init(&daemon->mods);
|
||||
if(!(daemon->env = (struct module_env*)calloc(1,
|
||||
@@ -172,23 +212,74 @@ static void daemon_setup_modules(struct daemon* daemon)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Obtain allowed port numbers, concatenate the list, and shuffle them
|
||||
* (ready to be handed out to threads).
|
||||
* @param daemon: the daemon. Uses rand and cfg.
|
||||
* @param shufport: the portlist output.
|
||||
* @return number of ports available.
|
||||
*/
|
||||
int daemon_get_shufport(struct daemon* daemon, int* shufport)
|
||||
{
|
||||
int i, n, k, temp;
|
||||
int avail = 0;
|
||||
for(i=0; i<65536; i++) {
|
||||
if(daemon->cfg->outgoing_avail_ports[i]) {
|
||||
shufport[avail++] = daemon->cfg->
|
||||
outgoing_avail_ports[i];
|
||||
}
|
||||
}
|
||||
if(avail == 0)
|
||||
fatal_exit("no ports are permitted for UDP, add "
|
||||
"with outgoing-port-permit");
|
||||
/* Knuth shuffle */
|
||||
n = avail;
|
||||
while(--n > 0) {
|
||||
k = ub_random(daemon->rand) % (n+1); /* 0<= k<= n */
|
||||
temp = shufport[k];
|
||||
shufport[k] = shufport[n];
|
||||
shufport[n] = temp;
|
||||
}
|
||||
return avail;
|
||||
}
|
||||
|
||||
/**
|
||||
* Allocate empty worker structures. With backptr and thread-number,
|
||||
* from 0..numthread initialised. Used as user arguments to new threads.
|
||||
* Creates the daemon random generator if it does not exist yet.
|
||||
* The random generator stays existing between reloads with a unique state.
|
||||
* @param daemon: the daemon with (new) config settings.
|
||||
*/
|
||||
static void
|
||||
daemon_create_workers(struct daemon* daemon)
|
||||
{
|
||||
int i;
|
||||
int i, numport;
|
||||
int* shufport;
|
||||
log_assert(daemon && daemon->cfg);
|
||||
if(!daemon->rand) {
|
||||
unsigned int seed = (unsigned int)time(NULL) ^
|
||||
(unsigned int)getpid() ^ 0x438;
|
||||
daemon->rand = ub_initstate(seed, NULL);
|
||||
if(!daemon->rand)
|
||||
fatal_exit("could not init random generator");
|
||||
}
|
||||
shufport = (int*)calloc(65536, sizeof(int));
|
||||
if(!shufport)
|
||||
fatal_exit("out of memory during daemon init");
|
||||
numport = daemon_get_shufport(daemon, shufport);
|
||||
verbose(VERB_ALGO, "total of %d outgoing ports available", numport);
|
||||
|
||||
daemon->num = daemon->cfg->num_threads;
|
||||
daemon->workers = (struct worker**)calloc((size_t)daemon->num,
|
||||
sizeof(struct worker*));
|
||||
for(i=0; i<daemon->num; i++) {
|
||||
if(!(daemon->workers[i] = worker_create(daemon, i)))
|
||||
if(!(daemon->workers[i] = worker_create(daemon, i,
|
||||
shufport+numport*i/daemon->num,
|
||||
numport*(i+1)/daemon->num - numport*i/daemon->num)))
|
||||
/* the above is not ports/numthr, due to rounding */
|
||||
fatal_exit("could not create worker");
|
||||
}
|
||||
free(shufport);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -223,7 +314,7 @@ thread_start(void* arg)
|
||||
struct worker* worker = (struct worker*)arg;
|
||||
log_thread_set(&worker->thread_num);
|
||||
ub_thread_blocksigs();
|
||||
#if !defined(HAVE_PTHREAD) && !defined(HAVE_SOLARIS_THREADS)
|
||||
#ifdef THREADS_DISABLED
|
||||
/* close pipe ends used by main */
|
||||
close(worker->cmd_send_fd);
|
||||
worker->cmd_send_fd = -1;
|
||||
@@ -250,7 +341,7 @@ daemon_start_others(struct daemon* daemon)
|
||||
for(i=1; i<daemon->num; i++) {
|
||||
ub_thread_create(&daemon->workers[i]->thr_id,
|
||||
thread_start, daemon->workers[i]);
|
||||
#if !defined(HAVE_PTHREAD) && !defined(HAVE_SOLARIS_THREADS)
|
||||
#ifdef THREADS_DISABLED
|
||||
/* close pipe end of child */
|
||||
close(daemon->workers[i]->cmd_recv_fd);
|
||||
daemon->workers[i]->cmd_recv_fd = -1;
|
||||
@@ -363,6 +454,7 @@ daemon_delete(struct daemon* daemon)
|
||||
rrset_cache_delete(daemon->env->rrset_cache);
|
||||
infra_delete(daemon->env->infra_cache);
|
||||
}
|
||||
ub_randfree(daemon->rand);
|
||||
alloc_clear(&daemon->superalloc);
|
||||
acl_list_delete(daemon->acl);
|
||||
free(daemon->pidfile);
|
||||
@@ -377,4 +469,10 @@ daemon_delete(struct daemon* daemon)
|
||||
ERR_free_strings();
|
||||
RAND_cleanup();
|
||||
checklock_stop();
|
||||
#ifdef USE_WINSOCK
|
||||
if(WSACleanup() != 0) {
|
||||
log_err("Could not WSACleanup: %s",
|
||||
wsa_strerror(WSAGetLastError()));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -53,6 +53,7 @@ struct module_env;
|
||||
struct rrset_cache;
|
||||
struct acl_list;
|
||||
struct local_zones;
|
||||
struct ub_randstate;
|
||||
|
||||
/**
|
||||
* Structure holding worker list.
|
||||
@@ -73,6 +74,8 @@ struct daemon {
|
||||
struct worker** workers;
|
||||
/** do we need to exit unbound (or is it only a reload?) */
|
||||
int need_to_exit;
|
||||
/** master random table ; used for port div between threads on reload*/
|
||||
struct ub_randstate* rand;
|
||||
/** master allocation cache */
|
||||
struct alloc_cache superalloc;
|
||||
/** the module environment master value, copied and changed by threads*/
|
||||
|
||||
+89
-23
@@ -52,14 +52,22 @@
|
||||
#include "util/module.h"
|
||||
#include <signal.h>
|
||||
#include <fcntl.h>
|
||||
#ifdef HAVE_PWD_H
|
||||
#include <pwd.h>
|
||||
#include <sys/resource.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_SYS_RESOURCE_H
|
||||
#include <sys/resource.h>
|
||||
#endif
|
||||
|
||||
#ifdef USE_MINI_EVENT
|
||||
#include "util/mini_event.h"
|
||||
# ifdef USE_WINSOCK
|
||||
# include "util/winsock_event.h"
|
||||
# else
|
||||
# include "util/mini_event.h"
|
||||
# endif
|
||||
#else
|
||||
#include <event.h>
|
||||
# include <event.h>
|
||||
#endif
|
||||
|
||||
/** global debug value to keep track of heap memory allocation */
|
||||
@@ -86,23 +94,28 @@ static void usage()
|
||||
static void
|
||||
checkrlimits(struct config_file* cfg)
|
||||
{
|
||||
#ifdef HAVE_GETRLIMIT
|
||||
int list = ((cfg->do_ip4?1:0) + (cfg->do_ip6?1:0)) *
|
||||
((cfg->do_udp?1:0) + (cfg->do_tcp?1 +
|
||||
(int)cfg->incoming_num_tcp:0));
|
||||
size_t ifs = (size_t)(cfg->num_ifs==0?1:cfg->num_ifs);
|
||||
size_t listen_num = list*ifs;
|
||||
size_t out_ifs = (size_t)(cfg->num_out_ifs==0?1:cfg->num_out_ifs);
|
||||
size_t outnum = cfg->outgoing_num_ports*out_ifs + cfg->outgoing_num_tcp;
|
||||
size_t outudpnum = (size_t)cfg->outgoing_num_ports;
|
||||
size_t outtcpnum = cfg->outgoing_num_tcp;
|
||||
size_t misc = 4; /* logfile, pidfile, stdout... */
|
||||
size_t perthread = listen_num + outnum + 2/*cmdpipe*/ + 2/*libevent*/
|
||||
+ misc;
|
||||
size_t perthread_noudp = listen_num + outtcpnum +
|
||||
2/*cmdpipe*/ + 2/*libevent*/ + misc;
|
||||
size_t perthread = perthread_noudp + outudpnum;
|
||||
|
||||
#if !defined(HAVE_PTHREAD) && !defined(HAVE_SOLARIS_THREADS)
|
||||
int numthread = 1; /* it forks */
|
||||
#else
|
||||
int numthread = cfg->num_threads;
|
||||
#endif
|
||||
size_t total = numthread * perthread + misc;
|
||||
size_t avail;
|
||||
struct rlimit rlim;
|
||||
|
||||
if(getrlimit(RLIMIT_NOFILE, &rlim) < 0) {
|
||||
log_warn("getrlimit: %s", strerror(errno));
|
||||
return;
|
||||
@@ -110,14 +123,27 @@ checkrlimits(struct config_file* cfg)
|
||||
if(rlim.rlim_cur == (rlim_t)RLIM_INFINITY)
|
||||
return;
|
||||
if((size_t)rlim.rlim_cur < total) {
|
||||
log_err("Not enough sockets available. Increase "
|
||||
"ulimit(open files).");
|
||||
log_err("or decrease number of threads, outgoing num ports, "
|
||||
"outgoing num tcp or number of interfaces");
|
||||
log_err("estimate %u fds high mark, %u available",
|
||||
(unsigned)total, (unsigned)rlim.rlim_cur);
|
||||
fatal_exit("Not enough file descriptors available");
|
||||
avail = (size_t)rlim.rlim_cur;
|
||||
rlim.rlim_cur = (rlim_t)(total + 10);
|
||||
rlim.rlim_max = (rlim_t)(total + 10);
|
||||
if(setrlimit(RLIMIT_NOFILE, &rlim) < 0) {
|
||||
log_warn("setrlimit: %s", strerror(errno));
|
||||
log_warn("cannot increase max open fds from %u to %u",
|
||||
(unsigned)avail, (unsigned)total+10);
|
||||
cfg->outgoing_num_ports = (int)((avail
|
||||
- numthread*perthread_noudp
|
||||
- 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");
|
||||
return;
|
||||
}
|
||||
log_warn("increased limit(open files) from %u to %u",
|
||||
(unsigned)avail, (unsigned)total+10);
|
||||
}
|
||||
#else
|
||||
(void)cfg;
|
||||
#endif /* HAVE_GETRLIMIT */
|
||||
}
|
||||
|
||||
/** set verbosity, check rlimits, cache settings */
|
||||
@@ -150,6 +176,7 @@ apply_settings(struct daemon* daemon, struct config_file* cfg,
|
||||
checkrlimits(cfg);
|
||||
}
|
||||
|
||||
#ifdef HAVE_KILL
|
||||
/** Read existing pid from pidfile.
|
||||
* @param file: file name of pid file.
|
||||
* @return: the pid from the file or -1 if none.
|
||||
@@ -237,11 +264,13 @@ checkoldpid(struct config_file* cfg)
|
||||
(unsigned)old);
|
||||
}
|
||||
}
|
||||
#endif /* HAVE_KILL */
|
||||
|
||||
/** detach from command line */
|
||||
static void
|
||||
detach(struct config_file* cfg)
|
||||
{
|
||||
#ifdef HAVE_WORKING_FORK
|
||||
int fd;
|
||||
/* Take off... */
|
||||
switch (fork()) {
|
||||
@@ -255,8 +284,10 @@ detach(struct config_file* cfg)
|
||||
exit(0);
|
||||
}
|
||||
/* detach */
|
||||
#ifdef HAVE_SETSID
|
||||
if(setsid() == -1)
|
||||
fatal_exit("setsid() failed: %s", strerror(errno));
|
||||
#endif
|
||||
if ((fd = open("/dev/null", O_RDWR, 0)) != -1) {
|
||||
(void)dup2(fd, STDIN_FILENO);
|
||||
(void)dup2(fd, STDOUT_FILENO);
|
||||
@@ -264,12 +295,17 @@ detach(struct config_file* cfg)
|
||||
if (fd > 2)
|
||||
(void)close(fd);
|
||||
}
|
||||
#else
|
||||
(void)cfg;
|
||||
#endif /* HAVE_WORKING_FORK */
|
||||
}
|
||||
|
||||
/** daemonize, drop user priviliges and chroot if needed */
|
||||
static void
|
||||
do_chroot(struct daemon* daemon, struct config_file* cfg, int debug_mode)
|
||||
do_chroot(struct daemon* daemon, struct config_file* cfg, int debug_mode,
|
||||
char** cfgfile)
|
||||
{
|
||||
#ifdef HAVE_GETPWNAM
|
||||
uid_t uid;
|
||||
gid_t gid;
|
||||
/* initialize, but not to 0 (root) */
|
||||
@@ -278,13 +314,6 @@ do_chroot(struct daemon* daemon, struct config_file* cfg, int debug_mode)
|
||||
log_assert(cfg);
|
||||
|
||||
/* daemonize last to be able to print error to user */
|
||||
if(cfg->directory && cfg->directory[0]) {
|
||||
if(chdir(cfg->directory)) {
|
||||
fatal_exit("Could not chdir to %s: %s",
|
||||
cfg->directory, strerror(errno));
|
||||
}
|
||||
verbose(VERB_QUERY, "chdir to %s", cfg->directory);
|
||||
}
|
||||
if(cfg->username && cfg->username[0]) {
|
||||
struct passwd *pwd;
|
||||
if((pwd = getpwnam(cfg->username)) == NULL)
|
||||
@@ -293,12 +322,40 @@ do_chroot(struct daemon* daemon, struct config_file* cfg, int debug_mode)
|
||||
gid = pwd->pw_gid;
|
||||
endpwent();
|
||||
}
|
||||
#endif
|
||||
#ifdef HAVE_CHROOT
|
||||
if(cfg->chrootdir && cfg->chrootdir[0]) {
|
||||
if(chdir(cfg->chrootdir)) {
|
||||
fatal_exit("unable to chdir to chroot %s: %s",
|
||||
cfg->chrootdir, strerror(errno));
|
||||
}
|
||||
verbose(VERB_QUERY, "chdir to %s", cfg->chrootdir);
|
||||
if(chroot(cfg->chrootdir))
|
||||
fatal_exit("unable to chroot to %s: %s",
|
||||
cfg->chrootdir, strerror(errno));
|
||||
verbose(VERB_QUERY, "chroot to %s", cfg->chrootdir);
|
||||
if(strncmp(*cfgfile, cfg->chrootdir,
|
||||
strlen(cfg->chrootdir)) == 0)
|
||||
(*cfgfile) += strlen(cfg->chrootdir);
|
||||
}
|
||||
#else
|
||||
(void)cfgfile;
|
||||
#endif
|
||||
if(cfg->directory && cfg->directory[0]) {
|
||||
char* dir = cfg->directory;
|
||||
if(cfg->chrootdir && cfg->chrootdir[0] &&
|
||||
strncmp(dir, cfg->chrootdir,
|
||||
strlen(cfg->chrootdir)) == 0)
|
||||
dir += strlen(cfg->chrootdir);
|
||||
if(dir[0]) {
|
||||
if(chdir(dir)) {
|
||||
fatal_exit("Could not chdir to %s: %s",
|
||||
dir, strerror(errno));
|
||||
}
|
||||
verbose(VERB_QUERY, "chdir to %s", dir);
|
||||
}
|
||||
}
|
||||
#ifdef HAVE_GETPWNAM
|
||||
if(cfg->username && cfg->username[0]) {
|
||||
if(setgid(gid) != 0)
|
||||
fatal_exit("unable to set group id of %s: %s",
|
||||
@@ -309,16 +366,20 @@ do_chroot(struct daemon* daemon, struct config_file* cfg, int debug_mode)
|
||||
verbose(VERB_QUERY, "drop user privileges, run as %s",
|
||||
cfg->username);
|
||||
}
|
||||
#endif
|
||||
#ifdef HAVE_KILL
|
||||
/* check old pid file before forking */
|
||||
if(cfg->pidfile && cfg->pidfile[0]) {
|
||||
checkoldpid(cfg);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* init logfile just before fork */
|
||||
log_init(cfg->logfile, cfg->use_syslog, cfg->chrootdir);
|
||||
if(!debug_mode && cfg->do_daemonize) {
|
||||
detach(cfg);
|
||||
}
|
||||
#ifdef HAVE_KILL
|
||||
if(cfg->pidfile && cfg->pidfile[0]) {
|
||||
char* pf = cfg->pidfile;
|
||||
if(cfg->chrootdir && cfg->chrootdir[0] &&
|
||||
@@ -328,6 +389,9 @@ do_chroot(struct daemon* daemon, struct config_file* cfg, int debug_mode)
|
||||
if(!(daemon->pidfile = strdup(pf)))
|
||||
log_err("pidf: malloc failed");
|
||||
}
|
||||
#else
|
||||
(void)daemon;
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -366,7 +430,7 @@ run_daemon(char* cfgfile, int cmdline_verbose, int debug_mode)
|
||||
if(!daemon_open_shared_ports(daemon))
|
||||
fatal_exit("could not open ports");
|
||||
if(!done_chroot) {
|
||||
do_chroot(daemon, cfg, debug_mode);
|
||||
do_chroot(daemon, cfg, debug_mode, &cfgfile);
|
||||
done_chroot = 1;
|
||||
} else log_init(cfg->logfile, cfg->use_syslog, cfg->chrootdir);
|
||||
/* work */
|
||||
@@ -402,8 +466,10 @@ main(int argc, char* argv[])
|
||||
int cmdline_verbose = 0;
|
||||
int debug_mode = 0;
|
||||
|
||||
#ifdef HAVE_SBRK
|
||||
/* take debug snapshot of heap */
|
||||
unbound_start_brk = sbrk(0);
|
||||
#endif
|
||||
|
||||
log_init(NULL, 0, NULL);
|
||||
/* parse the options */
|
||||
|
||||
+50
-15
@@ -67,7 +67,9 @@
|
||||
#ifdef HAVE_SYS_TYPES_H
|
||||
# include <sys/types.h>
|
||||
#endif
|
||||
#ifdef HAVE_NETDB_H
|
||||
#include <netdb.h>
|
||||
#endif
|
||||
#include <signal.h>
|
||||
|
||||
/** Size of an UDP datagram */
|
||||
@@ -102,6 +104,7 @@ debug_memleak(size_t accounted, size_t heap,
|
||||
static void
|
||||
debug_total_mem(size_t calctotal)
|
||||
{
|
||||
#ifdef HAVE_SBRK
|
||||
extern void* unbound_start_brk;
|
||||
extern size_t unbound_mem_alloc, unbound_mem_freed;
|
||||
void* cur = sbrk(0);
|
||||
@@ -111,6 +114,9 @@ debug_total_mem(size_t calctotal)
|
||||
(unsigned)unbound_mem_alloc, (unsigned)unbound_mem_freed);
|
||||
debug_memleak(calctotal, (size_t)total,
|
||||
unbound_mem_alloc, unbound_mem_freed);
|
||||
#else
|
||||
(void)calctotal;
|
||||
#endif /* HAVE_SBRK */
|
||||
}
|
||||
#endif /* UNBOUND_ALLOC_STATS */
|
||||
|
||||
@@ -840,20 +846,24 @@ worker_sighandler(int sig, void* arg)
|
||||
* in the cause for unbound to exit */
|
||||
struct worker* worker = (struct worker*)arg;
|
||||
switch(sig) {
|
||||
#ifdef SIGHUP
|
||||
case SIGHUP:
|
||||
verbose(VERB_QUERY, "caught signal SIGHUP");
|
||||
comm_base_exit(worker->base);
|
||||
break;
|
||||
#endif
|
||||
case SIGINT:
|
||||
verbose(VERB_QUERY, "caught signal SIGINT");
|
||||
worker->need_to_exit = 1;
|
||||
comm_base_exit(worker->base);
|
||||
break;
|
||||
#ifdef SIGQUIT
|
||||
case SIGQUIT:
|
||||
verbose(VERB_QUERY, "caught signal SIGQUIT");
|
||||
worker->need_to_exit = 1;
|
||||
comm_base_exit(worker->base);
|
||||
break;
|
||||
#endif
|
||||
case SIGTERM:
|
||||
verbose(VERB_QUERY, "caught signal SIGTERM");
|
||||
worker->need_to_exit = 1;
|
||||
@@ -883,19 +893,27 @@ void worker_stat_timer_cb(void* arg)
|
||||
server_stats_log(&worker->stats, worker->thread_num);
|
||||
mesh_stats(worker->env.mesh, "mesh has");
|
||||
worker_mem_report(worker, NULL);
|
||||
server_stats_init(&worker->stats);
|
||||
mesh_stats_clear(worker->env.mesh);
|
||||
if(!worker->daemon->cfg->stat_cumulative) {
|
||||
server_stats_init(&worker->stats);
|
||||
mesh_stats_clear(worker->env.mesh);
|
||||
}
|
||||
/* start next timer */
|
||||
worker_restart_timer(worker);
|
||||
}
|
||||
|
||||
struct worker*
|
||||
worker_create(struct daemon* daemon, int id)
|
||||
worker_create(struct daemon* daemon, int id, int* ports, int n)
|
||||
{
|
||||
struct worker* worker = (struct worker*)calloc(1,
|
||||
sizeof(struct worker));
|
||||
if(!worker)
|
||||
return NULL;
|
||||
worker->numports = n;
|
||||
worker->ports = (int*)memdup(ports, sizeof(int)*n);
|
||||
if(!worker->ports) {
|
||||
free(worker);
|
||||
return NULL;
|
||||
}
|
||||
worker->daemon = daemon;
|
||||
worker->thread_num = id;
|
||||
worker->cmd_send_fd = -1;
|
||||
@@ -925,7 +943,6 @@ worker_init(struct worker* worker, struct config_file *cfg,
|
||||
struct listen_port* ports, int do_sigs)
|
||||
{
|
||||
unsigned int seed;
|
||||
int startport;
|
||||
worker->need_to_exit = 0;
|
||||
worker->base = comm_base_create();
|
||||
if(!worker->base) {
|
||||
@@ -934,17 +951,26 @@ worker_init(struct worker* worker, struct config_file *cfg,
|
||||
return 0;
|
||||
}
|
||||
if(do_sigs) {
|
||||
#ifdef SIGHUP
|
||||
ub_thread_sig_unblock(SIGHUP);
|
||||
#endif
|
||||
ub_thread_sig_unblock(SIGINT);
|
||||
#ifdef SIGQUIT
|
||||
ub_thread_sig_unblock(SIGQUIT);
|
||||
#endif
|
||||
ub_thread_sig_unblock(SIGTERM);
|
||||
#ifndef LIBEVENT_SIGNAL_PROBLEM
|
||||
worker->comsig = comm_signal_create(worker->base,
|
||||
worker_sighandler, worker);
|
||||
if(!worker->comsig || !comm_signal_bind(worker->comsig, SIGHUP)
|
||||
|| !comm_signal_bind(worker->comsig, SIGINT)
|
||||
if(!worker->comsig
|
||||
#ifdef SIGHUP
|
||||
|| !comm_signal_bind(worker->comsig, SIGHUP)
|
||||
#endif
|
||||
#ifdef SIGQUIT
|
||||
|| !comm_signal_bind(worker->comsig, SIGQUIT)
|
||||
#endif
|
||||
|| !comm_signal_bind(worker->comsig, SIGTERM)
|
||||
|| !comm_signal_bind(worker->comsig, SIGQUIT)) {
|
||||
|| !comm_signal_bind(worker->comsig, SIGINT)) {
|
||||
log_err("could not create signal handlers");
|
||||
worker_delete(worker);
|
||||
return 0;
|
||||
@@ -971,14 +997,12 @@ worker_init(struct worker* worker, struct config_file *cfg,
|
||||
worker_delete(worker);
|
||||
return 0;
|
||||
}
|
||||
startport = cfg->outgoing_base_port +
|
||||
cfg->outgoing_num_ports * worker->thread_num;
|
||||
worker->back = outside_network_create(worker->base,
|
||||
cfg->msg_buffer_size, (size_t)cfg->outgoing_num_ports,
|
||||
cfg->out_ifs, cfg->num_out_ifs, cfg->do_ip4, cfg->do_ip6,
|
||||
startport, cfg->do_tcp?cfg->outgoing_num_tcp:0,
|
||||
cfg->do_tcp?cfg->outgoing_num_tcp:0,
|
||||
worker->daemon->env->infra_cache, worker->rndstate,
|
||||
cfg->use_caps_bits_for_id);
|
||||
cfg->use_caps_bits_for_id, worker->ports, worker->numports);
|
||||
if(!worker->back) {
|
||||
log_err("could not create outgoing sockets");
|
||||
worker_delete(worker);
|
||||
@@ -1067,6 +1091,7 @@ worker_delete(struct worker* worker)
|
||||
comm_signal_delete(worker->comsig);
|
||||
comm_point_delete(worker->cmd_com);
|
||||
comm_timer_delete(worker->stat_timer);
|
||||
free(worker->ports);
|
||||
if(worker->thread_num == 0)
|
||||
log_set_time(NULL);
|
||||
comm_base_delete(worker->base);
|
||||
@@ -1091,12 +1116,10 @@ worker_send_packet(ldns_buffer* pkt, struct sockaddr_storage* addr,
|
||||
struct worker* worker = q->env->worker;
|
||||
if(use_tcp) {
|
||||
return pending_tcp_query(worker->back, pkt, addr, addrlen,
|
||||
timeout, worker_handle_reply, q,
|
||||
worker->rndstate) != 0;
|
||||
timeout, worker_handle_reply, q) != 0;
|
||||
}
|
||||
return pending_udp_query(worker->back, pkt, addr, addrlen,
|
||||
timeout*1000, worker_handle_reply, q,
|
||||
worker->rndstate) != 0;
|
||||
timeout*1000, worker_handle_reply, q) != 0;
|
||||
}
|
||||
|
||||
/** compare outbound entry qstates */
|
||||
@@ -1181,3 +1204,15 @@ int context_query_cmp(const void* ATTR_UNUSED(a), const void* ATTR_UNUSED(b))
|
||||
log_assert(0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int order_lock_cmp(const void* ATTR_UNUSED(e1), const void* ATTR_UNUSED(e2))
|
||||
{
|
||||
log_assert(0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int codeline_cmp(const void* ATTR_UNUSED(a), const void* ATTR_UNUSED(b))
|
||||
{
|
||||
log_assert(0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
+7
-1
@@ -86,6 +86,10 @@ struct worker {
|
||||
struct listen_dnsport* front;
|
||||
/** the backside outside network interface to the auth servers */
|
||||
struct outside_network* back;
|
||||
/** ports to be used by this worker. */
|
||||
int* ports;
|
||||
/** number of ports for this worker */
|
||||
int numports;
|
||||
/** the signal handler */
|
||||
struct comm_signal* comsig;
|
||||
/** commpoint to listen to commands. */
|
||||
@@ -116,9 +120,11 @@ struct worker {
|
||||
* with backpointers only. Use worker_init on it later.
|
||||
* @param daemon: the daemon that this worker thread is part of.
|
||||
* @param id: the thread number from 0.. numthreads-1.
|
||||
* @param ports: the ports it is allowed to use, array.
|
||||
* @param n: the number of ports.
|
||||
* @return: the new worker or NULL on alloc failure.
|
||||
*/
|
||||
struct worker* worker_create(struct daemon* daemon, int id);
|
||||
struct worker* worker_create(struct daemon* daemon, int id, int* ports, int n);
|
||||
|
||||
/**
|
||||
* Initialize worker.
|
||||
|
||||
+8
-4
@@ -1,10 +1,14 @@
|
||||
Unbound was developed at NLnet Labs by Wouter Wijngaards.
|
||||
|
||||
Unbound was devised by Bill Manning, David Blacka, and Matt Larson
|
||||
from the University of California and from Verisign. The Java prototype
|
||||
was made in further cooperation with Geoff Sisson and Roy Arends from Nominet.
|
||||
Unbound was architected in January of 2004 by Jakob Schlyter of Kirei
|
||||
and Roy Arends of Nominet. VeriSign and EP.Net funded development of
|
||||
the prototype, which was built by David Blacka and Matt Larson of VeriSign.
|
||||
Late in 2006, NLnet Labs joined the effort, writing an implementation in C
|
||||
based on the existing prototype and using experience NLnet Labs gained
|
||||
during the development of NSD, an authoritative DNS server.
|
||||
|
||||
At NLnet Labs, Jelte Jansen and Mark Santcroos reviewed the unbound C sources.
|
||||
At NLnet Labs, Jelte Jansen, Mark Santcroos and Matthijs Mekking
|
||||
reviewed the unbound C sources.
|
||||
|
||||
Jakob Schlyter - for advice on secure settings, random numbers and blacklists.
|
||||
|
||||
|
||||
+287
@@ -1,3 +1,290 @@
|
||||
15 July 2008: Wouter
|
||||
- Follow draft-ietf-dnsop-default-local-zones-06 added reverse
|
||||
IPv6 example prefix to AS112 default blocklist.
|
||||
- fixup lookup of DS records by client with trustanchor for same.
|
||||
- libunbound ub_resolve, fix handling of error condition during setup.
|
||||
- lowered log_hex blocksize to fit through BSD syslog linesize.
|
||||
- no useless initialisation if getpwnam not available.
|
||||
- iana, ldns snapshot updated.
|
||||
|
||||
3 July 2008: Wouter
|
||||
- Matthijs fixed memory leaks in root hints file reading.
|
||||
|
||||
26 June 2008: Wouter
|
||||
- fixup streamtcp bounds setting for udp mode, in the test framework.
|
||||
- contrib item for updating trust anchors.
|
||||
|
||||
25 June 2008: Wouter
|
||||
- fixup fwd_ancil test typos.
|
||||
- Fix for newegg lameness : ok for qtype=A, but lame for others.
|
||||
- fixup unit test for infra cache, test lame merging.
|
||||
- porting to mingw, bind, listen, getsockopt and setsockopt error
|
||||
handling.
|
||||
|
||||
24 June 2008: Wouter
|
||||
- removed testcode/checklocks from production code compilation path.
|
||||
- streamtcp can use UDP mode (connected UDP socket), for testing IPv6
|
||||
on windows.
|
||||
- fwd_ancil test fails if platform support is lacking.
|
||||
|
||||
23 June 2008: Wouter
|
||||
- fixup minitpkg to cleanup on windows with its file locking troubles.
|
||||
- minitpkg shows skipped tests in report.
|
||||
- skip ipv6 tests on ipv4 only hosts (requires only ipv6 localhost not
|
||||
ipv6 connectivity).
|
||||
- winsock event handler keeps track of sticky TCP events, that have
|
||||
not been fully handled yet. when interest in the event(s) resumes,
|
||||
they are sent again. When WOULDBLOCK is returned events are cleared.
|
||||
- skip tests that need signals when testing on mingw.
|
||||
|
||||
18 June 2008: Wouter
|
||||
- open testbound replay files in binary mode, because fseek/ftell
|
||||
do not work in ascii-mode on windows. The b does nothing on unix.
|
||||
unittest and testbound tests work on windows (xp too).
|
||||
- ioctlsocket prints nicer error message.
|
||||
- fixed up some TCP porting for winsock.
|
||||
- lack of IPv6 gives a warning, no fatal error.
|
||||
- use WSAGetLastError() on windows instead of errno for some errors.
|
||||
|
||||
17 June 2008: Wouter
|
||||
- outgoing num fds 32 by default on windows ; it supports less
|
||||
fds for waiting on than unixes.
|
||||
- winsock_event minievent handler for windows. (you could also
|
||||
attempt to link with libevent/libev ports for windows).
|
||||
- neater crypto check and gdi32 detection.
|
||||
- unbound.exe works to resolve and validate www.nlnetlabs.nl on vista.
|
||||
|
||||
16 June 2008: Wouter
|
||||
- on windows, use windows threads, mutex and thread-local-storage(Tls).
|
||||
- detect if openssl needs gdi32.
|
||||
- if no threading, THREADS_DISABLED is defined for use in the code.
|
||||
- sets USE_WINSOCK if using ws2_32 on windows.
|
||||
- wsa_strerror() function for more readable errors.
|
||||
- WSA Startup and Cleanup called in unbound.exe.
|
||||
|
||||
13 June 2008: Wouter
|
||||
- port mingw32, more signal ifdefs, detect sleep, usleep,
|
||||
random, srandom (used inside the tests).
|
||||
- signed or unsigned FD_SET is cast.
|
||||
|
||||
10 June 2008: Wouter
|
||||
- fixup warnings compiling on eeepc xandros linux.
|
||||
|
||||
9 June 2008: Wouter
|
||||
- in iteration response type code
|
||||
* first check for SOA record (negative answer) before NS record
|
||||
and lameness.
|
||||
* check if no AA bit for non-forwarder, and thus lame zone.
|
||||
In response to error report by Richard Doty for mail.opusnet.com.
|
||||
- fixup unput warning from lexer on freeBSD.
|
||||
- bug#183. pidfile, rundir, and chroot configure options. Also the
|
||||
example.conf and manual pages get the configured defaults.
|
||||
You can use: (or accept the defaults to /usr/local/etc/unbound/)
|
||||
--with-conf-file=filename
|
||||
--with-pidfile=filename
|
||||
--with-run-dir=path
|
||||
--with-chroot-dir=path
|
||||
|
||||
8 June 2008: Wouter
|
||||
- if multiple CNAMEs, use the first one. Fixup akamai CNAME bug.
|
||||
Reported by Robert Edmonds.
|
||||
- iana port updated.
|
||||
|
||||
4 June 2008: Wouter
|
||||
- updated libtool files with newer version.
|
||||
- iana portlist updated.
|
||||
|
||||
3 June 2008: Wouter
|
||||
- fixup local-zone: "30.172.in-addr.arpa." nodefault, so that the
|
||||
trailing dot is not used during comparison.
|
||||
|
||||
2 June 2008: Wouter
|
||||
- Jelte fixed bugs in my absence
|
||||
- bug 178: fixed unportable shell usage in configure (relied on
|
||||
bash shell).
|
||||
- bug 180: fixed buffer overflow in unbound-checkconf use of strncat.
|
||||
- bug 181: fixed buffer overflow in ldns (called by unbound to parse
|
||||
config file parts).
|
||||
- fixes by Wouter
|
||||
- bug 177: fixed compilation failure on opensuse, the
|
||||
--disable-static configure flag caused problems. (Patch from
|
||||
Klaus Singvogel)
|
||||
- bug 179: same fix as 177.
|
||||
- bug 185: --disable-shared not passed along to ldns included with
|
||||
unbound. Fixed so that configure parameters are passed to the
|
||||
subdir configure script.
|
||||
fixed that ./libtool is used always, you can still override
|
||||
manually with ./configure libtool=mylibtool or set $libtool in
|
||||
the environment.
|
||||
- update of the ldns tarball to current ldns svn version (fix 181).
|
||||
- bug 184: -r option for unbound-host, read resolv.conf for
|
||||
forwarder. (Note that forwarder must support DNSSEC for validation
|
||||
to succeed).
|
||||
|
||||
23 May 2008: Wouter
|
||||
- mingw32 porting.
|
||||
- test for sys/wait.h
|
||||
- WSAEWOULDBLOCK test after nonblocking TCP connect.
|
||||
- write_iov_buffer removed: unused and no struct iov on windows.
|
||||
- signed/unsigned warning fixup mini_event.
|
||||
- use ioctlsocket to set nonblocking I/O if fnctl is unavailable.
|
||||
- skip signals that are not defined
|
||||
- detect pwd.h.
|
||||
- detect getpwnam, getrlimit, setsid, sbrk, chroot.
|
||||
- default config has no chroot if chroot() unavailable.
|
||||
- if no kill() then no pidfile is read or written.
|
||||
- gmtime_r is replaced by nonthreadsafe alternative if unavail.
|
||||
used in rrsig time validation errors.
|
||||
|
||||
22 May 2008: Wouter
|
||||
- contrib unbound.spec from Patrick Vande Walle.
|
||||
- fixup bug#175: call tzset before chroot to have correct timestamps
|
||||
in system log.
|
||||
- do not generate lex input and lex unput functions.
|
||||
- mingw port. replacement functions labelled _unbound.
|
||||
- fix bug 174 - check for tcp_sigpipe that ldns-testns is installed.
|
||||
|
||||
19 May 2008: Wouter
|
||||
- fedora 9, check in6_pktinfo define in configure.
|
||||
- CREDITS fixup of history.
|
||||
- ignore ldns-1.2.2 if installed, use builtin 1.3.0-pre alternative.
|
||||
|
||||
16 May 2008: Wouter
|
||||
- fixup for MacOSX hosts file reading (reported by John Dickinson).
|
||||
- created 1.0.0 svn tag.
|
||||
- trunk version 1.0.1.
|
||||
|
||||
14 May 2008: Wouter
|
||||
- accepted patch from Ondrej Sury for library version libtool option.
|
||||
- configure --disable-rpath fixes up libtool for rpath trouble.
|
||||
Adapted from debian package patch file.
|
||||
|
||||
13 May 2008: Wouter
|
||||
- Added root ipv6 addresses to builtin root hints.
|
||||
- TODO modified for post 1.0 plans.
|
||||
- trunk version set to 1.0.0.
|
||||
- no unnecessary linking with librt (only when libevent/libev used).
|
||||
|
||||
7 May 2008: Wouter
|
||||
- fixup no-ip4 problem with error callback in outside network.
|
||||
|
||||
25 April 2008: Wouter
|
||||
- DESTDIR is honored by the Makefile for rpms.
|
||||
- contrib files unbound.spec and unbound.init, builds working RPM
|
||||
on FC7 Linux, a chrooted caching resolver, and libunbound.
|
||||
- iana ports update.
|
||||
|
||||
24 April 2008: Wouter
|
||||
- chroot checks improved. working directory relative to chroot.
|
||||
checks if config file path is inside chroot. Documentation on it.
|
||||
- nicer example.conf text.
|
||||
- created 0.11 tag.
|
||||
|
||||
23 April 2008: Wouter
|
||||
- parseunbound.pl contrib update from Kai Storbeck for threads.
|
||||
- iana ports update
|
||||
|
||||
22 April 2008: Wouter
|
||||
- ignore SIGPIPE.
|
||||
- unit test for SIGPIPE ignore.
|
||||
|
||||
21 April 2008: Wouter
|
||||
- FEATURES document.
|
||||
- fixup reread of config file if it was given as a full path
|
||||
and chroot was used.
|
||||
|
||||
16 April 2008: Wouter
|
||||
- requirements doc, updated clean query returns.
|
||||
- parseunbound.pl update from Kai Storbeck.
|
||||
- sunos4 porting changes.
|
||||
|
||||
15 April 2008: Wouter
|
||||
- fixup default rc.d pidfile location to /usr/local/etc.
|
||||
- iana ports updated.
|
||||
- copyright updated in ldns-testpkts to keep same as in ldns.
|
||||
- fixup checkconf chroot tests a bit more, chdir must be inside
|
||||
chroot dir.
|
||||
- documented 'gcc: unrecognized -KPIC option' errors on Solaris.
|
||||
- example.conf values changed to /usr/local/etc/unbound
|
||||
- DSA test work.
|
||||
- DSA signatures: unbound is compatible with both encodings found.
|
||||
It will detect and convert when necessary.
|
||||
|
||||
14 April 2008: Wouter
|
||||
- got update for parseunbound.pl statistics script from Kai Storbeck.
|
||||
- tpkg tests for udp wait list.
|
||||
- documented 0x20 status.
|
||||
- fixup chroot and checkconf, it is much smarter now.
|
||||
- fixup DSA EVP signature decoding. Solution that Jelte found copied.
|
||||
- and check first sig byte for the encoding type.
|
||||
|
||||
11 April 2008: Wouter
|
||||
- random port selection out of the configged ports.
|
||||
- fixup threadsafety for libevent-1.4.3+ (event_base_get_method).
|
||||
- removed base_port.
|
||||
- created 256-port ephemeral space for the OS, 59802 available.
|
||||
- fixup consistency of port_if out array during heavy use.
|
||||
|
||||
10 April 2008: Wouter
|
||||
- --with-libevent works with latest libevent 1.4.99-trunk.
|
||||
- added log file statistics perl script to contrib.
|
||||
- automatic iana ports update from makefile. 60058 available.
|
||||
|
||||
9 April 2008: Wouter
|
||||
- configure can detect libev(from its build directory) when passed
|
||||
--with-libevent=/home/wouter/libev-3.2
|
||||
libev-3.2 is a little faster than libevent-1.4.3-stable (about 5%).
|
||||
- unused commpoints not listed in epoll list.
|
||||
- statistics-cumulative option so that the values are not reset.
|
||||
- config creates array of available ports, 61841 available,
|
||||
it excludes <1024 and iana assigned numbers.
|
||||
config statements to modify the available port numbers.
|
||||
|
||||
8 April 2008: Wouter
|
||||
- unbound tries to set the ulimit fds when started as server.
|
||||
if that does not work, it will scale back its requirements.
|
||||
|
||||
27 March 2008: Wouter
|
||||
- documented /dev/random symlink from chrootdir as FAQ entry.
|
||||
|
||||
26 March 2008: Wouter
|
||||
- implemented AD bit signaling. If a query sets AD bit (but not DO)
|
||||
then the AD bit is set in the reply if the answer validated.
|
||||
Without including DNSSEC signatures. Useful if you have a trusted
|
||||
path from the client to the resolver. Follows dnssec-updates draft.
|
||||
|
||||
25 March 2008: Wouter
|
||||
- implemented check that for NXDOMAIN and NOERROR answers a query
|
||||
section must be present in the reply (by the scrubber). And it must
|
||||
be equal to the question sent, at least lowercase folded.
|
||||
Previously this feature happened because the cache code refused
|
||||
to store such messages. However blocking by the scrubber makes
|
||||
sure nothing gets into the RRset cache. Also, this looks like a
|
||||
timeout (instead of an allocation failure) and this retries are
|
||||
done (which is useful in a spoofing situation).
|
||||
- RTT banding. Band size 400 msec, this makes band around zero (fast)
|
||||
include unknown servers. This makes unbound explore unknown servers.
|
||||
|
||||
7 March 2008: Wouter
|
||||
- -C config feature for harvest program.
|
||||
- harvest handles CNAMEs too.
|
||||
|
||||
5 March 2008: Wouter
|
||||
- patch from Hugo Koji Kobayashi for iterator logs spelling.
|
||||
|
||||
4 March 2008: Wouter
|
||||
- From report by Jinmei Tatuya, rfc2181 trust value for remainder
|
||||
of a cname trust chain is lower; not full answer_AA.
|
||||
- test for this fix.
|
||||
- default config file location is /usr/local/etc/unbound.
|
||||
Thus prefix is used to determine the location. This is also the
|
||||
chroot and pidfile default location.
|
||||
|
||||
3 March 2008: Wouter
|
||||
- Create 0.10 svn tag.
|
||||
- 0.11 version in trunk.
|
||||
- indentation nicer.
|
||||
|
||||
29 February 2008: Wouter
|
||||
- documentation update.
|
||||
- fixup port to Solaris of perf test tool.
|
||||
|
||||
@@ -0,0 +1,91 @@
|
||||
Unbound Features
|
||||
|
||||
(C) Copyright 2008, Wouter Wijngaards, NLnet Labs.
|
||||
|
||||
|
||||
This document describes the features and RFCs that unbound
|
||||
adheres to, and which ones are decided to be out of scope.
|
||||
|
||||
|
||||
Big Features
|
||||
------------
|
||||
Recursive service.
|
||||
Caching service.
|
||||
Forwarding and stub zones.
|
||||
No authoritative service.
|
||||
DNSSEC Validation options.
|
||||
EDNS0, NSEC3, Unknown-RR-types.
|
||||
|
||||
|
||||
Details
|
||||
-------
|
||||
Processing support
|
||||
RFC 1034-1035: as a recursive, caching server. Not authoritative.
|
||||
including CNAMEs, referrals, wildcards, classes, ...
|
||||
RFC 4033-4035: as a validating caching server (unbound daemon).
|
||||
as a validating stub (libunbound).
|
||||
RFC 1918.
|
||||
RFC 2181: completely, including the trust model, keeping rrsets together.
|
||||
RFC 2672: DNAME support.
|
||||
RFC 3597: Unknown RR type support.
|
||||
RFC 2671: EDNS0 support, default advertisement 4Kb size.
|
||||
RFC 5155: NSEC3, NSEC3PARAM types
|
||||
AAAA type. and IP6 dual stack support.
|
||||
type ANY queries are supported.
|
||||
RFC 2308: TTL directive, and the rest of the RFC too.
|
||||
RFC 4592: wildcards.
|
||||
|
||||
RFC 1995, 1996, 2136: not authoritative, so no AXFR, IXFR, NOTIFY or
|
||||
dynamic update services are appropriate.
|
||||
|
||||
chroot and drop-root-privileges support, default enabled in config file.
|
||||
|
||||
AD bit in query can be used to request AD bit in response (w/o using DO bit).
|
||||
CD bit in query can be used to request bogus data.
|
||||
UDP and TCP service is provided downstream.
|
||||
UDP and TCP are used to request from upstream servers.
|
||||
Multiple queries can be made over a TCP stream.
|
||||
|
||||
No TSIG support at this time.
|
||||
No SIG0 support at this time.
|
||||
No dTLS support at this time.
|
||||
This is not a DNS statistics package, but some operationally useful
|
||||
values are provided.
|
||||
TXT RRs from the Chaos class (id.server, hostname.bind, ...) supported.
|
||||
|
||||
draft-forgery-resilience: all recommendations followed.
|
||||
draft-0x20: experimental implementation (incomplete).
|
||||
implements bitwise echo of the query to support downstream 0x20.
|
||||
draft-ietf-dnsop-default-local-zones is fully supported (-04).
|
||||
It is possible to block zones or return an address for localhost.
|
||||
This is a very limited authoritative service. Defaults as in draft.
|
||||
draft-ietf-dnsop-resolver-priming(-00): can prime and can fallback to
|
||||
a safety belt list.
|
||||
draft-ietf-dnsop-dnssec-trust-anchor(-01): DS records can be configured
|
||||
as trust anchors. Also DNSKEYs are allowed, by the way.
|
||||
draft-ietf-dnsop-reflectors-are-evil: access control list for recursive
|
||||
service. In fact for all DNS service so cache snooping is halted.
|
||||
|
||||
Record type syntax support, extensive, from lib ldns.
|
||||
For these types only syntax and parsing support is needed.
|
||||
RFC 1034-1035: basic RR types.
|
||||
RFC 1183: RP, AFSDB, X25, ISDN, RT
|
||||
RFC 1706: NSAP
|
||||
RFC 2535: KEY, SIG, NXT: treated as unknown data, syntax is parsed (obsolete).
|
||||
2163: PX
|
||||
AAAA type
|
||||
1876: LOC type
|
||||
2782: SRV type
|
||||
2915: NAPTR type.
|
||||
2230: KX type.
|
||||
2538: CERT type.
|
||||
2672: DNAME type.
|
||||
OPT type
|
||||
3123: APL
|
||||
SSHFP type
|
||||
4025: IPSECKEY
|
||||
4033-4035: DS, RRSIG, NSEC, DNSKEY
|
||||
4701: DHCID
|
||||
5155: NSEC3, NSEC3PARAM
|
||||
4408: SPF
|
||||
|
||||
+17
@@ -43,6 +43,18 @@ This software is under BSD license, see LICENSE for details.
|
||||
The server periodically checks if the amount of memory used fits with
|
||||
the amount of memory it thinks it should be using, and reports
|
||||
memory usage in detail.
|
||||
* --with-conf-file=filename
|
||||
Set default location of config file,
|
||||
the default is /usr/local/etc/unbound/unbound.conf.
|
||||
* --with-pidfile=filename
|
||||
Set default location of pidfile,
|
||||
the default is /usr/local/etc/unbound/unbound.pid.
|
||||
* --with-run-dir=path
|
||||
Set default working directory,
|
||||
the default is /usr/local/etc/unbound.
|
||||
* --with-chroot-dir=path
|
||||
Set default chroot directory,
|
||||
the default is /usr/local/etc/unbound.
|
||||
|
||||
* 'make test' attempts to run a series of tests, depending on the support
|
||||
programs that are installed.
|
||||
@@ -67,6 +79,11 @@ o If you are not receiving the correct source IP address on replies (e.g.
|
||||
source IP address on UDP replies. Listing all IP addresses explicitly in
|
||||
the config file is an alternative. The interface-automatic option uses
|
||||
non portable socket options, Linux and FreeBSD should work fine.
|
||||
o The warning 'openssl has no entropy, seeding with time', with chroot
|
||||
enabled, may be solved with a symbolic link to /dev/random from <chrootdir>.
|
||||
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...].
|
||||
|
||||
Acknowledgements
|
||||
----------------
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
TODO items.
|
||||
TODO items. These are interesting todo items.
|
||||
o understand synthesized DNAMEs, so those TTL=0 packets are cached properly.
|
||||
o NSEC/NSEC3 aggressive negative caching, so that updates to NSEC/NSEC3
|
||||
will result in proper negative responses.
|
||||
@@ -28,14 +28,49 @@ o (option) proactively prime root, stubs and trust anchors, feature.
|
||||
early failure, faster on first query, but more traffic.
|
||||
o On Windows use CryptGenRandom() to get random seed for arc4random.
|
||||
o library add convenience functions for A, AAAA, PTR, getaddrinfo, libresolve.
|
||||
o library add function to get signature data (or whole reply message).
|
||||
o library add function to validate input from app that is signed.
|
||||
o add dynamic-update requests (making a dynupd request) to libunbound api.
|
||||
o in an ipv6 connected only environment unbound cannot use outgoing IP6
|
||||
to send to ip4to6 mapped hosts, need ip4to6map of NS and disable
|
||||
V6ONLY socket option.
|
||||
o support multiple dns messages in a TCP query stream for the unbound server.
|
||||
o SIG(0) and TSIG.
|
||||
o support OPT record placement on recv anywhere in the additional section.
|
||||
o add local-file: config with authority features.
|
||||
o (option) to make local-data answers be secure for libunbound (default=no)
|
||||
o (option) to make chroot: copy all needed files into jail (or make jail)
|
||||
perhaps also print reminder to link /dev/random and sysloghack.
|
||||
o (option) for extended statistics. If enabled (not by default) collect print
|
||||
rcode, uptime, spoofnearmisses, cache size, qtype,
|
||||
bits(RD, CD, DO, EDNS-present, AD)query, (Secure, Bogus)reply.
|
||||
perhaps also see which slow auth servers cause >1sec values.
|
||||
stats-file possible with key: value or key=value lines in it.
|
||||
stats on SIGUSR1. addup stats over threads.
|
||||
o overhaul outside-network servicedquery to merge with udpwait and tcpwait,
|
||||
to make timers in servicedquery independent of udpwait queues.
|
||||
o 0x20 fallback so it can be enabled without trouble.
|
||||
o check into rebinding ports for efficiency, configure time test.
|
||||
o DLV is considered.
|
||||
o EVP hardware crypto support.
|
||||
|
||||
Features soon after 1.0.
|
||||
o EDNS fallback after timeout (firewall drops all edns traffic problem).
|
||||
o IPv6 reverse, IP4 reverse local-data shorthand for PTR records (?).
|
||||
cumbersome to reverse notate by hand for the operator.
|
||||
o zone name appending for local-data. Perhaps read zonefiles. Perhaps it is
|
||||
too much authority feature creep.
|
||||
|
||||
For 1.x; features that have been requested during the beta test.
|
||||
o command channel for couple of tasks. Like rndc.
|
||||
o see delegation; what servers would be used to get data for a name.
|
||||
o force stats display; easier than parsing logfiles.
|
||||
stats display added over threads, displayed in rddtool easy format.
|
||||
o flush names or domains (all under a name) from the cache. Include NSes.
|
||||
And the A, AAAA for its NSes.
|
||||
o add/del static preload data to change the domain redirections.
|
||||
o and maybe also start, stop, reload.
|
||||
|
||||
|
||||
o on windows version, libunbound uses a NamedPipe, examine security status
|
||||
make sure the OS makes it safe like on unix.
|
||||
o on windows version, implement that OS ancillary data capabilities for
|
||||
interface-automatic. IPPKTINFO, IP6PKTINFO for WSARecvMsg, WSASendMsg.
|
||||
|
||||
@@ -18,6 +18,9 @@ server:
|
||||
# print statistics to the log (for every thread) every N seconds.
|
||||
# Set to "" or 0 to disable. Default is disabled.
|
||||
# statistics-interval: 0
|
||||
|
||||
# enable cumulative statistics, without clearing them after printing.
|
||||
# statistics-cumulative: no
|
||||
|
||||
# number of threads to create. 1 disables threading.
|
||||
# num-threads: 1
|
||||
@@ -45,16 +48,20 @@ server:
|
||||
# outgoing-interface: 2001:DB8::5
|
||||
# outgoing-interface: 2001:DB8::6
|
||||
|
||||
# unbound needs to send packets to authoritative nameservers.
|
||||
# it uses a range of ports for that.
|
||||
# the start number of the port range
|
||||
# outgoing-port: 1053
|
||||
# number of ports to allocate per thread, determines the size of the
|
||||
# port range that can be open simultaneously.
|
||||
# outgoing-range: 256
|
||||
|
||||
# permit unbound to use this port number or port range for
|
||||
# making outgoing queries, using an outgoing interface.
|
||||
# outgoing-port-permit: 32768
|
||||
|
||||
# number of port to allocate per thread, determines the size of the
|
||||
# port range. A larger port range gives more resistance to certain
|
||||
# spoof attacks, as it gets harder to guess which port is used.
|
||||
# But also takes more system resources (for open sockets).
|
||||
# outgoing-range: 16
|
||||
# deny unbound the use this of port number or port range for
|
||||
# making outgoing queries, using an outgoing interface.
|
||||
# Use this to make sure unbound does not grab a UDP port that some
|
||||
# other server on this computer needs. The default is to avoid
|
||||
# IANA-assigned port numbers.
|
||||
# outgoing-port-avoid: "3200-3208"
|
||||
|
||||
# number of outgoing simultaneous tcp buffers to hold per thread.
|
||||
# outgoing-num-tcp: 10
|
||||
@@ -137,16 +144,35 @@ server:
|
||||
# if given, a chroot(2) is done to the given directory.
|
||||
# i.e. you can chroot to the working directory, for example,
|
||||
# for extra security, but make sure all files are in that directory.
|
||||
# If you give "" no chroot is performed.
|
||||
# chroot: "/etc/unbound"
|
||||
#
|
||||
# If chroot is enabled, you should pass the configfile (from the
|
||||
# commandline) as a full path from the original root. After the
|
||||
# chroot has been performed the now defunct portion of the config
|
||||
# file path is removed to be able to reread the config after a reload.
|
||||
#
|
||||
# All other file paths (working dir, pidfile, logfile, roothints,
|
||||
# key files) can be specified in several ways:
|
||||
# o as an absolute path relative to the new root.
|
||||
# o as a relative path to the working directory.
|
||||
# o as an absolute path relative to the original root.
|
||||
# In the last case the path is adjusted to remove the unused portion.
|
||||
#
|
||||
# Additionally, unbound may need to access /dev/random (for entropy)
|
||||
# and to /dev/log (if you use syslog) from inside the chroot.
|
||||
# How to do this is specific to your OS.
|
||||
#
|
||||
# If you give "" no chroot is performed. The path must not end in a /.
|
||||
# chroot: "@UNBOUND_CHROOT_DIR@"
|
||||
|
||||
# if given, user privileges are dropped (after binding port),
|
||||
# and the given username is assumed. Default is user "unbound".
|
||||
# If you give "" no privileges are dropped.
|
||||
# username: "unbound"
|
||||
|
||||
# the working directory.
|
||||
# directory: "/etc/unbound"
|
||||
# the working directory. The relative files in this config are
|
||||
# relative to this directory. If you give "" the working directory
|
||||
# is not changed.
|
||||
# directory: "@UNBOUND_RUN_DIR@"
|
||||
|
||||
# the log file, "" means log to stderr.
|
||||
# Use of this option sets use-syslog to "no".
|
||||
@@ -157,7 +183,7 @@ server:
|
||||
# use-syslog: yes
|
||||
|
||||
# the pid file.
|
||||
# pidfile: "/etc/unbound/unbound.pid"
|
||||
# pidfile: "@UNBOUND_PIDFILE@"
|
||||
|
||||
# file to read root hints from.
|
||||
# get one from ftp://FTP.INTERNIC.NET/domain/named.cache
|
||||
@@ -204,6 +230,8 @@ server:
|
||||
# Disabled by default, because some caching forwarders may not
|
||||
# support this (if you have forward-zones). Most authority servers do.
|
||||
# This feature is an experimental implementation of draft dns-0x20.
|
||||
# It is known that some authority servers do not support 0x20, and
|
||||
# resolution will fail for them. A solution is on the TODO list.
|
||||
# use-caps-for-id: no
|
||||
|
||||
# Do not query the following addresses. No DNS queries are sent there.
|
||||
@@ -203,6 +203,6 @@ o If a client makes a query without RD bit, in the case of a returned
|
||||
o Case preservation
|
||||
Unbound preserves the casing received from authority servers as best
|
||||
as possible. It compresses without case, so case can get lost there.
|
||||
The casing from the authority server is used in preference to the casing
|
||||
of the query name. This is different from BIND. RFC4343 allows either
|
||||
The casing from the query name is used in preference to the casing
|
||||
of the authority server. This is the same as BIND. RFC4343 allows either
|
||||
behaviour.
|
||||
|
||||
@@ -36,7 +36,7 @@ The unbound-checkconf program exits with status code 1 on error,
|
||||
0 for a correct config file.
|
||||
.SH "FILES"
|
||||
.TP
|
||||
.I /etc/unbound/unbound.conf
|
||||
.I @ub_conf_file@
|
||||
unbound configuration file.
|
||||
.SH "SEE ALSO"
|
||||
\fIunbound.conf\fR(5),
|
||||
+7
-1
@@ -14,7 +14,7 @@
|
||||
.SH "SYNOPSIS"
|
||||
.LP
|
||||
.B unbound\-host
|
||||
.RB [ \-vdh ]
|
||||
.RB [ \-vdhr ]
|
||||
.RB [ \-c
|
||||
.IR class ]
|
||||
.RB [ \-t
|
||||
@@ -81,6 +81,12 @@ are read.
|
||||
.B \-C \fIconfigfile
|
||||
Uses the specified unbound.conf to prime
|
||||
.IR libunbound (3).
|
||||
.TP
|
||||
.B \-r
|
||||
Read /etc/resolv.conf, and use the forward DNS servers from there (those could
|
||||
have been set by DHCP). More info in
|
||||
.IR resolv.conf (5).
|
||||
Breaks validation if those servers do not support DNSSEC.
|
||||
.SH "EXAMPLES"
|
||||
.LP
|
||||
Some examples of use. The keys shown below are fakes, thus a security failure
|
||||
|
||||
@@ -31,8 +31,8 @@ The available options are:
|
||||
Show the version and commandline option help.
|
||||
.TP
|
||||
.B \-c\fI cfgfile
|
||||
Set the config file with settings for unbound to read instead of the
|
||||
file at default location /etc/unbound/unbound.conf. The syntax is
|
||||
Set the config file with settings for unbound to read instead of reading the
|
||||
file at the default location, @ub_conf_file@. The syntax is
|
||||
described in \fIunbound.conf\fR(5).
|
||||
.TP
|
||||
.B \-d
|
||||
@@ -88,6 +88,10 @@ see
|
||||
The number of seconds between printing statistics to the log for every thread.
|
||||
Disable with value 0 or "". Default is disabled.
|
||||
.TP
|
||||
.B statistics-cumulative: \fI<yes or no>
|
||||
If enabled, statistics are cumulative since starting unbound, without clearing
|
||||
the statistics counters after logging the statistics. Default is no.
|
||||
.TP
|
||||
.B num\-threads: \fI<number>
|
||||
The number of threads to create to serve clients. Use 1 for no threading.
|
||||
.TP
|
||||
@@ -118,15 +122,24 @@ and
|
||||
lines, the interfaces are then used for both purposes. Outgoing queries are
|
||||
sent via a random outgoing interface to counter spoofing.
|
||||
.TP
|
||||
.B outgoing\-port: \fI<port number>
|
||||
The starting port number where the outgoing query port range is allocated.
|
||||
Default is 1053.
|
||||
.TP
|
||||
.B outgoing\-range: \fI<number>
|
||||
Number of ports to open. This number is opened per thread for every outgoing
|
||||
query interface. Must be at least 1. Default is 16.
|
||||
Larger numbers give more protection against spoofing attempts, but need
|
||||
extra resources from the operating system.
|
||||
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.
|
||||
.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.
|
||||
A larger number of permitted outgoing ports increases resilience against
|
||||
spoofing attempts. Make sure these ports are not needed by other daemons.
|
||||
By default only ports above 1024 that have not been assigned by IANA are used.
|
||||
Give a port number or a range of the form "low-high", without spaces.
|
||||
.TP
|
||||
.B outgoing\-port\-avoid: \fI<port number or range>
|
||||
Do not permit unbound to open this port or range of ports for use to send
|
||||
queries. Use this to make sure unbound does not grab a port that another
|
||||
daemon needs. The port is avoided on all outgoing interfaces, both IP4 and IP6.
|
||||
By default only ports above 1024 that have not been assigned by IANA are used.
|
||||
Give a port number or a range of the form "low-high", without spaces.
|
||||
.TP
|
||||
.B outgoing\-num\-tcp: \fI<number>
|
||||
Number of outgoing TCP buffers to allocate per thread. Default is 10. If set
|
||||
@@ -225,8 +238,23 @@ is not designed to handle dropped packets due to policy, and dropping may
|
||||
result in (possibly excessive) retried queries.
|
||||
.TP
|
||||
.B chroot: \fI<directory>
|
||||
If chroot is enabled, you should pass the configfile (from the
|
||||
commandline) as a full path from the original root. After the
|
||||
chroot has been performed the now defunct portion of the config
|
||||
file path is removed to be able to reread the config after a reload.
|
||||
.IP
|
||||
All other file paths (working dir, pidfile, logfile, roothints,
|
||||
key files) can be specified in several ways:
|
||||
as an absolute path relative to the new root,
|
||||
as a relative path to the working directory, or
|
||||
as an absolute path relative to the original root.
|
||||
In the last case the path is adjusted to remove the unused portion.
|
||||
.IP
|
||||
Additionally, unbound may need to access /dev/random (for entropy)
|
||||
and to /dev/log (if you use syslog) from inside the chroot.
|
||||
.IP
|
||||
If given a chroot is done to the given directory. The default is
|
||||
"/etc/unbound". If you give "" no chroot is performed.
|
||||
"@UNBOUND_CHROOT_DIR@". If you give "" no chroot is performed.
|
||||
.TP
|
||||
.B username: \fI<name>
|
||||
If given, after binding the port the user privileges are dropped. Default is
|
||||
@@ -238,7 +266,7 @@ If you change the port number in the config file, and that new port number
|
||||
requires privileges, then a reload will fail; a restart is needed.
|
||||
.TP
|
||||
.B directory: \fI<directory>
|
||||
Sets the working directory for the program.
|
||||
Sets the working directory for the program. Default is "@UNBOUND_RUN_DIR@".
|
||||
.TP
|
||||
.B logfile: \fI<filename>
|
||||
If "" is given, logging goes to stderr, or nowhere once daemonized.
|
||||
@@ -258,14 +286,14 @@ The logfile setting is overridden when use\-syslog is turned on.
|
||||
The default is to log to syslog.
|
||||
.TP
|
||||
.B pidfile: \fI<filename>
|
||||
The process id is written to the file. Default is "/etc/unbound/unbound.pid".
|
||||
The process id is written to the file. Default is "@UNBOUND_PIDFILE@".
|
||||
So,
|
||||
.nf
|
||||
kill \-HUP `cat /etc/unbound/unbound.pid`
|
||||
kill \-HUP `cat @UNBOUND_PIDFILE@`
|
||||
.fi
|
||||
triggers a reload,
|
||||
.nf
|
||||
kill \-QUIT `cat /etc/unbound/unbound.pid`
|
||||
kill \-QUIT `cat @UNBOUND_PIDFILE@`
|
||||
.fi
|
||||
gracefully terminates.
|
||||
.TP
|
||||
@@ -332,10 +360,9 @@ downgrade attack that disables security for a zone. Default is on.
|
||||
Use 0x20-encoded random bits in the query to foil spoof attempts.
|
||||
This perturbs the lowercase and uppercase of query names sent to
|
||||
authority servers and checks if the reply still has the correct casing.
|
||||
Use together with a large outgoing port range to obtain a high spoof resistance.
|
||||
Disabled by default, because some caching forwarders may not
|
||||
support this. If you have no forward\-zones it should be possible to enable
|
||||
this without problem, it works with most authority servers.
|
||||
support this. It is known that some authority servers do not support 0x20,
|
||||
and resolution will fail for them. A solution is on the TODO list.
|
||||
This feature is an experimental implementation of draft dns\-0x20.
|
||||
.TP
|
||||
.B do\-not\-query\-address: \fI<IP address>
|
||||
@@ -536,6 +563,14 @@ Reverse data for zone D.F.ip6.arpa.
|
||||
.TP 10
|
||||
\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 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:
|
||||
.nf
|
||||
local-zone: 8.B.D.0.1.0.0.2.ip6.arpa. nodefault
|
||||
.fi
|
||||
This also works with the other default zones.
|
||||
.\" End of local-zone listing.
|
||||
.TP 5
|
||||
.B local\-data: \fI"<resource record string>"
|
||||
@@ -618,7 +653,7 @@ server:
|
||||
num\-threads: 1
|
||||
outgoing\-num\-tcp: 1 # this limits TCP service, uses less buffers.
|
||||
incoming\-num\-tcp: 1
|
||||
outgoing\-range: 1 # uses less memory, but less port randomness.
|
||||
outgoing\-range: 16 # 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
|
||||
@@ -636,15 +671,18 @@ server:
|
||||
.fi
|
||||
.SH "FILES"
|
||||
.TP
|
||||
.I /etc/unbound
|
||||
default unbound working directory and default
|
||||
.I @UNBOUND_RUN_DIR@
|
||||
default unbound working directory.
|
||||
.TP
|
||||
.I @UNBOUND_CHROOT_DIR@
|
||||
default
|
||||
\fIchroot\fR(2)
|
||||
location.
|
||||
.TP
|
||||
.I unbound.conf
|
||||
.I @ub_conf_file@
|
||||
unbound configuration file.
|
||||
.TP
|
||||
.I unbound.pid
|
||||
.I @UNBOUND_PIDFILE@
|
||||
default unbound pidfile with process ID of the running daemon.
|
||||
.TP
|
||||
.I unbound.log
|
||||
@@ -106,6 +106,8 @@ struct delegpt_addr {
|
||||
socklen_t addrlen;
|
||||
/** number of attempts for this addr */
|
||||
int attempts;
|
||||
/** rtt stored here in the selection algorithm */
|
||||
int sel_rtt;
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -180,8 +180,10 @@ donotq_apply_cfg(struct iter_donotq* dq, struct config_file* cfg)
|
||||
if(cfg->donotquery_localhost) {
|
||||
if(!donotq_str_cfg(dq, "127.0.0.0/8"))
|
||||
return 0;
|
||||
if(!donotq_str_cfg(dq, "::1"))
|
||||
return 0;
|
||||
if(cfg->do_ip6) {
|
||||
if(!donotq_str_cfg(dq, "::1"))
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
donotq_init_parents(dq);
|
||||
return 1;
|
||||
|
||||
+32
-14
@@ -112,7 +112,7 @@ ah(struct delegpt* dp, struct regional* r, const char* sv, const char* ip)
|
||||
|
||||
/** obtain compiletime provided root hints */
|
||||
static struct delegpt*
|
||||
compile_time_root_prime(struct regional* r)
|
||||
compile_time_root_prime(struct regional* r, int do_ip4, int do_ip6)
|
||||
{
|
||||
/* from:
|
||||
; This file is made available by InterNIC
|
||||
@@ -121,14 +121,14 @@ compile_time_root_prime(struct regional* r)
|
||||
; on server FTP.INTERNIC.NET
|
||||
; -OR- RS.INTERNIC.NET
|
||||
;
|
||||
; last update: Jan 29, 2004
|
||||
; related version of root zone: 2004012900
|
||||
; related version of root zone: 2008051300
|
||||
*/
|
||||
struct delegpt* dp = delegpt_create(r);
|
||||
if(!dp)
|
||||
return NULL;
|
||||
if(!delegpt_set_name(dp, r, (uint8_t*)"\000"))
|
||||
return NULL;
|
||||
if(do_ip4) {
|
||||
if(!ah(dp, r, "A.ROOT-SERVERS.NET.", "198.41.0.4")) return 0;
|
||||
if(!ah(dp, r, "B.ROOT-SERVERS.NET.", "192.228.79.201")) return 0;
|
||||
if(!ah(dp, r, "C.ROOT-SERVERS.NET.", "192.33.4.12")) return 0;
|
||||
@@ -142,6 +142,15 @@ compile_time_root_prime(struct regional* r)
|
||||
if(!ah(dp, r, "K.ROOT-SERVERS.NET.", "193.0.14.129")) return 0;
|
||||
if(!ah(dp, r, "L.ROOT-SERVERS.NET.", "199.7.83.42")) return 0;
|
||||
if(!ah(dp, r, "M.ROOT-SERVERS.NET.", "202.12.27.33")) return 0;
|
||||
}
|
||||
if(do_ip6) {
|
||||
if(!ah(dp, r, "A.ROOT-SERVERS.NET.", "2001:503:ba3e::2:30")) 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, "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, "M.ROOT-SERVERS.NET.", "2001:dc3::35")) return 0;
|
||||
}
|
||||
return dp;
|
||||
}
|
||||
|
||||
@@ -325,23 +334,20 @@ read_root_hints(struct iter_hints* hints, char* fname)
|
||||
if(status != LDNS_STATUS_OK) {
|
||||
log_err("reading root hints %s %d: %s", fname,
|
||||
lineno, ldns_get_errorstr_by_id(status));
|
||||
fclose(f);
|
||||
return 0;
|
||||
goto stop_read;
|
||||
}
|
||||
if(ldns_rr_get_type(rr) == LDNS_RR_TYPE_NS) {
|
||||
if(!delegpt_add_ns(dp, hints->region,
|
||||
ldns_rdf_data(ldns_rr_rdf(rr, 0)))) {
|
||||
log_err("out of memory reading root hints");
|
||||
fclose(f);
|
||||
return 0;
|
||||
goto stop_read;
|
||||
}
|
||||
c = ldns_rr_get_class(rr);
|
||||
if(!dp->name) {
|
||||
if(!delegpt_set_name(dp, hints->region,
|
||||
ldns_rdf_data(ldns_rr_owner(rr)))){
|
||||
log_err("out of memory.");
|
||||
fclose(f);
|
||||
return 0;
|
||||
goto stop_read;
|
||||
}
|
||||
}
|
||||
} else if(ldns_rr_get_type(rr) == LDNS_RR_TYPE_A) {
|
||||
@@ -357,8 +363,7 @@ read_root_hints(struct iter_hints* hints, char* fname)
|
||||
ldns_rdf_size(ldns_rr_owner(rr)),
|
||||
(struct sockaddr_storage*)&sa, len)) {
|
||||
log_err("out of memory reading root hints");
|
||||
fclose(f);
|
||||
return 0;
|
||||
goto stop_read;
|
||||
}
|
||||
} else if(ldns_rr_get_type(rr) == LDNS_RR_TYPE_AAAA) {
|
||||
struct sockaddr_in6 sa;
|
||||
@@ -373,8 +378,7 @@ read_root_hints(struct iter_hints* hints, char* fname)
|
||||
ldns_rdf_size(ldns_rr_owner(rr)),
|
||||
(struct sockaddr_storage*)&sa, len)) {
|
||||
log_err("out of memory reading root hints");
|
||||
fclose(f);
|
||||
return 0;
|
||||
goto stop_read;
|
||||
}
|
||||
} else {
|
||||
log_warn("root hints %s:%d skipping type %d",
|
||||
@@ -383,6 +387,11 @@ read_root_hints(struct iter_hints* hints, char* fname)
|
||||
|
||||
ldns_rr_free(rr);
|
||||
}
|
||||
|
||||
if (origin)
|
||||
ldns_rdf_deep_free(origin);
|
||||
if (prev_rr)
|
||||
ldns_rdf_deep_free(prev_rr);
|
||||
fclose(f);
|
||||
if(!dp->name) {
|
||||
log_warn("root hints %s: no NS content", fname);
|
||||
@@ -393,6 +402,14 @@ read_root_hints(struct iter_hints* hints, char* fname)
|
||||
}
|
||||
delegpt_log(VERB_QUERY, dp);
|
||||
return 1;
|
||||
|
||||
stop_read:
|
||||
if (origin)
|
||||
ldns_rdf_deep_free(origin);
|
||||
if (prev_rr)
|
||||
ldns_rdf_deep_free(prev_rr);
|
||||
fclose(f);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** read root hints list */
|
||||
@@ -433,7 +450,8 @@ hints_apply_cfg(struct iter_hints* hints, struct config_file* cfg)
|
||||
|
||||
/* use fallback compiletime root hints */
|
||||
if(!hints_lookup_root(hints, LDNS_RR_CLASS_IN)) {
|
||||
struct delegpt* dp = compile_time_root_prime(hints->region);
|
||||
struct delegpt* dp = compile_time_root_prime(hints->region,
|
||||
cfg->do_ip4, cfg->do_ip6);
|
||||
verbose(VERB_ALGO, "no config, using builtin root hints.");
|
||||
if(!dp)
|
||||
return 0;
|
||||
|
||||
@@ -104,6 +104,7 @@ response_type_from_server(int rdset,
|
||||
struct dns_msg* msg, struct query_info* request, struct delegpt* dp)
|
||||
{
|
||||
uint8_t* origzone = (uint8_t*)"\000"; /* the default */
|
||||
struct ub_packed_rrset_key* s;
|
||||
size_t origzonelen = 1;
|
||||
size_t i;
|
||||
|
||||
@@ -188,12 +189,10 @@ response_type_from_server(int rdset,
|
||||
}
|
||||
|
||||
/* Looking at the authority section, we just look and see if
|
||||
* there is a delegation NS set, turning it into a delegation.
|
||||
* Otherwise, we will have to conclude ANSWER (either it is
|
||||
* NOERROR/NODATA, or an non-authoritative answer). */
|
||||
* there is a SOA record, that means a NOERROR/NODATA */
|
||||
for(i = msg->rep->an_numrrsets; i < (msg->rep->an_numrrsets +
|
||||
msg->rep->ns_numrrsets); i++) {
|
||||
struct ub_packed_rrset_key* s = msg->rep->rrsets[i];
|
||||
s = msg->rep->rrsets[i];
|
||||
|
||||
/* The normal way of detecting NOERROR/NODATA. */
|
||||
if(ntohs(s->rk.type) == LDNS_RR_TYPE_SOA &&
|
||||
@@ -204,19 +203,32 @@ response_type_from_server(int rdset,
|
||||
return RESPONSE_TYPE_LAME;
|
||||
return RESPONSE_TYPE_ANSWER;
|
||||
}
|
||||
}
|
||||
/* Looking at the authority section, we just look and see if
|
||||
* there is a delegation NS set, turning it into a delegation.
|
||||
* Otherwise, we will have to conclude ANSWER (either it is
|
||||
* NOERROR/NODATA, or an non-authoritative answer). */
|
||||
for(i = msg->rep->an_numrrsets; i < (msg->rep->an_numrrsets +
|
||||
msg->rep->ns_numrrsets); i++) {
|
||||
s = msg->rep->rrsets[i];
|
||||
|
||||
/* Detect REFERRAL/LAME/ANSWER based on the relationship
|
||||
* of the NS set to the originating zone name. */
|
||||
if(ntohs(s->rk.type) == LDNS_RR_TYPE_NS) {
|
||||
/* If we are getting an NS set for the zone we
|
||||
* thought we were contacting, then it is an answer.*/
|
||||
/* FIXME: is this correct? */
|
||||
if(query_dname_compare(s->rk.dname, origzone) == 0) {
|
||||
/* see if mistakenly a recursive server was
|
||||
* deployed and is responding nonAA */
|
||||
if( (msg->rep->flags&BIT_RA) &&
|
||||
!(msg->rep->flags&BIT_AA) && !rdset)
|
||||
return RESPONSE_TYPE_LAME;
|
||||
/* Or if a lame server is deployed,
|
||||
* which gives ns==zone delegation from cache
|
||||
* without AA bit as well, with nodata nosoa*/
|
||||
if(msg->rep->an_numrrsets==0 &&
|
||||
!(msg->rep->flags&BIT_AA) && !rdset)
|
||||
return RESPONSE_TYPE_LAME;
|
||||
return RESPONSE_TYPE_ANSWER;
|
||||
}
|
||||
/* If we are getting a referral upwards (or to
|
||||
|
||||
+13
-1
@@ -189,7 +189,11 @@ parse_get_cname_target(struct rrset_parse* rrset, uint8_t** sname,
|
||||
if(rrset->rr_count != 1) {
|
||||
verbose(VERB_ALGO, "Found CNAME rrset with "
|
||||
"size > 1: %u", (unsigned)rrset->rr_count);
|
||||
return 0;
|
||||
/* use the first CNAME! */
|
||||
rrset->rr_count = 1;
|
||||
rrset->size = rrset->rr_first->size;
|
||||
rrset->rr_last = rrset->rr_first;
|
||||
rrset->rr_first->next = NULL;
|
||||
}
|
||||
if(rrset->rr_first->size < sizeof(uint16_t)+1)
|
||||
return 0; /* CNAME rdata too small */
|
||||
@@ -564,6 +568,14 @@ scrub_message(ldns_buffer* pkt, struct msg_parse* msg,
|
||||
if( !(msg->flags&BIT_QR) )
|
||||
return 0;
|
||||
|
||||
/* make sure that a query is echoed back when NOERROR or NXDOMAIN */
|
||||
/* this is not required for basic operation but is a forgery
|
||||
* resistance (security) feature */
|
||||
if((FLAGS_GET_RCODE(msg->flags) == LDNS_RCODE_NOERROR ||
|
||||
FLAGS_GET_RCODE(msg->flags) == LDNS_RCODE_NXDOMAIN) &&
|
||||
msg->qdcount == 0)
|
||||
return 0;
|
||||
|
||||
/* if a query is echoed back, make sure it is correct. Otherwise,
|
||||
* this may be not a reply to our query. */
|
||||
if(msg->qdcount == 1) {
|
||||
|
||||
+44
-20
@@ -130,7 +130,8 @@ iter_apply_cfg(struct iter_env* iter_env, struct config_file* cfg)
|
||||
/** filter out unsuitable targets, return rtt or -1 */
|
||||
static int
|
||||
iter_filter_unsuitable(struct iter_env* iter_env, struct module_env* env,
|
||||
uint8_t* name, size_t namelen, uint32_t now, struct delegpt_addr* a)
|
||||
uint8_t* name, size_t namelen, uint16_t qtype, uint32_t now,
|
||||
struct delegpt_addr* a)
|
||||
{
|
||||
int rtt;
|
||||
int lame;
|
||||
@@ -143,7 +144,7 @@ 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, &lame, &dnsseclame, &rtt, now)) {
|
||||
name, namelen, qtype, &lame, &dnsseclame, &rtt, now)) {
|
||||
if(lame)
|
||||
return -1; /* server is lame */
|
||||
else if(rtt >= USEFUL_SERVER_TOP_TIMEOUT)
|
||||
@@ -156,38 +157,61 @@ iter_filter_unsuitable(struct iter_env* iter_env, struct module_env* env,
|
||||
return UNKNOWN_SERVER_NICENESS;
|
||||
}
|
||||
|
||||
/** lookup RTT information, and also store fastest rtt (if any) */
|
||||
static int
|
||||
iter_fill_rtt(struct iter_env* iter_env, struct module_env* env,
|
||||
uint8_t* name, size_t namelen, uint16_t qtype, uint32_t now,
|
||||
struct delegpt* dp, int* best_rtt)
|
||||
{
|
||||
int got_it = 0;
|
||||
struct delegpt_addr* a;
|
||||
for(a=dp->result_list; a; a = a->next_result) {
|
||||
a->sel_rtt = iter_filter_unsuitable(iter_env, env,
|
||||
name, namelen, qtype, now, a);
|
||||
if(a->sel_rtt != -1) {
|
||||
if(!got_it) {
|
||||
*best_rtt = a->sel_rtt;
|
||||
got_it = 1;
|
||||
} else if(a->sel_rtt < *best_rtt) {
|
||||
*best_rtt = a->sel_rtt;
|
||||
}
|
||||
}
|
||||
}
|
||||
return got_it;
|
||||
}
|
||||
|
||||
/** filter the addres list, putting best targets at front,
|
||||
* returns number of best targets (or 0, no suitable targets) */
|
||||
static int
|
||||
iter_filter_order(struct iter_env* iter_env, struct module_env* env,
|
||||
uint8_t* name, size_t namelen, uint32_t now, struct delegpt* dp,
|
||||
int* best_rtt)
|
||||
uint8_t* name, size_t namelen, uint16_t qtype, uint32_t now,
|
||||
struct delegpt* dp, int* selected_rtt)
|
||||
{
|
||||
int got_num = 0, got_rtt = 0, thisrtt, swap_to_front;
|
||||
int got_num = 0, low_rtt = 0, swap_to_front;
|
||||
struct delegpt_addr* a, *n, *prev=NULL;
|
||||
|
||||
/* fillup sel_rtt and find best rtt in the bunch */
|
||||
got_num = iter_fill_rtt(iter_env, env, name, namelen, qtype, now, dp,
|
||||
&low_rtt);
|
||||
if(got_num == 0)
|
||||
return 0;
|
||||
|
||||
got_num = 0;
|
||||
a = dp->result_list;
|
||||
while(a) {
|
||||
/* filter out unsuitable targets */
|
||||
thisrtt = iter_filter_unsuitable(iter_env, env, name, namelen,
|
||||
now, a);
|
||||
if(thisrtt == -1) {
|
||||
/* skip unsuitable targets */
|
||||
if(a->sel_rtt == -1) {
|
||||
prev = a;
|
||||
a = a->next_result;
|
||||
continue;
|
||||
}
|
||||
/* classify the server address and determine what to do */
|
||||
swap_to_front = 0;
|
||||
if(got_num == 0) {
|
||||
got_rtt = thisrtt;
|
||||
got_num = 1;
|
||||
swap_to_front = 1;
|
||||
} else if(thisrtt == got_rtt) {
|
||||
if(a->sel_rtt >= low_rtt && a->sel_rtt - low_rtt <= RTT_BAND) {
|
||||
got_num++;
|
||||
swap_to_front = 1;
|
||||
} else if(thisrtt < got_rtt) {
|
||||
got_rtt = thisrtt;
|
||||
got_num = 1; /* start back at count of 1 */
|
||||
} else if(a->sel_rtt<low_rtt && low_rtt-a->sel_rtt<=RTT_BAND) {
|
||||
got_num++;
|
||||
swap_to_front = 1;
|
||||
}
|
||||
/* swap to front if necessary, or move to next result */
|
||||
@@ -202,19 +226,19 @@ iter_filter_order(struct iter_env* iter_env, struct module_env* env,
|
||||
a = a->next_result;
|
||||
}
|
||||
}
|
||||
*best_rtt = got_rtt;
|
||||
*selected_rtt = low_rtt;
|
||||
return got_num;
|
||||
}
|
||||
|
||||
struct delegpt_addr*
|
||||
iter_server_selection(struct iter_env* iter_env,
|
||||
struct module_env* env, struct delegpt* dp,
|
||||
uint8_t* name, size_t namelen, int* dnssec_expected)
|
||||
uint8_t* name, size_t namelen, uint16_t qtype, int* dnssec_expected)
|
||||
{
|
||||
int sel;
|
||||
int selrtt;
|
||||
struct delegpt_addr* a, *prev;
|
||||
int num = iter_filter_order(iter_env, env, name, namelen,
|
||||
int num = iter_filter_order(iter_env, env, name, namelen, qtype,
|
||||
*env->now, dp, &selrtt);
|
||||
|
||||
if(num == 0)
|
||||
|
||||
@@ -74,6 +74,7 @@ int iter_apply_cfg(struct iter_env* iter_env, struct config_file* cfg);
|
||||
* @param dp: delegation point with result list.
|
||||
* @param name: zone name (for lameness check).
|
||||
* @param namelen: length of name.
|
||||
* @param qtype: query type that we want to send.
|
||||
* @param dnssec_expected: set to 0, if a known dnssec-lame server is selected
|
||||
* these are not preferred, but are used as a last resort.
|
||||
* @return best target or NULL if no target.
|
||||
@@ -81,7 +82,7 @@ int iter_apply_cfg(struct iter_env* iter_env, struct config_file* cfg);
|
||||
*/
|
||||
struct delegpt_addr* iter_server_selection(struct iter_env* iter_env,
|
||||
struct module_env* env, struct delegpt* dp, uint8_t* name,
|
||||
size_t namelen, int* dnssec_expected);
|
||||
size_t namelen, uint16_t qtype, int* dnssec_expected);
|
||||
|
||||
/**
|
||||
* Allocate dns_msg from parsed msg, in regional.
|
||||
|
||||
+5
-3
@@ -1100,7 +1100,8 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||
|
||||
/* Select the next usable target, filtering out unsuitable targets. */
|
||||
target = iter_server_selection(ie, qstate->env, iq->dp,
|
||||
iq->dp->name, iq->dp->namelen, &iq->dnssec_expected);
|
||||
iq->dp->name, iq->dp->namelen, iq->qchase.qtype,
|
||||
&iq->dnssec_expected);
|
||||
|
||||
/* If no usable target was selected... */
|
||||
if(!target) {
|
||||
@@ -1337,7 +1338,8 @@ processQueryResponse(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||
if(!infra_set_lame(qstate->env->infra_cache,
|
||||
&qstate->reply->addr, qstate->reply->addrlen,
|
||||
iq->dp->name, iq->dp->namelen,
|
||||
*qstate->env->now, dnsseclame))
|
||||
*qstate->env->now, dnsseclame,
|
||||
iq->qchase.qtype))
|
||||
log_err("mark host lame: out of memory");
|
||||
} else log_err("%slame response from cache",
|
||||
dnsseclame?"DNSSEC ":"");
|
||||
@@ -1717,7 +1719,7 @@ process_response(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||
iq->response = dns_alloc_msg(pkt, prs, qstate->region);
|
||||
if(!iq->response)
|
||||
goto handle_it;
|
||||
log_query_info(VERB_DETAIL, "reponse for", &qstate->qinfo);
|
||||
log_query_info(VERB_DETAIL, "response for", &qstate->qinfo);
|
||||
log_name_addr(VERB_DETAIL, "reply from", iq->dp->name,
|
||||
&qstate->reply->addr, qstate->reply->addrlen);
|
||||
if(verbosity >= VERB_ALGO)
|
||||
|
||||
@@ -66,6 +66,10 @@ struct iter_prep_list;
|
||||
#define USEFUL_SERVER_TOP_TIMEOUT 120000
|
||||
/** number of retries on outgoing queries */
|
||||
#define OUTBOUND_MSG_RETRY 4
|
||||
/** RTT band, within this amount from the best, servers are chosen randomly.
|
||||
* 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
|
||||
|
||||
/**
|
||||
* Global state for the iterator.
|
||||
|
||||
Binary file not shown.
+22
-3
@@ -64,8 +64,20 @@ ub_ctx_create()
|
||||
{
|
||||
struct ub_ctx* ctx;
|
||||
unsigned int seed;
|
||||
#ifdef USE_WINSOCK
|
||||
int r;
|
||||
WSADATA wsa_data;
|
||||
#endif
|
||||
|
||||
log_init(NULL, 0, NULL); /* logs to stderr */
|
||||
log_ident_set("libunbound");
|
||||
#ifdef USE_WINSOCK
|
||||
if((r = WSAStartup(MAKEWORD(2,2), &wsa_data)) != 0) {
|
||||
log_err("could not init winsock. WSAStartup: %s",
|
||||
wsa_strerror(r));
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
verbosity = 0; /* errors only */
|
||||
checklock_start();
|
||||
ctx = (struct ub_ctx*)calloc(1, sizeof(*ctx));
|
||||
@@ -97,6 +109,7 @@ ub_ctx_create()
|
||||
errno = e;
|
||||
return NULL;
|
||||
}
|
||||
#ifndef USE_WINSOCK
|
||||
if(!fd_set_nonblock(ctx->rrpipe[0]) ||
|
||||
!fd_set_nonblock(ctx->rrpipe[1]) ||
|
||||
!fd_set_nonblock(ctx->qqpipe[0]) ||
|
||||
@@ -111,6 +124,7 @@ ub_ctx_create()
|
||||
errno = e;
|
||||
return NULL;
|
||||
}
|
||||
#endif /* !USE_WINSOCK - it is a pipe(nonsocket) on windows) */
|
||||
lock_basic_init(&ctx->qqpipe_lock);
|
||||
lock_basic_init(&ctx->rrpipe_lock);
|
||||
lock_basic_init(&ctx->cfglock);
|
||||
@@ -231,6 +245,9 @@ ub_ctx_delete(struct ub_ctx* ctx)
|
||||
alloc_clear(&ctx->superalloc);
|
||||
traverse_postorder(&ctx->queries, delq, NULL);
|
||||
free(ctx);
|
||||
#ifdef USE_WINSOCK
|
||||
WSACleanup();
|
||||
#endif
|
||||
}
|
||||
|
||||
int
|
||||
@@ -345,7 +362,7 @@ int ub_ctx_debugout(struct ub_ctx* ctx, void* out)
|
||||
int
|
||||
ub_ctx_async(struct ub_ctx* ctx, int dothread)
|
||||
{
|
||||
#if !defined(HAVE_PTHREAD) && !defined(HAVE_SOLARIS_THREADS)
|
||||
#ifdef THREADS_DISABLED
|
||||
if(dothread) /* cannot do threading */
|
||||
return UB_NOERROR;
|
||||
#endif
|
||||
@@ -366,7 +383,7 @@ pollit(struct ub_ctx* ctx, struct timeval* t)
|
||||
fd_set r;
|
||||
#ifndef S_SPLINT_S
|
||||
FD_ZERO(&r);
|
||||
FD_SET(ctx->rrpipe[0], &r);
|
||||
FD_SET(FD_SET_T ctx->rrpipe[0], &r);
|
||||
#endif
|
||||
if(select(ctx->rrpipe[0]+1, &r, NULL, NULL, t) == -1) {
|
||||
return 0;
|
||||
@@ -559,6 +576,7 @@ ub_resolve(struct ub_ctx* ctx, char* name, int rrtype,
|
||||
{
|
||||
struct ctx_query* q;
|
||||
int r;
|
||||
*result = NULL;
|
||||
|
||||
lock_basic_lock(&ctx->cfglock);
|
||||
if(!ctx->finalized) {
|
||||
@@ -574,7 +592,6 @@ ub_resolve(struct ub_ctx* ctx, char* name, int rrtype,
|
||||
if(!q)
|
||||
return UB_NOMEM;
|
||||
/* become a resolver thread for a bit */
|
||||
*result = NULL;
|
||||
|
||||
r = libworker_fg(ctx, q);
|
||||
if(r) {
|
||||
@@ -889,6 +906,8 @@ ub_ctx_hosts(struct ub_ctx* ctx, char* fname)
|
||||
parse++;
|
||||
if(*parse == '\n' || *parse == 0)
|
||||
continue;
|
||||
if(*parse == '%')
|
||||
continue; /* ignore macOSX fe80::1%lo0 localhost */
|
||||
if(*parse != ' ' && *parse != '\t') {
|
||||
/* must have whitespace after address */
|
||||
fclose(in);
|
||||
|
||||
+33
-7
@@ -93,6 +93,8 @@ libworker_setup(struct ub_ctx* ctx, int is_bg)
|
||||
unsigned int seed;
|
||||
struct libworker* w = (struct libworker*)calloc(1, sizeof(*w));
|
||||
struct config_file* cfg = ctx->env->cfg;
|
||||
int* ports;
|
||||
int numports;
|
||||
if(!w) return NULL;
|
||||
w->is_bg = is_bg;
|
||||
w->ctx = ctx;
|
||||
@@ -149,14 +151,21 @@ libworker_setup(struct ub_ctx* ctx, int is_bg)
|
||||
if(!w->is_bg || w->is_bg_thread) {
|
||||
lock_basic_lock(&ctx->cfglock);
|
||||
}
|
||||
numports = cfg_condense_ports(cfg, &ports);
|
||||
if(numports == 0) {
|
||||
libworker_delete(w);
|
||||
return NULL;
|
||||
}
|
||||
w->back = outside_network_create(w->base, cfg->msg_buffer_size,
|
||||
(size_t)cfg->outgoing_num_ports, cfg->out_ifs,
|
||||
cfg->num_out_ifs, cfg->do_ip4, cfg->do_ip6, -1,
|
||||
cfg->num_out_ifs, cfg->do_ip4, cfg->do_ip6,
|
||||
cfg->do_tcp?cfg->outgoing_num_tcp:0,
|
||||
w->env->infra_cache, w->env->rnd, cfg->use_caps_bits_for_id);
|
||||
w->env->infra_cache, w->env->rnd, cfg->use_caps_bits_for_id,
|
||||
ports, numports);
|
||||
if(!w->is_bg || w->is_bg_thread) {
|
||||
lock_basic_unlock(&ctx->cfglock);
|
||||
}
|
||||
free(ports);
|
||||
if(!w->back) {
|
||||
libworker_delete(w);
|
||||
return NULL;
|
||||
@@ -357,7 +366,7 @@ libworker_dobg(void* arg)
|
||||
struct libworker* w = (struct libworker*)arg;
|
||||
struct ub_ctx* ctx = w->ctx;
|
||||
log_thread_set(&w->thread_num);
|
||||
#if !defined(HAVE_PTHREAD) && !defined(HAVE_SOLARIS_THREADS)
|
||||
#ifdef THREADS_DISABLED
|
||||
/* we are forked */
|
||||
w->is_bg_thread = 0;
|
||||
/* close non-used parts of the pipes */
|
||||
@@ -416,6 +425,10 @@ int libworker_bg(struct ub_ctx* ctx)
|
||||
ub_thread_create(&ctx->bg_tid, libworker_dobg, w);
|
||||
} else {
|
||||
lock_basic_unlock(&ctx->cfglock);
|
||||
#ifndef HAVE_FORK
|
||||
/* no fork on windows */
|
||||
return UB_FORKFAIL;
|
||||
#else /* HAVE_FORK */
|
||||
switch((ctx->bg_pid=fork())) {
|
||||
case 0:
|
||||
w = libworker_setup(ctx, 1);
|
||||
@@ -433,6 +446,7 @@ int libworker_bg(struct ub_ctx* ctx)
|
||||
default:
|
||||
break;
|
||||
}
|
||||
#endif /* HAVE_FORK */
|
||||
}
|
||||
return UB_NOERROR;
|
||||
}
|
||||
@@ -767,12 +781,10 @@ int libworker_send_packet(ldns_buffer* pkt, struct sockaddr_storage* addr,
|
||||
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,
|
||||
q->env->rnd) != 0;
|
||||
timeout, libworker_handle_reply, q) != 0;
|
||||
}
|
||||
return pending_udp_query(w->back, pkt, addr, addrlen,
|
||||
timeout*1000, libworker_handle_reply, q,
|
||||
q->env->rnd) != 0;
|
||||
timeout*1000, libworker_handle_reply, q) != 0;
|
||||
}
|
||||
|
||||
/** compare outbound entry qstates */
|
||||
@@ -1024,3 +1036,17 @@ void worker_stat_timer_cb(void* ATTR_UNUSED(arg))
|
||||
{
|
||||
log_assert(0);
|
||||
}
|
||||
|
||||
int order_lock_cmp(const void* ATTR_UNUSED(e1), const void* ATTR_UNUSED(e2))
|
||||
{
|
||||
log_assert(0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
codeline_cmp(const void* ATTR_UNUSED(a), const void* ATTR_UNUSED(b))
|
||||
{
|
||||
log_assert(0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
# ltmain.sh - Provide generalized library-building support services.
|
||||
# NOTE: Changing this file will not affect anything until you rerun configure.
|
||||
#
|
||||
# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005
|
||||
# Free Software Foundation, Inc.
|
||||
# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, 2006,
|
||||
# 2007 Free Software Foundation, Inc.
|
||||
# Originally by Gordon Matzigkeit <gord@gnu.ai.mit.edu>, 1996
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
@@ -43,8 +43,8 @@ EXIT_FAILURE=1
|
||||
|
||||
PROGRAM=ltmain.sh
|
||||
PACKAGE=libtool
|
||||
VERSION=1.5.22
|
||||
TIMESTAMP=" (1.1220.2.365 2005/12/18 22:14:06)"
|
||||
VERSION=1.5.24
|
||||
TIMESTAMP=" (1.1220.2.456 2007/06/24 02:25:32)"
|
||||
|
||||
# Be Bourne compatible (taken from Autoconf:_AS_BOURNE_COMPATIBLE).
|
||||
if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
|
||||
@@ -57,6 +57,8 @@ if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
|
||||
else
|
||||
case `(set -o) 2>/dev/null` in *posix*) set -o posix;; esac
|
||||
fi
|
||||
BIN_SH=xpg4; export BIN_SH # for Tru64
|
||||
DUALCASE=1; export DUALCASE # for MKS sh
|
||||
|
||||
# Check that we have a working $echo.
|
||||
if test "X$1" = X--no-reexec; then
|
||||
@@ -114,10 +116,10 @@ esac
|
||||
for lt_var in LANG LC_ALL LC_CTYPE LC_COLLATE LC_MESSAGES
|
||||
do
|
||||
eval "if test \"\${$lt_var+set}\" = set; then
|
||||
save_$lt_var=\$$lt_var
|
||||
$lt_var=C
|
||||
export $lt_var
|
||||
fi"
|
||||
save_$lt_var=\$$lt_var
|
||||
$lt_var=C
|
||||
export $lt_var
|
||||
fi"
|
||||
done
|
||||
|
||||
# Make sure IFS has a sensible default
|
||||
@@ -206,7 +208,13 @@ func_win32_libid ()
|
||||
if eval $OBJDUMP -f $1 | $SED -e '10q' 2>/dev/null | \
|
||||
$EGREP -e 'file format pe-i386(.*architecture: i386)?' >/dev/null ; then
|
||||
win32_nmres=`eval $NM -f posix -A $1 | \
|
||||
$SED -n -e '1,100{/ I /{s,.*,import,;p;q;};}'`
|
||||
$SED -n -e '1,100{
|
||||
/ I /{
|
||||
s,.*,import,
|
||||
p
|
||||
q
|
||||
}
|
||||
}'`
|
||||
case $win32_nmres in
|
||||
import*) win32_libid_type="x86 archive import";;
|
||||
*) win32_libid_type="x86 archive static";;
|
||||
@@ -340,11 +348,11 @@ func_extract_archives ()
|
||||
my_xlib_u=$my_xlib
|
||||
while :; do
|
||||
case " $extracted_archives " in
|
||||
*" $my_xlib_u "*)
|
||||
extracted_serial=`expr $extracted_serial + 1`
|
||||
my_xlib_u=lt$extracted_serial-$my_xlib ;;
|
||||
*) break ;;
|
||||
esac
|
||||
*" $my_xlib_u "*)
|
||||
extracted_serial=`expr $extracted_serial + 1`
|
||||
my_xlib_u=lt$extracted_serial-$my_xlib ;;
|
||||
*) break ;;
|
||||
esac
|
||||
done
|
||||
extracted_archives="$extracted_archives $my_xlib_u"
|
||||
my_xdir="$my_gentop/$my_xlib_u"
|
||||
@@ -474,11 +482,12 @@ do
|
||||
;;
|
||||
|
||||
--version)
|
||||
$echo "$PROGRAM (GNU $PACKAGE) $VERSION$TIMESTAMP"
|
||||
$echo
|
||||
$echo "Copyright (C) 2005 Free Software Foundation, Inc."
|
||||
$echo "This is free software; see the source for copying conditions. There is NO"
|
||||
$echo "warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
|
||||
echo "\
|
||||
$PROGRAM (GNU $PACKAGE) $VERSION$TIMESTAMP
|
||||
|
||||
Copyright (C) 2007 Free Software Foundation, Inc.
|
||||
This is free software; see the source for copying conditions. There is NO
|
||||
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
|
||||
exit $?
|
||||
;;
|
||||
|
||||
@@ -775,7 +784,7 @@ if test -z "$show_help"; then
|
||||
*.class) xform=class ;;
|
||||
*.cpp) xform=cpp ;;
|
||||
*.cxx) xform=cxx ;;
|
||||
*.f90) xform=f90 ;;
|
||||
*.[fF][09]?) xform=[fF][09]. ;;
|
||||
*.for) xform=for ;;
|
||||
*.java) xform=java ;;
|
||||
*.obj) xform=obj ;;
|
||||
@@ -1160,8 +1169,8 @@ EOF
|
||||
do
|
||||
case $arg in
|
||||
-all-static | -static | -static-libtool-libs)
|
||||
case $arg in
|
||||
-all-static)
|
||||
case $arg in
|
||||
-all-static)
|
||||
if test "$build_libtool_libs" = yes && test -z "$link_static_flag"; then
|
||||
$echo "$modename: warning: complete static linking is impossible in this configuration" 1>&2
|
||||
fi
|
||||
@@ -1170,19 +1179,19 @@ EOF
|
||||
fi
|
||||
prefer_static_libs=yes
|
||||
;;
|
||||
-static)
|
||||
-static)
|
||||
if test -z "$pic_flag" && test -n "$link_static_flag"; then
|
||||
dlopen_self=$dlopen_self_static
|
||||
fi
|
||||
prefer_static_libs=built
|
||||
;;
|
||||
-static-libtool-libs)
|
||||
if test -z "$pic_flag" && test -n "$link_static_flag"; then
|
||||
dlopen_self=$dlopen_self_static
|
||||
fi
|
||||
prefer_static_libs=yes
|
||||
;;
|
||||
esac
|
||||
-static-libtool-libs)
|
||||
if test -z "$pic_flag" && test -n "$link_static_flag"; then
|
||||
dlopen_self=$dlopen_self_static
|
||||
fi
|
||||
prefer_static_libs=yes
|
||||
;;
|
||||
esac
|
||||
build_libtool_libs=no
|
||||
build_old_libs=yes
|
||||
break
|
||||
@@ -1630,7 +1639,7 @@ EOF
|
||||
continue
|
||||
;;
|
||||
|
||||
-mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe)
|
||||
-mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe|-threads)
|
||||
compiler_flags="$compiler_flags $arg"
|
||||
compile_command="$compile_command $arg"
|
||||
finalize_command="$finalize_command $arg"
|
||||
@@ -1650,10 +1659,11 @@ EOF
|
||||
# -m* pass through architecture-specific compiler args for GCC
|
||||
# -m*, -t[45]*, -txscale* pass through architecture-specific
|
||||
# compiler args for GCC
|
||||
# -pg pass through profiling flag for GCC
|
||||
# -p, -pg, --coverage, -fprofile-* pass through profiling flag for GCC
|
||||
# -F/path gives path to uninstalled frameworks, gcc on darwin
|
||||
# @file GCC response files
|
||||
-64|-mips[0-9]|-r[0-9][0-9]*|-xarch=*|-xtarget=*|+DA*|+DD*|-q*|-m*|-pg| \
|
||||
-t[45]*|-txscale*|@*)
|
||||
-64|-mips[0-9]|-r[0-9][0-9]*|-xarch=*|-xtarget=*|+DA*|+DD*|-q*|-m*| \
|
||||
-t[45]*|-txscale*|-p|-pg|--coverage|-fprofile-*|-F*|@*)
|
||||
|
||||
# Unknown arguments in both finalize_command and compile_command need
|
||||
# to be aesthetically quoted because they are evaled later.
|
||||
@@ -1681,9 +1691,9 @@ EOF
|
||||
|
||||
-no-install)
|
||||
case $host in
|
||||
*-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2*)
|
||||
*-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-darwin*)
|
||||
# The PATH hackery in wrapper scripts is required on Windows
|
||||
# in order for the loader to find any dlls it needs.
|
||||
# and Darwin in order for the loader to find any dlls it needs.
|
||||
$echo "$modename: warning: \`-no-install' is ignored for $host" 1>&2
|
||||
$echo "$modename: warning: assuming \`-no-fast-install' instead" 1>&2
|
||||
fast_install=no
|
||||
@@ -2124,7 +2134,7 @@ EOF
|
||||
lib=
|
||||
found=no
|
||||
case $deplib in
|
||||
-mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe)
|
||||
-mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe|-threads)
|
||||
if test "$linkmode,$pass" = "prog,link"; then
|
||||
compile_deplibs="$deplib $compile_deplibs"
|
||||
finalize_deplibs="$deplib $finalize_deplibs"
|
||||
@@ -2520,9 +2530,9 @@ EOF
|
||||
|
||||
if test "$linkmode,$pass" = "prog,link"; then
|
||||
if test -n "$library_names" &&
|
||||
{ { test "$prefer_static_libs" = no ||
|
||||
test "$prefer_static_libs,$installed" = "built,yes"; } ||
|
||||
test -z "$old_library"; }; then
|
||||
{ { test "$prefer_static_libs" = no ||
|
||||
test "$prefer_static_libs,$installed" = "built,yes"; } ||
|
||||
test -z "$old_library"; }; then
|
||||
# We need to hardcode the library path
|
||||
if test -n "$shlibpath_var" && test -z "$avoidtemprpath" ; then
|
||||
# Make sure the rpath contains only unique directories.
|
||||
@@ -3229,9 +3239,10 @@ EOF
|
||||
age="0"
|
||||
;;
|
||||
irix|nonstopux)
|
||||
current=`expr $number_major + $number_minor - 1`
|
||||
current=`expr $number_major + $number_minor`
|
||||
age="$number_minor"
|
||||
revision="$number_minor"
|
||||
lt_irix_increment=no
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
@@ -3290,7 +3301,8 @@ EOF
|
||||
versuffix="$major.$age.$revision"
|
||||
# Darwin ld doesn't like 0 for these options...
|
||||
minor_current=`expr $current + 1`
|
||||
verstring="${wl}-compatibility_version ${wl}$minor_current ${wl}-current_version ${wl}$minor_current.$revision"
|
||||
xlcverstring="${wl}-compatibility_version ${wl}$minor_current ${wl}-current_version ${wl}$minor_current.$revision"
|
||||
verstring="-compatibility_version $minor_current -current_version $minor_current.$revision"
|
||||
;;
|
||||
|
||||
freebsd-aout)
|
||||
@@ -3304,8 +3316,11 @@ EOF
|
||||
;;
|
||||
|
||||
irix | nonstopux)
|
||||
major=`expr $current - $age + 1`
|
||||
|
||||
if test "X$lt_irix_increment" = "Xno"; then
|
||||
major=`expr $current - $age`
|
||||
else
|
||||
major=`expr $current - $age + 1`
|
||||
fi
|
||||
case $version_type in
|
||||
nonstopux) verstring_prefix=nonstopux ;;
|
||||
*) verstring_prefix=sgi ;;
|
||||
@@ -3442,11 +3457,11 @@ EOF
|
||||
fi
|
||||
|
||||
# Eliminate all temporary directories.
|
||||
# for path in $notinst_path; do
|
||||
# lib_search_path=`$echo "$lib_search_path " | ${SED} -e "s% $path % %g"`
|
||||
# deplibs=`$echo "$deplibs " | ${SED} -e "s% -L$path % %g"`
|
||||
# dependency_libs=`$echo "$dependency_libs " | ${SED} -e "s% -L$path % %g"`
|
||||
# done
|
||||
#for path in $notinst_path; do
|
||||
# lib_search_path=`$echo "$lib_search_path " | ${SED} -e "s% $path % %g"`
|
||||
# deplibs=`$echo "$deplibs " | ${SED} -e "s% -L$path % %g"`
|
||||
# dependency_libs=`$echo "$dependency_libs " | ${SED} -e "s% -L$path % %g"`
|
||||
#done
|
||||
|
||||
if test -n "$xrpath"; then
|
||||
# If the user specified any rpath flags, then add them.
|
||||
@@ -3547,7 +3562,7 @@ EOF
|
||||
int main() { return 0; }
|
||||
EOF
|
||||
$rm conftest
|
||||
if $LTCC $LTCFLAGS -o conftest conftest.c $deplibs; then
|
||||
if $LTCC $LTCFLAGS -o conftest conftest.c $deplibs; then
|
||||
ldd_output=`ldd conftest`
|
||||
for i in $deplibs; do
|
||||
name=`expr $i : '-l\(.*\)'`
|
||||
@@ -3909,7 +3924,10 @@ EOF
|
||||
test -n "$hardcode_libdirs"; then
|
||||
libdir="$hardcode_libdirs"
|
||||
if test -n "$hardcode_libdir_flag_spec_ld"; then
|
||||
eval dep_rpath=\"$hardcode_libdir_flag_spec_ld\"
|
||||
case $archive_cmds in
|
||||
*\$LD*) eval dep_rpath=\"$hardcode_libdir_flag_spec_ld\" ;;
|
||||
*) eval dep_rpath=\"$hardcode_libdir_flag_spec\" ;;
|
||||
esac
|
||||
else
|
||||
eval dep_rpath=\"$hardcode_libdir_flag_spec\"
|
||||
fi
|
||||
@@ -4275,7 +4293,7 @@ EOF
|
||||
if test -n "$convenience"; then
|
||||
if test -n "$whole_archive_flag_spec"; then
|
||||
eval tmp_whole_archive_flags=\"$whole_archive_flag_spec\"
|
||||
reload_conv_objs=$reload_objs\ `$echo "X$tmp_whole_archive_flags" | $Xsed -e 's|,| |g'`
|
||||
reload_conv_objs=$reload_objs\ `$echo "X$tmp_whole_archive_flags" | $Xsed -e 's|,| |g'`
|
||||
else
|
||||
gentop="$output_objdir/${obj}x"
|
||||
generated="$generated $gentop"
|
||||
@@ -5295,6 +5313,8 @@ if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then
|
||||
else
|
||||
case \`(set -o) 2>/dev/null\` in *posix*) set -o posix;; esac
|
||||
fi
|
||||
BIN_SH=xpg4; export BIN_SH # for Tru64
|
||||
DUALCASE=1; export DUALCASE # for MKS sh
|
||||
|
||||
# The HP-UX ksh and POSIX shell print the target directory to stdout
|
||||
# if CDPATH is set.
|
||||
@@ -6391,8 +6411,10 @@ relink_command=\"$relink_command\""
|
||||
if test -f "$dir/$objdir/$dlname"; then
|
||||
dir="$dir/$objdir"
|
||||
else
|
||||
$echo "$modename: cannot find \`$dlname' in \`$dir' or \`$dir/$objdir'" 1>&2
|
||||
exit $EXIT_FAILURE
|
||||
if test ! -f "$dir/$dlname"; then
|
||||
$echo "$modename: cannot find \`$dlname' in \`$dir' or \`$dir/$objdir'" 1>&2
|
||||
exit $EXIT_FAILURE
|
||||
fi
|
||||
fi
|
||||
;;
|
||||
|
||||
@@ -6458,12 +6480,11 @@ relink_command=\"$relink_command\""
|
||||
# Restore saved environment variables
|
||||
for lt_var in LANG LC_ALL LC_CTYPE LC_COLLATE LC_MESSAGES
|
||||
do
|
||||
eval "if test \"\${save_$lt_var+set}\" = set; then
|
||||
$lt_var=\$save_$lt_var; export $lt_var
|
||||
fi"
|
||||
eval "if test \"\${save_$lt_var+set}\" = set; then
|
||||
$lt_var=\$save_$lt_var; export $lt_var
|
||||
fi"
|
||||
done
|
||||
|
||||
|
||||
# Now prepare to actually exec the command.
|
||||
exec_cmd="\$cmd$args"
|
||||
else
|
||||
|
||||
+4
-4
@@ -212,11 +212,11 @@ if [ "$SNAPSHOT" = "yes" ]; then
|
||||
fi
|
||||
|
||||
replace_all doc/README
|
||||
replace_all doc/unbound.8
|
||||
replace_all doc/unbound.conf.5
|
||||
replace_all doc/unbound-checkconf.8
|
||||
replace_all doc/unbound.8.in
|
||||
replace_all doc/unbound.conf.5.in
|
||||
replace_all doc/unbound-checkconf.8.in
|
||||
replace_all doc/unbound-host.1
|
||||
replace_all doc/libunbound.3
|
||||
replace_all doc/libunbound.3.in
|
||||
|
||||
info "Renaming Unbound directory to unbound-$version."
|
||||
cd ..
|
||||
|
||||
Vendored
+37
-13
@@ -260,12 +260,12 @@ hash_lameness(uint8_t* name, size_t namelen)
|
||||
|
||||
int
|
||||
infra_lookup_lame(struct infra_host_data* host,
|
||||
uint8_t* name, size_t namelen, uint32_t timenow)
|
||||
uint8_t* name, size_t namelen, uint32_t timenow,
|
||||
int* dlame, int* alame, int* olame)
|
||||
{
|
||||
struct lruhash_entry* e;
|
||||
struct infra_lame_key k;
|
||||
struct infra_lame_data *d;
|
||||
int dl;
|
||||
if(!host->lameness)
|
||||
return 0;
|
||||
k.entry.hash = hash_lameness(name, namelen);
|
||||
@@ -281,9 +281,11 @@ infra_lookup_lame(struct infra_host_data* host,
|
||||
lock_rw_unlock(&e->lock);
|
||||
return 0;
|
||||
}
|
||||
dl = d->isdnsseclame;
|
||||
*dlame = d->isdnsseclame;
|
||||
*alame = d->lame_type_A;
|
||||
*olame = d->lame_other;
|
||||
lock_rw_unlock(&e->lock);
|
||||
return dl?2:1;
|
||||
return *dlame || *alame || *olame;
|
||||
}
|
||||
|
||||
size_t
|
||||
@@ -329,7 +331,8 @@ infra_lame_deldatafunc(void* d, void* ATTR_UNUSED(arg))
|
||||
int
|
||||
infra_set_lame(struct infra_cache* infra,
|
||||
struct sockaddr_storage* addr, socklen_t addrlen,
|
||||
uint8_t* name, size_t namelen, uint32_t timenow, int dnsseclame)
|
||||
uint8_t* name, size_t namelen, uint32_t timenow, int dnsseclame,
|
||||
uint16_t qtype)
|
||||
{
|
||||
struct infra_host_data* data;
|
||||
struct lruhash_entry* e;
|
||||
@@ -361,6 +364,8 @@ infra_set_lame(struct infra_cache* infra,
|
||||
k->entry.data = (void*)d;
|
||||
d->ttl = timenow + infra->lame_ttl;
|
||||
d->isdnsseclame = dnsseclame;
|
||||
d->lame_type_A = (!dnsseclame && qtype == LDNS_RR_TYPE_A);
|
||||
d->lame_other = (!dnsseclame && qtype != LDNS_RR_TYPE_A);
|
||||
k->namelen = namelen;
|
||||
e = infra_lookup_host_nottl(infra, addr, addrlen, 1);
|
||||
if(!e) {
|
||||
@@ -392,7 +397,18 @@ infra_set_lame(struct infra_cache* infra,
|
||||
free(d);
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
/* lookup existing lameness entry (if any) and merge data */
|
||||
int dlame, alame, olame;
|
||||
if(infra_lookup_lame(data, name, namelen, timenow,
|
||||
&dlame, &alame, &olame)) {
|
||||
/* merge data into new structure */
|
||||
if(dlame) d->isdnsseclame = 1;
|
||||
if(alame) d->lame_type_A = 1;
|
||||
if(olame) d->lame_other = 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* inserts new entry, or updates TTL of older entry */
|
||||
lruhash_insert(data->lameness, k->entry.hash, &k->entry, d, NULL);
|
||||
|
||||
@@ -477,28 +493,36 @@ infra_edns_update(struct infra_cache* infra,
|
||||
int
|
||||
infra_get_lame_rtt(struct infra_cache* infra,
|
||||
struct sockaddr_storage* addr, socklen_t addrlen,
|
||||
uint8_t* name, size_t namelen, int* lame, int* dnsseclame,
|
||||
int* rtt, uint32_t timenow)
|
||||
uint8_t* name, size_t namelen, uint16_t qtype,
|
||||
int* lame, int* dnsseclame, int* rtt, uint32_t timenow)
|
||||
{
|
||||
struct infra_host_data* host;
|
||||
struct lruhash_entry* e = infra_lookup_host_nottl(infra, addr,
|
||||
addrlen, 0);
|
||||
int lm;
|
||||
int dlm, alm, olm;
|
||||
if(!e)
|
||||
return 0;
|
||||
host = (struct infra_host_data*)e->data;
|
||||
*rtt = rtt_unclamped(&host->rtt);
|
||||
/* check lameness first, if so, ttl on host does not matter anymore */
|
||||
if((lm=infra_lookup_lame(host, name, namelen, timenow))) {
|
||||
lock_rw_unlock(&e->lock);
|
||||
if(lm == 1) {
|
||||
if(infra_lookup_lame(host, name, namelen, timenow, &dlm, &alm, &olm)) {
|
||||
if(alm && qtype == LDNS_RR_TYPE_A) {
|
||||
lock_rw_unlock(&e->lock);
|
||||
*lame = 1;
|
||||
*dnsseclame = 0;
|
||||
} else {
|
||||
return 1;
|
||||
} else if(olm && qtype != LDNS_RR_TYPE_A) {
|
||||
lock_rw_unlock(&e->lock);
|
||||
*lame = 1;
|
||||
*dnsseclame = 0;
|
||||
return 1;
|
||||
} else if(dlm) {
|
||||
lock_rw_unlock(&e->lock);
|
||||
*lame = 0;
|
||||
*dnsseclame = 1;
|
||||
return 1;
|
||||
}
|
||||
return 1;
|
||||
/* no lameness for this type of query */
|
||||
}
|
||||
*lame = 0;
|
||||
*dnsseclame = 0;
|
||||
|
||||
Vendored
+16
-5
@@ -94,6 +94,10 @@ struct infra_lame_data {
|
||||
/** is the host lame (does not serve the zone authoritatively),
|
||||
* or is the host dnssec lame (does not serve DNSSEC data) */
|
||||
int isdnsseclame;
|
||||
/** the host is lame (not authoritative) for A records */
|
||||
int lame_type_A;
|
||||
/** the host is lame (not authoritative) for other query types */
|
||||
int lame_other;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -175,10 +179,14 @@ int infra_host(struct infra_cache* infra, struct sockaddr_storage* addr,
|
||||
* @param name: domain name of zone apex.
|
||||
* @param namelen: length of domain name.
|
||||
* @param timenow: what time it is now.
|
||||
* @return: 0 if not lame or unknown or timed out, 1 if lame, 2 if dnsseclame.
|
||||
* @param dlame: if the function returns true, is set true if dnssec lame.
|
||||
* @param alame: if the function returns true, is set true if qtype A lame.
|
||||
* @param olame: if the function returns true, is set true if qtype other lame.
|
||||
* @return: 0 if not lame or unknown or timed out, 1 if lame
|
||||
*/
|
||||
int infra_lookup_lame(struct infra_host_data* host,
|
||||
uint8_t* name, size_t namelen, uint32_t timenow);
|
||||
uint8_t* name, size_t namelen, uint32_t timenow,
|
||||
int* dlame, int* alame, int* olame);
|
||||
|
||||
/**
|
||||
* Set a host to be lame for the given zone.
|
||||
@@ -190,11 +198,13 @@ int infra_lookup_lame(struct infra_host_data* host,
|
||||
* @param timenow: what time it is now.
|
||||
* @param dnsseclame: if true the host is set dnssec lame.
|
||||
* if false, the host is marked lame (not serving the zone).
|
||||
* @param qtype: the query type for which it is lame.
|
||||
* @return: 0 on error.
|
||||
*/
|
||||
int infra_set_lame(struct infra_cache* infra,
|
||||
struct sockaddr_storage* addr, socklen_t addrlen,
|
||||
uint8_t* name, size_t namelen, uint32_t timenow, int dnsseclame);
|
||||
uint8_t* name, size_t namelen, uint32_t timenow, int dnsseclame,
|
||||
uint16_t qtype);
|
||||
|
||||
/**
|
||||
* Update rtt information for the host.
|
||||
@@ -239,6 +249,7 @@ int infra_edns_update(struct infra_cache* infra,
|
||||
* @param addrlen: length of addr.
|
||||
* @param name: zone name.
|
||||
* @param namelen: zone name length.
|
||||
* @param qtype: the query to be made.
|
||||
* @param lame: if function returns true, this returns lameness of the zone.
|
||||
* @param dnsseclame: if function returns true, this returns if the zone
|
||||
* is dnssec-lame.
|
||||
@@ -249,8 +260,8 @@ int infra_edns_update(struct infra_cache* infra,
|
||||
*/
|
||||
int infra_get_lame_rtt(struct infra_cache* infra,
|
||||
struct sockaddr_storage* addr, socklen_t addrlen,
|
||||
uint8_t* name, size_t namelen, int* lame, int* dnsseclame,
|
||||
int* rtt, uint32_t timenow);
|
||||
uint8_t* name, size_t namelen, uint16_t qtype,
|
||||
int* lame, int* dnsseclame, int* rtt, uint32_t timenow);
|
||||
|
||||
/**
|
||||
* Get memory used by the infra cache.
|
||||
|
||||
+157
-35
@@ -49,7 +49,9 @@
|
||||
#ifdef HAVE_SYS_TYPES_H
|
||||
# include <sys/types.h>
|
||||
#endif
|
||||
#ifdef HAVE_NETDB_H
|
||||
#include <netdb.h>
|
||||
#endif
|
||||
#include <fcntl.h>
|
||||
|
||||
/** number of queued TCP connections for listen() */
|
||||
@@ -86,7 +88,8 @@ verbose_print_addr(struct addrinfo *addr)
|
||||
}
|
||||
|
||||
int
|
||||
create_udp_sock(struct addrinfo *addr, int v6only)
|
||||
create_udp_sock(int family, int socktype, struct sockaddr* addr,
|
||||
socklen_t addrlen, int v6only, int* inuse, int* noproto)
|
||||
{
|
||||
int s;
|
||||
# if defined(IPV6_USE_MIN_MTU)
|
||||
@@ -94,19 +97,43 @@ create_udp_sock(struct addrinfo *addr, int v6only)
|
||||
# else
|
||||
(void)v6only;
|
||||
# endif
|
||||
verbose_print_addr(addr);
|
||||
if((s = socket(addr->ai_family, addr->ai_socktype, 0)) == -1) {
|
||||
if((s = socket(family, socktype, 0)) == -1) {
|
||||
*inuse = 0;
|
||||
#ifndef USE_WINSOCK
|
||||
if(errno == EAFNOSUPPORT || errno == EPROTONOSUPPORT) {
|
||||
*noproto = 1;
|
||||
return -1;
|
||||
}
|
||||
log_err("can't create socket: %s", strerror(errno));
|
||||
#else
|
||||
if(WSAGetLastError() == WSAEAFNOSUPPORT ||
|
||||
WSAGetLastError() == WSAEPROTONOSUPPORT) {
|
||||
*noproto = 1;
|
||||
return -1;
|
||||
}
|
||||
log_err("can't create socket: %s",
|
||||
wsa_strerror(WSAGetLastError()));
|
||||
#endif
|
||||
*noproto = 0;
|
||||
return -1;
|
||||
}
|
||||
if(addr->ai_family == AF_INET6) {
|
||||
if(family == AF_INET6) {
|
||||
# if defined(IPV6_V6ONLY)
|
||||
if(v6only) {
|
||||
int val=(v6only==2)?0:1;
|
||||
if (setsockopt(s, IPPROTO_IPV6, IPV6_V6ONLY,
|
||||
&val, (socklen_t)sizeof(val)) < 0) {
|
||||
(void*)&val, (socklen_t)sizeof(val)) < 0) {
|
||||
#ifndef USE_WINSOCK
|
||||
log_err("setsockopt(..., IPV6_V6ONLY"
|
||||
", ...) failed: %s", strerror(errno));
|
||||
#else
|
||||
log_err("setsockopt(..., IPV6_V6ONLY"
|
||||
", ...) failed: %s",
|
||||
wsa_strerror(WSAGetLastError()));
|
||||
#endif
|
||||
close(s);
|
||||
*noproto = 0;
|
||||
*inuse = 0;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
@@ -121,19 +148,45 @@ create_udp_sock(struct addrinfo *addr, int v6only)
|
||||
* network stack supports IPV6_USE_MIN_MTU.
|
||||
*/
|
||||
if (setsockopt(s, IPPROTO_IPV6, IPV6_USE_MIN_MTU,
|
||||
&on, (socklen_t)sizeof(on)) < 0) {
|
||||
(void*)&on, (socklen_t)sizeof(on)) < 0) {
|
||||
#ifndef USE_WINSOCK
|
||||
log_err("setsockopt(..., IPV6_USE_MIN_MTU, "
|
||||
"...) failed: %s", strerror(errno));
|
||||
#else
|
||||
log_err("setsockopt(..., IPV6_USE_MIN_MTU, "
|
||||
"...) failed: %s",
|
||||
wsa_strerror(WSAGetLastError()));
|
||||
#endif
|
||||
close(s);
|
||||
*noproto = 0;
|
||||
*inuse = 0;
|
||||
return -1;
|
||||
}
|
||||
# endif
|
||||
}
|
||||
if(bind(s, (struct sockaddr*)addr->ai_addr, addr->ai_addrlen) != 0) {
|
||||
log_err("can't bind socket: %s", strerror(errno));
|
||||
if(bind(s, (struct sockaddr*)addr, addrlen) != 0) {
|
||||
*noproto = 0;
|
||||
#ifndef USE_WINSOCK
|
||||
#ifdef EADDRINUSE
|
||||
*inuse = (errno == EADDRINUSE);
|
||||
if(errno != EADDRINUSE)
|
||||
log_err("can't bind socket: %s", strerror(errno));
|
||||
#endif
|
||||
#else /* USE_WINSOCK */
|
||||
if(WSAGetLastError() != WSAEADDRINUSE &&
|
||||
WSAGetLastError() != WSAEADDRNOTAVAIL)
|
||||
log_err("can't bind socket: %s",
|
||||
wsa_strerror(WSAGetLastError()));
|
||||
#endif
|
||||
close(s);
|
||||
return -1;
|
||||
}
|
||||
if(!fd_set_nonblock(s))
|
||||
if(!fd_set_nonblock(s)) {
|
||||
*noproto = 0;
|
||||
*inuse = 0;
|
||||
close(s);
|
||||
return -1;
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
@@ -141,55 +194,84 @@ create_udp_sock(struct addrinfo *addr, int v6only)
|
||||
* Create and bind TCP listening socket
|
||||
* @param addr: address info ready to make socket.
|
||||
* @param v6only: enable ip6 only flag on ip6 sockets.
|
||||
* @param noproto: if error caused by lack of protocol support.
|
||||
* @return: the socket. -1 on error.
|
||||
*/
|
||||
static int
|
||||
create_tcp_accept_sock(struct addrinfo *addr, int v6only)
|
||||
create_tcp_accept_sock(struct addrinfo *addr, int v6only, int* noproto)
|
||||
{
|
||||
int s, flag;
|
||||
int s;
|
||||
#if defined(SO_REUSEADDR) || defined(IPV6_V6ONLY)
|
||||
int on = 1;
|
||||
#endif /* SO_REUSEADDR || IPV6_V6ONLY */
|
||||
verbose_print_addr(addr);
|
||||
*noproto = 0;
|
||||
if((s = socket(addr->ai_family, addr->ai_socktype, 0)) == -1) {
|
||||
#ifndef USE_WINSOCK
|
||||
if(errno == EAFNOSUPPORT || errno == EPROTONOSUPPORT) {
|
||||
*noproto = 1;
|
||||
return -1;
|
||||
}
|
||||
log_err("can't create socket: %s", strerror(errno));
|
||||
#else
|
||||
if(WSAGetLastError() == WSAEAFNOSUPPORT ||
|
||||
WSAGetLastError() == WSAEPROTONOSUPPORT) {
|
||||
*noproto = 1;
|
||||
return -1;
|
||||
}
|
||||
log_err("can't create socket: %s",
|
||||
wsa_strerror(WSAGetLastError()));
|
||||
#endif
|
||||
return -1;
|
||||
}
|
||||
#ifdef SO_REUSEADDR
|
||||
if(setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &on,
|
||||
if(setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (void*)&on,
|
||||
(socklen_t)sizeof(on)) < 0) {
|
||||
#ifndef USE_WINSOCK
|
||||
log_err("setsockopt(.. SO_REUSEADDR ..) failed: %s",
|
||||
strerror(errno));
|
||||
#else
|
||||
log_err("setsockopt(.. SO_REUSEADDR ..) failed: %s",
|
||||
wsa_strerror(WSAGetLastError()));
|
||||
#endif
|
||||
return -1;
|
||||
}
|
||||
#endif /* SO_REUSEADDR */
|
||||
#if defined(IPV6_V6ONLY)
|
||||
if(addr->ai_family == AF_INET6 && v6only) {
|
||||
if(setsockopt(s, IPPROTO_IPV6, IPV6_V6ONLY,
|
||||
&on, (socklen_t)sizeof(on)) < 0) {
|
||||
(void*)&on, (socklen_t)sizeof(on)) < 0) {
|
||||
#ifndef USE_WINSOCK
|
||||
log_err("setsockopt(..., IPV6_V6ONLY, ...) failed: %s",
|
||||
strerror(errno));
|
||||
#else
|
||||
log_err("setsockopt(..., IPV6_V6ONLY, ...) failed: %s",
|
||||
wsa_strerror(WSAGetLastError()));
|
||||
#endif
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
#else
|
||||
(void)v6only;
|
||||
#endif /* IPV6_V6ONLY */
|
||||
if(bind(s, (struct sockaddr*)addr->ai_addr, addr->ai_addrlen) != 0) {
|
||||
if(bind(s, addr->ai_addr, addr->ai_addrlen) != 0) {
|
||||
#ifndef USE_WINSOCK
|
||||
log_err("can't bind socket: %s", strerror(errno));
|
||||
#else
|
||||
log_err("can't bind socket: %s",
|
||||
wsa_strerror(WSAGetLastError()));
|
||||
#endif
|
||||
return -1;
|
||||
}
|
||||
if((flag = fcntl(s, F_GETFL)) == -1) {
|
||||
log_err("can't fcntl F_GETFL: %s", strerror(errno));
|
||||
flag = 0;
|
||||
}
|
||||
flag |= O_NONBLOCK;
|
||||
if(fcntl(s, F_SETFL, flag) == -1) {
|
||||
log_err("can't fcntl F_SETFL: %s", strerror(errno));
|
||||
if(!fd_set_nonblock(s)) {
|
||||
return -1;
|
||||
}
|
||||
if(listen(s, TCP_BACKLOG) == -1) {
|
||||
#ifndef USE_WINSOCK
|
||||
log_err("can't listen: %s", strerror(errno));
|
||||
#else
|
||||
log_err("can't listen: %s", wsa_strerror(WSAGetLastError()));
|
||||
#endif
|
||||
return -1;
|
||||
}
|
||||
return s;
|
||||
@@ -200,20 +282,39 @@ create_tcp_accept_sock(struct addrinfo *addr, int v6only)
|
||||
*/
|
||||
static int
|
||||
make_sock(int stype, const char* ifname, const char* port,
|
||||
struct addrinfo *hints, int v6only)
|
||||
struct addrinfo *hints, int v6only, int* noip6)
|
||||
{
|
||||
struct addrinfo *res = NULL;
|
||||
int r, s;
|
||||
int r, s, inuse, noproto;
|
||||
hints->ai_socktype = stype;
|
||||
*noip6 = 0;
|
||||
if((r=getaddrinfo(ifname, port, hints, &res)) != 0 || !res) {
|
||||
log_err("node %s:%s getaddrinfo: %s %s",
|
||||
ifname?ifname:"default", port, gai_strerror(r),
|
||||
r==EAI_SYSTEM?(char*)strerror(errno):"");
|
||||
#ifdef EAI_SYSTEM
|
||||
r==EAI_SYSTEM?(char*)strerror(errno):""
|
||||
#else
|
||||
""
|
||||
#endif
|
||||
);
|
||||
return -1;
|
||||
}
|
||||
if(stype == SOCK_DGRAM)
|
||||
s = create_udp_sock(res, v6only);
|
||||
else s = create_tcp_accept_sock(res, v6only);
|
||||
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);
|
||||
if(s == -1 && inuse) {
|
||||
log_err("bind: address already in use");
|
||||
} else if(s == -1 && noproto && hints->ai_family == AF_INET6){
|
||||
*noip6 = 1;
|
||||
}
|
||||
} else {
|
||||
s = create_tcp_accept_sock(res, v6only, &noproto);
|
||||
if(s == -1 && noproto && hints->ai_family == AF_INET6){
|
||||
*noip6 = 1;
|
||||
}
|
||||
}
|
||||
freeaddrinfo(res);
|
||||
return s;
|
||||
}
|
||||
@@ -243,18 +344,22 @@ port_insert(struct listen_port** list, int s, enum listen_type ftype)
|
||||
static int
|
||||
set_recvpktinfo(int s, int family)
|
||||
{
|
||||
#if defined(IPV6_RECVPKTINFO) || defined(IPV6_PKTINFO) || defined(IP_RECVDSTADDR) || defined(IP_PKTINFO)
|
||||
int on = 1;
|
||||
#else
|
||||
(void)s;
|
||||
#endif
|
||||
if(family == AF_INET6) {
|
||||
# ifdef IPV6_RECVPKTINFO
|
||||
if(setsockopt(s, IPPROTO_IPV6, IPV6_RECVPKTINFO,
|
||||
&on, (socklen_t)sizeof(on)) < 0) {
|
||||
(void*)&on, (socklen_t)sizeof(on)) < 0) {
|
||||
log_err("setsockopt(..., IPV6_RECVPKTINFO, ...) failed: %s",
|
||||
strerror(errno));
|
||||
return 0;
|
||||
}
|
||||
# elif defined(IPV6_PKTINFO)
|
||||
if(setsockopt(s, IPPROTO_IPV6, IPV6_PKTINFO,
|
||||
&on, (socklen_t)sizeof(on)) < 0) {
|
||||
(void*)&on, (socklen_t)sizeof(on)) < 0) {
|
||||
log_err("setsockopt(..., IPV6_PKTINFO, ...) failed: %s",
|
||||
strerror(errno));
|
||||
return 0;
|
||||
@@ -268,14 +373,14 @@ set_recvpktinfo(int s, int family)
|
||||
} else if(family == AF_INET) {
|
||||
# ifdef IP_RECVDSTADDR
|
||||
if(setsockopt(s, IPPROTO_IP, IP_RECVDSTADDR,
|
||||
&on, (socklen_t)sizeof(on)) < 0) {
|
||||
(void*)&on, (socklen_t)sizeof(on)) < 0) {
|
||||
log_err("setsockopt(..., IP_RECVDSTADDR, ...) failed: %s",
|
||||
strerror(errno));
|
||||
return 0;
|
||||
}
|
||||
# elif defined(IP_PKTINFO)
|
||||
if(setsockopt(s, IPPROTO_IP, IP_PKTINFO,
|
||||
&on, (socklen_t)sizeof(on)) < 0) {
|
||||
(void*)&on, (socklen_t)sizeof(on)) < 0) {
|
||||
log_err("setsockopt(..., IP_PKTINFO, ...) failed: %s",
|
||||
strerror(errno));
|
||||
return 0;
|
||||
@@ -306,12 +411,18 @@ 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)
|
||||
{
|
||||
int s;
|
||||
int s, noip6=0;
|
||||
if(!do_udp && !do_tcp)
|
||||
return 0;
|
||||
if(do_auto) {
|
||||
if((s = make_sock(SOCK_DGRAM, ifname, port, hints, 1)) == -1)
|
||||
if((s = make_sock(SOCK_DGRAM, ifname, port, hints, 1,
|
||||
&noip6)) == -1) {
|
||||
if(noip6) {
|
||||
log_warn("IPv6 protocol not available");
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
/* getting source addr packet info is highly non-portable */
|
||||
if(!set_recvpktinfo(s, hints->ai_family))
|
||||
return 0;
|
||||
@@ -321,15 +432,26 @@ 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(SOCK_DGRAM, ifname, port, hints, 1)) == -1)
|
||||
if((s = make_sock(SOCK_DGRAM, ifname, port, hints, 1,
|
||||
&noip6)) == -1) {
|
||||
if(noip6) {
|
||||
log_warn("IPv6 protocol not available");
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
if(!port_insert(list, s, listen_type_udp)) {
|
||||
close(s);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
if(do_tcp) {
|
||||
if((s = make_sock(SOCK_STREAM, ifname, port, hints, 1)) == -1) {
|
||||
if((s = make_sock(SOCK_STREAM, ifname, port, hints, 1,
|
||||
&noip6)) == -1) {
|
||||
if(noip6) {
|
||||
/*log_warn("IPv6 protocol not available");*/
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
if(!port_insert(list, s, listen_type_tcp)) {
|
||||
|
||||
@@ -45,7 +45,6 @@
|
||||
#include "config.h"
|
||||
#include "util/netevent.h"
|
||||
struct listen_list;
|
||||
struct addrinfo;
|
||||
struct config_file;
|
||||
|
||||
/**
|
||||
@@ -165,11 +164,18 @@ size_t listen_get_mem(struct listen_dnsport* listen);
|
||||
|
||||
/**
|
||||
* Create and bind nonblocking UDP socket
|
||||
* @param addr: address info ready to make socket.
|
||||
* @param family: for socket call.
|
||||
* @param socktype: for socket call.
|
||||
* @param addr: for bind call.
|
||||
* @param addrlen: for bind call.
|
||||
* @param v6only: if enabled, IP6 sockets get IP6ONLY option set.
|
||||
* if enabled with value 2 IP6ONLY option is disabled.
|
||||
* @param inuse: on error, this is set true if the port was in use.
|
||||
* @param noproto: on error, this is set true if cause is that the
|
||||
IPv6 proto (family) is not available.
|
||||
* @return: the socket. -1 on error.
|
||||
*/
|
||||
int create_udp_sock(struct addrinfo* addr, int v6only);
|
||||
int create_udp_sock(int family, int socktype, struct sockaddr* addr,
|
||||
socklen_t addrlen, int v6only, int* inuse, int* noproto);
|
||||
|
||||
#endif /* LISTEN_DNSPORT_H */
|
||||
|
||||
+32
-25
@@ -528,9 +528,15 @@ static int
|
||||
lz_nodefault(struct config_file* cfg, const char* name)
|
||||
{
|
||||
struct config_strlist* p;
|
||||
size_t len = strlen(name);
|
||||
if(len == 0) return 0;
|
||||
if(name[len-1] == '.') len--;
|
||||
|
||||
for(p = cfg->local_zones_nodefault; p; p = p->next) {
|
||||
/* compare zone name, lowercase */
|
||||
if(strcasecmp(p->str, name) == 0)
|
||||
/* compare zone name, lowercase, compare without ending . */
|
||||
if(strncasecmp(p->str, name, len) == 0 &&
|
||||
(strlen(p->str) == len || (strlen(p->str)==len+1 &&
|
||||
p->str[len] == '.')))
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
@@ -614,34 +620,35 @@ lz_enter_defaults(struct local_zones* zones, struct config_file* cfg,
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
if ( !add_as112_default(zones, cfg, buf, "10.in-addr.arpa") ||
|
||||
!add_as112_default(zones, cfg, buf, "16.172.in-addr.arpa") ||
|
||||
!add_as112_default(zones, cfg, buf, "17.172.in-addr.arpa") ||
|
||||
!add_as112_default(zones, cfg, buf, "18.172.in-addr.arpa") ||
|
||||
!add_as112_default(zones, cfg, buf, "19.172.in-addr.arpa") ||
|
||||
!add_as112_default(zones, cfg, buf, "20.172.in-addr.arpa") ||
|
||||
!add_as112_default(zones, cfg, buf, "21.172.in-addr.arpa") ||
|
||||
!add_as112_default(zones, cfg, buf, "22.172.in-addr.arpa") ||
|
||||
!add_as112_default(zones, cfg, buf, "23.172.in-addr.arpa") ||
|
||||
!add_as112_default(zones, cfg, buf, "24.172.in-addr.arpa") ||
|
||||
!add_as112_default(zones, cfg, buf, "25.172.in-addr.arpa") ||
|
||||
!add_as112_default(zones, cfg, buf, "26.172.in-addr.arpa") ||
|
||||
!add_as112_default(zones, cfg, buf, "27.172.in-addr.arpa") ||
|
||||
!add_as112_default(zones, cfg, buf, "28.172.in-addr.arpa") ||
|
||||
!add_as112_default(zones, cfg, buf, "29.172.in-addr.arpa") ||
|
||||
!add_as112_default(zones, cfg, buf, "30.172.in-addr.arpa") ||
|
||||
!add_as112_default(zones, cfg, buf, "31.172.in-addr.arpa") ||
|
||||
!add_as112_default(zones, cfg, buf, "168.192.in-addr.arpa") ||
|
||||
!add_as112_default(zones, cfg, buf, "0.in-addr.arpa") ||
|
||||
!add_as112_default(zones, cfg, buf, "254.169.in-addr.arpa") ||
|
||||
!add_as112_default(zones, cfg, buf, "2.0.192.in-addr.arpa") ||
|
||||
!add_as112_default(zones, cfg, buf, "255.255.255.255.in-addr.arpa") ||
|
||||
if ( !add_as112_default(zones, cfg, buf, "10.in-addr.arpa.") ||
|
||||
!add_as112_default(zones, cfg, buf, "16.172.in-addr.arpa.") ||
|
||||
!add_as112_default(zones, cfg, buf, "17.172.in-addr.arpa.") ||
|
||||
!add_as112_default(zones, cfg, buf, "18.172.in-addr.arpa.") ||
|
||||
!add_as112_default(zones, cfg, buf, "19.172.in-addr.arpa.") ||
|
||||
!add_as112_default(zones, cfg, buf, "20.172.in-addr.arpa.") ||
|
||||
!add_as112_default(zones, cfg, buf, "21.172.in-addr.arpa.") ||
|
||||
!add_as112_default(zones, cfg, buf, "22.172.in-addr.arpa.") ||
|
||||
!add_as112_default(zones, cfg, buf, "23.172.in-addr.arpa.") ||
|
||||
!add_as112_default(zones, cfg, buf, "24.172.in-addr.arpa.") ||
|
||||
!add_as112_default(zones, cfg, buf, "25.172.in-addr.arpa.") ||
|
||||
!add_as112_default(zones, cfg, buf, "26.172.in-addr.arpa.") ||
|
||||
!add_as112_default(zones, cfg, buf, "27.172.in-addr.arpa.") ||
|
||||
!add_as112_default(zones, cfg, buf, "28.172.in-addr.arpa.") ||
|
||||
!add_as112_default(zones, cfg, buf, "29.172.in-addr.arpa.") ||
|
||||
!add_as112_default(zones, cfg, buf, "30.172.in-addr.arpa.") ||
|
||||
!add_as112_default(zones, cfg, buf, "31.172.in-addr.arpa.") ||
|
||||
!add_as112_default(zones, cfg, buf, "168.192.in-addr.arpa.") ||
|
||||
!add_as112_default(zones, cfg, buf, "0.in-addr.arpa.") ||
|
||||
!add_as112_default(zones, cfg, buf, "254.169.in-addr.arpa.") ||
|
||||
!add_as112_default(zones, cfg, buf, "2.0.192.in-addr.arpa.") ||
|
||||
!add_as112_default(zones, cfg, buf, "255.255.255.255.in-addr.arpa.") ||
|
||||
!add_as112_default(zones, cfg, buf, "0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.ip6.arpa.") ||
|
||||
!add_as112_default(zones, cfg, buf, "d.f.ip6.arpa.") ||
|
||||
!add_as112_default(zones, cfg, buf, "8.e.f.ip6.arpa.") ||
|
||||
!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, "b.e.f.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;
|
||||
}
|
||||
|
||||
+439
-242
@@ -56,17 +56,24 @@
|
||||
#ifdef HAVE_SYS_TYPES_H
|
||||
# include <sys/types.h>
|
||||
#endif
|
||||
#ifdef HAVE_NETDB_H
|
||||
#include <netdb.h>
|
||||
#endif
|
||||
#include <fcntl.h>
|
||||
|
||||
/** number of times to retry making a random ID that is unique. */
|
||||
#define MAX_ID_RETRY 1000
|
||||
/** number of times to retry finding interface, port that can be opened. */
|
||||
#define MAX_PORT_RETRY 10000
|
||||
/** number of retries on outgoing UDP queries */
|
||||
#define OUTBOUND_UDP_RETRY 1
|
||||
|
||||
/** initiate TCP transaction for serviced query */
|
||||
static void serviced_tcp_initiate(struct outside_network* outnet,
|
||||
struct serviced_query* sq, ldns_buffer* buff);
|
||||
/** with a fd available, randomize and send UDP */
|
||||
static int randomize_and_send_udp(struct outside_network* outnet,
|
||||
struct pending* pend, ldns_buffer* packet, int timeout);
|
||||
|
||||
int
|
||||
pending_cmp(const void* key1, const void* key2)
|
||||
@@ -137,14 +144,28 @@ outnet_tcp_take_into_use(struct waiting_tcp* w, uint8_t* pkt, size_t pkt_len)
|
||||
#endif
|
||||
s = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
|
||||
if(s == -1) {
|
||||
#ifndef USE_WINSOCK
|
||||
log_err("outgoing tcp: socket: %s", strerror(errno));
|
||||
#else
|
||||
log_err("outgoing tcp: socket: %s",
|
||||
wsa_strerror(WSAGetLastError()));
|
||||
#endif
|
||||
log_addr(0, "failed address", &w->addr, w->addrlen);
|
||||
return 0;
|
||||
}
|
||||
fd_set_nonblock(s);
|
||||
if(connect(s, (struct sockaddr*)&w->addr, w->addrlen) == -1) {
|
||||
#ifndef USE_WINSOCK
|
||||
#ifdef EINPROGRESS
|
||||
if(errno != EINPROGRESS) {
|
||||
#else
|
||||
if(1) {
|
||||
#endif
|
||||
log_err("outgoing tcp: connect: %s", strerror(errno));
|
||||
#else /* USE_WINSOCK */
|
||||
if(WSAGetLastError() != WSAEINPROGRESS &&
|
||||
WSAGetLastError() != WSAEWOULDBLOCK) {
|
||||
#endif
|
||||
log_addr(0, "failed address", &w->addr, w->addrlen);
|
||||
close(s);
|
||||
return 0;
|
||||
@@ -226,6 +247,55 @@ outnet_tcp_cb(struct comm_point* c, void* arg, int error,
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** lower use count on pc, see if it can be closed */
|
||||
static void
|
||||
portcomm_loweruse(struct outside_network* outnet, struct port_comm* pc)
|
||||
{
|
||||
struct port_if* pif;
|
||||
pc->num_outstanding--;
|
||||
if(pc->num_outstanding > 0) {
|
||||
return;
|
||||
}
|
||||
/* close it and replace in unused list */
|
||||
verbose(VERB_ALGO, "close of port %d", pc->number);
|
||||
comm_point_close(pc->cp);
|
||||
pif = pc->pif;
|
||||
log_assert(pif->inuse > 0);
|
||||
pif->avail_ports[pif->avail_total - pif->inuse] = pc->number;
|
||||
pif->inuse--;
|
||||
pif->out[pc->index] = pif->out[pif->inuse];
|
||||
pif->out[pc->index]->index = pc->index;
|
||||
pc->next = outnet->unused_fds;
|
||||
outnet->unused_fds = pc;
|
||||
}
|
||||
|
||||
/** try to send waiting UDP queries */
|
||||
static void
|
||||
outnet_send_wait_udp(struct outside_network* outnet)
|
||||
{
|
||||
struct pending* pend;
|
||||
/* process waiting queries */
|
||||
while(outnet->udp_wait_first && outnet->unused_fds) {
|
||||
pend = outnet->udp_wait_first;
|
||||
outnet->udp_wait_first = pend->next_waiting;
|
||||
if(!pend->next_waiting) outnet->udp_wait_last = NULL;
|
||||
ldns_buffer_clear(outnet->udp_buff);
|
||||
ldns_buffer_write(outnet->udp_buff, pend->pkt, pend->pkt_len);
|
||||
ldns_buffer_flip(outnet->udp_buff);
|
||||
free(pend->pkt); /* freeing now makes get_mem correct */
|
||||
pend->pkt = NULL;
|
||||
pend->pkt_len = 0;
|
||||
if(!randomize_and_send_udp(outnet, pend, outnet->udp_buff,
|
||||
pend->timeout)) {
|
||||
/* callback error on pending */
|
||||
fptr_ok(fptr_whitelist_pending_udp(pend->cb));
|
||||
(void)(*pend->cb)(outnet->unused_fds->cp, pend->cb_arg,
|
||||
NETEVENT_CLOSED, NULL);
|
||||
pending_delete(outnet, pend);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
outnet_udp_cb(struct comm_point* c, void* arg, int error,
|
||||
struct comm_reply *reply_info)
|
||||
@@ -246,7 +316,7 @@ outnet_udp_cb(struct comm_point* c, void* arg, int error,
|
||||
log_assert(reply_info);
|
||||
|
||||
/* setup lookup key */
|
||||
key.id = LDNS_ID_WIRE(ldns_buffer_begin(c->buffer));
|
||||
key.id = (unsigned)LDNS_ID_WIRE(ldns_buffer_begin(c->buffer));
|
||||
memcpy(&key.addr, &reply_info->addr, reply_info->addrlen);
|
||||
key.addrlen = reply_info->addrlen;
|
||||
verbose(VERB_ALGO, "Incoming reply id = %4.4x", key.id);
|
||||
@@ -264,7 +334,7 @@ outnet_udp_cb(struct comm_point* c, void* arg, int error,
|
||||
|
||||
verbose(VERB_ALGO, "received udp reply.");
|
||||
log_buf(VERB_ALGO, "udp message", c->buffer);
|
||||
if(p->c != c) {
|
||||
if(p->pc->cp != c) {
|
||||
verbose(VERB_QUERY, "received reply id,addr on wrong port. "
|
||||
"dropped.");
|
||||
return 0;
|
||||
@@ -274,114 +344,36 @@ outnet_udp_cb(struct comm_point* c, void* arg, int error,
|
||||
/* delete from tree first in case callback creates a retry */
|
||||
(void)rbtree_delete(outnet->pending, p->node.key);
|
||||
fptr_ok(fptr_whitelist_pending_udp(p->cb));
|
||||
(void)(*p->cb)(p->c, p->cb_arg, NETEVENT_NOERROR, reply_info);
|
||||
(void)(*p->cb)(p->pc->cp, p->cb_arg, NETEVENT_NOERROR, reply_info);
|
||||
portcomm_loweruse(outnet, p->pc);
|
||||
pending_delete(NULL, p);
|
||||
outnet_send_wait_udp(outnet);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** open another udp port to listen to, every thread has its own range
|
||||
* of open ports.
|
||||
* @param ifname: on which interface to open the port.
|
||||
* @param hints: hints on family and passiveness preset.
|
||||
* @param porthint: if not -1, it gives the port to base range on.
|
||||
* @return: file descriptor
|
||||
*/
|
||||
static int
|
||||
open_udp_port_range(const char* ifname, struct addrinfo* hints, int porthint)
|
||||
{
|
||||
struct addrinfo *res = NULL;
|
||||
int r, s;
|
||||
char portstr[32];
|
||||
if(porthint != -1)
|
||||
snprintf(portstr, sizeof(portstr), "%d", porthint);
|
||||
else if(!ifname) {
|
||||
if(hints->ai_family == AF_INET)
|
||||
ifname = "0.0.0.0";
|
||||
else ifname="::";
|
||||
}
|
||||
|
||||
if((r=getaddrinfo(ifname, ((porthint==-1)?NULL:portstr), hints,
|
||||
&res)) != 0 || !res) {
|
||||
log_err("node %s %s getaddrinfo: %s %s",
|
||||
ifname?ifname:"default", (porthint!=-1)?portstr:"eph",
|
||||
gai_strerror(r),
|
||||
r==EAI_SYSTEM?(char*)strerror(errno):"");
|
||||
return -1;
|
||||
}
|
||||
s = create_udp_sock(res, 1);
|
||||
freeaddrinfo(res);
|
||||
return s;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create range of UDP ports on the given interface.
|
||||
* Returns number of ports bound.
|
||||
* @param coms: communication point array start position. Filled with entries.
|
||||
* @param ifname: name of interface to make port on.
|
||||
* @param num_ports: number of ports opened.
|
||||
* @param do_ip4: if true make ip4 ports.
|
||||
* @param do_ip6: if true make ip6 ports.
|
||||
* @param porthint: -1 for system chosen port, or a base of port range.
|
||||
* @param outnet: network structure with comm base, shared udp buffer.
|
||||
* @return: the number of ports successfully opened, entries filled in coms.
|
||||
*/
|
||||
static size_t
|
||||
make_udp_range(struct comm_point** coms, const char* ifname,
|
||||
size_t num_ports, int do_ip4, int do_ip6, int porthint,
|
||||
struct outside_network* outnet)
|
||||
{
|
||||
size_t i;
|
||||
size_t done = 0;
|
||||
struct addrinfo hints;
|
||||
memset(&hints, 0, sizeof(hints));
|
||||
hints.ai_flags = AI_PASSIVE;
|
||||
if(ifname)
|
||||
hints.ai_flags |= AI_NUMERICHOST;
|
||||
hints.ai_family = AF_UNSPEC;
|
||||
if(do_ip4 && do_ip6)
|
||||
hints.ai_family = AF_UNSPEC;
|
||||
else if(do_ip4)
|
||||
hints.ai_family = AF_INET;
|
||||
else if(do_ip6)
|
||||
hints.ai_family = AF_INET6;
|
||||
hints.ai_socktype = SOCK_DGRAM;
|
||||
for(i=0; i<num_ports; i++) {
|
||||
int fd = open_udp_port_range(ifname, &hints, porthint);
|
||||
if(porthint != -1)
|
||||
porthint++;
|
||||
if(fd == -1)
|
||||
continue;
|
||||
coms[done] = comm_point_create_udp(outnet->base, fd,
|
||||
outnet->udp_buff, outnet_udp_cb, outnet);
|
||||
if(coms[done])
|
||||
done++;
|
||||
}
|
||||
return done;
|
||||
}
|
||||
|
||||
/** calculate number of ip4 and ip6 interfaces, times multiplier */
|
||||
/** calculate number of ip4 and ip6 interfaces*/
|
||||
static void
|
||||
calc_num46(char** ifs, int num_ifs, int do_ip4, int do_ip6,
|
||||
size_t multiplier, size_t* num_ip4, size_t* num_ip6)
|
||||
int* num_ip4, int* num_ip6)
|
||||
{
|
||||
int i;
|
||||
*num_ip4 = 0;
|
||||
*num_ip6 = 0;
|
||||
if(num_ifs <= 0) {
|
||||
if(do_ip4)
|
||||
*num_ip4 = multiplier;
|
||||
*num_ip4 = 1;
|
||||
if(do_ip6)
|
||||
*num_ip6 = multiplier;
|
||||
*num_ip6 = 1;
|
||||
return;
|
||||
}
|
||||
for(i=0; i<num_ifs; i++)
|
||||
{
|
||||
if(str_is_ip6(ifs[i])) {
|
||||
if(do_ip6)
|
||||
*num_ip6 += multiplier;
|
||||
(*num_ip6)++;
|
||||
} else {
|
||||
if(do_ip4)
|
||||
*num_ip4 += multiplier;
|
||||
(*num_ip4)++;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -391,11 +383,14 @@ void
|
||||
pending_udp_timer_cb(void *arg)
|
||||
{
|
||||
struct pending* p = (struct pending*)arg;
|
||||
struct outside_network* outnet = p->outnet;
|
||||
/* it timed out */
|
||||
verbose(VERB_ALGO, "timeout udp");
|
||||
fptr_ok(fptr_whitelist_pending_udp(p->cb));
|
||||
(void)(*p->cb)(p->c, p->cb_arg, NETEVENT_TIMEOUT, NULL);
|
||||
pending_delete(p->outnet, p);
|
||||
(void)(*p->cb)(p->pc->cp, p->cb_arg, NETEVENT_TIMEOUT, NULL);
|
||||
portcomm_loweruse(outnet, p->pc);
|
||||
pending_delete(outnet, p);
|
||||
outnet_send_wait_udp(outnet);
|
||||
}
|
||||
|
||||
/** create pending_tcp buffers */
|
||||
@@ -423,15 +418,35 @@ create_pending_tcp(struct outside_network* outnet, size_t bufsize)
|
||||
return 1;
|
||||
}
|
||||
|
||||
/** setup an outgoing interface, ready address */
|
||||
static int setup_if(struct port_if* pif, const char* addrstr,
|
||||
int* avail, int numavail, size_t numfd)
|
||||
{
|
||||
pif->avail_total = numavail;
|
||||
pif->avail_ports = (int*)memdup(avail, (size_t)numavail*sizeof(int));
|
||||
if(!pif->avail_ports)
|
||||
return 0;
|
||||
if(!ipstrtoaddr(addrstr, UNBOUND_DNS_PORT, &pif->addr, &pif->addrlen))
|
||||
return 0;
|
||||
pif->maxout = (int)numfd;
|
||||
pif->inuse = 0;
|
||||
pif->out = (struct port_comm**)calloc(numfd,
|
||||
sizeof(struct port_comm*));
|
||||
if(!pif->out)
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
struct outside_network*
|
||||
outside_network_create(struct comm_base *base, size_t bufsize,
|
||||
size_t num_ports, char** ifs, int num_ifs, int do_ip4,
|
||||
int do_ip6, int port_base, size_t num_tcp, struct infra_cache* infra,
|
||||
struct ub_randstate* rnd, int use_caps_for_id)
|
||||
int do_ip6, size_t num_tcp, struct infra_cache* infra,
|
||||
struct ub_randstate* rnd, int use_caps_for_id, int* availports,
|
||||
int numavailports)
|
||||
{
|
||||
struct outside_network* outnet = (struct outside_network*)
|
||||
calloc(1, sizeof(struct outside_network));
|
||||
int k;
|
||||
size_t k;
|
||||
if(!outnet) {
|
||||
log_err("malloc failed");
|
||||
return NULL;
|
||||
@@ -443,17 +458,33 @@ outside_network_create(struct comm_base *base, size_t bufsize,
|
||||
outnet->rnd = rnd;
|
||||
outnet->svcd_overhead = 0;
|
||||
outnet->use_caps_for_id = use_caps_for_id;
|
||||
if(numavailports == 0) {
|
||||
log_err("no outgoing ports available");
|
||||
outside_network_delete(outnet);
|
||||
return NULL;
|
||||
}
|
||||
#ifndef INET6
|
||||
do_ip6 = 0;
|
||||
#endif
|
||||
calc_num46(ifs, num_ifs, do_ip4, do_ip6, num_ports,
|
||||
&outnet->num_udp4, &outnet->num_udp6);
|
||||
/* adds +1 to portnums so we do not allocate zero bytes. */
|
||||
calc_num46(ifs, num_ifs, do_ip4, do_ip6,
|
||||
&outnet->num_ip4, &outnet->num_ip6);
|
||||
if(outnet->num_ip4 != 0) {
|
||||
if(!(outnet->ip4_ifs = (struct port_if*)calloc(
|
||||
(size_t)outnet->num_ip4, sizeof(struct port_if)))) {
|
||||
log_err("malloc failed");
|
||||
outside_network_delete(outnet);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
if(outnet->num_ip6 != 0) {
|
||||
if(!(outnet->ip6_ifs = (struct port_if*)calloc(
|
||||
(size_t)outnet->num_ip6, sizeof(struct port_if)))) {
|
||||
log_err("malloc failed");
|
||||
outside_network_delete(outnet);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
if( !(outnet->udp_buff = ldns_buffer_new(bufsize)) ||
|
||||
!(outnet->udp4_ports = (struct comm_point **)calloc(
|
||||
outnet->num_udp4+1, sizeof(struct comm_point*))) ||
|
||||
!(outnet->udp6_ports = (struct comm_point **)calloc(
|
||||
outnet->num_udp6+1, sizeof(struct comm_point*))) ||
|
||||
!(outnet->pending = rbtree_create(pending_cmp)) ||
|
||||
!(outnet->serviced = rbtree_create(serviced_cmp)) ||
|
||||
!create_pending_tcp(outnet, bufsize)) {
|
||||
@@ -461,49 +492,65 @@ outside_network_create(struct comm_base *base, size_t bufsize,
|
||||
outside_network_delete(outnet);
|
||||
return NULL;
|
||||
}
|
||||
/* Try to get ip6 and ip4 ports. Ip6 first, in case second fails. */
|
||||
|
||||
/* allocate commpoints */
|
||||
for(k=0; k<num_ports; k++) {
|
||||
struct port_comm* pc;
|
||||
pc = (struct port_comm*)calloc(1, sizeof(*pc));
|
||||
if(!pc) {
|
||||
log_err("malloc failed");
|
||||
outside_network_delete(outnet);
|
||||
return NULL;
|
||||
}
|
||||
pc->cp = comm_point_create_udp(outnet->base, -1,
|
||||
outnet->udp_buff, outnet_udp_cb, outnet);
|
||||
if(!pc->cp) {
|
||||
log_err("malloc failed");
|
||||
free(pc);
|
||||
outside_network_delete(outnet);
|
||||
return NULL;
|
||||
}
|
||||
pc->next = outnet->unused_fds;
|
||||
outnet->unused_fds = pc;
|
||||
}
|
||||
|
||||
/* allocate interfaces */
|
||||
if(num_ifs == 0) {
|
||||
if(do_ip6) {
|
||||
outnet->num_udp6 = make_udp_range(outnet->udp6_ports,
|
||||
NULL, num_ports, 0, 1, port_base, outnet);
|
||||
}
|
||||
if(do_ip4) {
|
||||
outnet->num_udp4 = make_udp_range(outnet->udp4_ports,
|
||||
NULL, num_ports, 1, 0, port_base, outnet);
|
||||
}
|
||||
if( (do_ip4 && outnet->num_udp4 != num_ports) ||
|
||||
(do_ip6 && outnet->num_udp6 != num_ports)) {
|
||||
log_err("Could not open all networkside ports");
|
||||
if(do_ip4 && !setup_if(&outnet->ip4_ifs[0], "0.0.0.0",
|
||||
availports, numavailports, num_ports)) {
|
||||
log_err("malloc failed");
|
||||
outside_network_delete(outnet);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if(do_ip6 && !setup_if(&outnet->ip6_ifs[0], "::",
|
||||
availports, numavailports, num_ports)) {
|
||||
log_err("malloc failed");
|
||||
outside_network_delete(outnet);
|
||||
return NULL;
|
||||
}
|
||||
} else {
|
||||
size_t done_4 = 0, done_6 = 0;
|
||||
for(k=0; k<num_ifs; k++) {
|
||||
if(str_is_ip6(ifs[k]) && do_ip6) {
|
||||
done_6 += make_udp_range(
|
||||
outnet->udp6_ports+done_6, ifs[k],
|
||||
num_ports, 0, 1, port_base, outnet);
|
||||
int i;
|
||||
for(i=0; i<num_ifs; i++) {
|
||||
if(str_is_ip6(ifs[i]) && do_ip6) {
|
||||
if(!setup_if(&outnet->ip6_ifs[done_6], ifs[i],
|
||||
availports, numavailports, num_ports)){
|
||||
log_err("malloc failed");
|
||||
outside_network_delete(outnet);
|
||||
return NULL;
|
||||
}
|
||||
done_6++;
|
||||
}
|
||||
if(!str_is_ip6(ifs[k]) && do_ip4) {
|
||||
done_4 += make_udp_range(
|
||||
outnet->udp4_ports+done_4, ifs[k],
|
||||
num_ports, 1, 0, port_base, outnet);
|
||||
if(!str_is_ip6(ifs[i]) && do_ip4) {
|
||||
if(!setup_if(&outnet->ip4_ifs[done_4], ifs[i],
|
||||
availports, numavailports, num_ports)){
|
||||
log_err("malloc failed");
|
||||
outside_network_delete(outnet);
|
||||
return NULL;
|
||||
}
|
||||
done_4++;
|
||||
}
|
||||
}
|
||||
if(done_6 != outnet->num_udp6 || done_4 != outnet->num_udp4) {
|
||||
log_err("Could not open all ports on all interfaces");
|
||||
outside_network_delete(outnet);
|
||||
return NULL;
|
||||
}
|
||||
outnet->num_udp6 = done_6;
|
||||
outnet->num_udp4 = done_4;
|
||||
}
|
||||
if(outnet->num_udp4 + outnet->num_udp6 == 0) {
|
||||
log_err("Could not open any ports on outgoing interfaces");
|
||||
outside_network_delete(outnet);
|
||||
return NULL;
|
||||
}
|
||||
return outnet;
|
||||
}
|
||||
@@ -549,17 +596,43 @@ outside_network_delete(struct outside_network* outnet)
|
||||
}
|
||||
if(outnet->udp_buff)
|
||||
ldns_buffer_free(outnet->udp_buff);
|
||||
if(outnet->udp4_ports) {
|
||||
size_t i;
|
||||
for(i=0; i<outnet->num_udp4; i++)
|
||||
comm_point_delete(outnet->udp4_ports[i]);
|
||||
free(outnet->udp4_ports);
|
||||
if(outnet->unused_fds) {
|
||||
struct port_comm* p = outnet->unused_fds, *np;
|
||||
while(p) {
|
||||
np = p->next;
|
||||
comm_point_delete(p->cp);
|
||||
free(p);
|
||||
p = np;
|
||||
}
|
||||
outnet->unused_fds = NULL;
|
||||
}
|
||||
if(outnet->udp6_ports) {
|
||||
size_t i;
|
||||
for(i=0; i<outnet->num_udp6; i++)
|
||||
comm_point_delete(outnet->udp6_ports[i]);
|
||||
free(outnet->udp6_ports);
|
||||
if(outnet->ip4_ifs) {
|
||||
int i, k;
|
||||
for(i=0; i<outnet->num_ip4; i++) {
|
||||
for(k=0; k<outnet->ip4_ifs[i].inuse; k++) {
|
||||
struct port_comm* pc = outnet->ip4_ifs[i].
|
||||
out[k];
|
||||
comm_point_delete(pc->cp);
|
||||
free(pc);
|
||||
}
|
||||
free(outnet->ip4_ifs[i].avail_ports);
|
||||
free(outnet->ip4_ifs[i].out);
|
||||
}
|
||||
free(outnet->ip4_ifs);
|
||||
}
|
||||
if(outnet->ip6_ifs) {
|
||||
int i, k;
|
||||
for(i=0; i<outnet->num_ip6; i++) {
|
||||
for(k=0; k<outnet->ip6_ifs[i].inuse; k++) {
|
||||
struct port_comm* pc = outnet->ip6_ifs[i].
|
||||
out[k];
|
||||
comm_point_delete(pc->cp);
|
||||
free(pc);
|
||||
}
|
||||
free(outnet->ip6_ifs[i].avail_ports);
|
||||
free(outnet->ip6_ifs[i].out);
|
||||
}
|
||||
free(outnet->ip6_ifs);
|
||||
}
|
||||
if(outnet->tcp_conns) {
|
||||
size_t i;
|
||||
@@ -579,7 +652,14 @@ outside_network_delete(struct outside_network* outnet)
|
||||
p = np;
|
||||
}
|
||||
}
|
||||
|
||||
if(outnet->udp_wait_first) {
|
||||
struct pending* p = outnet->udp_wait_first, *np;
|
||||
while(p) {
|
||||
np = p->next_waiting;
|
||||
pending_delete(NULL, p);
|
||||
p = np;
|
||||
}
|
||||
}
|
||||
free(outnet);
|
||||
}
|
||||
|
||||
@@ -593,123 +673,162 @@ pending_delete(struct outside_network* outnet, struct pending* p)
|
||||
}
|
||||
if(p->timer)
|
||||
comm_timer_delete(p->timer);
|
||||
free(p->pkt);
|
||||
free(p);
|
||||
}
|
||||
|
||||
/** create a new pending item with given characteristics, false on failure */
|
||||
static struct pending*
|
||||
new_pending(struct outside_network* outnet, ldns_buffer* packet,
|
||||
struct sockaddr_storage* addr, socklen_t addrlen,
|
||||
comm_point_callback_t* callback, void* callback_arg,
|
||||
struct ub_randstate* rnd)
|
||||
/**
|
||||
* Try to open a UDP socket for outgoing communication.
|
||||
* Sets sockets options as needed.
|
||||
* @param addr: socket address.
|
||||
* @param addrlen: length of address.
|
||||
* @param port: port override for addr.
|
||||
* @param inuse: if -1 is returned, this bool means the port was in use.
|
||||
* @return fd or -1
|
||||
*/
|
||||
static int
|
||||
udp_sockport(struct sockaddr_storage* addr, socklen_t addrlen, int port,
|
||||
int* inuse)
|
||||
{
|
||||
int fd, noproto;
|
||||
if(addr_is_ip6(addr, addrlen)) {
|
||||
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);
|
||||
} 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);
|
||||
}
|
||||
return fd;
|
||||
}
|
||||
|
||||
/** Select random ID */
|
||||
static int
|
||||
select_id(struct outside_network* outnet, struct pending* pend,
|
||||
ldns_buffer* packet)
|
||||
{
|
||||
/* alloc */
|
||||
int id_tries = 0;
|
||||
struct pending* pend = (struct pending*)calloc(1,
|
||||
sizeof(struct pending));
|
||||
if(!pend) {
|
||||
log_err("malloc failure");
|
||||
return NULL;
|
||||
}
|
||||
pend->timer = comm_timer_create(outnet->base, pending_udp_timer_cb,
|
||||
pend);
|
||||
if(!pend->timer) {
|
||||
free(pend);
|
||||
return NULL;
|
||||
}
|
||||
/* set */
|
||||
pend->id = ((unsigned)ub_random(rnd)>>8) & 0xffff;
|
||||
pend->id = ((unsigned)ub_random(outnet->rnd)>>8) & 0xffff;
|
||||
LDNS_ID_SET(ldns_buffer_begin(packet), pend->id);
|
||||
memcpy(&pend->addr, addr, addrlen);
|
||||
pend->addrlen = addrlen;
|
||||
pend->cb = callback;
|
||||
pend->cb_arg = callback_arg;
|
||||
pend->outnet = outnet;
|
||||
|
||||
/* insert in tree */
|
||||
pend->node.key = pend;
|
||||
while(!rbtree_insert(outnet->pending, &pend->node)) {
|
||||
/* change ID to avoid collision */
|
||||
pend->id = ((unsigned)ub_random(rnd)>>8) & 0xffff;
|
||||
pend->id = ((unsigned)ub_random(outnet->rnd)>>8) & 0xffff;
|
||||
LDNS_ID_SET(ldns_buffer_begin(packet), pend->id);
|
||||
id_tries++;
|
||||
if(id_tries == MAX_ID_RETRY) {
|
||||
pend->id=99999; /* non existant ID */
|
||||
log_err("failed to generate unique ID, drop msg");
|
||||
pending_delete(NULL, pend);
|
||||
return NULL;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
verbose(VERB_ALGO, "inserted new pending reply id=%4.4x", pend->id);
|
||||
return pend;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Select outgoing comm point for a query. Fills in c.
|
||||
* @param outnet: network structure that has arrays of ports to choose from.
|
||||
* @param pend: the message to send. c is filled in, randomly chosen.
|
||||
* @param rnd: random state for generating ID and port.
|
||||
*/
|
||||
static void
|
||||
select_port(struct outside_network* outnet, struct pending* pend,
|
||||
struct ub_randstate* rnd)
|
||||
/** Select random interface and port */
|
||||
static int
|
||||
select_ifport(struct outside_network* outnet, struct pending* pend,
|
||||
int num_if, struct port_if* ifs)
|
||||
{
|
||||
double precho;
|
||||
int chosen, nummax;
|
||||
|
||||
log_assert(outnet && pend);
|
||||
/* first select ip4 or ip6. */
|
||||
if(addr_is_ip6(&pend->addr, pend->addrlen))
|
||||
nummax = (int)outnet->num_udp6;
|
||||
else nummax = (int)outnet->num_udp4;
|
||||
|
||||
if(nummax == 0) {
|
||||
/* could try ip4to6 mapping if no ip4 ports available */
|
||||
log_err("Need to send query but have no ports of that family");
|
||||
return;
|
||||
int my_if, my_port, fd, portno, inuse, tries=0;
|
||||
struct port_if* pif;
|
||||
/* randomly select interface and port */
|
||||
if(num_if == 0) {
|
||||
verbose(VERB_QUERY, "Need to send query but have no "
|
||||
"outgoing interfaces of that family");
|
||||
return 0;
|
||||
}
|
||||
log_assert(outnet->unused_fds);
|
||||
tries = 0;
|
||||
while(1) {
|
||||
my_if = ub_random(outnet->rnd) % num_if;
|
||||
pif = &ifs[my_if];
|
||||
my_port = ub_random(outnet->rnd) % pif->avail_total;
|
||||
if(my_port < pif->inuse) {
|
||||
/* port already open */
|
||||
pend->pc = pif->out[my_port];
|
||||
verbose(VERB_ALGO, "using UDP if=%d port=%d",
|
||||
my_if, pend->pc->number);
|
||||
break;
|
||||
}
|
||||
/* try to open new port, if fails, loop to try again */
|
||||
log_assert(pif->inuse < pif->maxout);
|
||||
portno = pif->avail_ports[my_port - pif->inuse];
|
||||
fd = udp_sockport(&pif->addr, pif->addrlen, portno, &inuse);
|
||||
if(fd == -1 && !inuse) {
|
||||
/* nonrecoverable error making socket */
|
||||
return 0;
|
||||
}
|
||||
if(fd != -1) {
|
||||
verbose(VERB_ALGO, "opened UDP if=%d port=%d",
|
||||
my_if, portno);
|
||||
/* grab fd */
|
||||
pend->pc = outnet->unused_fds;
|
||||
outnet->unused_fds = pend->pc->next;
|
||||
|
||||
/* choose a random outgoing port and interface */
|
||||
precho = (double)ub_random(rnd) * (double)nummax /
|
||||
((double)RAND_MAX + 1.0);
|
||||
chosen = (int)precho;
|
||||
/* setup portcomm */
|
||||
pend->pc->next = NULL;
|
||||
pend->pc->number = portno;
|
||||
pend->pc->pif = pif;
|
||||
pend->pc->index = pif->inuse;
|
||||
pend->pc->num_outstanding = 0;
|
||||
comm_point_start_listening(pend->pc->cp, fd, -1);
|
||||
|
||||
/* don't trust in perfect double rounding */
|
||||
if(chosen < 0) chosen = 0;
|
||||
if(chosen >= nummax) chosen = nummax-1;
|
||||
/* grab port in interface */
|
||||
pif->out[pif->inuse] = pend->pc;
|
||||
pif->avail_ports[my_port - pif->inuse] =
|
||||
pif->avail_ports[pif->avail_total-pif->inuse-1];
|
||||
pif->inuse++;
|
||||
break;
|
||||
}
|
||||
/* failed, already in use */
|
||||
verbose(VERB_QUERY, "port %d in use, trying another", portno);
|
||||
tries++;
|
||||
if(tries == MAX_PORT_RETRY) {
|
||||
log_err("failed to find an open port, drop msg");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
log_assert(pend->pc);
|
||||
pend->pc->num_outstanding++;
|
||||
|
||||
if(addr_is_ip6(&pend->addr, pend->addrlen))
|
||||
pend->c = outnet->udp6_ports[chosen];
|
||||
else pend->c = outnet->udp4_ports[chosen];
|
||||
log_assert(pend->c);
|
||||
|
||||
verbose(VERB_ALGO, "query %x outbound on port %d of %d", pend->id, chosen, nummax);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
struct pending*
|
||||
pending_udp_query(struct outside_network* outnet, ldns_buffer* packet,
|
||||
struct sockaddr_storage* addr, socklen_t addrlen, int timeout,
|
||||
comm_point_callback_t* cb, void* cb_arg, struct ub_randstate* rnd)
|
||||
static int
|
||||
randomize_and_send_udp(struct outside_network* outnet, struct pending* pend,
|
||||
ldns_buffer* packet, int timeout)
|
||||
{
|
||||
struct pending* pend;
|
||||
struct timeval tv;
|
||||
|
||||
/* create pending struct and change ID to be unique */
|
||||
if(!(pend=new_pending(outnet, packet, addr, addrlen, cb, cb_arg,
|
||||
rnd))) {
|
||||
return NULL;
|
||||
}
|
||||
select_port(outnet, pend, rnd);
|
||||
if(!pend->c) {
|
||||
pending_delete(outnet, pend);
|
||||
return NULL;
|
||||
/* select id */
|
||||
if(!select_id(outnet, pend, packet)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* select src_if, port */
|
||||
if(addr_is_ip6(&pend->addr, pend->addrlen)) {
|
||||
if(!select_ifport(outnet, pend,
|
||||
outnet->num_ip6, outnet->ip6_ifs))
|
||||
return 0;
|
||||
} else {
|
||||
if(!select_ifport(outnet, pend,
|
||||
outnet->num_ip4, outnet->ip4_ifs))
|
||||
return 0;
|
||||
}
|
||||
log_assert(pend->pc && pend->pc->cp);
|
||||
|
||||
/* send it over the commlink */
|
||||
if(!comm_point_send_udp_msg(pend->c, packet, (struct sockaddr*)addr,
|
||||
addrlen)) {
|
||||
pending_delete(outnet, pend);
|
||||
return NULL;
|
||||
if(!comm_point_send_udp_msg(pend->pc->cp, packet,
|
||||
(struct sockaddr*)&pend->addr, pend->addrlen)) {
|
||||
portcomm_loweruse(outnet, pend->pc);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* system calls to set timeout after sending UDP to make roundtrip
|
||||
@@ -717,6 +836,53 @@ pending_udp_query(struct outside_network* outnet, ldns_buffer* packet,
|
||||
tv.tv_sec = timeout/1000;
|
||||
tv.tv_usec = (timeout%1000)*1000;
|
||||
comm_timer_set(pend->timer, &tv);
|
||||
return 1;
|
||||
}
|
||||
|
||||
struct pending*
|
||||
pending_udp_query(struct outside_network* outnet, ldns_buffer* packet,
|
||||
struct sockaddr_storage* addr, socklen_t addrlen, int timeout,
|
||||
comm_point_callback_t* cb, void* cb_arg)
|
||||
{
|
||||
struct pending* pend = (struct pending*)calloc(1, sizeof(*pend));
|
||||
if(!pend) return NULL;
|
||||
pend->outnet = outnet;
|
||||
pend->addrlen = addrlen;
|
||||
memmove(&pend->addr, addr, addrlen);
|
||||
pend->cb = cb;
|
||||
pend->cb_arg = cb_arg;
|
||||
pend->node.key = pend;
|
||||
pend->timer = comm_timer_create(outnet->base, pending_udp_timer_cb,
|
||||
pend);
|
||||
if(!pend->timer) {
|
||||
free(pend);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if(outnet->unused_fds == NULL) {
|
||||
/* no unused fd, cannot create a new port (randomly) */
|
||||
verbose(VERB_ALGO, "no fds available, udp query waiting");
|
||||
pend->timeout = timeout;
|
||||
pend->pkt_len = ldns_buffer_limit(packet);
|
||||
pend->pkt = (uint8_t*)memdup(ldns_buffer_begin(packet),
|
||||
pend->pkt_len);
|
||||
if(!pend->pkt) {
|
||||
comm_timer_delete(pend->timer);
|
||||
free(pend);
|
||||
return NULL;
|
||||
}
|
||||
/* put at end of waiting list */
|
||||
if(outnet->udp_wait_last)
|
||||
outnet->udp_wait_last->next_waiting = pend;
|
||||
else
|
||||
outnet->udp_wait_first = pend;
|
||||
outnet->udp_wait_last = pend;
|
||||
return pend;
|
||||
}
|
||||
if(!randomize_and_send_udp(outnet, pend, packet, timeout)) {
|
||||
pending_delete(outnet, pend);
|
||||
return NULL;
|
||||
}
|
||||
return pend;
|
||||
}
|
||||
|
||||
@@ -759,8 +925,7 @@ outnet_tcptimer(void* arg)
|
||||
struct waiting_tcp*
|
||||
pending_tcp_query(struct outside_network* outnet, ldns_buffer* packet,
|
||||
struct sockaddr_storage* addr, socklen_t addrlen, int timeout,
|
||||
comm_point_callback_t* callback, void* callback_arg,
|
||||
struct ub_randstate* rnd)
|
||||
comm_point_callback_t* callback, void* callback_arg)
|
||||
{
|
||||
struct pending_tcp* pend = outnet->tcp_free;
|
||||
struct waiting_tcp* w;
|
||||
@@ -778,7 +943,7 @@ pending_tcp_query(struct outside_network* outnet, ldns_buffer* packet,
|
||||
}
|
||||
w->pkt = NULL;
|
||||
w->pkt_len = 0;
|
||||
id = ((unsigned)ub_random(rnd)>>8) & 0xffff;
|
||||
id = ((unsigned)ub_random(outnet->rnd)>>8) & 0xffff;
|
||||
LDNS_ID_SET(ldns_buffer_begin(packet), id);
|
||||
memcpy(&w->addr, addr, addrlen);
|
||||
w->addrlen = addrlen;
|
||||
@@ -902,7 +1067,9 @@ serviced_delete(struct serviced_query* sq)
|
||||
if(sq->status == serviced_query_UDP_EDNS ||
|
||||
sq->status == serviced_query_UDP) {
|
||||
struct pending* p = (struct pending*)sq->pending;
|
||||
portcomm_loweruse(sq->outnet, p->pc);
|
||||
pending_delete(sq->outnet, p);
|
||||
outnet_send_wait_udp(sq->outnet);
|
||||
} else {
|
||||
struct waiting_tcp* p = (struct waiting_tcp*)
|
||||
sq->pending;
|
||||
@@ -1011,7 +1178,7 @@ serviced_udp_send(struct serviced_query* sq, ldns_buffer* buff)
|
||||
sq->last_sent_time = *sq->outnet->now_tv;
|
||||
verbose(VERB_ALGO, "serviced query UDP timeout=%d msec", rtt);
|
||||
sq->pending = pending_udp_query(sq->outnet, buff, &sq->addr,
|
||||
sq->addrlen, rtt, serviced_udp_callback, sq, sq->outnet->rnd);
|
||||
sq->addrlen, rtt, serviced_udp_callback, sq);
|
||||
if(!sq->pending)
|
||||
return 0;
|
||||
return 1;
|
||||
@@ -1184,7 +1351,7 @@ serviced_tcp_initiate(struct outside_network* outnet,
|
||||
serviced_encode(sq, buff, sq->status == serviced_query_TCP_EDNS);
|
||||
sq->pending = pending_tcp_query(outnet, buff, &sq->addr,
|
||||
sq->addrlen, TCP_AUTH_QUERY_TIMEOUT, serviced_tcp_callback,
|
||||
sq, outnet->rnd);
|
||||
sq);
|
||||
if(!sq->pending) {
|
||||
/* delete from tree so that a retry by above layer does not
|
||||
* clash with this entry */
|
||||
@@ -1367,22 +1534,52 @@ waiting_tcp_get_mem(struct waiting_tcp* w)
|
||||
return s;
|
||||
}
|
||||
|
||||
/** get memory used by port if */
|
||||
static size_t
|
||||
if_get_mem(struct port_if* pif)
|
||||
{
|
||||
size_t s;
|
||||
int i;
|
||||
s = sizeof(*pif) + sizeof(int)*pif->avail_total +
|
||||
sizeof(struct port_comm*)*pif->maxout;
|
||||
for(i=0; i<pif->inuse; i++)
|
||||
s += sizeof(*pif->out[i]) +
|
||||
comm_point_get_mem(pif->out[i]->cp);
|
||||
return s;
|
||||
}
|
||||
|
||||
/** get memory used by waiting udp */
|
||||
static size_t
|
||||
waiting_udp_get_mem(struct pending* w)
|
||||
{
|
||||
size_t s;
|
||||
s = sizeof(*w) + comm_timer_get_mem(w->timer) + w->pkt_len;
|
||||
return s;
|
||||
}
|
||||
|
||||
size_t outnet_get_mem(struct outside_network* outnet)
|
||||
{
|
||||
size_t i;
|
||||
int k;
|
||||
struct waiting_tcp* w;
|
||||
struct pending* u;
|
||||
struct serviced_query* sq;
|
||||
struct service_callback* sb;
|
||||
struct port_comm* pc;
|
||||
size_t s = sizeof(*outnet) + sizeof(*outnet->base) +
|
||||
sizeof(*outnet->udp_buff) +
|
||||
ldns_buffer_capacity(outnet->udp_buff);
|
||||
/* second buffer is not ours */
|
||||
s += sizeof(struct comm_point*)*outnet->num_udp4;
|
||||
for(i=0; i<outnet->num_udp4; i++)
|
||||
s += comm_point_get_mem(outnet->udp4_ports[i]);
|
||||
s += sizeof(struct comm_point*)*outnet->num_udp6;
|
||||
for(i=0; i<outnet->num_udp6; i++)
|
||||
s += comm_point_get_mem(outnet->udp6_ports[i]);
|
||||
for(pc = outnet->unused_fds; pc; pc = pc->next) {
|
||||
s += sizeof(*pc) + comm_point_get_mem(pc->cp);
|
||||
}
|
||||
for(k=0; k<outnet->num_ip4; k++)
|
||||
s += if_get_mem(&outnet->ip4_ifs[k]);
|
||||
for(k=0; k<outnet->num_ip6; k++)
|
||||
s += if_get_mem(&outnet->ip6_ifs[k]);
|
||||
for(u=outnet->udp_wait_first; u; u=u->next_waiting)
|
||||
s += waiting_udp_get_mem(u);
|
||||
|
||||
s += sizeof(struct pending_tcp*)*outnet->num_tcp;
|
||||
for(i=0; i<outnet->num_tcp; i++) {
|
||||
s += sizeof(struct pending_tcp);
|
||||
|
||||
+85
-25
@@ -51,7 +51,10 @@ struct pending_timeout;
|
||||
struct ub_randstate;
|
||||
struct pending_tcp;
|
||||
struct waiting_tcp;
|
||||
struct waiting_udp;
|
||||
struct infra_cache;
|
||||
struct port_comm;
|
||||
struct port_if;
|
||||
|
||||
/**
|
||||
* Send queries to outside servers and wait for answers from servers.
|
||||
@@ -74,20 +77,24 @@ struct outside_network {
|
||||
/** use x20 bits to encode additional ID random bits */
|
||||
int use_caps_for_id;
|
||||
|
||||
/**
|
||||
* Array of udp comm point* that are used to listen to pending events.
|
||||
* Each is on a different port. This is for ip4 ports.
|
||||
*/
|
||||
struct comm_point** udp4_ports;
|
||||
/** number of udp4 ports */
|
||||
size_t num_udp4;
|
||||
/** linked list of available commpoints, unused file descriptors,
|
||||
* for use as outgoing UDP ports. cp.fd=-1 in them. */
|
||||
struct port_comm* unused_fds;
|
||||
|
||||
/**
|
||||
* The opened ip6 ports.
|
||||
*/
|
||||
struct comm_point** udp6_ports;
|
||||
/** number of udp6 ports */
|
||||
size_t num_udp6;
|
||||
/** array of outgoing IP4 interfaces */
|
||||
struct port_if* ip4_ifs;
|
||||
/** number of outgoing IP4 interfaces */
|
||||
int num_ip4;
|
||||
|
||||
/** array of outgoing IP6 interfaces */
|
||||
struct port_if* ip6_ifs;
|
||||
/** number of outgoing IP6 interfaces */
|
||||
int num_ip6;
|
||||
|
||||
/** pending udp queries waiting to be sent out, waiting for fd */
|
||||
struct pending* udp_wait_first;
|
||||
/** last pending udp query in list */
|
||||
struct pending* udp_wait_last;
|
||||
|
||||
/** pending udp answers. sorted by id, addr */
|
||||
rbtree_t* pending;
|
||||
@@ -115,20 +122,65 @@ struct outside_network {
|
||||
struct waiting_tcp* tcp_wait_last;
|
||||
};
|
||||
|
||||
/**
|
||||
* Outgoing interface. Ports available and currently used are tracked
|
||||
* per interface
|
||||
*/
|
||||
struct port_if {
|
||||
/** address ready to allocate new socket (except port no). */
|
||||
struct sockaddr_storage addr;
|
||||
/** length of addr field */
|
||||
socklen_t addrlen;
|
||||
|
||||
/** the available ports array. These are unused.
|
||||
* Only the first total-inuse part is filled. */
|
||||
int* avail_ports;
|
||||
/** the total number of available ports (size of the array) */
|
||||
int avail_total;
|
||||
|
||||
/** array of the commpoints currently in use.
|
||||
* allocated for max number of fds, first part in use. */
|
||||
struct port_comm** out;
|
||||
/** max number of fds, size of out array */
|
||||
int maxout;
|
||||
/** number of commpoints (and thus also ports) in use */
|
||||
int inuse;
|
||||
};
|
||||
|
||||
/**
|
||||
* Outgoing commpoint for UDP port.
|
||||
*/
|
||||
struct port_comm {
|
||||
/** next in free list */
|
||||
struct port_comm* next;
|
||||
/** which port number (when in use) */
|
||||
int number;
|
||||
/** interface it is used in */
|
||||
struct port_if* pif;
|
||||
/** index in the out array of the interface */
|
||||
int index;
|
||||
/** number of outstanding queries on this port */
|
||||
int num_outstanding;
|
||||
/** UDP commpoint, fd=-1 if not in use */
|
||||
struct comm_point* cp;
|
||||
};
|
||||
|
||||
/**
|
||||
* A query that has an answer pending for it.
|
||||
*/
|
||||
struct pending {
|
||||
/** redblacktree entry, key is the pending struct(id, addr). */
|
||||
rbnode_t node;
|
||||
/** the ID for the query */
|
||||
uint16_t id;
|
||||
/** the ID for the query. int so that a value out of range can
|
||||
* be used to signify a pending that is for certain not present in
|
||||
* the rbtree. (and for which deletion is safe). */
|
||||
unsigned int id;
|
||||
/** remote address. */
|
||||
struct sockaddr_storage addr;
|
||||
/** length of addr field in use. */
|
||||
socklen_t addrlen;
|
||||
/** comm point it was sent on (and reply must come back on). */
|
||||
struct comm_point* c;
|
||||
struct port_comm* pc;
|
||||
/** timeout event */
|
||||
struct comm_timer* timer;
|
||||
/** callback for the timeout, error or reply to the message */
|
||||
@@ -137,6 +189,16 @@ struct pending {
|
||||
void* cb_arg;
|
||||
/** the outside network it is part of */
|
||||
struct outside_network* outnet;
|
||||
|
||||
/*---- filled if udp pending is waiting -----*/
|
||||
/** next in waiting list. */
|
||||
struct pending* next_waiting;
|
||||
/** timeout in msec */
|
||||
int timeout;
|
||||
/** The query itself, the query packet to send. */
|
||||
uint8_t* pkt;
|
||||
/** length of query packet. */
|
||||
size_t pkt_len;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -258,19 +320,19 @@ struct serviced_query {
|
||||
* @param num_ifs: number of names in array ifs.
|
||||
* @param do_ip4: service IP4.
|
||||
* @param do_ip6: service IP6.
|
||||
* @param port_base: if -1 system assigns ports, otherwise try to get
|
||||
* the ports numbered from this starting number.
|
||||
* @param num_tcp: number of outgoing tcp buffers to preallocate.
|
||||
* @param infra: pointer to infra cached used for serviced queries.
|
||||
* @param rnd: stored to create random numbers for serviced queries.
|
||||
* @param use_caps_for_id: enable to use 0x20 bits to encode id randomness.
|
||||
* @param availports: array of available ports.
|
||||
* @param numavailports: number of available ports in array.
|
||||
* @return: the new structure (with no pending answers) or NULL on error.
|
||||
*/
|
||||
struct outside_network* outside_network_create(struct comm_base* base,
|
||||
size_t bufsize, size_t num_ports, char** ifs, int num_ifs,
|
||||
int do_ip4, int do_ip6, int port_base, size_t num_tcp,
|
||||
struct infra_cache* infra, struct ub_randstate* rnd,
|
||||
int use_caps_for_id);
|
||||
int do_ip4, int do_ip6, size_t num_tcp, struct infra_cache* infra,
|
||||
struct ub_randstate* rnd, int use_caps_for_id, int* availports,
|
||||
int numavailports);
|
||||
|
||||
/**
|
||||
* Delete outside_network structure.
|
||||
@@ -288,13 +350,12 @@ void outside_network_delete(struct outside_network* outnet);
|
||||
* @param timeout: in milliseconds from now.
|
||||
* @param callback: function to call on error, timeout or reply.
|
||||
* @param callback_arg: user argument for callback function.
|
||||
* @param rnd: random state for generating ID and port.
|
||||
* @return: NULL on error for malloc or socket. Else the pending query object.
|
||||
*/
|
||||
struct pending* pending_udp_query(struct outside_network* outnet,
|
||||
ldns_buffer* packet, struct sockaddr_storage* addr,
|
||||
socklen_t addrlen, int timeout, comm_point_callback_t* callback,
|
||||
void* callback_arg, struct ub_randstate* rnd);
|
||||
void* callback_arg);
|
||||
|
||||
/**
|
||||
* Send TCP query. May wait for TCP buffer. Selects ID to be random, and
|
||||
@@ -308,13 +369,12 @@ struct pending* pending_udp_query(struct outside_network* outnet,
|
||||
* without any query been sent to the server yet.
|
||||
* @param callback: function to call on error, timeout or reply.
|
||||
* @param callback_arg: user argument for callback function.
|
||||
* @param rnd: random state for generating ID.
|
||||
* @return: false on error for malloc or socket. Else the pending TCP object.
|
||||
*/
|
||||
struct waiting_tcp* pending_tcp_query(struct outside_network* outnet,
|
||||
ldns_buffer* packet, struct sockaddr_storage* addr,
|
||||
socklen_t addrlen, int timeout, comm_point_callback_t* callback,
|
||||
void* callback_arg, struct ub_randstate* rnd);
|
||||
void* callback_arg);
|
||||
|
||||
/**
|
||||
* Delete pending answer.
|
||||
|
||||
+161
-25
@@ -51,7 +51,12 @@
|
||||
#include "iterator/iterator.h"
|
||||
#include "validator/validator.h"
|
||||
#include "services/localzone.h"
|
||||
#ifdef HAVE_PWD_H
|
||||
#include <pwd.h>
|
||||
#endif
|
||||
#ifdef HAVE_SYS_STAT_H
|
||||
#include <sys/stat.h>
|
||||
#endif
|
||||
|
||||
/** Give checkconf usage, and exit (1). */
|
||||
static void
|
||||
@@ -171,25 +176,130 @@ aclchecks(struct config_file* cfg)
|
||||
}
|
||||
}
|
||||
|
||||
/** true if fname is a file */
|
||||
static int
|
||||
is_file(const char* fname)
|
||||
{
|
||||
struct stat buf;
|
||||
if(stat(fname, &buf) < 0) {
|
||||
if(errno==EACCES) {
|
||||
printf("warning: no search permission for one of the directories in path: %s\n", fname);
|
||||
return 1;
|
||||
}
|
||||
perror(fname);
|
||||
return 0;
|
||||
}
|
||||
if(S_ISDIR(buf.st_mode)) {
|
||||
printf("%s is not a file\n", fname);
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/** true if fname is a directory */
|
||||
static int
|
||||
is_dir(const char* fname)
|
||||
{
|
||||
struct stat buf;
|
||||
if(stat(fname, &buf) < 0) {
|
||||
if(errno==EACCES) {
|
||||
printf("warning: no search permission for one of the directories in path: %s\n", fname);
|
||||
return 1;
|
||||
}
|
||||
perror(fname);
|
||||
return 0;
|
||||
}
|
||||
if(!(S_ISDIR(buf.st_mode))) {
|
||||
printf("%s is not a directory\n", fname);
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/** convert a filename to full pathname in original filesys
|
||||
* @param fname: the path name to convert.
|
||||
* Must not be null or empty.
|
||||
* @param cfg: config struct for chroot and chdir (if set).
|
||||
* @param use_chdir: if false, only chroot is applied.
|
||||
* @return pointer to static buffer which is: [chroot][chdir]fname
|
||||
*/
|
||||
static char*
|
||||
fname_after_chroot(const char* fname, struct config_file* cfg, int use_chdir)
|
||||
{
|
||||
static char buf[1024];
|
||||
int slashit = 0;
|
||||
buf[0] = 0;
|
||||
if(cfg->chrootdir && cfg->chrootdir[0] &&
|
||||
strncmp(cfg->chrootdir, fname, strlen(cfg->chrootdir)) == 0) {
|
||||
/* already full pathname, return it */
|
||||
strncpy(buf, fname, sizeof(buf)-1);
|
||||
buf[sizeof(buf)-1] = 0;
|
||||
return buf;
|
||||
}
|
||||
/* chroot */
|
||||
if(cfg->chrootdir && cfg->chrootdir[0]) {
|
||||
/* start with chrootdir */
|
||||
strncpy(buf, cfg->chrootdir, sizeof(buf)-1);
|
||||
slashit = 1;
|
||||
}
|
||||
/* chdir */
|
||||
if(fname[0] == '/' || !use_chdir) {
|
||||
/* full path, no chdir */
|
||||
} else if(cfg->directory && cfg->directory[0]) {
|
||||
/* prepend chdir */
|
||||
if(slashit && cfg->directory[0] != '/')
|
||||
strncat(buf, "/", sizeof(buf)-strlen(buf)-1);
|
||||
if(strncmp(cfg->chrootdir, cfg->directory,
|
||||
strlen(cfg->chrootdir)) == 0)
|
||||
strncat(buf, cfg->directory+strlen(cfg->chrootdir),
|
||||
sizeof(buf)-strlen(buf)-1);
|
||||
else strncat(buf, cfg->directory, sizeof(buf)-strlen(buf)-1);
|
||||
slashit = 1;
|
||||
}
|
||||
/* fname */
|
||||
if(slashit && fname[0] != '/')
|
||||
strncat(buf, "/", sizeof(buf)-strlen(buf)-1);
|
||||
strncat(buf, fname, sizeof(buf)-strlen(buf)-1);
|
||||
buf[sizeof(buf)-1] = 0;
|
||||
return buf;
|
||||
}
|
||||
|
||||
/** get base dir of a fname */
|
||||
static char*
|
||||
basedir(const char* fname, struct config_file* cfg)
|
||||
{
|
||||
char* d = fname_after_chroot(fname, cfg, 1);
|
||||
char* rev = strrchr(d, '/');
|
||||
if(!rev) return NULL;
|
||||
if(d == rev) return NULL;
|
||||
rev[0] = 0;
|
||||
return d;
|
||||
}
|
||||
|
||||
/** check file list, every file must be inside the chroot location */
|
||||
static void
|
||||
check_chroot_filelist(const char* desc, struct config_strlist* list,
|
||||
const char* chrootdir)
|
||||
const char* chrootdir, struct config_file* cfg)
|
||||
{
|
||||
struct config_strlist* p;
|
||||
if(!chrootdir) return;
|
||||
char* old;
|
||||
for(p=list; p; p=p->next) {
|
||||
if(p->str && p->str[0] && strncmp(chrootdir, p->str,
|
||||
strlen(chrootdir)) != 0) {
|
||||
fatal_exit("%s: \"%s\" not in chrootdir %s",
|
||||
desc, p->str, chrootdir);
|
||||
if(p->str && p->str[0]) {
|
||||
if(!is_file(fname_after_chroot(p->str, cfg, 1))) {
|
||||
fatal_exit("%s: \"%s\" does not exist in chrootdir %s",
|
||||
desc, p->str, chrootdir);
|
||||
}
|
||||
old = p->str;
|
||||
/* put in a new full path for continued checking */
|
||||
p->str = strdup(fname_after_chroot(p->str, cfg, 1));
|
||||
free(old);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** check configuration for errors */
|
||||
static void
|
||||
morechecks(struct config_file* cfg)
|
||||
morechecks(struct config_file* cfg, char* fname)
|
||||
{
|
||||
warn_hosts("stub-host", cfg->stubs);
|
||||
warn_hosts("forward-host", cfg->forwards);
|
||||
@@ -209,26 +319,50 @@ morechecks(struct config_file* cfg)
|
||||
cfg->chrootdir[strlen(cfg->chrootdir)-1] == '/')
|
||||
fatal_exit("chootdir %s has trailing slash '/' please remove.",
|
||||
cfg->chrootdir);
|
||||
if(cfg->chrootdir && strncmp(cfg->chrootdir, cfg->directory,
|
||||
strlen(cfg->chrootdir)) != 0)
|
||||
fatal_exit("working directory %s not in chrootdir %s",
|
||||
cfg->directory, cfg->chrootdir);
|
||||
if(cfg->chrootdir && cfg->pidfile && cfg->pidfile[0] &&
|
||||
strncmp(cfg->chrootdir, cfg->pidfile,
|
||||
strlen(cfg->chrootdir)) != 0)
|
||||
fatal_exit("pid file %s not in chrootdir %s",
|
||||
cfg->pidfile, cfg->chrootdir);
|
||||
if(cfg->chrootdir && cfg->logfile && cfg->logfile[0] &&
|
||||
strncmp(cfg->chrootdir, cfg->logfile,
|
||||
strlen(cfg->chrootdir)) != 0)
|
||||
fatal_exit("log file %s not in chrootdir %s",
|
||||
cfg->logfile, cfg->chrootdir);
|
||||
if(cfg->chrootdir && cfg->chrootdir[0] &&
|
||||
!is_dir(cfg->chrootdir)) {
|
||||
fatal_exit("bad chroot directory");
|
||||
}
|
||||
if(cfg->chrootdir && cfg->chrootdir[0]) {
|
||||
char buf[10240];
|
||||
buf[0] = 0;
|
||||
if(fname[0] != '/') {
|
||||
if(getcwd(buf, sizeof(buf)) == NULL)
|
||||
fatal_exit("getcwd: %s", strerror(errno));
|
||||
strncat(buf, "/", sizeof(buf)-strlen(buf)-1);
|
||||
}
|
||||
strncat(buf, fname, sizeof(buf)-strlen(buf)-1);
|
||||
if(strncmp(buf, cfg->chrootdir, strlen(cfg->chrootdir)) != 0)
|
||||
fatal_exit("config file %s is not inside chroot %s",
|
||||
buf, cfg->chrootdir);
|
||||
}
|
||||
if(cfg->directory && cfg->directory[0] && !is_dir(
|
||||
fname_after_chroot(cfg->directory, cfg, 0))) {
|
||||
fatal_exit("bad chdir directory");
|
||||
}
|
||||
if( (cfg->chrootdir && cfg->chrootdir[0]) ||
|
||||
(cfg->directory && cfg->directory[0])) {
|
||||
if(cfg->pidfile && cfg->pidfile[0] &&
|
||||
basedir(cfg->pidfile, cfg) &&
|
||||
!is_dir(basedir(cfg->pidfile, cfg))) {
|
||||
fatal_exit("pidfile directory does not exist");
|
||||
}
|
||||
if(cfg->logfile && cfg->logfile[0] &&
|
||||
basedir(cfg->logfile, cfg) &&
|
||||
!is_dir(basedir(cfg->logfile, cfg))) {
|
||||
fatal_exit("logfile directory does not exist");
|
||||
}
|
||||
}
|
||||
|
||||
check_chroot_filelist("file with root-hints",
|
||||
cfg->root_hints, cfg->chrootdir);
|
||||
cfg->root_hints, cfg->chrootdir, cfg);
|
||||
check_chroot_filelist("trust-anchor-file",
|
||||
cfg->trust_anchor_file_list, cfg->chrootdir);
|
||||
cfg->trust_anchor_file_list, cfg->chrootdir, cfg);
|
||||
check_chroot_filelist("trusted-keys-file",
|
||||
cfg->trusted_keys_file_list, cfg->chrootdir);
|
||||
cfg->trusted_keys_file_list, cfg->chrootdir, cfg);
|
||||
/* remove chroot setting so that modules are not stripping pathnames*/
|
||||
free(cfg->chrootdir);
|
||||
cfg->chrootdir = NULL;
|
||||
|
||||
if(strcmp(cfg->module_conf, "iterator") != 0 &&
|
||||
strcmp(cfg->module_conf, "validator iterator") != 0) {
|
||||
@@ -236,11 +370,13 @@ morechecks(struct config_file* cfg)
|
||||
cfg->module_conf);
|
||||
}
|
||||
|
||||
#ifdef HAVE_GETPWNAM
|
||||
if(cfg->username && cfg->username[0]) {
|
||||
if(getpwnam(cfg->username) == NULL)
|
||||
fatal_exit("user '%s' does not exist.", cfg->username);
|
||||
endpwent();
|
||||
}
|
||||
#endif
|
||||
|
||||
localzonechecks(cfg);
|
||||
}
|
||||
@@ -257,7 +393,7 @@ checkconf(char* cfgfile)
|
||||
config_delete(cfg);
|
||||
exit(1);
|
||||
}
|
||||
morechecks(cfg);
|
||||
morechecks(cfg, cfgfile);
|
||||
check_mod(cfg, iter_get_funcblock());
|
||||
check_mod(cfg, val_get_funcblock());
|
||||
config_delete(cfg);
|
||||
|
||||
@@ -51,7 +51,7 @@ static int verb = 0;
|
||||
static void
|
||||
usage()
|
||||
{
|
||||
printf("Usage: unbound-host [-vdh] [-c class] [-t type] hostname\n");
|
||||
printf("Usage: unbound-host [-vdhr] [-c class] [-t type] hostname\n");
|
||||
printf(" [-y key] [-f keyfile] [-F namedkeyfile]\n");
|
||||
printf(" [-C configfile]\n");
|
||||
printf(" Queries the DNS for information.\n");
|
||||
@@ -65,6 +65,8 @@ usage()
|
||||
printf(" -f keyfile read trust anchors from file, with lines as -y.\n");
|
||||
printf(" -F keyfile read named.conf-style trust anchors.\n");
|
||||
printf(" -C config use the specified unbound.conf\n");
|
||||
printf(" -r read forwarder information from /etc/resolv.conf\n");
|
||||
printf(" breaks validation if the fwder does not do DNSSEC.\n");
|
||||
printf(" -v be more verbose, shows nodata and security.\n");
|
||||
printf(" -d debug, traces the action, -d -d shows more.\n");
|
||||
printf(" -h show this usage help.\n");
|
||||
@@ -411,7 +413,7 @@ int main(int argc, char* argv[])
|
||||
}
|
||||
|
||||
/* parse the options */
|
||||
while( (c=getopt(argc, argv, "F:c:df:ht:vy:C:")) != -1) {
|
||||
while( (c=getopt(argc, argv, "F:c:df:hrt:vy:C:")) != -1) {
|
||||
switch(c) {
|
||||
case 'c':
|
||||
qclass = optarg;
|
||||
@@ -425,6 +427,9 @@ int main(int argc, char* argv[])
|
||||
debuglevel = 2; /* at least VERB_DETAIL */
|
||||
check_ub_res(ub_ctx_debuglevel(ctx, debuglevel));
|
||||
break;
|
||||
case 'r':
|
||||
check_ub_res(ub_ctx_resolvconf(ctx, "/etc/resolv.conf"));
|
||||
break;
|
||||
case 't':
|
||||
qtype = optarg;
|
||||
break;
|
||||
|
||||
@@ -160,3 +160,28 @@ void worker_stat_timer_cb(void* ATTR_UNUSED(arg))
|
||||
{
|
||||
log_assert(0);
|
||||
}
|
||||
|
||||
/** keep track of lock id in lock-verify application */
|
||||
struct order_id {
|
||||
/** the thread id that created it */
|
||||
int thr;
|
||||
/** the instance number of creation */
|
||||
int instance;
|
||||
};
|
||||
|
||||
int order_lock_cmp(const void* e1, const void* e2)
|
||||
{
|
||||
struct order_id* o1 = (struct order_id*)e1;
|
||||
struct order_id* o2 = (struct order_id*)e2;
|
||||
if(o1->thr < o2->thr) return -1;
|
||||
if(o1->thr > o2->thr) return 1;
|
||||
if(o1->instance < o2->instance) return -1;
|
||||
if(o1->instance > o2->instance) return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
codeline_cmp(const void* a, const void* b)
|
||||
{
|
||||
return strcmp((const char*)a, (const char*)b);
|
||||
}
|
||||
|
||||
@@ -129,7 +129,7 @@ checkerr(const char* desc, int err)
|
||||
}
|
||||
}
|
||||
|
||||
#if !defined(HAVE_PTHREAD) && !defined(HAVE_SOLARIS_THREADS)
|
||||
#ifdef THREADS_DISABLED
|
||||
/** only one process can communicate with async worker */
|
||||
#define NUMTHR 1
|
||||
#else /* have threads */
|
||||
|
||||
@@ -832,20 +832,3 @@ checklock_thrjoin(pthread_t thread)
|
||||
}
|
||||
|
||||
#endif /* USE_THREAD_DEBUG */
|
||||
|
||||
int order_lock_cmp(const void* e1, const void* e2)
|
||||
{
|
||||
struct order_id* o1 = (struct order_id*)e1;
|
||||
struct order_id* o2 = (struct order_id*)e2;
|
||||
if(o1->thr < o2->thr) return -1;
|
||||
if(o1->thr > o2->thr) return 1;
|
||||
if(o1->instance < o2->instance) return -1;
|
||||
if(o1->instance > o2->instance) return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
codeline_cmp(const void* a, const void* b)
|
||||
{
|
||||
return strcmp((const char*)a, (const char*)b);
|
||||
}
|
||||
|
||||
@@ -340,17 +340,4 @@ typedef pthread_key_t ub_thread_key_t;
|
||||
#define ub_thread_key_get(key) pthread_getspecific(key)
|
||||
|
||||
#endif /* USE_THREAD_DEBUG */
|
||||
|
||||
/** keep track of lock id in lock-verify application */
|
||||
struct order_id {
|
||||
/** the thread id that created it */
|
||||
int thr;
|
||||
/** the instance number of creation */
|
||||
int instance;
|
||||
};
|
||||
/** compare two order_ids */
|
||||
int order_lock_cmp(const void* e1, const void* e2);
|
||||
/** compare two codeline structs for rbtree */
|
||||
int codeline_cmp(const void* a, const void* b);
|
||||
|
||||
#endif /* TESTCODE_CHECK_LOCKS_H */
|
||||
|
||||
+129
-26
@@ -364,7 +364,11 @@ service_send(struct ringbuf* ring, struct timeval* now, ldns_buffer* pkt,
|
||||
ldns_buffer_limit(pkt), 0,
|
||||
(struct sockaddr*)srv_addr, srv_len);
|
||||
if(sent == -1) {
|
||||
#ifndef USE_WINSOCK
|
||||
log_err("sendto: %s", strerror(errno));
|
||||
#else
|
||||
log_err("sendto: %s", wsa_strerror(WSAGetLastError()));
|
||||
#endif
|
||||
} else if(sent != (ssize_t)ldns_buffer_limit(pkt)) {
|
||||
log_err("sendto: partial send");
|
||||
}
|
||||
@@ -383,9 +387,16 @@ do_proxy(struct proxy* p, int retsock, ldns_buffer* pkt)
|
||||
r = recv(p->s, ldns_buffer_begin(pkt),
|
||||
ldns_buffer_capacity(pkt), 0);
|
||||
if(r == -1) {
|
||||
#ifndef USE_WINSOCK
|
||||
if(errno == EAGAIN || errno == EINTR)
|
||||
return;
|
||||
log_err("recv: %s", strerror(errno));
|
||||
#else
|
||||
if(WSAGetLastError() == WSAEINPROGRESS ||
|
||||
WSAGetLastError() == WSAEWOULDBLOCK)
|
||||
return;
|
||||
log_err("recv: %s", wsa_strerror(WSAGetLastError()));
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
ldns_buffer_set_limit(pkt, (size_t)r);
|
||||
@@ -395,7 +406,11 @@ do_proxy(struct proxy* p, int retsock, ldns_buffer* pkt)
|
||||
r = sendto(retsock, ldns_buffer_begin(pkt), (size_t)r, 0,
|
||||
(struct sockaddr*)&p->addr, p->addr_len);
|
||||
if(r == -1) {
|
||||
#ifndef USE_WINSOCK
|
||||
log_err("sendto: %s", strerror(errno));
|
||||
#else
|
||||
log_err("sendto: %s", wsa_strerror(WSAGetLastError()));
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -445,13 +460,19 @@ find_create_proxy(struct sockaddr_storage* from, socklen_t from_len,
|
||||
p = (struct proxy*)calloc(1, sizeof(*p));
|
||||
if(!p) fatal_exit("out of memory");
|
||||
p->s = socket(serv_ip6?AF_INET6:AF_INET, SOCK_DGRAM, 0);
|
||||
if(p->s == -1) fatal_exit("socket: %s", strerror(errno));
|
||||
if(p->s == -1) {
|
||||
#ifndef USE_WINSOCK
|
||||
fatal_exit("socket: %s", strerror(errno));
|
||||
#else
|
||||
fatal_exit("socket: %s", wsa_strerror(WSAGetLastError()));
|
||||
#endif
|
||||
}
|
||||
fd_set_nonblock(p->s);
|
||||
memmove(&p->addr, from, from_len);
|
||||
p->addr_len = from_len;
|
||||
p->next = *proxies;
|
||||
*proxies = p;
|
||||
FD_SET(p->s, rorig);
|
||||
FD_SET(FD_SET_T p->s, rorig);
|
||||
if(p->s+1 > *max)
|
||||
*max = p->s+1;
|
||||
return p;
|
||||
@@ -475,9 +496,17 @@ service_recv(int s, struct ringbuf* ring, ldns_buffer* pkt,
|
||||
ldns_buffer_capacity(pkt), 0,
|
||||
(struct sockaddr*)&from, &from_len);
|
||||
if(len < 0) {
|
||||
#ifndef USE_WINSOCK
|
||||
if(errno == EAGAIN || errno == EINTR)
|
||||
return;
|
||||
fatal_exit("recvfrom: %s", strerror(errno));
|
||||
#else
|
||||
if(WSAGetLastError() == WSAEWOULDBLOCK ||
|
||||
WSAGetLastError() == WSAEINPROGRESS)
|
||||
return;
|
||||
fatal_exit("recvfrom: %s",
|
||||
wsa_strerror(WSAGetLastError()));
|
||||
#endif
|
||||
}
|
||||
ldns_buffer_set_limit(pkt, (size_t)len);
|
||||
/* find its proxy element */
|
||||
@@ -531,9 +560,17 @@ service_tcp_listen(int s, fd_set* rorig, int* max, struct tcp_proxy** proxies,
|
||||
socklen_t addr_len;
|
||||
newfd = accept(s, (struct sockaddr*)&addr, &addr_len);
|
||||
if(newfd == -1) {
|
||||
#ifndef USE_WINSOCK
|
||||
if(errno == EAGAIN || errno == EINTR)
|
||||
return;
|
||||
fatal_exit("accept: %s", strerror(errno));
|
||||
#else
|
||||
if(WSAGetLastError() == WSAEWOULDBLOCK ||
|
||||
WSAGetLastError() == WSAEINPROGRESS ||
|
||||
WSAGetLastError() == WSAECONNRESET)
|
||||
return;
|
||||
fatal_exit("accept: %s", wsa_strerror(WSAGetLastError()));
|
||||
#endif
|
||||
}
|
||||
p = (struct tcp_proxy*)calloc(1, sizeof(*p));
|
||||
if(!p) fatal_exit("out of memory");
|
||||
@@ -543,13 +580,25 @@ service_tcp_listen(int s, fd_set* rorig, int* max, struct tcp_proxy** proxies,
|
||||
p->client_s = newfd;
|
||||
p->server_s = socket(addr_is_ip6(srv_addr, srv_len)?AF_INET6:AF_INET,
|
||||
SOCK_STREAM, 0);
|
||||
if(p->server_s == -1)
|
||||
if(p->server_s == -1) {
|
||||
#ifndef USE_WINSOCK
|
||||
fatal_exit("tcp socket: %s", strerror(errno));
|
||||
#else
|
||||
fatal_exit("tcp socket: %s", wsa_strerror(WSAGetLastError()));
|
||||
#endif
|
||||
}
|
||||
fd_set_nonblock(p->client_s);
|
||||
fd_set_nonblock(p->server_s);
|
||||
if(connect(p->server_s, (struct sockaddr*)srv_addr, srv_len) == -1) {
|
||||
#ifndef USE_WINSOCK
|
||||
if(errno != EINPROGRESS) {
|
||||
log_err("tcp connect: %s", strerror(errno));
|
||||
#else
|
||||
if(WSAGetLastError() != WSAEWOULDBLOCK &&
|
||||
WSAGetLastError() != WSAEINPROGRESS) {
|
||||
log_err("tcp connect: %s",
|
||||
wsa_strerror(WSAGetLastError()));
|
||||
#endif
|
||||
close(p->server_s);
|
||||
close(p->client_s);
|
||||
free(p);
|
||||
@@ -560,8 +609,8 @@ service_tcp_listen(int s, fd_set* rorig, int* max, struct tcp_proxy** proxies,
|
||||
dl_tv_add(&p->timeout, tcp_timeout);
|
||||
|
||||
/* listen to client and server */
|
||||
FD_SET(p->client_s, rorig);
|
||||
FD_SET(p->server_s, rorig);
|
||||
FD_SET(FD_SET_T p->client_s, rorig);
|
||||
FD_SET(FD_SET_T p->server_s, rorig);
|
||||
if(p->client_s+1 > *max)
|
||||
*max = p->client_s+1;
|
||||
if(p->server_s+1 > *max)
|
||||
@@ -579,11 +628,19 @@ tcp_relay_read(int s, struct tcp_send_list** first,
|
||||
struct timeval* delay, ldns_buffer* pkt)
|
||||
{
|
||||
struct tcp_send_list* item;
|
||||
ssize_t r = read(s, ldns_buffer_begin(pkt), ldns_buffer_capacity(pkt));
|
||||
ssize_t r = recv(s, ldns_buffer_begin(pkt),
|
||||
ldns_buffer_capacity(pkt), 0);
|
||||
if(r == -1) {
|
||||
#ifndef USE_WINSOCK
|
||||
if(errno == EINTR || errno == EAGAIN)
|
||||
return 1;
|
||||
log_err("tcp read: %s", strerror(errno));
|
||||
#else
|
||||
if(WSAGetLastError() == WSAEINPROGRESS ||
|
||||
WSAGetLastError() == WSAEWOULDBLOCK)
|
||||
return 1;
|
||||
log_err("tcp read: %s", wsa_strerror(WSAGetLastError()));
|
||||
#endif
|
||||
return 0;
|
||||
} else if(r == 0) {
|
||||
/* connection closed */
|
||||
@@ -630,11 +687,19 @@ tcp_relay_write(int s, struct tcp_send_list** first,
|
||||
if(!dl_tv_smaller(&p->wait, now))
|
||||
return 1;
|
||||
/* write it */
|
||||
r = write(s, p->item + p->done, p->len - p->done);
|
||||
r = send(s, (void*)(p->item + p->done), p->len - p->done, 0);
|
||||
if(r == -1) {
|
||||
#ifndef USE_WINSOCK
|
||||
if(errno == EAGAIN || errno == EINTR)
|
||||
return 1;
|
||||
log_err("tcp write: %s", strerror(errno));
|
||||
#else
|
||||
if(WSAGetLastError() == WSAEWOULDBLOCK ||
|
||||
WSAGetLastError() == WSAEINPROGRESS)
|
||||
return 1;
|
||||
log_err("tcp write: %s",
|
||||
wsa_strerror(WSAGetLastError()));
|
||||
#endif
|
||||
return 0;
|
||||
} else if(r == 0) {
|
||||
/* closed */
|
||||
@@ -689,8 +754,8 @@ service_tcp_relay(struct tcp_proxy** tcp_proxies, struct timeval* now,
|
||||
if(!tcp_relay_read(p->server_s, &p->answerlist,
|
||||
&p->answerlast, now, delay, pkt)) {
|
||||
close(p->server_s);
|
||||
FD_CLR(p->server_s, worig);
|
||||
FD_CLR(p->server_s, rorig);
|
||||
FD_CLR(FD_SET_T p->server_s, worig);
|
||||
FD_CLR(FD_SET_T p->server_s, rorig);
|
||||
p->server_s = -1;
|
||||
}
|
||||
}
|
||||
@@ -705,8 +770,8 @@ service_tcp_relay(struct tcp_proxy** tcp_proxies, struct timeval* now,
|
||||
delete_it = 1;
|
||||
if(p->querylist && p->server_s != -1 &&
|
||||
dl_tv_smaller(&p->querylist->wait, now))
|
||||
FD_SET(p->server_s, worig);
|
||||
else FD_CLR(p->server_s, worig);
|
||||
FD_SET(FD_SET_T p->server_s, worig);
|
||||
else FD_CLR(FD_SET_T p->server_s, worig);
|
||||
}
|
||||
|
||||
/* can we send on further answers */
|
||||
@@ -720,8 +785,8 @@ service_tcp_relay(struct tcp_proxy** tcp_proxies, struct timeval* now,
|
||||
delete_it = 1;
|
||||
if(p->answerlist && dl_tv_smaller(&p->answerlist->wait,
|
||||
now))
|
||||
FD_SET(p->client_s, worig);
|
||||
else FD_CLR(p->client_s, worig);
|
||||
FD_SET(FD_SET_T p->client_s, worig);
|
||||
else FD_CLR(FD_SET_T p->client_s, worig);
|
||||
if(!p->answerlist && p->server_s == -1)
|
||||
delete_it = 1;
|
||||
}
|
||||
@@ -733,11 +798,11 @@ service_tcp_relay(struct tcp_proxy** tcp_proxies, struct timeval* now,
|
||||
if(delete_it) {
|
||||
struct tcp_proxy* np = p->next;
|
||||
*prev = np;
|
||||
FD_CLR(p->client_s, rorig);
|
||||
FD_CLR(p->client_s, worig);
|
||||
FD_CLR(FD_SET_T p->client_s, rorig);
|
||||
FD_CLR(FD_SET_T p->client_s, worig);
|
||||
if(p->server_s != -1) {
|
||||
FD_CLR(p->server_s, rorig);
|
||||
FD_CLR(p->server_s, worig);
|
||||
FD_CLR(FD_SET_T p->server_s, rorig);
|
||||
FD_CLR(FD_SET_T p->server_s, worig);
|
||||
}
|
||||
tcp_proxy_delete(p);
|
||||
p = np;
|
||||
@@ -853,8 +918,8 @@ service_loop(int udp_s, int listen_s, struct ringbuf* ring,
|
||||
#ifndef S_SPLINT_S
|
||||
FD_ZERO(&rorig);
|
||||
FD_ZERO(&worig);
|
||||
FD_SET(udp_s, &rorig);
|
||||
FD_SET(listen_s, &rorig);
|
||||
FD_SET(FD_SET_T udp_s, &rorig);
|
||||
FD_SET(FD_SET_T listen_s, &rorig);
|
||||
#endif
|
||||
max = udp_s + 1;
|
||||
if(listen_s + 1 > max) max = listen_s + 1;
|
||||
@@ -926,15 +991,29 @@ service(char* bind_str, int bindport, char* serv_str, size_t memsize,
|
||||
if(!pkt)
|
||||
fatal_exit("out of memory");
|
||||
if( signal(SIGINT, delayer_sigh) == SIG_ERR ||
|
||||
signal(SIGTERM, delayer_sigh) == SIG_ERR ||
|
||||
#ifdef SIGHUP
|
||||
signal(SIGHUP, delayer_sigh) == SIG_ERR ||
|
||||
#endif
|
||||
#ifdef SIGQUIT
|
||||
signal(SIGQUIT, delayer_sigh) == SIG_ERR ||
|
||||
signal(SIGALRM, delayer_sigh) == SIG_ERR)
|
||||
#endif
|
||||
#ifdef SIGBREAK
|
||||
signal(SIGBREAK, delayer_sigh) == SIG_ERR ||
|
||||
#endif
|
||||
#ifdef SIGALRM
|
||||
signal(SIGALRM, delayer_sigh) == SIG_ERR ||
|
||||
#endif
|
||||
signal(SIGTERM, delayer_sigh) == SIG_ERR)
|
||||
fatal_exit("could not bind to signal");
|
||||
/* bind UDP port */
|
||||
if((s = socket(str_is_ip6(bind_str)?AF_INET6:AF_INET,
|
||||
SOCK_DGRAM, 0)) == -1)
|
||||
SOCK_DGRAM, 0)) == -1) {
|
||||
#ifndef USE_WINSOCK
|
||||
fatal_exit("socket: %s", strerror(errno));
|
||||
#else
|
||||
fatal_exit("socket: %s", wsa_strerror(WSAGetLastError()));
|
||||
#endif
|
||||
}
|
||||
i=0;
|
||||
if(bindport == 0) {
|
||||
bindport = 1024 + random()%64000;
|
||||
@@ -946,7 +1025,11 @@ service(char* bind_str, int bindport, char* serv_str, size_t memsize,
|
||||
exit(1);
|
||||
}
|
||||
if(bind(s, (struct sockaddr*)&bind_addr, bind_len) == -1) {
|
||||
#ifndef USE_WINSOCK
|
||||
log_err("bind: %s", strerror(errno));
|
||||
#else
|
||||
log_err("bind: %s", wsa_strerror(WSAGetLastError()));
|
||||
#endif
|
||||
if(i--==0)
|
||||
fatal_exit("cannot bind any port");
|
||||
bindport = 1024 + random()%64000;
|
||||
@@ -955,21 +1038,41 @@ service(char* bind_str, int bindport, char* serv_str, size_t memsize,
|
||||
fd_set_nonblock(s);
|
||||
/* and TCP port */
|
||||
if((listen_s = socket(str_is_ip6(bind_str)?AF_INET6:AF_INET,
|
||||
SOCK_STREAM, 0)) == -1)
|
||||
SOCK_STREAM, 0)) == -1) {
|
||||
#ifndef USE_WINSOCK
|
||||
fatal_exit("tcp socket: %s", strerror(errno));
|
||||
#else
|
||||
fatal_exit("tcp socket: %s", wsa_strerror(WSAGetLastError()));
|
||||
#endif
|
||||
}
|
||||
#ifdef SO_REUSEADDR
|
||||
if(1) {
|
||||
int on = 1;
|
||||
if(setsockopt(listen_s, SOL_SOCKET, SO_REUSEADDR, &on,
|
||||
if(setsockopt(listen_s, SOL_SOCKET, SO_REUSEADDR, (void*)&on,
|
||||
(socklen_t)sizeof(on)) < 0)
|
||||
#ifndef USE_WINSOCK
|
||||
fatal_exit("setsockopt(.. SO_REUSEADDR ..) failed: %s",
|
||||
strerror(errno));
|
||||
#else
|
||||
fatal_exit("setsockopt(.. SO_REUSEADDR ..) failed: %s",
|
||||
wsa_strerror(WSAGetLastError()));
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
if(bind(listen_s, (struct sockaddr*)&bind_addr, bind_len) == -1)
|
||||
if(bind(listen_s, (struct sockaddr*)&bind_addr, bind_len) == -1) {
|
||||
#ifndef USE_WINSOCK
|
||||
fatal_exit("tcp bind: %s", strerror(errno));
|
||||
if(listen(listen_s, 5) == -1)
|
||||
#else
|
||||
fatal_exit("tcp bind: %s", wsa_strerror(WSAGetLastError()));
|
||||
#endif
|
||||
}
|
||||
if(listen(listen_s, 5) == -1) {
|
||||
#ifndef USE_WINSOCK
|
||||
fatal_exit("tcp listen: %s", strerror(errno));
|
||||
#else
|
||||
fatal_exit("tcp listen: %s", wsa_strerror(WSAGetLastError()));
|
||||
#endif
|
||||
}
|
||||
fd_set_nonblock(listen_s);
|
||||
printf("listening on port: %d\n", bindport);
|
||||
|
||||
|
||||
+39
-1
@@ -2,9 +2,27 @@
|
||||
|
||||
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'
|
||||
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'
|
||||
NEED_XXD='fwd_compress_c00c.tpkg'
|
||||
NEED_NC='fwd_compress_c00c.tpkg'
|
||||
NEED_CURL='06-ianaports.tpkg'
|
||||
NEED_WHOAMI='07-confroot.tpkg'
|
||||
NEED_IPV6='fwd_ancil.tpkg fwd_tcp_tc6.tpkg'
|
||||
NEED_JOBCONTROL='tcp_sigpipe.tpkg'
|
||||
|
||||
# test if job control - and also signals - are available (not on mingw).
|
||||
if wait %% 2>&1 | grep "job control not enabled" >/dev/null 2>&1; then
|
||||
JOBCONTROL=no
|
||||
else
|
||||
JOBCONTROL=yes
|
||||
fi
|
||||
|
||||
# test for ipv6, uses streamptcp peculiarity.
|
||||
if ./streamtcp -f ::1 2>&1 | grep "not supported" >/dev/null 2>&1; then
|
||||
HAVE_IPV6=no
|
||||
else
|
||||
HAVE_IPV6=yes
|
||||
fi
|
||||
|
||||
cd testdata;
|
||||
sh ../testcode/mini_tpkg.sh clean
|
||||
@@ -21,6 +39,11 @@ for test in `ls *.tpkg`; do
|
||||
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;
|
||||
@@ -36,6 +59,21 @@ for test in `ls *.tpkg`; do
|
||||
SKIP=1;
|
||||
fi
|
||||
fi
|
||||
if echo $NEED_WHOAMI | grep $test >/dev/null; then
|
||||
if test ! -x "`which whoami`"; then
|
||||
SKIP=1;
|
||||
fi
|
||||
fi
|
||||
if echo $NEED_IPV6 | grep $test >/dev/null; then
|
||||
if test "$HAVE_IPV6" = no; then
|
||||
SKIP=1;
|
||||
fi
|
||||
fi
|
||||
if echo $NEED_JOBCONTROL | grep $test >/dev/null; then
|
||||
if test "$JOBCONTROL" = no; then
|
||||
SKIP=1;
|
||||
fi
|
||||
fi
|
||||
if test $SKIP -eq 0; then
|
||||
echo $test
|
||||
sh ../testcode/mini_tpkg.sh -a ../.. exe $test
|
||||
|
||||
@@ -684,9 +684,11 @@ struct outside_network*
|
||||
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), int ATTR_UNUSED(port_base),
|
||||
size_t ATTR_UNUSED(num_tcp), struct infra_cache* ATTR_UNUSED(infra),
|
||||
struct ub_randstate* ATTR_UNUSED(rnd), int ATTR_UNUSED(use_caps_for_id))
|
||||
int ATTR_UNUSED(do_ip6), size_t ATTR_UNUSED(num_tcp),
|
||||
struct infra_cache* ATTR_UNUSED(infra),
|
||||
struct ub_randstate* ATTR_UNUSED(rnd),
|
||||
int ATTR_UNUSED(use_caps_for_id), int* ATTR_UNUSED(availports),
|
||||
int ATTR_UNUSED(numavailports))
|
||||
{
|
||||
struct outside_network* outnet = calloc(1,
|
||||
sizeof(struct outside_network));
|
||||
@@ -711,8 +713,7 @@ outside_network_delete(struct outside_network* outnet)
|
||||
struct pending*
|
||||
pending_udp_query(struct outside_network* outnet, ldns_buffer* packet,
|
||||
struct sockaddr_storage* addr, socklen_t addrlen, int timeout,
|
||||
comm_point_callback_t* callback, void* callback_arg,
|
||||
struct ub_randstate* ATTR_UNUSED(rnd))
|
||||
comm_point_callback_t* callback, void* callback_arg)
|
||||
{
|
||||
struct replay_runtime* runtime = (struct replay_runtime*)outnet->base;
|
||||
struct fake_pending* pend = (struct fake_pending*)calloc(1,
|
||||
@@ -764,8 +765,7 @@ pending_udp_query(struct outside_network* outnet, ldns_buffer* packet,
|
||||
struct waiting_tcp*
|
||||
pending_tcp_query(struct outside_network* outnet, ldns_buffer* packet,
|
||||
struct sockaddr_storage* addr, socklen_t addrlen, int timeout,
|
||||
comm_point_callback_t* callback, void* callback_arg,
|
||||
struct ub_randstate* ATTR_UNUSED(rnd))
|
||||
comm_point_callback_t* callback, void* callback_arg)
|
||||
{
|
||||
struct replay_runtime* runtime = (struct replay_runtime*)outnet->base;
|
||||
struct fake_pending* pend = (struct fake_pending*)calloc(1,
|
||||
|
||||
+30
-3
@@ -160,6 +160,7 @@ static void usage(char* nm)
|
||||
printf("-f fnm query list to read from file\n");
|
||||
printf(" every line has format: qname qclass qtype\n");
|
||||
printf("-v verbose (-v -v even more)\n");
|
||||
printf("-C cfg config file with resolver options\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
@@ -389,6 +390,18 @@ process_rr(struct harvest_data* data, ldns_rr* rr, int depth)
|
||||
} else if(ldns_rr_get_type(rr) == LDNS_RR_TYPE_SOA) {
|
||||
new_todo_infra(data, find_create_lab(data,
|
||||
ldns_rr_rdf(rr, 0)), depth+1);
|
||||
} else if(ldns_rr_get_type(rr) == LDNS_RR_TYPE_CNAME) {
|
||||
int t = ldns_rr_get_type(rr);
|
||||
if(t!=LDNS_RR_TYPE_A && t!=LDNS_RR_TYPE_AAAA &&
|
||||
t!=LDNS_RR_TYPE_SOA && t!=LDNS_RR_TYPE_NS &&
|
||||
t!=LDNS_RR_TYPE_DS && t!=LDNS_RR_TYPE_DNSKEY)
|
||||
new_todo_item(data, ldns_rr_rdf(rr, 0), t,
|
||||
ldns_rr_get_class(rr), depth+1);
|
||||
/* can get caught in CNAME loop, but depth will
|
||||
* catch that; unbound cache helps too(servfails on
|
||||
* a cname loop) */
|
||||
new_todo_infra(data, find_create_lab(data,
|
||||
ldns_rr_rdf(rr, 0)), depth+1);
|
||||
}
|
||||
/* store it */
|
||||
if(ldns_rr_get_type(rr) == LDNS_RR_TYPE_NSEC) {
|
||||
@@ -479,14 +492,19 @@ process(struct harvest_data* data, struct todo_item* it)
|
||||
free(nm);
|
||||
return;
|
||||
}
|
||||
if(result->rcode == LDNS_RCODE_SERVFAIL) {
|
||||
free(nm);
|
||||
return;
|
||||
}
|
||||
/* even if result is a negative, try to store resulting SOA/NSEC */
|
||||
|
||||
/* create ldns pkt */
|
||||
s = ldns_wire2pkt(&pkt, result->answer_packet,
|
||||
(size_t)result->answer_len);
|
||||
if(s != LDNS_STATUS_OK) {
|
||||
printf("ldns_wire2pkt failed! %s %d %d %s", nm,
|
||||
it->qtype, it->qclass, ldns_get_errorstr_by_id(s));
|
||||
printf("ldns_wire2pkt failed! %s %d %d %s %d\n", nm,
|
||||
it->qtype, it->qclass, ldns_get_errorstr_by_id(s),
|
||||
result->answer_len);
|
||||
free(nm);
|
||||
return;
|
||||
}
|
||||
@@ -531,6 +549,7 @@ harvest_main(struct harvest_data* data)
|
||||
}
|
||||
data->numtodo--;
|
||||
process(data, it);
|
||||
usleep(1000000/100);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -538,7 +557,11 @@ harvest_main(struct harvest_data* data)
|
||||
static void
|
||||
hv_mkdir(char* dir)
|
||||
{
|
||||
#ifdef MKDIR_HAS_ONE_ARG
|
||||
if(mkdir(dir) == -1) {
|
||||
#else
|
||||
if(mkdir(dir, 0755) == -1) {
|
||||
#endif
|
||||
if(errno == EEXIST)
|
||||
return;
|
||||
perror(dir);
|
||||
@@ -785,8 +808,12 @@ int main(int argc, char* argv[])
|
||||
data.maxdepth = 2;
|
||||
|
||||
/* parse the options */
|
||||
while( (c=getopt(argc, argv, "hf:v")) != -1) {
|
||||
while( (c=getopt(argc, argv, "hf:vC:")) != -1) {
|
||||
switch(c) {
|
||||
case 'C':
|
||||
if(ub_ctx_config(data.ctx, optarg) != 0)
|
||||
error_exit("config read failed");
|
||||
break;
|
||||
case 'f':
|
||||
qlist_read_file(&data, optarg);
|
||||
break;
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
*
|
||||
* Data storage for specially crafted replies for testing purposes.
|
||||
*
|
||||
* (c) NLnet Labs, 2005, 2006, 2007
|
||||
* (c) NLnet Labs, 2005, 2006, 2007, 2008
|
||||
* See the file LICENSE for the license
|
||||
*/
|
||||
|
||||
@@ -708,7 +708,11 @@ adjust_packet(struct entry* match, ldns_pkt* answer_pkt, ldns_pkt* query_pkt)
|
||||
}
|
||||
if(match->sleeptime > 0) {
|
||||
verbose(3, "sleeping for %d seconds\n", match->sleeptime);
|
||||
#ifdef HAVE_SLEEP
|
||||
sleep(match->sleeptime);
|
||||
#else
|
||||
Sleep(match->sleeptime * 1000);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
@@ -808,7 +812,11 @@ handle_query(uint8_t* inbuf, ssize_t inlen, struct entry* entries, int* count,
|
||||
if(p->packet_sleep) {
|
||||
verbose(3, "sleeping for next packet %d secs\n",
|
||||
p->packet_sleep);
|
||||
#ifdef HAVE_SLEEP
|
||||
sleep(p->packet_sleep);
|
||||
#else
|
||||
Sleep(p->packet_sleep * 1000);
|
||||
#endif
|
||||
verbose(3, "wakeup for next packet "
|
||||
"(slept %d secs)\n", p->packet_sleep);
|
||||
}
|
||||
|
||||
+11
-1
@@ -47,11 +47,21 @@
|
||||
#include "util/log.h"
|
||||
#include "util/rbtree.h"
|
||||
#include "util/locks.h"
|
||||
#include "testcode/checklocks.h"
|
||||
#include "util/fptr_wlist.h"
|
||||
|
||||
/* --- data structures --- */
|
||||
struct lock_ref;
|
||||
|
||||
/** keep track of lock id in lock-verify application
|
||||
* Also defined in smallapp/worker_cb.c for fptr_wlist encapsulation
|
||||
* breakage (the security tests break encapsulation for this test app) */
|
||||
struct order_id {
|
||||
/** the thread id that created it */
|
||||
int thr;
|
||||
/** the instance number of creation */
|
||||
int instance;
|
||||
};
|
||||
|
||||
/** a lock */
|
||||
struct order_lock {
|
||||
/** rbnode in all tree */
|
||||
|
||||
+1
-1
@@ -43,7 +43,7 @@
|
||||
#include "util/log.h"
|
||||
#include "util/rbtree.h"
|
||||
#include "util/locks.h"
|
||||
#include "testcode/checklocks.h"
|
||||
#include "util/fptr_wlist.h"
|
||||
#include <sys/stat.h>
|
||||
|
||||
/**
|
||||
|
||||
+19
-4
@@ -18,14 +18,18 @@ if test "$1" = "fake"; then
|
||||
fi
|
||||
if test "$1" = "report" || test "$2" = "report"; then
|
||||
echo "Minitpkg Report"
|
||||
for result in result.*; do
|
||||
name=`echo $result | sed -e 's/result\.//'`
|
||||
for result in *.tpkg; do
|
||||
name=`basename $result .tpkg`
|
||||
if test -f ".done-$name"; then
|
||||
if test "$1" != "-q"; then
|
||||
echo "** PASSED ** : $name"
|
||||
fi
|
||||
else
|
||||
echo "!! FAILED !! : $name"
|
||||
if test -f "result.$name"; then
|
||||
echo "!! FAILED !! : $name"
|
||||
else
|
||||
echo ">> SKIPPED<< : $name"
|
||||
fi
|
||||
fi
|
||||
done
|
||||
exit 0
|
||||
@@ -56,7 +60,11 @@ dir=$name.$$
|
||||
result=result.$name
|
||||
done=.done-$name
|
||||
success="no"
|
||||
shell="bash"
|
||||
if test -x "`which bash`"; then
|
||||
shell="bash"
|
||||
else
|
||||
shell="sh"
|
||||
fi
|
||||
|
||||
# check already done
|
||||
if test -f .done-$name; then
|
||||
@@ -109,3 +117,10 @@ fi
|
||||
mv $result ..
|
||||
cd ..
|
||||
rm -rf $dir
|
||||
# compat for windows where deletion may not succeed initially (files locked
|
||||
# by processes that still have to exit).
|
||||
if test $? -eq 1; then
|
||||
echo "minitpkg waiting for processes to terminate"
|
||||
sleep 2 # some time to exit, and try again
|
||||
rm -rf $dir
|
||||
fi
|
||||
|
||||
+38
-6
@@ -202,9 +202,16 @@ perfsetup(struct perfinfo* info)
|
||||
fatal_exit("gettimeofday: %s", strerror(errno));
|
||||
sig_info = info;
|
||||
if( signal(SIGINT, perf_sigh) == SIG_ERR ||
|
||||
signal(SIGTERM, perf_sigh) == SIG_ERR ||
|
||||
#ifdef SIGQUIT
|
||||
signal(SIGQUIT, perf_sigh) == SIG_ERR ||
|
||||
#endif
|
||||
#ifdef SIGHUP
|
||||
signal(SIGHUP, perf_sigh) == SIG_ERR ||
|
||||
signal(SIGQUIT, perf_sigh) == SIG_ERR)
|
||||
#endif
|
||||
#ifdef SIGBREAK
|
||||
signal(SIGBREAK, perf_sigh) == SIG_ERR ||
|
||||
#endif
|
||||
signal(SIGTERM, perf_sigh) == SIG_ERR)
|
||||
fatal_exit("could not bind to signal");
|
||||
info->io = (struct perfio*)calloc(sizeof(struct perfio), info->io_num);
|
||||
if(!info->io) fatal_exit("out of memory");
|
||||
@@ -218,12 +225,18 @@ perfsetup(struct perfinfo* info)
|
||||
info->io[i].fd = socket(
|
||||
addr_is_ip6(&info->dest, info->destlen)?
|
||||
AF_INET6:AF_INET, SOCK_DGRAM, 0);
|
||||
if(info->io[i].fd == -1)
|
||||
if(info->io[i].fd == -1) {
|
||||
#ifndef USE_WINSOCK
|
||||
fatal_exit("socket: %s", strerror(errno));
|
||||
#else
|
||||
fatal_exit("socket: %s",
|
||||
wsa_strerror(WSAGetLastError()));
|
||||
#endif
|
||||
}
|
||||
if(info->io[i].fd > info->maxfd)
|
||||
info->maxfd = info->io[i].fd;
|
||||
#ifndef S_SPLINT_S
|
||||
FD_SET(info->io[i].fd, &info->rset);
|
||||
FD_SET(FD_SET_T info->io[i].fd, &info->rset);
|
||||
info->io[i].timeout.tv_usec = ((START_IO_INTERVAL*i)%1000)
|
||||
*1000;
|
||||
info->io[i].timeout.tv_sec = (START_IO_INTERVAL*i)/1000;
|
||||
@@ -260,9 +273,13 @@ perfsend(struct perfinfo* info, size_t n, struct timeval* now)
|
||||
(struct sockaddr*)&info->dest, info->destlen);
|
||||
/*log_hex("send", info->qlist_data[info->qlist_idx],
|
||||
info->qlist_len[info->qlist_idx]);*/
|
||||
if(r == -1)
|
||||
if(r == -1) {
|
||||
#ifndef USE_WINSOCK
|
||||
log_err("sendto: %s", strerror(errno));
|
||||
else if(r != (ssize_t)info->qlist_len[info->qlist_idx]) {
|
||||
#else
|
||||
log_err("sendto: %s", wsa_strerror(WSAGetLastError()));
|
||||
#endif
|
||||
} else if(r != (ssize_t)info->qlist_len[info->qlist_idx]) {
|
||||
log_err("partial sendto");
|
||||
}
|
||||
info->qlist_idx = (info->qlist_idx+1) % info->qlist_size;
|
||||
@@ -281,7 +298,11 @@ perfreply(struct perfinfo* info, size_t n, struct timeval* now)
|
||||
r = recv(info->io[n].fd, ldns_buffer_begin(info->buf),
|
||||
ldns_buffer_capacity(info->buf), 0);
|
||||
if(r == -1) {
|
||||
#ifndef USE_WINSOCK
|
||||
log_err("recv: %s", strerror(errno));
|
||||
#else
|
||||
log_err("recv: %s", wsa_strerror(WSAGetLastError()));
|
||||
#endif
|
||||
} else {
|
||||
info->by_rcode[LDNS_RCODE_WIRE(ldns_buffer_begin(
|
||||
info->buf))]++;
|
||||
@@ -552,6 +573,10 @@ int main(int argc, char* argv[])
|
||||
char* nm = argv[0];
|
||||
int c;
|
||||
struct perfinfo info;
|
||||
#ifdef USE_WINSOCK
|
||||
int r;
|
||||
WSADATA wsa_data;
|
||||
#endif
|
||||
|
||||
/* defaults */
|
||||
memset(&info, 0, sizeof(info));
|
||||
@@ -560,6 +585,10 @@ int main(int argc, char* argv[])
|
||||
log_init(NULL, 0, NULL);
|
||||
log_ident_set("perf");
|
||||
checklock_start();
|
||||
#ifdef USE_WINSOCK
|
||||
if((r = WSAStartup(MAKEWORD(2,2), &wsa_data)) != 0)
|
||||
fatal_exit("WSAStartup failed: %s", wsa_strerror(r));
|
||||
#endif
|
||||
|
||||
info.buf = ldns_buffer_new(65553);
|
||||
if(!info.buf) fatal_exit("out of memory");
|
||||
@@ -609,6 +638,9 @@ int main(int argc, char* argv[])
|
||||
perfmain(&info);
|
||||
|
||||
ldns_buffer_free(info.buf);
|
||||
#ifdef USE_WINSOCK
|
||||
WSACleanup();
|
||||
#endif
|
||||
checklock_stop();
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -235,7 +235,6 @@ replay_moment_read(char* remain, FILE* in, const char* name, int* lineno,
|
||||
remain++;
|
||||
if(strlen(remain) > 0) /* remove \n */
|
||||
remain[strlen(remain)-1] = 0;
|
||||
printf("remain '%s'\n", remain);
|
||||
if(!extstrtoaddr(remain, &mom->addr, &mom->addrlen)) {
|
||||
log_err("line %d: could not parse ADDRESS: %s",
|
||||
*lineno, remain);
|
||||
|
||||
+99
-27
@@ -54,13 +54,15 @@ void usage(char* argv[])
|
||||
printf("usage: %s [options] name type class ...\n", argv[0]);
|
||||
printf(" sends the name-type-class queries over TCP.\n");
|
||||
printf("-f server what ipaddr@portnr to send the queries to\n");
|
||||
printf("-u use UDP. No retries are attempted.\n");
|
||||
printf("-n do not wait for an answer.\n");
|
||||
printf("-h this help text\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/** open TCP socket to svr */
|
||||
static int
|
||||
open_svr(char* svr)
|
||||
open_svr(char* svr, int udp)
|
||||
{
|
||||
struct sockaddr_storage addr;
|
||||
socklen_t addrlen;
|
||||
@@ -71,13 +73,21 @@ open_svr(char* svr)
|
||||
exit(1);
|
||||
}
|
||||
fd = socket(addr_is_ip6(&addr, addrlen)?PF_INET6:PF_INET,
|
||||
SOCK_STREAM, 0);
|
||||
udp?SOCK_DGRAM:SOCK_STREAM, 0);
|
||||
if(fd == -1) {
|
||||
#ifndef USE_WINSOCK
|
||||
perror("socket() error");
|
||||
#else
|
||||
printf("socket: %s\n", wsa_strerror(WSAGetLastError()));
|
||||
#endif
|
||||
exit(1);
|
||||
}
|
||||
if(connect(fd, (struct sockaddr*)&addr, addrlen) < 0) {
|
||||
#ifndef USE_WINSOCK
|
||||
perror("connect() error");
|
||||
#else
|
||||
printf("connect: %s\n", wsa_strerror(WSAGetLastError()));
|
||||
#endif
|
||||
exit(1);
|
||||
}
|
||||
return fd;
|
||||
@@ -85,7 +95,7 @@ open_svr(char* svr)
|
||||
|
||||
/** write a query over the TCP fd */
|
||||
static void
|
||||
write_q(int fd, ldns_buffer* buf, int id,
|
||||
write_q(int fd, int udp, ldns_buffer* buf, int id,
|
||||
char* strname, char* strtype, char* strclass)
|
||||
{
|
||||
struct query_info qinfo;
|
||||
@@ -113,15 +123,26 @@ write_q(int fd, ldns_buffer* buf, int id,
|
||||
ldns_buffer_write_u16_at(buf, 2, BIT_RD);
|
||||
|
||||
/* send it */
|
||||
len = (uint16_t)ldns_buffer_limit(buf);
|
||||
len = htons(len);
|
||||
if(write(fd, &len, sizeof(len)) < (ssize_t)sizeof(len)) {
|
||||
perror("write() len failed");
|
||||
exit(1);
|
||||
if(!udp) {
|
||||
len = (uint16_t)ldns_buffer_limit(buf);
|
||||
len = htons(len);
|
||||
if(send(fd, (void*)&len, sizeof(len), 0)<(ssize_t)sizeof(len)){
|
||||
#ifndef USE_WINSOCK
|
||||
perror("send() len failed");
|
||||
#else
|
||||
printf("send len: %s\n",
|
||||
wsa_strerror(WSAGetLastError()));
|
||||
#endif
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
if(write(fd, ldns_buffer_begin(buf), ldns_buffer_limit(buf)) <
|
||||
if(send(fd, ldns_buffer_begin(buf), ldns_buffer_limit(buf), 0) <
|
||||
(ssize_t)ldns_buffer_limit(buf)) {
|
||||
perror("write() data failed");
|
||||
#ifndef USE_WINSOCK
|
||||
perror("send() data failed");
|
||||
#else
|
||||
printf("send data: %s\n", wsa_strerror(WSAGetLastError()));
|
||||
#endif
|
||||
exit(1);
|
||||
}
|
||||
|
||||
@@ -130,21 +151,48 @@ write_q(int fd, ldns_buffer* buf, int id,
|
||||
|
||||
/** receive DNS datagram over TCP and print it */
|
||||
static void
|
||||
recv_one(int fd, ldns_buffer* buf)
|
||||
recv_one(int fd, int udp, ldns_buffer* buf)
|
||||
{
|
||||
uint16_t len;
|
||||
ldns_pkt* pkt;
|
||||
ldns_status status;
|
||||
if(read(fd, &len, sizeof(len)) < (ssize_t)sizeof(len)) {
|
||||
perror("read() len failed");
|
||||
exit(1);
|
||||
}
|
||||
len = ntohs(len);
|
||||
ldns_buffer_clear(buf);
|
||||
ldns_buffer_set_limit(buf, len);
|
||||
if(read(fd, ldns_buffer_begin(buf), len) < (ssize_t)len) {
|
||||
perror("read() data failed");
|
||||
exit(1);
|
||||
if(!udp) {
|
||||
if(recv(fd, (void*)&len, sizeof(len), 0)<(ssize_t)sizeof(len)){
|
||||
#ifndef USE_WINSOCK
|
||||
perror("read() len failed");
|
||||
#else
|
||||
printf("read len: %s\n",
|
||||
wsa_strerror(WSAGetLastError()));
|
||||
#endif
|
||||
exit(1);
|
||||
}
|
||||
len = ntohs(len);
|
||||
ldns_buffer_clear(buf);
|
||||
ldns_buffer_set_limit(buf, len);
|
||||
if(recv(fd, ldns_buffer_begin(buf), len, 0) < (ssize_t)len) {
|
||||
#ifndef USE_WINSOCK
|
||||
perror("read() data failed");
|
||||
#else
|
||||
printf("read data: %s\n",
|
||||
wsa_strerror(WSAGetLastError()));
|
||||
#endif
|
||||
exit(1);
|
||||
}
|
||||
} else {
|
||||
ssize_t l;
|
||||
ldns_buffer_clear(buf);
|
||||
if((l=recv(fd, ldns_buffer_begin(buf),
|
||||
ldns_buffer_capacity(buf), 0)) < 0) {
|
||||
#ifndef USE_WINSOCK
|
||||
perror("read() data failed");
|
||||
#else
|
||||
printf("read data: %s\n",
|
||||
wsa_strerror(WSAGetLastError()));
|
||||
#endif
|
||||
exit(1);
|
||||
}
|
||||
ldns_buffer_set_limit(buf, (size_t)l);
|
||||
len = (size_t)l;
|
||||
}
|
||||
printf("\nnext received packet\n");
|
||||
log_buf(0, "data", buf);
|
||||
@@ -162,17 +210,18 @@ recv_one(int fd, ldns_buffer* buf)
|
||||
|
||||
/** send the TCP queries and print answers */
|
||||
static void
|
||||
send_em(char* svr, int num, char** qs)
|
||||
send_em(char* svr, int udp, int noanswer, int num, char** qs)
|
||||
{
|
||||
ldns_buffer* buf = ldns_buffer_new(65553);
|
||||
int fd = open_svr(svr);
|
||||
int fd = open_svr(svr, udp);
|
||||
int i;
|
||||
if(!buf) fatal_exit("out of memory");
|
||||
for(i=0; i<num; i+=3) {
|
||||
printf("\nNext query is %s %s %s\n", qs[i], qs[i+1], qs[i+2]);
|
||||
write_q(fd, buf, i, qs[i], qs[i+1], qs[i+2]);
|
||||
write_q(fd, udp, buf, i, qs[i], qs[i+1], qs[i+2]);
|
||||
/* print at least one result */
|
||||
recv_one(fd, buf);
|
||||
if(!noanswer)
|
||||
recv_one(fd, udp, buf);
|
||||
}
|
||||
|
||||
close(fd);
|
||||
@@ -180,6 +229,7 @@ send_em(char* svr, int num, char** qs)
|
||||
printf("orderly exit\n");
|
||||
}
|
||||
|
||||
#ifdef SIGPIPE
|
||||
/** SIGPIPE handler */
|
||||
static RETSIGTYPE sigh(int sig)
|
||||
{
|
||||
@@ -190,6 +240,7 @@ static RETSIGTYPE sigh(int sig)
|
||||
printf("Got unhandled signal %d\n", sig);
|
||||
exit(1);
|
||||
}
|
||||
#endif /* SIGPIPE */
|
||||
|
||||
/** getopt global, in case header files fail to declare it. */
|
||||
extern int optind;
|
||||
@@ -201,25 +252,43 @@ int main(int argc, char** argv)
|
||||
{
|
||||
int c;
|
||||
char* svr = "127.0.0.1";
|
||||
int udp = 0;
|
||||
int noanswer = 0;
|
||||
|
||||
#ifdef USE_WINSOCK
|
||||
WSADATA wsa_data;
|
||||
if(WSAStartup(MAKEWORD(2,2), &wsa_data) != 0) {
|
||||
printf("WSAStartup failed\n");
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* lock debug start (if any) */
|
||||
log_init(0, 0, 0);
|
||||
checklock_start();
|
||||
|
||||
#ifdef SIGPIPE
|
||||
if(signal(SIGPIPE, &sigh) == SIG_ERR) {
|
||||
perror("could not install signal handler");
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* command line options */
|
||||
if(argc == 1) {
|
||||
usage(argv);
|
||||
}
|
||||
while( (c=getopt(argc, argv, "f:h")) != -1) {
|
||||
while( (c=getopt(argc, argv, "f:hnu")) != -1) {
|
||||
switch(c) {
|
||||
case 'f':
|
||||
svr = optarg;
|
||||
break;
|
||||
case 'n':
|
||||
noanswer = 1;
|
||||
break;
|
||||
case 'u':
|
||||
udp = 1;
|
||||
break;
|
||||
case 'h':
|
||||
case '?':
|
||||
default:
|
||||
@@ -233,7 +302,10 @@ int main(int argc, char** argv)
|
||||
printf("queries must be multiples of name,type,class\n");
|
||||
return 1;
|
||||
}
|
||||
send_em(svr, argc, argv);
|
||||
send_em(svr, udp, noanswer, argc, argv);
|
||||
checklock_stop();
|
||||
#ifdef USE_WINSOCK
|
||||
WSACleanup();
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -127,8 +127,13 @@ setup_config(FILE* in, char* configfile, int* lineno,
|
||||
char line[MAX_LINE_LEN];
|
||||
char* parse;
|
||||
FILE* cfg;
|
||||
#ifdef USE_WINSOCK
|
||||
snprintf(configfile, MAX_LINE_LEN, "testbound_cfg_%u.tmp",
|
||||
(unsigned)getpid());
|
||||
#else
|
||||
snprintf(configfile, MAX_LINE_LEN, "/tmp/testbound_cfg_%u.tmp",
|
||||
(unsigned)getpid());
|
||||
#endif
|
||||
add_opts("-c", pass_argc, pass_argv);
|
||||
add_opts(configfile, pass_argc, pass_argv);
|
||||
cfg = fopen(configfile, "w");
|
||||
@@ -172,7 +177,7 @@ setup_playback(const char* filename, char* configfile,
|
||||
int lineno = 0;
|
||||
|
||||
if(filename) {
|
||||
FILE *in = fopen(filename, "r");
|
||||
FILE *in = fopen(filename, "rb");
|
||||
if(!in) {
|
||||
perror(filename);
|
||||
exit(1);
|
||||
|
||||
+23
-4
@@ -319,6 +319,7 @@ infra_test()
|
||||
struct infra_host_key* k;
|
||||
struct infra_host_data* d;
|
||||
int init = 376;
|
||||
int dlame, alame, olame;
|
||||
|
||||
slab = infra_create(cfg);
|
||||
unit_assert( infra_host(slab, (struct sockaddr_storage*)&one,
|
||||
@@ -343,15 +344,30 @@ infra_test()
|
||||
unit_assert( vs == 0 && to == init );
|
||||
|
||||
unit_assert( infra_set_lame(slab, (struct sockaddr_storage*)&one,
|
||||
(socklen_t)sizeof(int), zone, zonelen, now, 0) );
|
||||
(socklen_t)sizeof(int), zone, zonelen, now, 0,
|
||||
LDNS_RR_TYPE_A) );
|
||||
unit_assert( (d=infra_lookup_host(slab, (struct sockaddr_storage*)&one,
|
||||
(socklen_t)sizeof(int), 0, now, &k)) );
|
||||
unit_assert( d->ttl == now+cfg->host_ttl );
|
||||
unit_assert( d->edns_version == 0 );
|
||||
unit_assert( infra_lookup_lame(d, zone, zonelen, now)==1 );
|
||||
unit_assert( infra_lookup_lame(d, zone, zonelen, now,
|
||||
&dlame, &alame, &olame) );
|
||||
unit_assert(!dlame && alame && !olame);
|
||||
unit_assert( !infra_lookup_lame(d, zone, zonelen,
|
||||
now+cfg->lame_ttl+10) );
|
||||
unit_assert( !infra_lookup_lame(d, (uint8_t*)"\000", 1, now) );
|
||||
now+cfg->lame_ttl+10, &dlame, &alame, &olame) );
|
||||
unit_assert( !infra_lookup_lame(d, (uint8_t*)"\000", 1, now,
|
||||
&dlame, &alame, &olame) );
|
||||
lock_rw_unlock(&k->entry.lock);
|
||||
|
||||
/* test merge of data */
|
||||
unit_assert( infra_set_lame(slab, (struct sockaddr_storage*)&one,
|
||||
(socklen_t)sizeof(int), zone, zonelen, now, 0,
|
||||
LDNS_RR_TYPE_AAAA) );
|
||||
unit_assert( (d=infra_lookup_host(slab, (struct sockaddr_storage*)&one,
|
||||
(socklen_t)sizeof(int), 0, now, &k)) );
|
||||
unit_assert( infra_lookup_lame(d, zone, zonelen, now,
|
||||
&dlame, &alame, &olame) );
|
||||
unit_assert(!dlame && alame && olame);
|
||||
lock_rw_unlock(&k->entry.lock);
|
||||
|
||||
infra_delete(slab);
|
||||
@@ -394,6 +410,7 @@ main(int argc, char* argv[])
|
||||
return 1;
|
||||
}
|
||||
printf("Start of %s unit test.\n", PACKAGE_STRING);
|
||||
ERR_load_crypto_strings();
|
||||
checklock_start();
|
||||
rnd_test();
|
||||
verify_test();
|
||||
@@ -411,5 +428,7 @@ main(int argc, char* argv[])
|
||||
printf("%d checks ok.\n", testcount);
|
||||
EVP_cleanup();
|
||||
CRYPTO_cleanup_all_ex_data();
|
||||
ERR_remove_state(0);
|
||||
ERR_free_strings();
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -461,6 +461,13 @@ verify_test()
|
||||
{
|
||||
printf("verify test\n");
|
||||
verifytest_file("testdata/test_signatures.1", "20070818005004");
|
||||
verifytest_file("testdata/test_signatures.2", "20080414005004");
|
||||
verifytest_file("testdata/test_signatures.3", "20080416005004");
|
||||
verifytest_file("testdata/test_signatures.4", "20080416005004");
|
||||
verifytest_file("testdata/test_signatures.5", "20080416005004");
|
||||
verifytest_file("testdata/test_signatures.6", "20080416005004");
|
||||
verifytest_file("testdata/test_signatures.7", "20070829144150");
|
||||
verifytest_file("testdata/test_signatures.8", "20070829144150");
|
||||
dstest_file("testdata/test_ds_sig.1");
|
||||
nsectest();
|
||||
nsec3_hash_test("testdata/test_nsec3_hash.1");
|
||||
|
||||
Vendored
BIN
Binary file not shown.
Vendored
BIN
Binary file not shown.
Vendored
BIN
Binary file not shown.
Vendored
BIN
Binary file not shown.
Vendored
BIN
Binary file not shown.
Vendored
BIN
Binary file not shown.
Vendored
BIN
Binary file not shown.
Vendored
BIN
Binary file not shown.
Vendored
BIN
Binary file not shown.
Vendored
BIN
Binary file not shown.
Vendored
BIN
Binary file not shown.
Vendored
BIN
Binary file not shown.
Vendored
BIN
Binary file not shown.
Vendored
BIN
Binary file not shown.
Vendored
BIN
Binary file not shown.
Vendored
BIN
Binary file not shown.
Vendored
BIN
Binary file not shown.
Vendored
BIN
Binary file not shown.
Vendored
+124
@@ -0,0 +1,124 @@
|
||||
; config options
|
||||
stub-zone:
|
||||
name: "."
|
||||
stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
|
||||
CONFIG_END
|
||||
|
||||
SCENARIO_BEGIN Test double cname in reply.
|
||||
; this is in response to an error report from Robert Edmonds,
|
||||
; about resolution of images-na.ssl-images-amazon.com.
|
||||
|
||||
; K.ROOT-SERVERS.NET.
|
||||
RANGE_BEGIN 0 100
|
||||
ADDRESS 193.0.14.129
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname
|
||||
ADJUST copy_id
|
||||
REPLY QR NOERROR
|
||||
SECTION QUESTION
|
||||
. IN NS
|
||||
SECTION ANSWER
|
||||
. IN NS K.ROOT-SERVERS.NET.
|
||||
SECTION ADDITIONAL
|
||||
K.ROOT-SERVERS.NET. IN A 193.0.14.129
|
||||
ENTRY_END
|
||||
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname
|
||||
ADJUST copy_id
|
||||
REPLY QR NOERROR
|
||||
SECTION QUESTION
|
||||
www.example.com. IN A
|
||||
SECTION AUTHORITY
|
||||
com. IN NS a.gtld-servers.net.
|
||||
SECTION ADDITIONAL
|
||||
a.gtld-servers.net. IN A 192.5.6.30
|
||||
ENTRY_END
|
||||
RANGE_END
|
||||
|
||||
; a.gtld-servers.net.
|
||||
RANGE_BEGIN 0 100
|
||||
ADDRESS 192.5.6.30
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname
|
||||
ADJUST copy_id
|
||||
REPLY QR NOERROR
|
||||
SECTION QUESTION
|
||||
www.example.com. IN A
|
||||
SECTION AUTHORITY
|
||||
example.com. IN NS ns.example.com.
|
||||
SECTION ADDITIONAL
|
||||
ns.example.com. IN A 1.2.3.4
|
||||
ENTRY_END
|
||||
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname
|
||||
ADJUST copy_id
|
||||
REPLY QR NOERROR
|
||||
SECTION QUESTION
|
||||
www.next.com. IN A
|
||||
SECTION AUTHORITY
|
||||
next.com. IN NS ns.next.com.
|
||||
SECTION ADDITIONAL
|
||||
ns.next.com. IN A 1.2.3.5
|
||||
ENTRY_END
|
||||
RANGE_END
|
||||
|
||||
; ns.example.com.
|
||||
RANGE_BEGIN 0 100
|
||||
ADDRESS 1.2.3.4
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname
|
||||
ADJUST copy_id
|
||||
REPLY QR AA NOERROR
|
||||
SECTION QUESTION
|
||||
www.example.com. IN A
|
||||
SECTION ANSWER
|
||||
; two CNAMEs for one name?
|
||||
www.example.com. IN CNAME www.next.com.
|
||||
www.example.com. IN CNAME www.next.com.
|
||||
SECTION AUTHORITY
|
||||
example.com. IN NS ns.example.com.
|
||||
SECTION ADDITIONAL
|
||||
ns.example.com. IN A 1.2.3.4
|
||||
ENTRY_END
|
||||
RANGE_END
|
||||
|
||||
; ns.next.com.
|
||||
RANGE_BEGIN 0 100
|
||||
ADDRESS 1.2.3.5
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname
|
||||
ADJUST copy_id
|
||||
REPLY QR AA
|
||||
SECTION QUESTION
|
||||
www.next.com. IN A
|
||||
SECTION ANSWER
|
||||
www.next.com. IN A 10.20.30.40
|
||||
SECTION AUTHORITY
|
||||
SECTION ADDITIONAL
|
||||
ENTRY_END
|
||||
RANGE_END
|
||||
|
||||
STEP 1 QUERY
|
||||
ENTRY_BEGIN
|
||||
REPLY RD
|
||||
SECTION QUESTION
|
||||
www.example.com. IN A
|
||||
ENTRY_END
|
||||
|
||||
; recursion happens here.
|
||||
STEP 10 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all
|
||||
REPLY QR RD RA NOERROR
|
||||
SECTION QUESTION
|
||||
www.example.com. IN A
|
||||
SECTION ANSWER
|
||||
www.example.com. IN CNAME www.next.com.
|
||||
www.next.com. IN A 10.20.30.40
|
||||
SECTION AUTHORITY
|
||||
SECTION ADDITIONAL
|
||||
ENTRY_END
|
||||
|
||||
SCENARIO_END
|
||||
Vendored
+135
@@ -0,0 +1,135 @@
|
||||
; config options
|
||||
stub-zone:
|
||||
name: "."
|
||||
stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
|
||||
CONFIG_END
|
||||
|
||||
SCENARIO_BEGIN Test iterator lameness detection of AAAA-only lameness
|
||||
|
||||
; K.ROOT-SERVERS.NET.
|
||||
RANGE_BEGIN 0 100
|
||||
ADDRESS 193.0.14.129
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname
|
||||
ADJUST copy_id
|
||||
REPLY QR NOERROR
|
||||
SECTION QUESTION
|
||||
. IN NS
|
||||
SECTION ANSWER
|
||||
. IN NS K.ROOT-SERVERS.NET.
|
||||
SECTION ADDITIONAL
|
||||
K.ROOT-SERVERS.NET. IN A 193.0.14.129
|
||||
ENTRY_END
|
||||
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname
|
||||
ADJUST copy_id
|
||||
REPLY QR NOERROR
|
||||
SECTION QUESTION
|
||||
example.com. IN AAAA
|
||||
SECTION AUTHORITY
|
||||
com. IN NS a.gtld-servers.net.
|
||||
SECTION ADDITIONAL
|
||||
a.gtld-servers.net. IN A 192.5.6.30
|
||||
ENTRY_END
|
||||
RANGE_END
|
||||
|
||||
; a.gtld-servers.net.
|
||||
RANGE_BEGIN 0 100
|
||||
ADDRESS 192.5.6.30
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname
|
||||
ADJUST copy_id
|
||||
REPLY QR NOERROR
|
||||
SECTION QUESTION
|
||||
example.com. IN AAAA
|
||||
SECTION AUTHORITY
|
||||
example.com. IN NS ns.example.com.
|
||||
SECTION ADDITIONAL
|
||||
ns.example.com. IN A 1.2.3.4
|
||||
ENTRY_END
|
||||
RANGE_END
|
||||
|
||||
; ns.example.com.
|
||||
RANGE_BEGIN 0 100
|
||||
ADDRESS 1.2.3.4
|
||||
|
||||
; response to AAAA query
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname
|
||||
ADJUST copy_id
|
||||
REPLY QR AA NOERROR
|
||||
SECTION QUESTION
|
||||
example.com. IN AAAA
|
||||
SECTION ANSWER
|
||||
SECTION AUTHORITY
|
||||
. 3600000 IN NS a.root-servers.net.
|
||||
. 3600000 IN NS b.root-servers.net.
|
||||
. 3600000 IN NS c.root-servers.net.
|
||||
. 3600000 IN NS d.root-servers.net.
|
||||
. 3600000 IN NS e.root-servers.net.
|
||||
. 3600000 IN NS f.root-servers.net.
|
||||
. 3600000 IN NS g.root-servers.net.
|
||||
. 3600000 IN NS h.root-servers.net.
|
||||
. 3600000 IN NS i.root-servers.net.
|
||||
. 3600000 IN NS j.root-servers.net.
|
||||
. 3600000 IN NS k.root-servers.net.
|
||||
. 3600000 IN NS l.root-servers.net.
|
||||
. 3600000 IN NS m.root-servers.net.
|
||||
SECTION ADDITIONAL
|
||||
a.root-servers.net. 3600000 IN A 198.41.0.4
|
||||
b.root-servers.net. 3600000 IN A 128.9.0.107
|
||||
c.root-servers.net. 3600000 IN A 192.33.4.12
|
||||
ENTRY_END
|
||||
|
||||
; response to A query
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname
|
||||
ADJUST copy_id
|
||||
REPLY QR AA NOERROR
|
||||
SECTION QUESTION
|
||||
example.com. IN A
|
||||
SECTION ANSWER
|
||||
example.com. 120 IN A 204.14.213.188
|
||||
ENTRY_END
|
||||
RANGE_END
|
||||
|
||||
STEP 1 QUERY
|
||||
ENTRY_BEGIN
|
||||
MATCH TCP
|
||||
REPLY RD
|
||||
SECTION QUESTION
|
||||
example.com. IN AAAA
|
||||
ENTRY_END
|
||||
|
||||
; this fails; it is LAME
|
||||
STEP 10 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all
|
||||
REPLY QR RD RA SERVFAIL
|
||||
SECTION QUESTION
|
||||
example.com. IN AAAA
|
||||
SECTION ANSWER
|
||||
ENTRY_END
|
||||
|
||||
; Now try the A type, which works, and is not LAME.
|
||||
STEP 20 QUERY
|
||||
ENTRY_BEGIN
|
||||
MATCH TCP
|
||||
REPLY RD
|
||||
SECTION QUESTION
|
||||
example.com. IN A
|
||||
ENTRY_END
|
||||
|
||||
; this fails; it is LAME
|
||||
STEP 30 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all
|
||||
REPLY QR RD RA NOERROR
|
||||
SECTION QUESTION
|
||||
example.com. IN A
|
||||
SECTION ANSWER
|
||||
example.com. 120 IN A 204.14.213.188
|
||||
ENTRY_END
|
||||
|
||||
SCENARIO_END
|
||||
Vendored
+150
@@ -0,0 +1,150 @@
|
||||
; config options
|
||||
stub-zone:
|
||||
name: "."
|
||||
stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
|
||||
CONFIG_END
|
||||
|
||||
SCENARIO_BEGIN Test lame detection if AA bit is omitted
|
||||
; the query is answered with a reply that has
|
||||
; no AA bit
|
||||
; no SOA record
|
||||
; noanswer/noerror
|
||||
; NS record in there which is not a down delegation (==).
|
||||
; the query is not sent to a forward zone
|
||||
|
||||
STEP 10 QUERY
|
||||
ENTRY_BEGIN
|
||||
REPLY RD
|
||||
SECTION QUESTION
|
||||
www.example.com. IN A
|
||||
ENTRY_END
|
||||
|
||||
; root prime is sent
|
||||
STEP 20 CHECK_OUT_QUERY
|
||||
ENTRY_BEGIN
|
||||
MATCH qname qtype opcode
|
||||
SECTION QUESTION
|
||||
. IN NS
|
||||
ENTRY_END
|
||||
STEP 30 REPLY
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname
|
||||
ADJUST copy_id
|
||||
REPLY QR AA NOERROR
|
||||
SECTION QUESTION
|
||||
. IN NS
|
||||
SECTION ANSWER
|
||||
. IN NS K.ROOT-SERVERS.NET.
|
||||
SECTION ADDITIONAL
|
||||
K.ROOT-SERVERS.NET. IN A 193.0.14.129
|
||||
ENTRY_END
|
||||
|
||||
; query sent to root server
|
||||
STEP 40 CHECK_OUT_QUERY
|
||||
ENTRY_BEGIN
|
||||
MATCH qname qtype opcode
|
||||
SECTION QUESTION
|
||||
www.example.com. IN A
|
||||
ENTRY_END
|
||||
STEP 50 REPLY
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname
|
||||
ADJUST copy_id
|
||||
REPLY QR NOERROR
|
||||
SECTION QUESTION
|
||||
www.example.com. IN A
|
||||
SECTION AUTHORITY
|
||||
com. IN NS a.gtld-servers.net.
|
||||
SECTION ADDITIONAL
|
||||
a.gtld-servers.net. IN A 192.5.6.30
|
||||
ENTRY_END
|
||||
|
||||
; query sent to .com server
|
||||
STEP 60 CHECK_OUT_QUERY
|
||||
ENTRY_BEGIN
|
||||
MATCH qname qtype opcode
|
||||
SECTION QUESTION
|
||||
www.example.com. IN A
|
||||
ENTRY_END
|
||||
STEP 70 REPLY
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname
|
||||
ADJUST copy_id
|
||||
REPLY QR NOERROR
|
||||
SECTION QUESTION
|
||||
www.example.com. IN A
|
||||
SECTION AUTHORITY
|
||||
example.com. IN NS ns1.example.com.
|
||||
example.com. IN NS ns2.example.com.
|
||||
SECTION ADDITIONAL
|
||||
ns1.example.com. IN A 168.192.2.2
|
||||
ns2.example.com. IN A 168.192.3.3
|
||||
ENTRY_END
|
||||
|
||||
; no matter which one the iterator tries first, we present it as 'lame'
|
||||
; query to ns1.example.com or ns2.example.com.
|
||||
STEP 80 CHECK_OUT_QUERY
|
||||
ENTRY_BEGIN
|
||||
MATCH qname qtype opcode
|
||||
SECTION QUESTION
|
||||
www.example.com. IN A
|
||||
ENTRY_END
|
||||
STEP 90 REPLY
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname
|
||||
ADJUST copy_id
|
||||
REPLY QR NOERROR
|
||||
SECTION QUESTION
|
||||
www.example.com. IN A
|
||||
SECTION AUTHORITY
|
||||
; This is the BROKEN ANSWER here.
|
||||
; it is lame. A delegation to example.com. itself.
|
||||
example.com. IN NS ns1.example.com.
|
||||
example.com. IN NS ns2.example.com.
|
||||
SECTION ADDITIONAL
|
||||
ns1.example.com. IN A 168.192.2.2
|
||||
ns2.example.com. IN A 168.192.3.3
|
||||
ENTRY_END
|
||||
|
||||
; iterator should try again and ask the other nameserver.
|
||||
STEP 100 CHECK_OUT_QUERY
|
||||
ENTRY_BEGIN
|
||||
MATCH qname qtype opcode
|
||||
SECTION QUESTION
|
||||
www.example.com. IN A
|
||||
ENTRY_END
|
||||
STEP 110 REPLY
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname
|
||||
ADJUST copy_id
|
||||
REPLY QR AA NOERROR
|
||||
SECTION QUESTION
|
||||
www.example.com. IN A
|
||||
SECTION ANSWER
|
||||
www.example.com. IN A 10.20.30.40
|
||||
SECTION AUTHORITY
|
||||
example.com. IN NS ns1.example.com.
|
||||
example.com. IN NS ns2.example.com.
|
||||
SECTION ADDITIONAL
|
||||
ns1.example.com. IN A 168.192.2.2
|
||||
ns2.example.com. IN A 168.192.3.3
|
||||
ENTRY_END
|
||||
|
||||
; is the final answer correct?
|
||||
STEP 200 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all
|
||||
REPLY QR RD RA
|
||||
SECTION QUESTION
|
||||
www.example.com. IN A
|
||||
SECTION ANSWER
|
||||
www.example.com. IN A 10.20.30.40
|
||||
SECTION AUTHORITY
|
||||
example.com. IN NS ns1.example.com.
|
||||
example.com. IN NS ns2.example.com.
|
||||
SECTION ADDITIONAL
|
||||
ns1.example.com. IN A 168.192.2.2
|
||||
ns2.example.com. IN A 168.192.3.3
|
||||
ENTRY_END
|
||||
|
||||
SCENARIO_END
|
||||
Vendored
+91
@@ -0,0 +1,91 @@
|
||||
; config options
|
||||
stub-zone:
|
||||
name: "."
|
||||
stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
|
||||
CONFIG_END
|
||||
|
||||
SCENARIO_BEGIN Test a query name in the reply is required by resolver
|
||||
|
||||
; K.ROOT-SERVERS.NET.
|
||||
RANGE_BEGIN 0 100
|
||||
ADDRESS 193.0.14.129
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname
|
||||
ADJUST copy_id
|
||||
REPLY QR NOERROR
|
||||
SECTION QUESTION
|
||||
. IN NS
|
||||
SECTION ANSWER
|
||||
. IN NS K.ROOT-SERVERS.NET.
|
||||
SECTION ADDITIONAL
|
||||
K.ROOT-SERVERS.NET. IN A 193.0.14.129
|
||||
ENTRY_END
|
||||
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname
|
||||
ADJUST copy_id
|
||||
REPLY QR NOERROR
|
||||
SECTION QUESTION
|
||||
www.example.com. IN A
|
||||
SECTION AUTHORITY
|
||||
com. IN NS a.gtld-servers.net.
|
||||
SECTION ADDITIONAL
|
||||
a.gtld-servers.net. IN A 192.5.6.30
|
||||
ENTRY_END
|
||||
RANGE_END
|
||||
|
||||
; a.gtld-servers.net.
|
||||
RANGE_BEGIN 0 100
|
||||
ADDRESS 192.5.6.30
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname
|
||||
ADJUST copy_id
|
||||
REPLY QR NOERROR
|
||||
SECTION QUESTION
|
||||
www.example.com. IN A
|
||||
SECTION AUTHORITY
|
||||
example.com. IN NS ns.example.com.
|
||||
SECTION ADDITIONAL
|
||||
ns.example.com. IN A 1.2.3.4
|
||||
ENTRY_END
|
||||
RANGE_END
|
||||
|
||||
; ns.example.com.
|
||||
; always the same reply since we cannot match anything from the qsection.
|
||||
RANGE_BEGIN 0 100
|
||||
ADDRESS 1.2.3.4
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode
|
||||
ADJUST copy_id
|
||||
REPLY QR NOERROR
|
||||
SECTION QUESTION
|
||||
; no query section!
|
||||
; www.example.com. IN A
|
||||
SECTION ANSWER
|
||||
www.example.com. IN A 10.20.30.40
|
||||
SECTION AUTHORITY
|
||||
example.com. IN NS ns.example.com.
|
||||
SECTION ADDITIONAL
|
||||
ns.example.com. IN A 1.2.3.4
|
||||
ENTRY_END
|
||||
RANGE_END
|
||||
|
||||
STEP 1 QUERY
|
||||
ENTRY_BEGIN
|
||||
REPLY RD
|
||||
SECTION QUESTION
|
||||
www.example.com. IN A
|
||||
ENTRY_END
|
||||
|
||||
; recursion happens here.
|
||||
|
||||
; the query name is echoed properly to *our* client
|
||||
STEP 10 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all
|
||||
REPLY QR RD RA SERVFAIL
|
||||
SECTION QUESTION
|
||||
www.example.com. IN A
|
||||
ENTRY_END
|
||||
|
||||
SCENARIO_END
|
||||
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