mirror of https://github.com/getdnsapi/getdns.git
Merge branch 'features/zeroconf-dnssec' into release/v1.2.0
This commit is contained in:
commit
7c229c40cd
|
@ -2,6 +2,9 @@
|
|||
path = src/jsmn
|
||||
url = https://github.com/getdnsapi/jsmn.git
|
||||
branch = getdns
|
||||
[submodule "src/yxml"]
|
||||
path = src/yxml
|
||||
url = git://g.blicky.net/yxml.git
|
||||
[submodule "stubby"]
|
||||
path = stubby
|
||||
url = https://github.com/getdnsapi/stubby.git
|
||||
|
|
|
@ -12,6 +12,7 @@ addons:
|
|||
- check
|
||||
- libevent-dev
|
||||
- libev-dev
|
||||
- libuv-dev
|
||||
- valgrind
|
||||
- clang
|
||||
- wget
|
||||
|
|
|
@ -198,6 +198,7 @@ $(distdir):
|
|||
mkdir -p $(distdir)/src/gldns
|
||||
mkdir -p $(distdir)/src/tools
|
||||
mkdir -p $(distdir)/src/jsmn
|
||||
mkdir -p $(distdir)/src/yxml
|
||||
mkdir -p $(distdir)/doc
|
||||
mkdir -p $(distdir)/spec
|
||||
mkdir -p $(distdir)/spec/example
|
||||
|
@ -253,6 +254,9 @@ $(distdir):
|
|||
cp $(srcdir)/src/jsmn/*.[ch] $(distdir)/src/jsmn
|
||||
cp $(srcdir)/src/jsmn/LICENSE $(distdir)/src/jsmn
|
||||
cp $(srcdir)/src/jsmn/README.md $(distdir)/src/jsmn
|
||||
cp $(srcdir)/src/yxml/*.[ch] $(distdir)/src/yxml
|
||||
cp $(srcdir)/src/yxml/COPYING $(distdir)/src/yxml
|
||||
cp $(srcdir)/src/yxml/yxml.pod $(distdir)/src/yxml
|
||||
rm -f $(distdir)/Makefile $(distdir)/src/Makefile $(distdir)/src/getdns/getdns.h $(distdir)/spec/example/Makefile $(distdir)/src/test/Makefile $(distdir)/doc/Makefile $(distdir)/src/config.h
|
||||
|
||||
distcheck: $(distdir).tar.gz
|
||||
|
|
44
configure.ac
44
configure.ac
|
@ -163,7 +163,8 @@ AC_ARG_ENABLE(debug-stub, AC_HELP_STRING([--enable-debug-stub], [Enable stub deb
|
|||
AC_ARG_ENABLE(debug-daemon, AC_HELP_STRING([--enable-debug-daemon], [Enable daemon debugging messages]))
|
||||
AC_ARG_ENABLE(debug-sec, AC_HELP_STRING([--enable-debug-sec], [Enable dnssec debugging messages]))
|
||||
AC_ARG_ENABLE(debug-server, AC_HELP_STRING([--enable-debug-server], [Enable server debugging messages]))
|
||||
AC_ARG_ENABLE(all-debugging, AC_HELP_STRING([--enable-all-debugging], [Enable all debugging messages]))
|
||||
AC_ARG_ENABLE(debug-anchor, AC_HELP_STRING([--enable-debug-anchor], [Enable anchor debugging messages]))
|
||||
AC_ARG_ENABLE(all-debugging, AC_HELP_STRING([--enable-all-debugging], [Enable scheduling, stub and dnssec debugging]))
|
||||
case "$enable_all_debugging" in
|
||||
yes)
|
||||
enable_debug_req=yes
|
||||
|
@ -172,6 +173,7 @@ case "$enable_all_debugging" in
|
|||
enable_debug_daemon=yes
|
||||
enable_debug_sec=yes
|
||||
enable_debug_server=yes
|
||||
enable_debug_anchor=yes
|
||||
;;
|
||||
no|*)
|
||||
;;
|
||||
|
@ -218,6 +220,13 @@ case "$enable_debug_server" in
|
|||
no|*)
|
||||
;;
|
||||
esac
|
||||
case "$enable_debug_anchor" in
|
||||
yes)
|
||||
AC_DEFINE_UNQUOTED([ANCHOR_DEBUG], [1], [Define this enable printing of anchor debugging messages.])
|
||||
;;
|
||||
no|*)
|
||||
;;
|
||||
esac
|
||||
|
||||
|
||||
dnl Hidden debugging options
|
||||
|
@ -281,6 +290,33 @@ case "$enable_native_stub_dnssec" in
|
|||
;;
|
||||
esac
|
||||
|
||||
# check wether strptime also works
|
||||
AC_DEFUN([AC_CHECK_STRPTIME_WORKS],
|
||||
[AC_REQUIRE([AC_PROG_CC])
|
||||
AC_MSG_CHECKING(whether strptime works)
|
||||
if test c${cross_compiling} = cno; then
|
||||
AC_RUN_IFELSE([AC_LANG_SOURCE([[
|
||||
#define _XOPEN_SOURCE 600
|
||||
#include <time.h>
|
||||
int main(void) { struct tm tm; char *res;
|
||||
res = strptime("2010-07-15T00:00:00+00:00", "%t%Y%t-%t%m%t-%t%d%tT%t%H%t:%t%M%t:%t%S%t", &tm);
|
||||
if (!res) return 2;
|
||||
res = strptime("20070207111842", "%Y%m%d%H%M%S", &tm);
|
||||
if (!res) return 1; return 0; }
|
||||
]])] , [eval "ac_cv_c_strptime_works=yes"], [eval "ac_cv_c_strptime_works=no"])
|
||||
else
|
||||
eval "ac_cv_c_strptime_works=maybe"
|
||||
fi
|
||||
AC_MSG_RESULT($ac_cv_c_strptime_works)
|
||||
if test $ac_cv_c_strptime_works = no; then
|
||||
AC_LIBOBJ(strptime)
|
||||
else
|
||||
AC_DEFINE_UNQUOTED([STRPTIME_WORKS], 1, [use default strptime.])
|
||||
fi
|
||||
])dnl
|
||||
|
||||
AC_CHECK_FUNCS([strptime],[AC_CHECK_STRPTIME_WORKS],[AC_LIBOBJ([strptime])])
|
||||
|
||||
# search to set include and library paths right
|
||||
# find libidn (no libidn on windows though)
|
||||
AC_CHECK_HEADERS([windows.h winsock.h stdio.h winsock2.h ws2tcpip.h],,, [AC_INCLUDES_DEFAULT])
|
||||
|
@ -1438,6 +1474,12 @@ static inline int _gldns_custom_vsnprintf(char *str, size_t size, const char *fo
|
|||
# endif
|
||||
#endif
|
||||
|
||||
#if !defined(HAVE_STRPTIME) || !defined(STRPTIME_WORKS)
|
||||
#define strptime unbound_strptime
|
||||
struct tm;
|
||||
char *strptime(const char *s, const char *format, struct tm *tm);
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_LIBUNBOUND
|
||||
# include <unbound.h>
|
||||
# ifdef HAVE_UNBOUND_EVENT_H
|
||||
|
|
|
@ -91,12 +91,13 @@ COMPAT_OBJ=$(LIBOBJS:.o=.lo)
|
|||
UTIL_OBJ=rbtree.lo val_secalgo.lo lruhash.lo lookup3.lo locks.lo
|
||||
|
||||
JSMN_OBJ=jsmn.lo
|
||||
YXML_OBJ=yxml.lo
|
||||
|
||||
YAML_OBJ=convert_yaml_to_json.lo
|
||||
|
||||
EXTENSION_OBJ=$(DEFAULT_EVENTLOOP_OBJ) libevent.lo libev.lo
|
||||
|
||||
NON_C99_OBJS=context.lo libuv.lo
|
||||
NON_C99_OBJS=libuv.lo context.lo anchor.lo
|
||||
|
||||
.SUFFIXES: .c .o .a .lo .h
|
||||
|
||||
|
@ -128,9 +129,15 @@ $(JSMN_OBJ):
|
|||
$(YAML_OBJ):
|
||||
$(LIBTOOL) --quiet --tag=CC --mode=compile $(CC) $(CFLAGS) -c $(srcdir)/yaml/$(@:.lo=.c) -o $@
|
||||
|
||||
$(YXML_OBJ):
|
||||
$(LIBTOOL) --quiet --tag=CC --mode=compile $(CC) $(CFLAGS) -I$(srcdir)/yxml -DYXML_GETDNS -Wno-unused-parameter -c $(srcdir)/yxml/$(@:.lo=.c) -o $@
|
||||
|
||||
$(EXTENSION_OBJ):
|
||||
$(LIBTOOL) --quiet --tag=CC --mode=compile $(CC) $(CFLAGS) $(WPEDANTICFLAG) -c $(srcdir)/extension/$(@:.lo=.c) -o $@
|
||||
|
||||
anchor.lo:
|
||||
$(LIBTOOL) --quiet --tag=CC --mode=compile $(CC) $(CFLAGS) $(WPEDANTICFLAG) $(C99COMPATFLAGS) -c $(srcdir)/anchor.c -o anchor.lo
|
||||
|
||||
context.lo:
|
||||
$(LIBTOOL) --quiet --tag=CC --mode=compile $(CC) $(CFLAGS) $(WPEDANTICFLAG) $(C99COMPATFLAGS) -c $(srcdir)/context.c -o context.lo
|
||||
|
||||
|
@ -177,9 +184,8 @@ libgetdns_ext_uv.la: libgetdns.la libuv.lo
|
|||
libgetdns_ext_ev.la: libgetdns.la libev.lo
|
||||
$(LIBTOOL) --tag=CC --mode=link $(CC) -o $@ libev.lo libgetdns.la $(LDFLAGS) $(EXTENSION_LIBEV_LDFLAGS) $(EXTENSION_LIBEV_EXT_LIBS) -rpath $(libdir) -version-info $(libversion) -no-undefined -export-symbols $(srcdir)/extension/libev.symbols
|
||||
|
||||
|
||||
libgetdns.la: $(GETDNS_OBJ) version.lo context.lo $(DEFAULT_EVENTLOOP_OBJ) $(GLDNS_OBJ) $(COMPAT_OBJ) $(UTIL_OBJ) $(JSMN_OBJ) $(YAML_OBJ)
|
||||
$(LIBTOOL) --tag=CC --mode=link $(CC) -o $@ $(GETDNS_OBJ) version.lo context.lo $(DEFAULT_EVENTLOOP_OBJ) $(GLDNS_OBJ) $(COMPAT_OBJ) $(UTIL_OBJ) $(JSMN_OBJ) $(YAML_OBJ) $(LDFLAGS) -rpath $(libdir) -version-info $(libversion) -no-undefined -export-symbols $(srcdir)/libgetdns.symbols
|
||||
libgetdns.la: $(GETDNS_OBJ) version.lo context.lo anchor.lo $(DEFAULT_EVENTLOOP_OBJ) $(GLDNS_OBJ) $(COMPAT_OBJ) $(UTIL_OBJ) $(JSMN_OBJ) $(YXML_OBJ) $(YAML_OBJ)
|
||||
$(LIBTOOL) --tag=CC --mode=link $(CC) -o $@ $(GETDNS_OBJ) version.lo context.lo anchor.lo $(DEFAULT_EVENTLOOP_OBJ) $(GLDNS_OBJ) $(COMPAT_OBJ) $(UTIL_OBJ) $(JSMN_OBJ) $(YXML_OBJ) $(YAML_OBJ) $(LDFLAGS) -rpath $(libdir) -version-info $(libversion) -no-undefined -export-symbols $(srcdir)/libgetdns.symbols
|
||||
|
||||
test: default
|
||||
cd test && $(MAKE) $@
|
||||
|
@ -231,7 +237,8 @@ Makefile: $(srcdir)/Makefile.in ../config.status
|
|||
|
||||
depend:
|
||||
(cd $(srcdir) ; awk 'BEGIN{P=1}{if(P)print}/^# Dependencies/{P=0}' Makefile.in > Makefile.in.new )
|
||||
(blddir=`pwd`; cd $(srcdir) ; gcc -MM -I. -I"$$blddir" -Iutil/auxiliary *.c gldns/*.c compat/*.c util/*.c jsmn/*.c yaml/*.c extension/*.c| \
|
||||
|
||||
(blddir=`pwd`; cd $(srcdir) ; gcc -MM -I. -I"$$blddir" -Iyxml -Iutil/auxiliary *.c gldns/*.c compat/*.c util/*.c jsmn/*.c yxml/*.c yaml/*.c extension/*.c| \
|
||||
sed -e "s? $$blddir/? ?g" \
|
||||
-e 's? gldns/? $$(srcdir)/gldns/?g' \
|
||||
-e 's? compat/? $$(srcdir)/compat/?g' \
|
||||
|
@ -239,6 +246,7 @@ depend:
|
|||
-e 's? util/? $$(srcdir)/util/?g' \
|
||||
-e 's? jsmn/? $$(srcdir)/jsmn/?g' \
|
||||
-e 's? yaml/? $$(srcdir)/yaml/?g' \
|
||||
-e 's? yxml/? $$(srcdir)/yxml/?g' \
|
||||
-e 's? extension/? $$(srcdir)/extension/?g' \
|
||||
-e 's? \([a-z_-]*\)\.\([ch]\)? $$(srcdir)/\1.\2?g' \
|
||||
-e 's? \$$(srcdir)/config\.h? config.h?g' \
|
||||
|
@ -257,21 +265,34 @@ depend:
|
|||
FORCE:
|
||||
|
||||
# Dependencies for gldns, utils, the extensions and compat functions
|
||||
anchor.lo anchor.o: $(srcdir)/anchor.c \
|
||||
config.h \
|
||||
$(srcdir)/debug.h $(srcdir)/anchor.h \
|
||||
getdns/getdns.h \
|
||||
getdns/getdns_extra.h \
|
||||
$(srcdir)/types-internal.h $(srcdir)/util/rbtree.h $(srcdir)/util/orig-headers/rbtree.h $(srcdir)/context.h \
|
||||
$(srcdir)/extension/default_eventloop.h $(srcdir)/extension/poll_eventloop.h \
|
||||
$(srcdir)/types-internal.h $(srcdir)/ub_loop.h $(srcdir)/server.h $(srcdir)/util/lruhash.h \
|
||||
$(srcdir)/util/orig-headers/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/orig-headers/locks.h \
|
||||
$(srcdir)/util/auxiliary/util/log.h $(srcdir)/debug.h $(srcdir)/rr-iter.h $(srcdir)/rr-dict.h $(srcdir)/gldns/gbuffer.h \
|
||||
$(srcdir)/gldns/pkthdr.h $(srcdir)/dnssec.h $(srcdir)/gldns/rrdef.h $(srcdir)/yxml/yxml.h $(srcdir)/gldns/parseutil.h \
|
||||
$(srcdir)/gldns/str2wire.h $(srcdir)/gldns/rrdef.h $(srcdir)/general.h $(srcdir)/util-internal.h
|
||||
const-info.lo const-info.o: $(srcdir)/const-info.c \
|
||||
getdns/getdns.h \
|
||||
getdns/getdns_extra.h \
|
||||
$(srcdir)/const-info.h
|
||||
context.lo context.o: $(srcdir)/context.c \
|
||||
config.h \
|
||||
$(srcdir)/debug.h $(srcdir)/gldns/str2wire.h $(srcdir)/gldns/rrdef.h $(srcdir)/gldns/wire2str.h $(srcdir)/context.h \
|
||||
$(srcdir)/anchor.h \
|
||||
getdns/getdns.h \
|
||||
getdns/getdns_extra.h \
|
||||
$(srcdir)/debug.h $(srcdir)/gldns/str2wire.h $(srcdir)/gldns/rrdef.h $(srcdir)/gldns/wire2str.h $(srcdir)/context.h \
|
||||
$(srcdir)/types-internal.h $(srcdir)/util/rbtree.h $(srcdir)/util/orig-headers/rbtree.h \
|
||||
$(srcdir)/extension/default_eventloop.h $(srcdir)/extension/poll_eventloop.h \
|
||||
$(srcdir)/types-internal.h $(srcdir)/ub_loop.h $(srcdir)/server.h $(srcdir)/util/lruhash.h \
|
||||
$(srcdir)/util/orig-headers/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/orig-headers/locks.h \
|
||||
$(srcdir)/util/auxiliary/util/log.h $(srcdir)/debug.h $(srcdir)/util-internal.h $(srcdir)/rr-iter.h $(srcdir)/rr-dict.h \
|
||||
$(srcdir)/gldns/gbuffer.h $(srcdir)/gldns/pkthdr.h $(srcdir)/dnssec.h $(srcdir)/gldns/rrdef.h $(srcdir)/stub.h $(srcdir)/list.h \
|
||||
$(srcdir)/util/auxiliary/util/log.h $(srcdir)/debug.h $(srcdir)/rr-iter.h $(srcdir)/rr-dict.h $(srcdir)/gldns/gbuffer.h \
|
||||
$(srcdir)/gldns/pkthdr.h $(srcdir)/util-internal.h $(srcdir)/dnssec.h $(srcdir)/gldns/rrdef.h $(srcdir)/stub.h $(srcdir)/list.h \
|
||||
$(srcdir)/dict.h $(srcdir)/pubkey-pinning.h
|
||||
convert.lo convert.o: $(srcdir)/convert.c \
|
||||
config.h \
|
||||
|
@ -307,11 +328,11 @@ dnssec.lo dnssec.o: $(srcdir)/dnssec.c \
|
|||
$(srcdir)/extension/default_eventloop.h $(srcdir)/extension/poll_eventloop.h \
|
||||
$(srcdir)/types-internal.h $(srcdir)/ub_loop.h $(srcdir)/server.h $(srcdir)/util/lruhash.h \
|
||||
$(srcdir)/util/orig-headers/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/orig-headers/locks.h \
|
||||
$(srcdir)/util/auxiliary/util/log.h $(srcdir)/debug.h $(srcdir)/util-internal.h $(srcdir)/rr-iter.h $(srcdir)/rr-dict.h \
|
||||
$(srcdir)/gldns/gbuffer.h $(srcdir)/gldns/pkthdr.h $(srcdir)/dnssec.h $(srcdir)/gldns/rrdef.h $(srcdir)/gldns/str2wire.h \
|
||||
$(srcdir)/util/auxiliary/util/log.h $(srcdir)/debug.h $(srcdir)/rr-iter.h $(srcdir)/rr-dict.h $(srcdir)/gldns/gbuffer.h \
|
||||
$(srcdir)/gldns/pkthdr.h $(srcdir)/util-internal.h $(srcdir)/dnssec.h $(srcdir)/gldns/rrdef.h $(srcdir)/gldns/str2wire.h \
|
||||
$(srcdir)/gldns/rrdef.h $(srcdir)/gldns/wire2str.h $(srcdir)/gldns/keyraw.h $(srcdir)/gldns/parseutil.h \
|
||||
$(srcdir)/general.h $(srcdir)/dict.h $(srcdir)/list.h $(srcdir)/util/val_secalgo.h \
|
||||
$(srcdir)/util/orig-headers/val_secalgo.h
|
||||
$(srcdir)/util/orig-headers/val_secalgo.h $(srcdir)/anchor.h
|
||||
general.lo general.o: $(srcdir)/general.c \
|
||||
config.h \
|
||||
$(srcdir)/general.h \
|
||||
|
@ -322,9 +343,9 @@ general.lo general.o: $(srcdir)/general.c \
|
|||
$(srcdir)/gldns/wire2str.h $(srcdir)/context.h $(srcdir)/extension/default_eventloop.h \
|
||||
$(srcdir)/extension/poll_eventloop.h $(srcdir)/types-internal.h $(srcdir)/server.h $(srcdir)/util/lruhash.h \
|
||||
$(srcdir)/util/orig-headers/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/orig-headers/locks.h \
|
||||
$(srcdir)/util/auxiliary/util/log.h $(srcdir)/debug.h $(srcdir)/util-internal.h $(srcdir)/rr-iter.h $(srcdir)/rr-dict.h \
|
||||
$(srcdir)/gldns/gbuffer.h $(srcdir)/gldns/pkthdr.h $(srcdir)/dnssec.h $(srcdir)/gldns/rrdef.h $(srcdir)/stub.h $(srcdir)/dict.h \
|
||||
$(srcdir)/mdns.h
|
||||
$(srcdir)/util/auxiliary/util/log.h $(srcdir)/debug.h $(srcdir)/rr-iter.h $(srcdir)/rr-dict.h $(srcdir)/gldns/gbuffer.h \
|
||||
$(srcdir)/gldns/pkthdr.h $(srcdir)/util-internal.h $(srcdir)/dnssec.h $(srcdir)/gldns/rrdef.h $(srcdir)/stub.h $(srcdir)/dict.h \
|
||||
$(srcdir)/mdns.h $(srcdir)/anchor.h
|
||||
list.lo list.o: $(srcdir)/list.c $(srcdir)/types-internal.h \
|
||||
getdns/getdns.h \
|
||||
getdns/getdns_extra.h \
|
||||
|
@ -344,8 +365,8 @@ mdns.lo mdns.o: $(srcdir)/mdns.c \
|
|||
$(srcdir)/extension/default_eventloop.h $(srcdir)/extension/poll_eventloop.h \
|
||||
$(srcdir)/types-internal.h $(srcdir)/ub_loop.h $(srcdir)/server.h $(srcdir)/util/lruhash.h \
|
||||
$(srcdir)/util/orig-headers/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/orig-headers/locks.h \
|
||||
$(srcdir)/util/auxiliary/util/log.h $(srcdir)/debug.h $(srcdir)/general.h $(srcdir)/gldns/pkthdr.h $(srcdir)/gldns/rrdef.h \
|
||||
$(srcdir)/util-internal.h $(srcdir)/rr-iter.h $(srcdir)/rr-dict.h $(srcdir)/gldns/gbuffer.h $(srcdir)/mdns.h \
|
||||
$(srcdir)/util/auxiliary/util/log.h $(srcdir)/debug.h $(srcdir)/rr-iter.h $(srcdir)/rr-dict.h $(srcdir)/gldns/gbuffer.h \
|
||||
$(srcdir)/gldns/pkthdr.h $(srcdir)/general.h $(srcdir)/gldns/rrdef.h $(srcdir)/util-internal.h $(srcdir)/mdns.h \
|
||||
$(srcdir)/util/auxiliary/util/fptr_wlist.h $(srcdir)/util/lookup3.h \
|
||||
$(srcdir)/util/orig-headers/lookup3.h
|
||||
pubkey-pinning.lo pubkey-pinning.o: $(srcdir)/pubkey-pinning.c \
|
||||
|
@ -358,8 +379,8 @@ pubkey-pinning.lo pubkey-pinning.o: $(srcdir)/pubkey-pinning.c \
|
|||
$(srcdir)/extension/default_eventloop.h $(srcdir)/extension/poll_eventloop.h \
|
||||
$(srcdir)/types-internal.h $(srcdir)/ub_loop.h $(srcdir)/server.h $(srcdir)/util/lruhash.h \
|
||||
$(srcdir)/util/orig-headers/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/orig-headers/locks.h \
|
||||
$(srcdir)/util/auxiliary/util/log.h $(srcdir)/debug.h $(srcdir)/util-internal.h $(srcdir)/rr-iter.h $(srcdir)/rr-dict.h \
|
||||
$(srcdir)/gldns/gbuffer.h $(srcdir)/gldns/pkthdr.h
|
||||
$(srcdir)/util/auxiliary/util/log.h $(srcdir)/debug.h $(srcdir)/rr-iter.h $(srcdir)/rr-dict.h $(srcdir)/gldns/gbuffer.h \
|
||||
$(srcdir)/gldns/pkthdr.h $(srcdir)/util-internal.h
|
||||
request-internal.lo request-internal.o: $(srcdir)/request-internal.c \
|
||||
config.h \
|
||||
$(srcdir)/types-internal.h \
|
||||
|
@ -394,7 +415,8 @@ server.lo server.o: $(srcdir)/server.c \
|
|||
$(srcdir)/extension/default_eventloop.h $(srcdir)/extension/poll_eventloop.h \
|
||||
$(srcdir)/types-internal.h $(srcdir)/ub_loop.h $(srcdir)/debug.h $(srcdir)/server.h $(srcdir)/util/lruhash.h \
|
||||
$(srcdir)/util/orig-headers/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/orig-headers/locks.h \
|
||||
$(srcdir)/util/auxiliary/util/log.h $(srcdir)/debug.h
|
||||
$(srcdir)/util/auxiliary/util/log.h $(srcdir)/debug.h $(srcdir)/rr-iter.h $(srcdir)/rr-dict.h $(srcdir)/gldns/gbuffer.h \
|
||||
$(srcdir)/gldns/pkthdr.h
|
||||
stub.lo stub.o: $(srcdir)/stub.c \
|
||||
config.h \
|
||||
$(srcdir)/debug.h $(srcdir)/stub.h \
|
||||
|
@ -417,8 +439,8 @@ sync.lo sync.o: $(srcdir)/sync.c \
|
|||
$(srcdir)/extension/default_eventloop.h $(srcdir)/extension/poll_eventloop.h \
|
||||
$(srcdir)/types-internal.h $(srcdir)/ub_loop.h $(srcdir)/debug.h $(srcdir)/server.h $(srcdir)/util/lruhash.h \
|
||||
$(srcdir)/util/orig-headers/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/orig-headers/locks.h \
|
||||
$(srcdir)/util/auxiliary/util/log.h $(srcdir)/debug.h $(srcdir)/general.h $(srcdir)/util-internal.h $(srcdir)/rr-iter.h \
|
||||
$(srcdir)/rr-dict.h $(srcdir)/gldns/gbuffer.h $(srcdir)/gldns/pkthdr.h $(srcdir)/dnssec.h $(srcdir)/gldns/rrdef.h $(srcdir)/stub.h \
|
||||
$(srcdir)/util/auxiliary/util/log.h $(srcdir)/debug.h $(srcdir)/rr-iter.h $(srcdir)/rr-dict.h $(srcdir)/gldns/gbuffer.h \
|
||||
$(srcdir)/gldns/pkthdr.h $(srcdir)/general.h $(srcdir)/util-internal.h $(srcdir)/dnssec.h $(srcdir)/gldns/rrdef.h $(srcdir)/stub.h \
|
||||
$(srcdir)/gldns/wire2str.h
|
||||
ub_loop.lo ub_loop.o: $(srcdir)/ub_loop.c $(srcdir)/ub_loop.h \
|
||||
config.h \
|
||||
|
@ -485,6 +507,8 @@ sha512.lo sha512.o: $(srcdir)/compat/sha512.c \
|
|||
config.h
|
||||
strlcpy.lo strlcpy.o: $(srcdir)/compat/strlcpy.c \
|
||||
config.h
|
||||
strptime.lo strptime.o: $(srcdir)/compat/strptime.c \
|
||||
config.h
|
||||
locks.lo locks.o: $(srcdir)/util/locks.c \
|
||||
config.h \
|
||||
$(srcdir)/util/locks.h $(srcdir)/util/orig-headers/locks.h $(srcdir)/util/auxiliary/util/log.h $(srcdir)/debug.h
|
||||
|
@ -511,6 +535,7 @@ val_secalgo.lo val_secalgo.o: $(srcdir)/util/val_secalgo.c \
|
|||
$(srcdir)/gldns/rrdef.h $(srcdir)/util/auxiliary/sldns/keyraw.h $(srcdir)/gldns/keyraw.h \
|
||||
$(srcdir)/util/auxiliary/sldns/sbuffer.h $(srcdir)/gldns/gbuffer.h
|
||||
jsmn.lo jsmn.o: $(srcdir)/jsmn/jsmn.c $(srcdir)/jsmn/jsmn.h
|
||||
yxml.lo yxml.o: $(srcdir)/yxml/yxml.c $(srcdir)/yxml/yxml.h
|
||||
libev.lo libev.o: $(srcdir)/extension/libev.c \
|
||||
config.h \
|
||||
$(srcdir)/types-internal.h \
|
||||
|
@ -540,4 +565,4 @@ select_eventloop.lo select_eventloop.o: $(srcdir)/extension/select_eventloop.c \
|
|||
$(srcdir)/extension/select_eventloop.h \
|
||||
getdns/getdns.h \
|
||||
getdns/getdns_extra.h \
|
||||
$(srcdir)/debug.h $(srcdir)/types-internal.h $(srcdir)/util/rbtree.h $(srcdir)/util/orig-headers/rbtree.h
|
||||
$(srcdir)/types-internal.h $(srcdir)/util/rbtree.h $(srcdir)/util/orig-headers/rbtree.h $(srcdir)/debug.h
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,59 @@
|
|||
/**
|
||||
*
|
||||
* /brief functions for DNSSEC trust anchor management
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 2017, NLnet Labs
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the names of the copyright holders nor the
|
||||
* names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL Verisign, Inc. BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef ANCHOR_H_
|
||||
#define ANCHOR_H_
|
||||
|
||||
#include "getdns/getdns.h"
|
||||
#include "getdns/getdns_extra.h"
|
||||
#include <time.h>
|
||||
#include "rr-iter.h"
|
||||
|
||||
void _getdns_context_equip_with_anchor(getdns_context *context, uint64_t *now_ms);
|
||||
|
||||
void _getdns_start_fetching_ta(getdns_context *context, getdns_eventloop *loop);
|
||||
|
||||
#define MAX_KSKS 16
|
||||
#define RRSIG_RDATA_LEN 16
|
||||
typedef struct _getdns_ksks {
|
||||
size_t n;
|
||||
uint16_t ids[MAX_KSKS];
|
||||
size_t n_rrsigs;
|
||||
uint8_t rrsigs[MAX_KSKS][RRSIG_RDATA_LEN];
|
||||
} _getdns_ksks;
|
||||
|
||||
void _getdns_context_update_root_ksk(
|
||||
getdns_context *context, _getdns_rrset *dnskey_set);
|
||||
|
||||
#endif
|
||||
/* anchor.h */
|
|
@ -0,0 +1,345 @@
|
|||
/** strptime workaround (for oa macos leopard)
|
||||
* This strptime follows the man strptime (2001-11-12)
|
||||
* conforming to SUSv2, POSIX.1-2001
|
||||
*
|
||||
* This very simple version of strptime has no:
|
||||
* - E alternatives
|
||||
* - O alternatives
|
||||
* - Glibc additions
|
||||
* - Does not process week numbers
|
||||
* - Does not properly processes year day
|
||||
*
|
||||
* LICENSE
|
||||
* Copyright (c) 2008, NLnet Labs, Matthijs Mekking
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* * Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of NLnetLabs nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
**/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#ifndef HAVE_CONFIG_H
|
||||
#include <time.h>
|
||||
#endif
|
||||
|
||||
#ifndef STRPTIME_WORKS
|
||||
|
||||
#define TM_YEAR_BASE 1900
|
||||
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
|
||||
static const char *abb_weekdays[] = {
|
||||
"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", NULL
|
||||
};
|
||||
static const char *full_weekdays[] = {
|
||||
"Sunday", "Monday", "Tuesday", "Wednesday",
|
||||
"Thursday", "Friday", "Saturday", NULL
|
||||
};
|
||||
static const char *abb_months[] = {
|
||||
"Jan", "Feb", "Mar", "Apr", "May", "Jun",
|
||||
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec", NULL
|
||||
};
|
||||
static const char *full_months[] = {
|
||||
"January", "February", "March", "April", "May", "June",
|
||||
"July", "August", "September", "October", "November", "December", NULL
|
||||
};
|
||||
static const char *ampm[] = {
|
||||
"am", "pm", NULL
|
||||
};
|
||||
|
||||
static int
|
||||
match_string(const char **buf, const char **strs)
|
||||
{
|
||||
int i = 0;
|
||||
|
||||
for (i = 0; strs[i] != NULL; i++) {
|
||||
int len = strlen(strs[i]);
|
||||
if (strncasecmp (*buf, strs[i], len) == 0) {
|
||||
*buf += len;
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int
|
||||
str2int(const char **buf, int max)
|
||||
{
|
||||
int ret=0, count=0;
|
||||
|
||||
while (*buf[0] != '\0' && isdigit((unsigned char)*buf[0]) && count<max) {
|
||||
ret = ret*10 + (*buf[0] - '0');
|
||||
(*buf)++;
|
||||
count++;
|
||||
}
|
||||
|
||||
if (!count)
|
||||
return -1;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/** Converts the character string s to values which are stored in tm
|
||||
* using the format specified by format
|
||||
**/
|
||||
char *
|
||||
unbound_strptime(const char *s, const char *format, struct tm *tm)
|
||||
{
|
||||
int c, ret;
|
||||
int split_year = 0;
|
||||
|
||||
while ((c = *format) != '\0') {
|
||||
/* whitespace, literal or format */
|
||||
if (isspace((unsigned char)c)) { /* whitespace */
|
||||
/** whitespace matches zero or more whitespace characters in the
|
||||
* input string.
|
||||
**/
|
||||
while (isspace((unsigned char)*s))
|
||||
s++;
|
||||
}
|
||||
else if (c == '%') { /* format */
|
||||
format++;
|
||||
c = *format;
|
||||
switch (c) {
|
||||
case '%': /* %% is converted to % */
|
||||
if (*s != c) {
|
||||
return NULL;
|
||||
}
|
||||
s++;
|
||||
break;
|
||||
case 'a': /* weekday name, abbreviated or full */
|
||||
case 'A':
|
||||
ret = match_string(&s, full_weekdays);
|
||||
if (ret < 0)
|
||||
ret = match_string(&s, abb_weekdays);
|
||||
if (ret < 0) {
|
||||
return NULL;
|
||||
}
|
||||
tm->tm_wday = ret;
|
||||
break;
|
||||
case 'b': /* month name, abbreviated or full */
|
||||
case 'B':
|
||||
case 'h':
|
||||
ret = match_string(&s, full_months);
|
||||
if (ret < 0)
|
||||
ret = match_string(&s, abb_months);
|
||||
if (ret < 0) {
|
||||
return NULL;
|
||||
}
|
||||
tm->tm_mon = ret;
|
||||
break;
|
||||
case 'c': /* date and time representation */
|
||||
if (!(s = unbound_strptime(s, "%x %X", tm))) {
|
||||
return NULL;
|
||||
}
|
||||
break;
|
||||
case 'C': /* century number */
|
||||
ret = str2int(&s, 2);
|
||||
if (ret < 0 || ret > 99) { /* must be in [00,99] */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (split_year) {
|
||||
tm->tm_year = ret*100 + (tm->tm_year%100);
|
||||
}
|
||||
else {
|
||||
tm->tm_year = ret*100 - TM_YEAR_BASE;
|
||||
split_year = 1;
|
||||
}
|
||||
break;
|
||||
case 'd': /* day of month */
|
||||
case 'e':
|
||||
ret = str2int(&s, 2);
|
||||
if (ret < 1 || ret > 31) { /* must be in [01,31] */
|
||||
return NULL;
|
||||
}
|
||||
tm->tm_mday = ret;
|
||||
break;
|
||||
case 'D': /* equivalent to %m/%d/%y */
|
||||
if (!(s = unbound_strptime(s, "%m/%d/%y", tm))) {
|
||||
return NULL;
|
||||
}
|
||||
break;
|
||||
case 'H': /* hour */
|
||||
ret = str2int(&s, 2);
|
||||
if (ret < 0 || ret > 23) { /* must be in [00,23] */
|
||||
return NULL;
|
||||
}
|
||||
tm->tm_hour = ret;
|
||||
break;
|
||||
case 'I': /* 12hr clock hour */
|
||||
ret = str2int(&s, 2);
|
||||
if (ret < 1 || ret > 12) { /* must be in [01,12] */
|
||||
return NULL;
|
||||
}
|
||||
if (ret == 12) /* actually [0,11] */
|
||||
ret = 0;
|
||||
tm->tm_hour = ret;
|
||||
break;
|
||||
case 'j': /* day of year */
|
||||
ret = str2int(&s, 2);
|
||||
if (ret < 1 || ret > 366) { /* must be in [001,366] */
|
||||
return NULL;
|
||||
}
|
||||
tm->tm_yday = ret;
|
||||
break;
|
||||
case 'm': /* month */
|
||||
ret = str2int(&s, 2);
|
||||
if (ret < 1 || ret > 12) { /* must be in [01,12] */
|
||||
return NULL;
|
||||
}
|
||||
/* months go from 0-11 */
|
||||
tm->tm_mon = (ret-1);
|
||||
break;
|
||||
case 'M': /* minute */
|
||||
ret = str2int(&s, 2);
|
||||
if (ret < 0 || ret > 59) { /* must be in [00,59] */
|
||||
return NULL;
|
||||
}
|
||||
tm->tm_min = ret;
|
||||
break;
|
||||
case 'n': /* arbitrary whitespace */
|
||||
case 't':
|
||||
while (isspace((unsigned char)*s))
|
||||
s++;
|
||||
break;
|
||||
case 'p': /* am pm */
|
||||
ret = match_string(&s, ampm);
|
||||
if (ret < 0) {
|
||||
return NULL;
|
||||
}
|
||||
if (tm->tm_hour < 0 || tm->tm_hour > 11) { /* %I */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (ret == 1) /* pm */
|
||||
tm->tm_hour += 12;
|
||||
break;
|
||||
case 'r': /* equivalent of %I:%M:%S %p */
|
||||
if (!(s = unbound_strptime(s, "%I:%M:%S %p", tm))) {
|
||||
return NULL;
|
||||
}
|
||||
break;
|
||||
case 'R': /* equivalent of %H:%M */
|
||||
if (!(s = unbound_strptime(s, "%H:%M", tm))) {
|
||||
return NULL;
|
||||
}
|
||||
break;
|
||||
case 'S': /* seconds */
|
||||
ret = str2int(&s, 2);
|
||||
/* 60 may occur for leap seconds */
|
||||
/* earlier 61 was also allowed */
|
||||
if (ret < 0 || ret > 60) { /* must be in [00,60] */
|
||||
return NULL;
|
||||
}
|
||||
tm->tm_sec = ret;
|
||||
break;
|
||||
case 'T': /* equivalent of %H:%M:%S */
|
||||
if (!(s = unbound_strptime(s, "%H:%M:%S", tm))) {
|
||||
return NULL;
|
||||
}
|
||||
break;
|
||||
case 'U': /* week number, with the first Sun of Jan being w1 */
|
||||
ret = str2int(&s, 2);
|
||||
if (ret < 0 || ret > 53) { /* must be in [00,53] */
|
||||
return NULL;
|
||||
}
|
||||
/** it is hard (and not necessary for nsd) to determine time
|
||||
* data from week number.
|
||||
**/
|
||||
break;
|
||||
case 'w': /* day of week */
|
||||
ret = str2int(&s, 1);
|
||||
if (ret < 0 || ret > 6) { /* must be in [0,6] */
|
||||
return NULL;
|
||||
}
|
||||
tm->tm_wday = ret;
|
||||
break;
|
||||
case 'W': /* week number, with the first Mon of Jan being w1 */
|
||||
ret = str2int(&s, 2);
|
||||
if (ret < 0 || ret > 53) { /* must be in [00,53] */
|
||||
return NULL;
|
||||
}
|
||||
/** it is hard (and not necessary for nsd) to determine time
|
||||
* data from week number.
|
||||
**/
|
||||
break;
|
||||
case 'x': /* date format */
|
||||
if (!(s = unbound_strptime(s, "%m/%d/%y", tm))) {
|
||||
return NULL;
|
||||
}
|
||||
break;
|
||||
case 'X': /* time format */
|
||||
if (!(s = unbound_strptime(s, "%H:%M:%S", tm))) {
|
||||
return NULL;
|
||||
}
|
||||
break;
|
||||
case 'y': /* last two digits of a year */
|
||||
ret = str2int(&s, 2);
|
||||
if (ret < 0 || ret > 99) { /* must be in [00,99] */
|
||||
return NULL;
|
||||
}
|
||||
if (split_year) {
|
||||
tm->tm_year = ((tm->tm_year/100) * 100) + ret;
|
||||
}
|
||||
else {
|
||||
split_year = 1;
|
||||
|
||||
/** currently:
|
||||
* if in [0,68] we are in 21th century,
|
||||
* if in [69,99] we are in 20th century.
|
||||
**/
|
||||
if (ret < 69) /* 2000 */
|
||||
ret += 100;
|
||||
tm->tm_year = ret;
|
||||
}
|
||||
break;
|
||||
case 'Y': /* year */
|
||||
ret = str2int(&s, 4);
|
||||
if (ret < 0 || ret > 9999) {
|
||||
return NULL;
|
||||
}
|
||||
tm->tm_year = ret - TM_YEAR_BASE;
|
||||
break;
|
||||
case '\0':
|
||||
default: /* unsupported, cannot match format */
|
||||
return NULL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else { /* literal */
|
||||
/* if input cannot match format, return NULL */
|
||||
if (*s != c)
|
||||
return NULL;
|
||||
s++;
|
||||
}
|
||||
|
||||
format++;
|
||||
}
|
||||
|
||||
/* return pointer to remainder of s */
|
||||
return (char*) s;
|
||||
}
|
||||
|
||||
#endif /* STRPTIME_WORKS */
|
|
@ -82,6 +82,9 @@ static struct const_info consts_info[] = {
|
|||
{ 622, "GETDNS_CONTEXT_CODE_ROUND_ROBIN_UPSTREAMS", GETDNS_CONTEXT_CODE_ROUND_ROBIN_UPSTREAMS_TEXT },
|
||||
{ 623, "GETDNS_CONTEXT_CODE_TLS_BACKOFF_TIME", GETDNS_CONTEXT_CODE_TLS_BACKOFF_TIME_TEXT },
|
||||
{ 624, "GETDNS_CONTEXT_CODE_TLS_CONNECTION_RETRIES", GETDNS_CONTEXT_CODE_TLS_CONNECTION_RETRIES_TEXT },
|
||||
{ 625, "GETDNS_CONTEXT_CODE_TRUST_ANCHOR_URL", GETDNS_CONTEXT_CODE_TRUST_ANCHOR_URL_TEXT },
|
||||
{ 626, "GETDNS_CONTEXT_CODE_TRUST_ANCHOR_VERIFY_CA", GETDNS_CONTEXT_CODE_TRUST_ANCHOR_VERIFY_CA_TEXT },
|
||||
{ 627, "GETDNS_CONTEXT_CODE_TRUST_ANCHOR_VERIFY_EMAIL", GETDNS_CONTEXT_CODE_TRUST_ANCHOR_VERIFY_EMAIL_TEXT },
|
||||
{ 700, "GETDNS_CALLBACK_COMPLETE", GETDNS_CALLBACK_COMPLETE_TEXT },
|
||||
{ 701, "GETDNS_CALLBACK_CANCEL", GETDNS_CALLBACK_CANCEL_TEXT },
|
||||
{ 702, "GETDNS_CALLBACK_TIMEOUT", GETDNS_CALLBACK_TIMEOUT_TEXT },
|
||||
|
@ -174,6 +177,9 @@ static struct const_name_info consts_name_info[] = {
|
|||
{ "GETDNS_CONTEXT_CODE_TLS_BACKOFF_TIME", 623 },
|
||||
{ "GETDNS_CONTEXT_CODE_TLS_CONNECTION_RETRIES", 624 },
|
||||
{ "GETDNS_CONTEXT_CODE_TLS_QUERY_PADDING_BLOCKSIZE", 620 },
|
||||
{ "GETDNS_CONTEXT_CODE_TRUST_ANCHOR_URL", 625 },
|
||||
{ "GETDNS_CONTEXT_CODE_TRUST_ANCHOR_VERIFY_CA", 626 },
|
||||
{ "GETDNS_CONTEXT_CODE_TRUST_ANCHOR_VERIFY_EMAIL", 627 },
|
||||
{ "GETDNS_CONTEXT_CODE_UPSTREAM_RECURSIVE_SERVERS", 603 },
|
||||
{ "GETDNS_DNSSEC_BOGUS", 401 },
|
||||
{ "GETDNS_DNSSEC_INDETERMINATE", 402 },
|
||||
|
|
396
src/context.c
396
src/context.c
|
@ -35,11 +35,13 @@
|
|||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include "anchor.h"
|
||||
|
||||
#ifndef USE_WINSOCK
|
||||
#include <arpa/inet.h>
|
||||
#include <sys/time.h>
|
||||
#include <netdb.h>
|
||||
#include <pwd.h>
|
||||
#else
|
||||
#include <winsock2.h>
|
||||
#include <iphlpapi.h>
|
||||
|
@ -68,7 +70,6 @@ typedef unsigned short in_port_t;
|
|||
#endif
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "config.h"
|
||||
#ifdef HAVE_LIBUNBOUND
|
||||
#include <unbound.h>
|
||||
#endif
|
||||
|
@ -1362,6 +1363,37 @@ static void _getdns_check_expired_pending_netreqs_cb(void *arg)
|
|||
_getdns_check_expired_pending_netreqs((getdns_context *)arg, &now_ms);
|
||||
}
|
||||
|
||||
static const char *_getdns_default_root_anchor_url =
|
||||
"http://data.iana.org/root-anchors/root-anchors.xml";
|
||||
|
||||
/* The ICANN CA fetched at 24 Sep 2010. Valid to 2028 */
|
||||
static const char *_getdns_default_root_anchor_verify_CA =
|
||||
"-----BEGIN CERTIFICATE-----\n"
|
||||
"MIIDdzCCAl+gAwIBAgIBATANBgkqhkiG9w0BAQsFADBdMQ4wDAYDVQQKEwVJQ0FO\n"
|
||||
"TjEmMCQGA1UECxMdSUNBTk4gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxFjAUBgNV\n"
|
||||
"BAMTDUlDQU5OIFJvb3QgQ0ExCzAJBgNVBAYTAlVTMB4XDTA5MTIyMzA0MTkxMloX\n"
|
||||
"DTI5MTIxODA0MTkxMlowXTEOMAwGA1UEChMFSUNBTk4xJjAkBgNVBAsTHUlDQU5O\n"
|
||||
"IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MRYwFAYDVQQDEw1JQ0FOTiBSb290IENB\n"
|
||||
"MQswCQYDVQQGEwJVUzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKDb\n"
|
||||
"cLhPNNqc1NB+u+oVvOnJESofYS9qub0/PXagmgr37pNublVThIzyLPGCJ8gPms9S\n"
|
||||
"G1TaKNIsMI7d+5IgMy3WyPEOECGIcfqEIktdR1YWfJufXcMReZwU4v/AdKzdOdfg\n"
|
||||
"ONiwc6r70duEr1IiqPbVm5T05l1e6D+HkAvHGnf1LtOPGs4CHQdpIUcy2kauAEy2\n"
|
||||
"paKcOcHASvbTHK7TbbvHGPB+7faAztABLoneErruEcumetcNfPMIjXKdv1V1E3C7\n"
|
||||
"MSJKy+jAqqQJqjZoQGB0necZgUMiUv7JK1IPQRM2CXJllcyJrm9WFxY0c1KjBO29\n"
|
||||
"iIKK69fcglKcBuFShUECAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8B\n"
|
||||
"Af8EBAMCAf4wHQYDVR0OBBYEFLpS6UmDJIZSL8eZzfyNa2kITcBQMA0GCSqGSIb3\n"
|
||||
"DQEBCwUAA4IBAQAP8emCogqHny2UYFqywEuhLys7R9UKmYY4suzGO4nkbgfPFMfH\n"
|
||||
"6M+Zj6owwxlwueZt1j/IaCayoKU3QsrYYoDRolpILh+FPwx7wseUEV8ZKpWsoDoD\n"
|
||||
"2JFbLg2cfB8u/OlE4RYmcxxFSmXBg0yQ8/IoQt/bxOcEEhhiQ168H2yE5rxJMt9h\n"
|
||||
"15nu5JBSewrCkYqYYmaxyOC3WrVGfHZxVI7MpIFcGdvSb2a1uyuua8l0BKgk3ujF\n"
|
||||
"0/wsHNeP22qNyVO+XVBzrM8fk8BSUFuiT/6tZTYXRtEt5aKQZgXbKU5dUF3jT9qg\n"
|
||||
"j/Br5BZw3X/zd325TvnswzMC1+ljLzHnQGGk\n"
|
||||
"-----END CERTIFICATE-----\n";
|
||||
|
||||
static const char *_getdns_default_root_anchor_verify_email =
|
||||
"dnssec@iana.org";
|
||||
|
||||
|
||||
/*
|
||||
* getdns_context_create
|
||||
*
|
||||
|
@ -1461,6 +1493,20 @@ getdns_context_create_with_extended_memory_functions(
|
|||
result->suffixes = no_suffixes;
|
||||
result->suffixes_len = sizeof(no_suffixes);
|
||||
|
||||
result->trust_anchors_source = GETDNS_TASRC_NONE;
|
||||
result->can_write_appdata = PROP_UNKNOWN;
|
||||
result->root_anchor_url = _getdns_default_root_anchor_url;
|
||||
result->root_anchor_verify_email
|
||||
= _getdns_default_root_anchor_verify_email;
|
||||
result->root_anchor_verify_CA = _getdns_default_root_anchor_verify_CA;
|
||||
|
||||
(void) memset(&result->root_ksk, 0, sizeof(result->root_ksk));
|
||||
|
||||
(void) memset(&result->a, 0, sizeof(result->a));
|
||||
(void) memset(&result->aaaa, 0, sizeof(result->aaaa));
|
||||
result->a.fd = -1;
|
||||
result->aaaa.fd = -1;
|
||||
|
||||
gldns_buffer_init_vfixed_frm_data(&gbuf, result->trust_anchors_spc
|
||||
, sizeof(result->trust_anchors_spc));
|
||||
|
||||
|
@ -1478,12 +1524,16 @@ getdns_context_create_with_extended_memory_functions(
|
|||
, result->trust_anchors
|
||||
, result->trust_anchors_len);
|
||||
if (!_getdns_parse_ta_file(NULL, &gbuf)) {
|
||||
GETDNS_FREE(result->mf, result->trust_anchors);
|
||||
result->trust_anchors = NULL;
|
||||
result->trust_anchors_len = 0;
|
||||
}
|
||||
} else
|
||||
result->trust_anchors_source = GETDNS_TASRC_ZONE;
|
||||
}
|
||||
} else
|
||||
} else {
|
||||
result->trust_anchors = result->trust_anchors_spc;
|
||||
result->trust_anchors_source = GETDNS_TASRC_ZONE;
|
||||
}
|
||||
|
||||
result->upstreams = NULL;
|
||||
|
||||
|
@ -1517,6 +1567,9 @@ getdns_context_create_with_extended_memory_functions(
|
|||
result->return_call_reporting = 0;
|
||||
result->specify_class = GETDNS_RRCLASS_IN;
|
||||
|
||||
result->sys_ctxt = NULL;
|
||||
result->ta_notify = NULL;
|
||||
|
||||
/* state data used to detect changes to the system config files
|
||||
*/
|
||||
result->fchg_resolvconf = NULL;
|
||||
|
@ -1553,7 +1606,15 @@ getdns_context_create_with_extended_memory_functions(
|
|||
#endif
|
||||
/* Only initialise SSL once and ideally in a thread-safe manner */
|
||||
if (ssl_init == false) {
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10100000 || defined(HAVE_LIBRESSL)
|
||||
OpenSSL_add_all_algorithms();
|
||||
SSL_library_init();
|
||||
#else
|
||||
OPENSSL_init_crypto( OPENSSL_INIT_ADD_ALL_CIPHERS
|
||||
| OPENSSL_INIT_ADD_ALL_DIGESTS
|
||||
| OPENSSL_INIT_LOAD_CRYPTO_STRINGS, NULL);
|
||||
(void)OPENSSL_init_ssl(0, NULL);
|
||||
#endif
|
||||
ssl_init = true;
|
||||
}
|
||||
#ifdef HAVE_PTHREAD
|
||||
|
@ -1561,7 +1622,6 @@ getdns_context_create_with_extended_memory_functions(
|
|||
#else
|
||||
/* XXX implement Windows-style unlock here */
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_LIBUNBOUND
|
||||
result->unbound_ctx = NULL;
|
||||
if ((r = rebuild_ub_ctx(result)))
|
||||
|
@ -1636,6 +1696,10 @@ getdns_context_destroy(struct getdns_context *context)
|
|||
return;
|
||||
|
||||
context->destroying = 1;
|
||||
|
||||
if (context->sys_ctxt)
|
||||
getdns_context_destroy(context->sys_ctxt);
|
||||
|
||||
/* cancel all outstanding requests */
|
||||
cancel_outstanding_requests(context);
|
||||
|
||||
|
@ -2648,9 +2712,11 @@ getdns_context_set_dnssec_trust_anchors(
|
|||
context->trust_anchors = _getdns_list2wire(value,
|
||||
context->trust_anchors_spc, &context->trust_anchors_len,
|
||||
&context->mf);
|
||||
context->trust_anchors_source = GETDNS_TASRC_APP;
|
||||
} else {
|
||||
context->trust_anchors = NULL;
|
||||
context->trust_anchors_len = 0;
|
||||
context->trust_anchors_source = GETDNS_TASRC_NONE;
|
||||
}
|
||||
dispatch_updated(context, GETDNS_CONTEXT_CODE_DNSSEC_TRUST_ANCHORS);
|
||||
return GETDNS_RETURN_GOOD;
|
||||
|
@ -4542,4 +4608,326 @@ getdns_context_config(getdns_context *context, const getdns_dict *config_dict)
|
|||
return r;
|
||||
}
|
||||
|
||||
static size_t _getdns_get_appdata(char *path)
|
||||
{
|
||||
size_t len;
|
||||
|
||||
#ifdef USE_WINSOCK
|
||||
# define APPDATA_SUBDIR "getdns"
|
||||
|
||||
if (! SUCCEEDED(SHGetFolderPath(NULL,
|
||||
CSIDL_APPDATA | CSIDL_FLAG_CREATE, NULL, 0, path)))
|
||||
DEBUG_ANCHOR("ERROR %s(): Could not get \%AppData\% directory\n"
|
||||
, __FUNC__);
|
||||
|
||||
else if ((len = strlen(path)) + sizeof(APPDATA_SUBDIR) + 2 >= PATH_MAX)
|
||||
DEBUG_ANCHOR("ERROR %s(): Home path too long for appdata\n"
|
||||
, __FUNC__);
|
||||
#else
|
||||
# define APPDATA_SUBDIR ".getdns"
|
||||
struct passwd *p = getpwuid(getuid());
|
||||
char *home = NULL;
|
||||
|
||||
if (!(home = p ? p->pw_dir : getenv("HOME")))
|
||||
DEBUG_ANCHOR("ERROR %s(): Could not get home directory\n"
|
||||
, __FUNC__);
|
||||
|
||||
else if ((len = strlen(home)) + sizeof(APPDATA_SUBDIR) + 2 >= PATH_MAX)
|
||||
DEBUG_ANCHOR("ERROR %s(): Home path too long for appdata\n"
|
||||
, __FUNC__);
|
||||
|
||||
else if (!strcpy(path, home))
|
||||
; /* strcpy returns path always */
|
||||
#endif
|
||||
else {
|
||||
if (len == 0 || ( path[len - 1] != '/'
|
||||
&& path[len - 1] != '\\')) {
|
||||
path[len++] = '/';
|
||||
path[len ] = '\0';
|
||||
}
|
||||
(void) strcpy(path + len, APPDATA_SUBDIR);
|
||||
len += sizeof(APPDATA_SUBDIR) - 1;
|
||||
|
||||
if (mkdir(path, 0755) < 0 && errno != EEXIST)
|
||||
DEBUG_ANCHOR("ERROR %s(): Could not mkdir %s: %s\n"
|
||||
, __FUNC__, path, strerror(errno));
|
||||
else {
|
||||
path[len++] = '/';
|
||||
path[len ] = '\0';
|
||||
return len;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
FILE *_getdns_context_get_priv_fp(getdns_context *context, const char *fn)
|
||||
{
|
||||
char path[PATH_MAX];
|
||||
FILE *f = NULL;
|
||||
size_t len;
|
||||
|
||||
(void) context;
|
||||
if (!(len = _getdns_get_appdata(path)))
|
||||
DEBUG_ANCHOR("ERROR %s(): Could nog get application data path\n"
|
||||
, __FUNC__);
|
||||
|
||||
else if (len + strlen(fn) >= sizeof(path))
|
||||
DEBUG_ANCHOR("ERROR %s(): Application data too long\n", __FUNC__);
|
||||
|
||||
else if (!strcpy(path + len, fn))
|
||||
; /* strcpy returns path + len always */
|
||||
|
||||
else if (!(f = fopen(path, "r")))
|
||||
DEBUG_ANCHOR("ERROR %s(): Opening \"%s\": %s\n"
|
||||
, __FUNC__, path, strerror(errno));
|
||||
|
||||
return f;
|
||||
}
|
||||
|
||||
uint8_t *_getdns_context_get_priv_file(getdns_context *context,
|
||||
const char *fn, uint8_t *buf, size_t buf_len, size_t *file_sz)
|
||||
{
|
||||
FILE *f = NULL;
|
||||
|
||||
if (!(f = _getdns_context_get_priv_fp(context, fn)))
|
||||
; /* pass */
|
||||
|
||||
else if ((*file_sz = fread(buf, 1, buf_len, f)) < (buf_len - 1) && feof(f)) {
|
||||
buf[*file_sz] = 0;
|
||||
(void) fclose(f);
|
||||
return buf;
|
||||
}
|
||||
else if (fseek(f, 0, SEEK_END) < 0)
|
||||
DEBUG_ANCHOR("ERROR %s(): Determining size of \"%s\": %s\n"
|
||||
, __FUNC__, fn, strerror(errno));
|
||||
|
||||
else if (!(buf = GETDNS_XMALLOC(
|
||||
context->mf, uint8_t, (buf_len = ftell(f) + 1))))
|
||||
DEBUG_ANCHOR("ERROR %s(): Allocating %d memory for \"%s\"\n"
|
||||
, __FUNC__, (int)buf_len, fn);
|
||||
|
||||
else {
|
||||
rewind(f);
|
||||
if ((*file_sz = fread(buf, 1, buf_len, f)) >= buf_len || !feof(f)) {
|
||||
GETDNS_FREE(context->mf, buf);
|
||||
DEBUG_ANCHOR("ERROR %s(): Reading \"%s\": %s\n"
|
||||
, __FUNC__, fn, strerror(errno));
|
||||
}
|
||||
else {
|
||||
buf[*file_sz] = 0;
|
||||
(void) fclose(f);
|
||||
return buf;
|
||||
}
|
||||
}
|
||||
if (f)
|
||||
(void) fclose(f);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
int _getdns_context_write_priv_file(getdns_context *context,
|
||||
const char *fn, getdns_bindata *content)
|
||||
{
|
||||
char path[PATH_MAX], tmpfn[PATH_MAX];
|
||||
int fd = -1;
|
||||
FILE *f = NULL;
|
||||
size_t len;
|
||||
|
||||
if (!(len = _getdns_get_appdata(path)))
|
||||
DEBUG_ANCHOR("ERROR %s(): Could nog get application data path\n"
|
||||
, __FUNC__);
|
||||
|
||||
else if (len + 6 >= sizeof(tmpfn)
|
||||
|| len + strlen(fn) >= sizeof(path))
|
||||
DEBUG_ANCHOR("ERROR %s(): Application data too long\n", __FUNC__);
|
||||
|
||||
|
||||
else if (snprintf(tmpfn, sizeof(tmpfn), "%sXXXXXX", path) < 0)
|
||||
DEBUG_ANCHOR("ERROR %s(): Creating temporary filename template\n"
|
||||
, __FUNC__);
|
||||
|
||||
else if (!strcpy(path + len, fn))
|
||||
; /* strcpy returns path + len always */
|
||||
|
||||
else if ((fd = mkstemp(tmpfn)) < 0)
|
||||
DEBUG_ANCHOR("ERROR %s(): Creating temporary file: %s\n"
|
||||
, __FUNC__, strerror(errno));
|
||||
|
||||
else if (!(f = fdopen(fd, "w")))
|
||||
DEBUG_ANCHOR("ERROR %s(): Opening temporary file: %s\n"
|
||||
, __FUNC__, strerror(errno));
|
||||
|
||||
else if (fwrite(content->data, 1, content->size, f) < content->size)
|
||||
DEBUG_ANCHOR("ERROR %s(): Writing temporary file: %s\n"
|
||||
, __FUNC__, strerror(errno));
|
||||
|
||||
else if (fclose(f) < 0)
|
||||
DEBUG_ANCHOR("ERROR %s(): Closing temporary file: %s\n"
|
||||
, __FUNC__, strerror(errno));
|
||||
|
||||
else if (rename(tmpfn, path) < 0)
|
||||
DEBUG_ANCHOR("ERROR %s(): Renaming temporary file: %s\n"
|
||||
, __FUNC__, strerror(errno));
|
||||
else {
|
||||
context->can_write_appdata = PROP_ABLE;
|
||||
return 1;
|
||||
}
|
||||
if (f)
|
||||
(void) fclose(f);
|
||||
|
||||
else if (fd >= 0)
|
||||
(void) close(fd);
|
||||
|
||||
context->can_write_appdata = PROP_UNABLE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int _getdns_context_can_write_appdata(getdns_context *context)
|
||||
{
|
||||
char test_fn[30], path[PATH_MAX];
|
||||
size_t len;
|
||||
getdns_bindata test_content = { 4, (void *)"TEST" };
|
||||
|
||||
if (context->can_write_appdata == PROP_ABLE)
|
||||
return 1;
|
||||
|
||||
else if (context->can_write_appdata == PROP_UNABLE)
|
||||
return 0;
|
||||
|
||||
(void) snprintf( test_fn, sizeof(test_fn)
|
||||
, "write-test-%d.tmp", arc4random());
|
||||
|
||||
if (!_getdns_context_write_priv_file(context, test_fn, &test_content))
|
||||
return 0;
|
||||
|
||||
if (!(len = _getdns_get_appdata(path)))
|
||||
DEBUG_ANCHOR("ERROR %s(): Could nog get application data path\n"
|
||||
, __FUNC__);
|
||||
|
||||
else if (len + strlen(test_fn) >= sizeof(path))
|
||||
DEBUG_ANCHOR("ERROR %s(): Application data too long\n", __FUNC__);
|
||||
|
||||
else if (!strcpy(path + len, test_fn))
|
||||
; /* strcpy returns path + len always */
|
||||
|
||||
else if (unlink(path) < 0)
|
||||
DEBUG_ANCHOR("ERROR %s(): Unlinking write test file \"%s\": %s\n"
|
||||
, __FUNC__, path, strerror(errno));
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
getdns_return_t
|
||||
getdns_context_set_trust_anchor_url(
|
||||
getdns_context *context, const char *zone, const char *url)
|
||||
{
|
||||
const char *path;
|
||||
size_t path_len;
|
||||
|
||||
if (!context || !url)
|
||||
return GETDNS_RETURN_INVALID_PARAMETER;
|
||||
|
||||
if (zone && !(zone[0] == '.' && zone[1] == '\0'))
|
||||
return GETDNS_RETURN_NOT_IMPLEMENTED;
|
||||
|
||||
if (! ((url[0] == 'h' || url[0] == 'H')
|
||||
&& (url[1] == 't' || url[1] == 'T')
|
||||
&& (url[2] == 't' || url[2] == 'T')
|
||||
&& (url[3] == 'p' || url[3] == 'P')
|
||||
&& url[4] == ':' && url[5] == '/' && url[6] == '/'
|
||||
&& (path = strchr(url + 7, '/'))))
|
||||
return GETDNS_RETURN_NOT_IMPLEMENTED;
|
||||
|
||||
path_len = strlen(path);
|
||||
if (! ( path_len >= 5
|
||||
&& path[path_len - 4] == '.'
|
||||
&& (path[path_len - 3] == 'x' || path[path_len - 3] == 'X')
|
||||
&& (path[path_len - 2] == 'm' || path[path_len - 2] == 'M')
|
||||
&& (path[path_len - 1] == 'l' || path[path_len - 1] == 'L')))
|
||||
return GETDNS_RETURN_NOT_IMPLEMENTED;
|
||||
|
||||
context->root_anchor_url = url;
|
||||
dispatch_updated(context, GETDNS_CONTEXT_CODE_TRUST_ANCHOR_URL);
|
||||
return GETDNS_RETURN_GOOD;
|
||||
}
|
||||
|
||||
getdns_return_t
|
||||
getdns_context_get_trust_anchor_url(
|
||||
getdns_context *context, const char *zone, const char **url)
|
||||
{
|
||||
if (!context || !url)
|
||||
return GETDNS_RETURN_INVALID_PARAMETER;
|
||||
|
||||
if (zone && (zone[0] != '.' || zone[1] != '\0'))
|
||||
return GETDNS_RETURN_NOT_IMPLEMENTED;
|
||||
|
||||
*url = context && context->root_anchor_url
|
||||
? context->root_anchor_url
|
||||
: _getdns_default_root_anchor_url;
|
||||
return GETDNS_RETURN_GOOD;
|
||||
}
|
||||
|
||||
getdns_return_t
|
||||
getdns_context_set_trust_anchor_verify_CA(
|
||||
getdns_context *context, const char *zone, const char *verify_CA)
|
||||
{
|
||||
if (!context || !verify_CA)
|
||||
return GETDNS_RETURN_INVALID_PARAMETER;
|
||||
|
||||
if (zone && (zone[0] != '.' || zone[1] != '\0'))
|
||||
return GETDNS_RETURN_NOT_IMPLEMENTED;
|
||||
|
||||
context->root_anchor_verify_CA = verify_CA;
|
||||
dispatch_updated(context, GETDNS_CONTEXT_CODE_TRUST_ANCHOR_VERIFY_CA);
|
||||
return GETDNS_RETURN_GOOD;
|
||||
}
|
||||
|
||||
getdns_return_t
|
||||
getdns_context_get_trust_anchor_verify_CA(
|
||||
getdns_context *context, const char *zone, const char **verify_CA)
|
||||
{
|
||||
if (!verify_CA)
|
||||
return GETDNS_RETURN_INVALID_PARAMETER;
|
||||
|
||||
if (zone && (zone[0] != '.' || zone[1] != '\0'))
|
||||
return GETDNS_RETURN_NOT_IMPLEMENTED;
|
||||
|
||||
*verify_CA = context && context->root_anchor_verify_CA
|
||||
? context->root_anchor_verify_CA
|
||||
: _getdns_default_root_anchor_verify_CA;
|
||||
return GETDNS_RETURN_GOOD;
|
||||
}
|
||||
|
||||
getdns_return_t
|
||||
getdns_context_set_trust_anchor_verify_email(
|
||||
getdns_context *context, const char *zone, const char *verify_email)
|
||||
{
|
||||
if (!context || !verify_email)
|
||||
return GETDNS_RETURN_INVALID_PARAMETER;
|
||||
|
||||
if (zone && (zone[0] != '.' || zone[1] != '\0'))
|
||||
return GETDNS_RETURN_NOT_IMPLEMENTED;
|
||||
|
||||
context->root_anchor_verify_email = verify_email;
|
||||
dispatch_updated(context, GETDNS_CONTEXT_CODE_TRUST_ANCHOR_VERIFY_EMAIL);
|
||||
return GETDNS_RETURN_GOOD;
|
||||
}
|
||||
|
||||
getdns_return_t
|
||||
getdns_context_get_trust_anchor_verify_email(
|
||||
getdns_context *context, const char *zone, const char **verify_email)
|
||||
{
|
||||
if (!verify_email)
|
||||
return GETDNS_RETURN_INVALID_PARAMETER;
|
||||
|
||||
if (zone && (zone[0] != '.' || zone[1] != '\0'))
|
||||
return GETDNS_RETURN_NOT_IMPLEMENTED;
|
||||
|
||||
*verify_email = context && context->root_anchor_verify_email
|
||||
? context->root_anchor_verify_email
|
||||
: _getdns_default_root_anchor_verify_email;
|
||||
return GETDNS_RETURN_GOOD;
|
||||
}
|
||||
|
||||
|
||||
/* context.c */
|
||||
|
|
|
@ -48,6 +48,8 @@
|
|||
#ifdef HAVE_MDNS_SUPPORT
|
||||
#include "util/lruhash.h"
|
||||
#endif
|
||||
#include "rr-iter.h"
|
||||
#include "anchor.h"
|
||||
|
||||
struct getdns_dns_req;
|
||||
struct ub_ctx;
|
||||
|
@ -92,6 +94,16 @@ typedef enum getdns_conn_state {
|
|||
GETDNS_CONN_BACKOFF
|
||||
} getdns_conn_state_t;
|
||||
|
||||
typedef enum getdns_tasrc {
|
||||
GETDNS_TASRC_NONE,
|
||||
GETDNS_TASRC_ZONE,
|
||||
GETDNS_TASRC_APP,
|
||||
GETDNS_TASRC_FETCHING,
|
||||
GETDNS_TASRC_XML,
|
||||
GETDNS_TASRC_XML_UPDATE,
|
||||
GETDNS_TASRC_FAILED
|
||||
} getdns_tasrc;
|
||||
|
||||
typedef enum getdns_tsig_algo {
|
||||
GETDNS_NO_TSIG = 0, /* Do not use tsig */
|
||||
GETDNS_HMAC_MD5 = 1, /* 128 bits */
|
||||
|
@ -103,6 +115,7 @@ typedef enum getdns_tsig_algo {
|
|||
GETDNS_HMAC_SHA512 = 7
|
||||
} getdns_tsig_algo;
|
||||
|
||||
|
||||
typedef struct getdns_tsig_info {
|
||||
getdns_tsig_algo alg;
|
||||
const char *name;
|
||||
|
@ -256,6 +269,44 @@ typedef struct getdns_upstreams {
|
|||
getdns_upstream upstreams[];
|
||||
} getdns_upstreams;
|
||||
|
||||
typedef enum tas_state {
|
||||
TAS_LOOKUP_ADDRESSES = 0,
|
||||
TAS_WRITE_GET_XML,
|
||||
TAS_READ_XML_HDR,
|
||||
TAS_READ_XML_DOC,
|
||||
TAS_WRITE_GET_PS7,
|
||||
TAS_READ_PS7_HDR,
|
||||
TAS_READ_PS7_DOC,
|
||||
TAS_DONE,
|
||||
TAS_RETRY,
|
||||
TAS_RETRY_GET_PS7,
|
||||
TAS_RETRY_PS7_HDR,
|
||||
TAS_RETRY_PS7_DOC,
|
||||
TAS_RETRY_DONE
|
||||
} tas_state;
|
||||
|
||||
typedef enum _getdns_property {
|
||||
PROP_INHERIT = 0,
|
||||
PROP_UNKNOWN = 1,
|
||||
PROP_UNABLE = 2,
|
||||
PROP_ABLE = 3
|
||||
} _getdns_property;
|
||||
|
||||
typedef struct tas_connection {
|
||||
getdns_eventloop *loop;
|
||||
getdns_network_req *req;
|
||||
_getdns_rrset_spc rrset_spc;
|
||||
_getdns_rrset *rrset;
|
||||
_getdns_rrtype_iter rr_spc;
|
||||
_getdns_rrtype_iter *rr;
|
||||
int fd;
|
||||
getdns_eventloop_event event;
|
||||
tas_state state;
|
||||
getdns_tcp_state tcp;
|
||||
char *http;
|
||||
getdns_bindata xml;
|
||||
} tas_connection;
|
||||
|
||||
struct getdns_context {
|
||||
/* Context values */
|
||||
getdns_resolution_t resolution_type;
|
||||
|
@ -277,8 +328,23 @@ struct getdns_context {
|
|||
const uint8_t *suffixes;
|
||||
/* Length of all suffixes in the suffix buffer */
|
||||
size_t suffixes_len;
|
||||
|
||||
uint8_t *trust_anchors;
|
||||
size_t trust_anchors_len;
|
||||
getdns_tasrc trust_anchors_source;
|
||||
|
||||
tas_connection a;
|
||||
tas_connection aaaa;
|
||||
uint8_t tas_hdr_spc[512];
|
||||
|
||||
_getdns_property can_write_appdata;
|
||||
|
||||
const char *root_anchor_url;
|
||||
const char *root_anchor_verify_CA;
|
||||
const char *root_anchor_verify_email;
|
||||
|
||||
_getdns_ksks root_ksk;
|
||||
|
||||
getdns_upstreams *upstreams;
|
||||
uint16_t limit_outstanding_queries;
|
||||
uint32_t dnssec_allowed_skew;
|
||||
|
@ -373,6 +439,18 @@ struct getdns_context {
|
|||
unsigned return_call_reporting : 1;
|
||||
uint16_t specify_class;
|
||||
|
||||
/*
|
||||
* Context for doing system queries.
|
||||
* For example to resolve data.iana.org or to resolver the addresses
|
||||
* of upstreams without specified addresses.
|
||||
*/
|
||||
getdns_context *sys_ctxt;
|
||||
|
||||
/* List of dnsreqs that want to be notified when we have fetched a
|
||||
* trust anchor from data.iana.org.
|
||||
*/
|
||||
getdns_dns_req *ta_notify;
|
||||
|
||||
/*
|
||||
* state data used to detect changes to the system config files
|
||||
*/
|
||||
|
@ -471,6 +549,15 @@ void _getdns_upstreams_dereference(getdns_upstreams *upstreams);
|
|||
|
||||
void _getdns_upstream_shutdown(getdns_upstream *upstream);
|
||||
|
||||
FILE *_getdns_context_get_priv_fp(getdns_context *context, const char *fn);
|
||||
uint8_t *_getdns_context_get_priv_file(getdns_context *context,
|
||||
const char *fn, uint8_t *buf, size_t buf_len, size_t *file_sz);
|
||||
|
||||
int _getdns_context_write_priv_file(getdns_context *context,
|
||||
const char *fn, getdns_bindata *content);
|
||||
|
||||
int _getdns_context_can_write_appdata(getdns_context *context);
|
||||
|
||||
void _getdns_upstream_reset(getdns_upstream *upstream);
|
||||
|
||||
#endif /* _GETDNS_CONTEXT_H_ */
|
||||
|
|
59
src/debug.h
59
src/debug.h
|
@ -47,41 +47,41 @@
|
|||
|
||||
#ifdef GETDNS_ON_WINDOWS
|
||||
#define DEBUG_ON(...) do { \
|
||||
struct timeval tv; \
|
||||
struct tm tm; \
|
||||
char buf[10]; \
|
||||
time_t tsec; \
|
||||
struct timeval tv_dEbUgSyM; \
|
||||
struct tm tm_dEbUgSyM; \
|
||||
char buf_dEbUgSyM[10]; \
|
||||
time_t tsec_dEbUgSyM; \
|
||||
\
|
||||
gettimeofday(&tv, NULL); \
|
||||
tsec = (time_t) tv.tv_sec; \
|
||||
gmtime_s(&tm, (const time_t *) &tsec); \
|
||||
strftime(buf, 10, "%H:%M:%S", &tm); \
|
||||
fprintf(stderr, "[%s.%.6d] ", buf, (int)tv.tv_usec); \
|
||||
gettimeofday(&tv_dEbUgSyM, NULL); \
|
||||
tsec = (time_t) tv_dEbUgSyM.tv_sec; \
|
||||
gmtime_s(&tm_dEbUgSyM, (const time_t *) &tsec_dEbUgSyM); \
|
||||
strftime(buf_dEbUgSyM, 10, "%H:%M:%S", &tm_dEbUgSyM); \
|
||||
fprintf(stderr, "[%s.%.6d] ", buf_dEbUgSyM, (int)tv_dEbUgSyM.tv_usec); \
|
||||
fprintf(stderr, __VA_ARGS__); \
|
||||
} while (0)
|
||||
#else
|
||||
#define DEBUG_ON(...) do { \
|
||||
struct timeval tv; \
|
||||
struct tm tm; \
|
||||
char buf[10]; \
|
||||
struct timeval tv_dEbUgSyM; \
|
||||
struct tm tm_dEbUgSyM; \
|
||||
char buf_dEbUgSyM[10]; \
|
||||
\
|
||||
gettimeofday(&tv, NULL); \
|
||||
gmtime_r(&tv.tv_sec, &tm); \
|
||||
strftime(buf, 10, "%H:%M:%S", &tm); \
|
||||
fprintf(stderr, "[%s.%.6d] ", buf, (int)tv.tv_usec); \
|
||||
gettimeofday(&tv_dEbUgSyM, NULL); \
|
||||
gmtime_r(&tv_dEbUgSyM.tv_sec, &tm_dEbUgSyM); \
|
||||
strftime(buf_dEbUgSyM, 10, "%H:%M:%S", &tm_dEbUgSyM); \
|
||||
fprintf(stderr, "[%s.%.6d] ", buf_dEbUgSyM, (int)tv_dEbUgSyM.tv_usec); \
|
||||
fprintf(stderr, __VA_ARGS__); \
|
||||
} while (0)
|
||||
#endif
|
||||
|
||||
#define DEBUG_NL(...) do { \
|
||||
struct timeval tv; \
|
||||
struct tm tm; \
|
||||
char buf[10]; \
|
||||
struct timeval tv_dEbUgSyM; \
|
||||
struct tm tm_dEbUgSyM; \
|
||||
char buf_dEbUgSyM[10]; \
|
||||
\
|
||||
gettimeofday(&tv, NULL); \
|
||||
gmtime_r(&tv.tv_sec, &tm); \
|
||||
strftime(buf, 10, "%H:%M:%S", &tm); \
|
||||
fprintf(stderr, "[%s.%.6d] ", buf, (int)tv.tv_usec); \
|
||||
gettimeofday(&tv_dEbUgSyM, NULL); \
|
||||
gmtime_r(&tv_dEbUgSyM.tv_sec, &tm_dEbUgSyM); \
|
||||
strftime(buf_dEbUgSyM, 10, "%H:%M:%S", &tm_dEbUgSyM); \
|
||||
fprintf(stderr, "[%s.%.6d] ", buf_dEbUgSyM, (int)tv_dEbUgSyM.tv_usec); \
|
||||
fprintf(stderr, __VA_ARGS__); \
|
||||
fprintf(stderr, "\n"); \
|
||||
} while (0)
|
||||
|
@ -162,14 +162,25 @@ static inline void debug_req(const char *msg, getdns_network_req *netreq)
|
|||
#define DEBUG_MDNS(...) DEBUG_OFF(__VA_ARGS__)
|
||||
#endif
|
||||
|
||||
#if defined(ANCHOR_DEBUG) && ANCHOR_DEBUG
|
||||
#include <time.h>
|
||||
#define DEBUG_ANCHOR(...) DEBUG_ON(__VA_ARGS__)
|
||||
#else
|
||||
#define DEBUG_ANCHOR(...) DEBUG_OFF(__VA_ARGS__)
|
||||
#endif
|
||||
|
||||
#if (defined(REQ_DEBUG) && REQ_DEBUG) || \
|
||||
(defined(SCHED_DEBUG) && SCHED_DEBUG) || \
|
||||
(defined(STUB_DEBUG) && STUB_DEBUG) || \
|
||||
(defined(DAEMON_DEBUG) && DAEMON_DEBUG) || \
|
||||
(defined(SEC_DEBUG) && SEC_DEBUG) || \
|
||||
(defined(SERVER_DEBUG) && SERVER_DEBUG) || \
|
||||
(defined(MDNS_DEBUG) && MDNS_DEBUG)
|
||||
(defined(MDNS_DEBUG) && MDNS_DEBUG) || \
|
||||
(defined(ANCHOR_DEBUG) && ANCHOR_DEBUG)
|
||||
#define DEBUGGING 1
|
||||
static inline int
|
||||
_getdns_ERR_print_errors_cb_f(const char *str, size_t len, void *u)
|
||||
{ DEBUG_ON("%.*s (u: %p)\n", (int)len, str, u); return 1; }
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
175
src/dnssec.c
175
src/dnssec.c
|
@ -209,6 +209,7 @@
|
|||
#include "dict.h"
|
||||
#include "list.h"
|
||||
#include "util/val_secalgo.h"
|
||||
#include "anchor.h"
|
||||
|
||||
#define SIGNATURE_VERIFIED 0x10000
|
||||
#define NSEC3_ITERATION_COUNT_HIGH 0x20000
|
||||
|
@ -2544,8 +2545,13 @@ static int chain_node_get_trusted_keys(
|
|||
} else
|
||||
return GETDNS_DNSSEC_BOGUS;
|
||||
|
||||
if (GETDNS_DNSSEC_SECURE != (s = chain_node_get_trusted_keys(
|
||||
mf, now, skew, node->parent, ta, keys)))
|
||||
s = chain_node_get_trusted_keys(mf, now, skew, node->parent, ta, keys);
|
||||
/* Set dnssec status on root DNSKEY request (for TA management) */
|
||||
if (!node->parent && node->dnskey_req &&
|
||||
node->dnskey.name && *node->dnskey.name == 0)
|
||||
node->dnskey_req->dnssec_status = s;
|
||||
|
||||
if (s != GETDNS_DNSSEC_SECURE)
|
||||
return s;
|
||||
|
||||
/* keys is an authenticated dnskey rrset always now (i.e. ZSK) */
|
||||
|
@ -2750,6 +2756,33 @@ static void chain_set_netreq_dnssec_status(chain_head *chain, _getdns_rrset_iter
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void chain_clear_netreq_dnssec_status(chain_head *chain)
|
||||
{
|
||||
chain_head *head;
|
||||
size_t node_count;
|
||||
chain_node *node;
|
||||
|
||||
/* The netreq status is the worst for any head */
|
||||
for (head = chain; head; head = head->next) {
|
||||
if (!head->netreq)
|
||||
continue;
|
||||
|
||||
head->netreq->dnssec_status = GETDNS_DNSSEC_INDETERMINATE;
|
||||
for ( node_count = head->node_count, node = head->parent
|
||||
; node && node_count ; node_count--, node = node->parent ) {
|
||||
|
||||
node->ds_signer = -1;
|
||||
node->dnskey_signer = -1;
|
||||
|
||||
if ( ! node->parent && node->dnskey_req
|
||||
&& node->dnskey.name && !*node->dnskey.name) {
|
||||
node->dnskey_req->dnssec_status =
|
||||
GETDNS_DNSSEC_INDETERMINATE;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* The DNSSEC status of all heads for a chain structure is evaluated by
|
||||
|
@ -2997,6 +3030,22 @@ static void append_empty_ds2val_chain_list(
|
|||
if (_getdns_list_append_this_dict(val_chain_list, rr_dict))
|
||||
getdns_dict_destroy(rr_dict);
|
||||
}
|
||||
static inline chain_node *_to_the_root(chain_node *node)
|
||||
{
|
||||
while (node->parent) node = node->parent;
|
||||
return node;
|
||||
}
|
||||
|
||||
int _getdns_bogus(getdns_dns_req *dnsreq)
|
||||
{
|
||||
getdns_network_req **netreq_p, *netreq;
|
||||
|
||||
for (netreq_p = dnsreq->netreqs; (netreq = *netreq_p) ; netreq_p++) {
|
||||
if (netreq->dnssec_status == GETDNS_DNSSEC_BOGUS)
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void check_chain_complete(chain_head *chain)
|
||||
{
|
||||
|
@ -3017,23 +3066,33 @@ static void check_chain_complete(chain_head *chain)
|
|||
dnsreq = chain->netreq->owner;
|
||||
context = dnsreq->context;
|
||||
|
||||
if (dnsreq->waiting_for_ta) {
|
||||
getdns_dns_req **d;
|
||||
|
||||
for (d = &context->ta_notify; *d; d = &(*d)->ta_notify) {
|
||||
if (*d == dnsreq) {
|
||||
*d = dnsreq->ta_notify;
|
||||
dnsreq->ta_notify = NULL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
if (context->trust_anchors_source == GETDNS_TASRC_FETCHING) {
|
||||
dnsreq->waiting_for_ta = 1;
|
||||
dnsreq->ta_notify = context->ta_notify;
|
||||
context->ta_notify = dnsreq;
|
||||
return;
|
||||
}
|
||||
}
|
||||
#ifdef STUB_NATIVE_DNSSEC
|
||||
/* Perform validation only on GETDNS_RESOLUTION_STUB (unbound_id == -1)
|
||||
* Or when asked for the validation chain (to identify the RRSIGs that
|
||||
* signed the RRSETs, so that only those will be included in the
|
||||
* validation chain)
|
||||
* In any case we must have a trust anchor.
|
||||
*/
|
||||
if (( chain->netreq->unbound_id == -1
|
||||
|| dnsreq->dnssec_return_validation_chain)
|
||||
&& context->trust_anchors)
|
||||
if (context->trust_anchors)
|
||||
|
||||
chain_set_netreq_dnssec_status(chain,_getdns_rrset_iter_init(&tas_iter,
|
||||
context->trust_anchors, context->trust_anchors_len,
|
||||
SECTION_ANSWER));
|
||||
#else
|
||||
if (dnsreq->dnssec_return_validation_chain
|
||||
&& context->trust_anchors)
|
||||
if (context->trust_anchors)
|
||||
|
||||
(void) chain_validate_dnssec(priv_getdns_context_mf(context),
|
||||
time(NULL), context->dnssec_allowed_skew,
|
||||
|
@ -3042,10 +3101,52 @@ static void check_chain_complete(chain_head *chain)
|
|||
, context->trust_anchors_len
|
||||
, SECTION_ANSWER));
|
||||
#endif
|
||||
if (context->trust_anchors_source == GETDNS_TASRC_XML) {
|
||||
if ((head = chain) && (node = _to_the_root(head->parent)) &&
|
||||
node->dnskey.name && *node->dnskey.name == 0)
|
||||
_getdns_context_update_root_ksk(context,&node->dnskey);
|
||||
|
||||
} else if (_getdns_bogus(dnsreq)) {
|
||||
DEBUG_ANCHOR("Request was bogus!\n");
|
||||
|
||||
if ((head = chain) && (node = _to_the_root(head->parent))
|
||||
&& node->dnskey.name && *node->dnskey.name == 0
|
||||
&& node->dnskey_req->dnssec_status == GETDNS_DNSSEC_BOGUS){
|
||||
|
||||
DEBUG_ANCHOR("root DNSKEY set was bogus!\n");
|
||||
if (!dnsreq->waiting_for_ta) {
|
||||
uint64_t now = 0;
|
||||
|
||||
dnsreq->waiting_for_ta = 1;
|
||||
_getdns_context_equip_with_anchor(
|
||||
context, &now);
|
||||
|
||||
if (context->trust_anchors_source
|
||||
== GETDNS_TASRC_XML) {
|
||||
chain_clear_netreq_dnssec_status(chain);
|
||||
check_chain_complete(chain);
|
||||
return;
|
||||
}
|
||||
_getdns_start_fetching_ta(
|
||||
context, dnsreq->loop);
|
||||
|
||||
if (dnsreq->waiting_for_ta &&
|
||||
context->trust_anchors_source
|
||||
== GETDNS_TASRC_FETCHING) {
|
||||
|
||||
chain_clear_netreq_dnssec_status(chain);
|
||||
dnsreq->ta_notify = context->ta_notify;
|
||||
context->ta_notify = dnsreq;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef DNSSEC_ROADBLOCK_AVOIDANCE
|
||||
if ( dnsreq->dnssec_roadblock_avoidance
|
||||
&& !dnsreq->avoid_dnssec_roadblocks
|
||||
&& dnsreq->netreqs[0]->dnssec_status == GETDNS_DNSSEC_BOGUS) {
|
||||
&& _getdns_bogus(dnsreq)) {
|
||||
|
||||
getdns_network_req **netreq_p, *netreq;
|
||||
uint64_t now_ms = 0;
|
||||
|
@ -3095,6 +3196,7 @@ static void check_chain_complete(chain_head *chain)
|
|||
return;
|
||||
}
|
||||
#endif
|
||||
dnsreq->waiting_for_ta = 0;
|
||||
val_chain_list = dnsreq->dnssec_return_validation_chain
|
||||
? getdns_list_create_with_context(context) : NULL;
|
||||
|
||||
|
@ -3161,6 +3263,45 @@ static void check_chain_complete(chain_head *chain)
|
|||
_getdns_call_user_callback(dnsreq, response_dict);
|
||||
}
|
||||
|
||||
void _getdns_ta_notify_dnsreqs(getdns_context *context)
|
||||
{
|
||||
getdns_dns_req **dnsreq_p, *dnsreq = NULL;
|
||||
uint64_t now_ms = 0;
|
||||
|
||||
assert(context);
|
||||
|
||||
if (context->trust_anchors_source == GETDNS_TASRC_NONE ||
|
||||
context->trust_anchors_source == GETDNS_TASRC_FETCHING)
|
||||
return;
|
||||
|
||||
dnsreq_p = &context->ta_notify;
|
||||
while ((dnsreq = *dnsreq_p)) {
|
||||
assert(dnsreq->waiting_for_ta);
|
||||
|
||||
if (dnsreq->chain)
|
||||
check_chain_complete(dnsreq->chain);
|
||||
else {
|
||||
getdns_network_req *netreq, **netreq_p;
|
||||
int r = GETDNS_RETURN_GOOD;
|
||||
|
||||
(void) _getdns_context_prepare_for_resolution(context, 0);
|
||||
|
||||
*dnsreq_p = dnsreq->ta_notify;
|
||||
for ( netreq_p = dnsreq->netreqs
|
||||
; !r && (netreq = *netreq_p)
|
||||
; netreq_p++ ) {
|
||||
|
||||
if (!(r = _getdns_submit_netreq(netreq, &now_ms)))
|
||||
continue;
|
||||
if (r == DNS_REQ_FINISHED)
|
||||
break;
|
||||
_getdns_netreq_change_state(netreq, NET_REQ_ERRORED);
|
||||
}
|
||||
}
|
||||
assert(*dnsreq_p != dnsreq);
|
||||
}
|
||||
}
|
||||
|
||||
void _getdns_validation_chain_timeout(getdns_dns_req *dnsreq)
|
||||
{
|
||||
chain_head *head = dnsreq->chain, *next;
|
||||
|
@ -3243,6 +3384,7 @@ void _getdns_get_validation_chain(getdns_dns_req *dnsreq)
|
|||
|
||||
if (dnsreq->avoid_dnssec_roadblocks && chain->lock == 0)
|
||||
; /* pass */
|
||||
|
||||
else for (netreq_p = dnsreq->netreqs; (netreq = *netreq_p) ; netreq_p++) {
|
||||
if (! netreq->response
|
||||
|| netreq->response_len < GLDNS_HEADER_SIZE
|
||||
|
@ -3253,7 +3395,10 @@ void _getdns_get_validation_chain(getdns_dns_req *dnsreq)
|
|||
|
||||
netreq->dnssec_status = GETDNS_DNSSEC_INSECURE;
|
||||
continue;
|
||||
}
|
||||
|
||||
} else if (netreq->unbound_id != -1)
|
||||
netreq->dnssec_status = GETDNS_DNSSEC_INDETERMINATE;
|
||||
|
||||
add_pkt2val_chain( &dnsreq->my_mf, &chain
|
||||
, netreq->response, netreq->response_len
|
||||
, netreq
|
||||
|
|
|
@ -48,6 +48,7 @@
|
|||
void _getdns_get_validation_chain(getdns_dns_req *dns_req);
|
||||
void _getdns_cancel_validation_chain(getdns_dns_req *dns_req);
|
||||
void _getdns_validation_chain_timeout(getdns_dns_req *dns_req);
|
||||
void _getdns_ta_notify_dnsreqs(getdns_context *context);
|
||||
|
||||
uint16_t _getdns_parse_ta_file(time_t *ta_mtime, gldns_buffer *gbuf);
|
||||
|
||||
|
@ -66,6 +67,8 @@ static inline int _dnssec_rdata_to_canonicalize(uint16_t rr_type)
|
|||
|| rr_type == GLDNS_RR_TYPE_DNAME || rr_type == GLDNS_RR_TYPE_RRSIG;
|
||||
}
|
||||
|
||||
int _getdns_bogus(getdns_dns_req *dns_req);
|
||||
|
||||
#endif
|
||||
|
||||
/* dnssec.h */
|
||||
|
|
|
@ -172,6 +172,9 @@ getdns_libuv_timeout_cb(uv_timer_t *timer, int status)
|
|||
#endif
|
||||
{
|
||||
getdns_eventloop_event *el_ev = (getdns_eventloop_event *)timer->data;
|
||||
#ifndef HAVE_NEW_UV_TIMER_CB
|
||||
(void)status;
|
||||
#endif
|
||||
assert(el_ev->timeout_cb);
|
||||
DEBUG_UV("enter libuv_timeout_cb(el_ev = %p, el_ev->ev = %p)\n"
|
||||
, el_ev, el_ev->ev);
|
||||
|
|
|
@ -296,7 +296,8 @@ poll_read_cb(int fd, getdns_eventloop_event *event)
|
|||
(void)fd;
|
||||
#endif
|
||||
DEBUG_SCHED( "%s(fd: %d, event: %p)\n", __FUNC__, fd, (void *)event);
|
||||
event->read_cb(event->userarg);
|
||||
if (event && event->read_cb)
|
||||
event->read_cb(event->userarg);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -306,14 +307,16 @@ poll_write_cb(int fd, getdns_eventloop_event *event)
|
|||
(void)fd;
|
||||
#endif
|
||||
DEBUG_SCHED( "%s(fd: %d, event: %p)\n", __FUNC__, fd, (void *)event);
|
||||
event->write_cb(event->userarg);
|
||||
if (event && event->write_cb)
|
||||
event->write_cb(event->userarg);
|
||||
}
|
||||
|
||||
static void
|
||||
poll_timeout_cb(getdns_eventloop_event *event)
|
||||
{
|
||||
DEBUG_SCHED( "%s(event: %p)\n", __FUNC__, (void *)event);
|
||||
event->timeout_cb(event->userarg);
|
||||
if (event && event->timeout_cb)
|
||||
event->timeout_cb(event->userarg);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
|
@ -34,6 +34,7 @@
|
|||
#include "config.h"
|
||||
#include "getdns/getdns.h"
|
||||
#include "getdns/getdns_extra.h"
|
||||
#include "types-internal.h"
|
||||
|
||||
/* No more than select's capability queries can be outstanding,
|
||||
* The number of outstanding timeouts should be less or equal then
|
||||
|
|
|
@ -54,6 +54,7 @@
|
|||
#include "dict.h"
|
||||
#include "mdns.h"
|
||||
#include "debug.h"
|
||||
#include "anchor.h"
|
||||
|
||||
void _getdns_call_user_callback(getdns_dns_req *dnsreq, getdns_dict *response)
|
||||
{
|
||||
|
@ -213,13 +214,15 @@ _getdns_check_dns_req_complete(getdns_dns_req *dns_req)
|
|||
#endif
|
||||
|
||||
#ifdef STUB_NATIVE_DNSSEC
|
||||
|| (dns_req->context->resolution_type == GETDNS_RESOLUTION_STUB
|
||||
|| ( dns_req->context->resolution_type == GETDNS_RESOLUTION_STUB
|
||||
&& !dns_req->avoid_dnssec_roadblocks
|
||||
&& (dns_req->dnssec_return_status ||
|
||||
dns_req->dnssec_return_only_secure ||
|
||||
dns_req->dnssec_return_all_statuses
|
||||
))
|
||||
#endif
|
||||
|| ( dns_req->context->resolution_type == GETDNS_RESOLUTION_RECURSING
|
||||
&& _getdns_bogus(dns_req))
|
||||
)) {
|
||||
/* Reschedule timeout for this DNS request
|
||||
*/
|
||||
|
@ -235,6 +238,7 @@ _getdns_check_dns_req_complete(getdns_dns_req *dns_req)
|
|||
#if defined(REQ_DEBUG) && REQ_DEBUG
|
||||
debug_req("getting validation chain for ", *dns_req->netreqs);
|
||||
#endif
|
||||
DEBUG_ANCHOR("Valchain lookup\n");
|
||||
_getdns_get_validation_chain(dns_req);
|
||||
} else
|
||||
_getdns_call_user_callback(
|
||||
|
@ -570,11 +574,6 @@ getdns_general_ns(getdns_context *context, getdns_eventloop *loop,
|
|||
if (extensions && (r = validate_extensions(extensions)))
|
||||
return r;
|
||||
|
||||
/* Set up the context assuming we won't use the specified namespaces.
|
||||
This is (currently) identical to setting up a pure DNS namespace */
|
||||
if ((r = _getdns_context_prepare_for_resolution(context, 0)))
|
||||
return r;
|
||||
|
||||
/* create the request */
|
||||
if (!(req = _getdns_dns_req_new(
|
||||
context, loop, name, request_type, extensions, &now_ms)))
|
||||
|
@ -590,7 +589,28 @@ getdns_general_ns(getdns_context *context, getdns_eventloop *loop,
|
|||
|
||||
_getdns_context_track_outbound_request(req);
|
||||
|
||||
if (!usenamespaces)
|
||||
if (req->dnssec_extension_set) {
|
||||
if (context->trust_anchors_source == GETDNS_TASRC_XML_UPDATE)
|
||||
_getdns_start_fetching_ta(context, loop);
|
||||
|
||||
else if (context->trust_anchors_source == GETDNS_TASRC_NONE) {
|
||||
_getdns_context_equip_with_anchor(context, &now_ms);
|
||||
if (context->trust_anchors_source == GETDNS_TASRC_NONE) {
|
||||
_getdns_start_fetching_ta(context, loop);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!usenamespaces) {
|
||||
if (context->trust_anchors_source == GETDNS_TASRC_FETCHING
|
||||
&& context->resolution_type == GETDNS_RESOLUTION_RECURSING
|
||||
&& context->resolution_type != context->resolution_type_set) {
|
||||
req->waiting_for_ta = 1;
|
||||
req->ta_notify = context->ta_notify;
|
||||
context->ta_notify = req;
|
||||
return GETDNS_RETURN_GOOD;
|
||||
}
|
||||
(void) _getdns_context_prepare_for_resolution(context, 0);
|
||||
|
||||
/* issue all network requests */
|
||||
for ( netreq_p = req->netreqs
|
||||
; !r && (netreq = *netreq_p)
|
||||
|
@ -605,7 +625,7 @@ getdns_general_ns(getdns_context *context, getdns_eventloop *loop,
|
|||
}
|
||||
}
|
||||
|
||||
else for (i = 0; i < context->namespace_count; i++) {
|
||||
} else for (i = 0; i < context->namespace_count; i++) {
|
||||
if (context->namespaces[i] == GETDNS_NAMESPACE_LOCALNAMES) {
|
||||
|
||||
if (!(r = _getdns_context_local_namespace_resolve(
|
||||
|
@ -639,6 +659,15 @@ getdns_general_ns(getdns_context *context, getdns_eventloop *loop,
|
|||
}
|
||||
#endif /* HAVE_MDNS_SUPPORT */
|
||||
} else if (context->namespaces[i] == GETDNS_NAMESPACE_DNS) {
|
||||
if (context->trust_anchors_source == GETDNS_TASRC_FETCHING
|
||||
&& context->resolution_type == GETDNS_RESOLUTION_RECURSING
|
||||
&& context->resolution_type != context->resolution_type_set) {
|
||||
req->waiting_for_ta = 1;
|
||||
req->ta_notify = context->ta_notify;
|
||||
context->ta_notify = req;
|
||||
return GETDNS_RETURN_GOOD;
|
||||
}
|
||||
(void) _getdns_context_prepare_for_resolution(context, 0);
|
||||
|
||||
/* TODO: We will get a good return code here even if
|
||||
the name is not found (NXDOMAIN). We should consider
|
||||
|
|
|
@ -79,6 +79,13 @@ extern "C" {
|
|||
#define GETDNS_CONTEXT_CODE_TLS_BACKOFF_TIME_TEXT "Change related to getdns_context_set_tls_backoff_time"
|
||||
#define GETDNS_CONTEXT_CODE_TLS_CONNECTION_RETRIES 624
|
||||
#define GETDNS_CONTEXT_CODE_TLS_CONNECTION_RETRIES_TEXT "Change related to getdns_context_set_tls_connection_retries"
|
||||
|
||||
#define GETDNS_CONTEXT_CODE_TRUST_ANCHOR_URL 625
|
||||
#define GETDNS_CONTEXT_CODE_TRUST_ANCHOR_URL_TEXT "Change related to getdns_context_set_trust_anchor_url"
|
||||
#define GETDNS_CONTEXT_CODE_TRUST_ANCHOR_VERIFY_CA 626
|
||||
#define GETDNS_CONTEXT_CODE_TRUST_ANCHOR_VERIFY_CA_TEXT "Change related to getdns_context_set_trust_anchor_verify_ca"
|
||||
#define GETDNS_CONTEXT_CODE_TRUST_ANCHOR_VERIFY_EMAIL 627
|
||||
#define GETDNS_CONTEXT_CODE_TRUST_ANCHOR_VERIFY_EMAIL_TEXT "Change related to getdns_context_set_trust_anchor_verify_email"
|
||||
/** @}
|
||||
*/
|
||||
|
||||
|
@ -537,6 +544,28 @@ getdns_return_t
|
|||
getdns_context_set_logfunc(getdns_context *context, void *userarg,
|
||||
uint64_t system, getdns_loglevel_type level, getdns_logfunc_type func);
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
getdns_return_t
|
||||
getdns_context_set_trust_anchor_url(
|
||||
getdns_context *context, const char *zone, const char *url);
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
getdns_return_t
|
||||
getdns_context_set_trust_anchor_verify_CA(
|
||||
getdns_context *context, const char *zone, const char *verify_CA);
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
getdns_return_t
|
||||
getdns_context_set_trust_anchor_verify_email(
|
||||
getdns_context *context, const char *zone, const char *verify_email);
|
||||
|
||||
|
||||
/**
|
||||
* Get the current resolution type setting from this context.
|
||||
* @see getdns_context_set_resolution_type
|
||||
|
@ -902,6 +931,28 @@ getdns_return_t
|
|||
getdns_context_get_update_callback(getdns_context *context, void **userarg,
|
||||
void (**value) (getdns_context *, getdns_context_code_t, void *));
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
getdns_return_t
|
||||
getdns_context_get_trust_anchor_url(
|
||||
getdns_context *context, const char *zone, const char **url);
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
getdns_return_t
|
||||
getdns_context_get_trust_anchor_verify_CA(
|
||||
getdns_context *context, const char *zone, const char **verify_CA);
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
getdns_return_t
|
||||
getdns_context_get_trust_anchor_verify_email(
|
||||
getdns_context *context, const char *zone, const char **verify_email);
|
||||
|
||||
|
||||
/** @}
|
||||
*/
|
||||
|
||||
|
|
|
@ -95,7 +95,7 @@ gldns_rr_dnskey_key_size_raw(const unsigned char* keydata,
|
|||
}
|
||||
}
|
||||
|
||||
uint16_t gldns_calc_keytag_raw(uint8_t* key, size_t keysize)
|
||||
uint16_t gldns_calc_keytag_raw(const uint8_t* key, size_t keysize)
|
||||
{
|
||||
if(keysize < 4) {
|
||||
return 0;
|
||||
|
|
|
@ -44,7 +44,7 @@ size_t gldns_rr_dnskey_key_size_raw(const unsigned char *keydata,
|
|||
* \param[in] keysize length of key data.
|
||||
* \return the keytag
|
||||
*/
|
||||
uint16_t gldns_calc_keytag_raw(uint8_t* key, size_t keysize);
|
||||
uint16_t gldns_calc_keytag_raw(const uint8_t* key, size_t keysize);
|
||||
|
||||
#if GLDNS_BUILD_CONFIG_HAVE_SSL
|
||||
/**
|
||||
|
|
|
@ -33,6 +33,9 @@ getdns_context_get_tls_authentication
|
|||
getdns_context_get_tls_backoff_time
|
||||
getdns_context_get_tls_connection_retries
|
||||
getdns_context_get_tls_query_padding_blocksize
|
||||
getdns_context_get_trust_anchor_url
|
||||
getdns_context_get_trust_anchor_verify_CA
|
||||
getdns_context_get_trust_anchor_verify_email
|
||||
getdns_context_get_update_callback
|
||||
getdns_context_get_upstream_recursive_servers
|
||||
getdns_context_process_async
|
||||
|
@ -67,6 +70,9 @@ getdns_context_set_tls_authentication
|
|||
getdns_context_set_tls_backoff_time
|
||||
getdns_context_set_tls_connection_retries
|
||||
getdns_context_set_tls_query_padding_blocksize
|
||||
getdns_context_set_trust_anchor_url
|
||||
getdns_context_set_trust_anchor_verify_CA
|
||||
getdns_context_set_trust_anchor_verify_email
|
||||
getdns_context_set_update_callback
|
||||
getdns_context_set_upstream_recursive_servers
|
||||
getdns_context_set_use_threads
|
||||
|
|
|
@ -914,6 +914,7 @@ _getdns_dns_req_new(getdns_context *context, getdns_eventloop *loop,
|
|||
dnssec_return_full_validation_chain;
|
||||
result->dnssec_return_validation_chain = dnssec_return_validation_chain
|
||||
|| dnssec_return_full_validation_chain;
|
||||
result->dnssec_extension_set = dnssec_extension_set;
|
||||
result->edns_cookies = edns_cookies;
|
||||
#ifdef DNSSEC_ROADBLOCK_AVOIDANCE
|
||||
result->dnssec_roadblock_avoidance = dnssec_roadblock_avoidance;
|
||||
|
@ -940,8 +941,10 @@ _getdns_dns_req_new(getdns_context *context, getdns_eventloop *loop,
|
|||
result->upstreams->referenced++;
|
||||
|
||||
result->finished_next = NULL;
|
||||
result->ta_notify = NULL;
|
||||
result->freed = NULL;
|
||||
result->validating = 0;
|
||||
result->waiting_for_ta = 0;
|
||||
result->is_dns_request = 1;
|
||||
result->request_timed_out = 0;
|
||||
result->chain = NULL;
|
||||
|
|
12
src/stub.c
12
src/stub.c
|
@ -66,18 +66,6 @@
|
|||
#include "general.h"
|
||||
#include "pubkey-pinning.h"
|
||||
|
||||
#ifdef USE_WINSOCK
|
||||
typedef u_short sa_family_t;
|
||||
#define _getdns_EWOULDBLOCK (WSAGetLastError() == WSATRY_AGAIN ||\
|
||||
WSAGetLastError() == WSAEWOULDBLOCK)
|
||||
#define _getdns_EINPROGRESS (WSAGetLastError() == WSAEINPROGRESS)
|
||||
#define _getdns_EMFILE (WSAGetLastError() == WSAEMFILE)
|
||||
#else
|
||||
#define _getdns_EWOULDBLOCK (errno == EAGAIN || errno == EWOULDBLOCK)
|
||||
#define _getdns_EINPROGRESS (errno == EINPROGRESS)
|
||||
#define _getdns_EMFILE (errno == EMFILE)
|
||||
#endif
|
||||
|
||||
/* WSA TODO:
|
||||
* STUB_TCP_WOULDBLOCK added to deal with edge triggered event loops (versus
|
||||
* level triggered). See also lines containing WSA TODO below...
|
||||
|
|
|
@ -25,4 +25,4 @@ done
|
|||
rm -fr "${BUILDDIR}/build"
|
||||
mkdir "${BUILDDIR}/build"
|
||||
cd "${BUILDDIR}/build"
|
||||
"${SRCROOT}/configure" $* --prefix "${BUILDDIR}/install"
|
||||
"${SRCROOT}/configure" $* --prefix "${BUILDDIR}/install" --enable-debug-anchor
|
||||
|
|
|
@ -15,6 +15,11 @@ find . -type f -name "Makefile.in" -print0 | xargs -0 rm -f && (
|
|||
)
|
||||
(
|
||||
cd "${BUILDDIR}/build-event-loops"
|
||||
if test "`hostname`" != "bonobo"
|
||||
then
|
||||
echo Sorry, running dependency test on bonobo only
|
||||
exit 0
|
||||
fi
|
||||
if ! ./config.status --config | grep -q 'enable-all-drafts.*--with-libevent.*--with-libev.*--with-libuv'
|
||||
then
|
||||
echo Skipping because not covering enough code
|
||||
|
|
|
@ -5,10 +5,43 @@
|
|||
[ -f .tpkg.var.test ] && source .tpkg.var.test
|
||||
|
||||
cd "${BUILDDIR}/build-event-loops"
|
||||
if make -j 4 test
|
||||
make -j 4 test
|
||||
if test -e "${BUILDDIR}/build-event-loops/src/test/fails"
|
||||
then
|
||||
if test -e "${BUILDDIR}/build-event-loops/src/test/fails"
|
||||
if test -e "${BUILDDIR}/build-event-loops/src/test/check_getdns.failed"
|
||||
then
|
||||
exit 1
|
||||
echo ""
|
||||
echo "********************"
|
||||
echo "*** check_getdns ***"
|
||||
echo "********************"
|
||||
cat "${BUILDDIR}/build-event-loops/src/test/check_getdns.log"
|
||||
fi
|
||||
if test -e "${BUILDDIR}/build-event-loops/src/test/check_getdns_event.failed"
|
||||
then
|
||||
echo ""
|
||||
echo "**************************"
|
||||
echo "*** check_getdns_event ***"
|
||||
echo "**************************"
|
||||
cat "${BUILDDIR}/build-event-loops/src/test/check_getdns_event.log"
|
||||
fi
|
||||
if test -e "${BUILDDIR}/build-event-loops/src/test/check_getdns_ev.failed"
|
||||
then
|
||||
echo ""
|
||||
echo "***********************"
|
||||
echo "*** check_getdns_ev ***"
|
||||
echo "***********************"
|
||||
cat "${BUILDDIR}/build-event-loops/src/test/check_getdns_ev.log"
|
||||
fi
|
||||
if test -e "${BUILDDIR}/build-event-loops/src/test/check_getdns_uv.failed"
|
||||
then
|
||||
echo ""
|
||||
echo "***********************"
|
||||
echo "*** check_getdns_uv ***"
|
||||
echo "***********************"
|
||||
cat "${BUILDDIR}/build-event-loops/src/test/check_getdns_uv.log"
|
||||
fi
|
||||
exit 1
|
||||
else
|
||||
exit 0
|
||||
fi
|
||||
|
||||
|
|
|
@ -25,4 +25,4 @@ do
|
|||
done
|
||||
lcov $LCOV_MERGE -o run-all.info
|
||||
genhtml run-all.info --output-directory coverage-html
|
||||
"${TPKG}" r
|
||||
"${TPKG}" -n -1 r
|
||||
|
|
|
@ -17,4 +17,4 @@ do
|
|||
# trap keyboard interrupt (control-c)
|
||||
trap control_c 2
|
||||
done
|
||||
"${TPKG}" r
|
||||
"${TPKG}" -n -1 r
|
||||
|
|
|
@ -31,7 +31,7 @@ do
|
|||
fi
|
||||
done
|
||||
echo "${ALL}" >> Makefile
|
||||
printf '\t"%s" r\n\n' "${TPKG}" >> Makefile
|
||||
printf '\t"%s" -n -1 r\n\n' "${TPKG}" >> Makefile
|
||||
printf 'clean:\n\t"%s" clean\n\trm -fr build build-stub-only build-event-loops build-static-analysis install scan-build-reports .tpkg.var.master *.info\n\n' "${TPKG}" >> Makefile
|
||||
for P in ${OTHERS}
|
||||
do
|
||||
|
|
|
@ -193,6 +193,8 @@ function usage() {
|
|||
out " -p PRI\tlog using PRI as priority"
|
||||
out " -k\t\tdon't remove test directory when creating/executing a tpkg package"
|
||||
out " -n NUM\tif less than NUM of the tests are passed exit with 1"
|
||||
out " \t\tOtherwise exit with 0. When NUM is -1, no tests may fail"
|
||||
out " \t\tOnly valid when running tpkg report"
|
||||
out " \t\tOtherwise exit with 0. Only valid when running tpkg report"
|
||||
out " -b DIR\tuse DIR is a base directory in stead of ."
|
||||
out " -a ARGS\tpass the string ARGS through to the test scripts"
|
||||
|
@ -330,11 +332,12 @@ function report() {
|
|||
if [[ $passed -lt $TPKG_PASS ]]; then
|
||||
exit 1
|
||||
fi
|
||||
elif [[ $failed -gt 0 ]]; then
|
||||
exit 1
|
||||
else
|
||||
exit 0
|
||||
elif [[ $TPKG_PASS -lt 0 ]]; then
|
||||
if [[ $failed -gt 0 ]]; then
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
exit 0
|
||||
}
|
||||
|
||||
# clone test1 to test2
|
||||
|
|
|
@ -171,7 +171,7 @@ typedef enum network_req_state_enum
|
|||
/* State for async tcp stub resolving */
|
||||
typedef struct getdns_tcp_state {
|
||||
|
||||
uint8_t *write_buf;
|
||||
const uint8_t *write_buf;
|
||||
size_t write_buf_len;
|
||||
size_t written;
|
||||
|
||||
|
@ -300,6 +300,7 @@ typedef struct getdns_dns_req {
|
|||
unsigned dnssec_return_all_statuses : 1;
|
||||
unsigned dnssec_return_validation_chain : 1;
|
||||
unsigned dnssec_return_full_validation_chain : 1;
|
||||
unsigned dnssec_extension_set : 1;
|
||||
#ifdef DNSSEC_ROADBLOCK_AVOIDANCE
|
||||
unsigned dnssec_roadblock_avoidance : 1;
|
||||
unsigned avoid_dnssec_roadblocks : 1;
|
||||
|
@ -324,6 +325,7 @@ typedef struct getdns_dns_req {
|
|||
* freed is touched by _getdns_submit_netreq only
|
||||
*/
|
||||
unsigned validating : 1;
|
||||
unsigned waiting_for_ta : 1;
|
||||
int *freed;
|
||||
|
||||
/* Validation chain to be canceled when this request is canceled */
|
||||
|
@ -365,6 +367,11 @@ typedef struct getdns_dns_req {
|
|||
*/
|
||||
struct getdns_dns_req *finished_next;
|
||||
|
||||
/* Linked list pointer for dns requests, which need to validate DNSSEC
|
||||
* and are waiting for the root trust-anchors fetch.
|
||||
*/
|
||||
struct getdns_dns_req *ta_notify;
|
||||
|
||||
/* network requests for this dns request.
|
||||
* The array is terminated with NULL.
|
||||
*
|
||||
|
|
|
@ -218,5 +218,18 @@ INLINE uint64_t _getdns_ms_until_expiry2(uint64_t expires, uint64_t *now_ms)
|
|||
return *now_ms >= expires ? 0 : expires - *now_ms;
|
||||
}
|
||||
|
||||
|
||||
#ifdef USE_WINSOCK
|
||||
typedef u_short sa_family_t;
|
||||
#define _getdns_EWOULDBLOCK (WSAGetLastError() == WSATRY_AGAIN ||\
|
||||
WSAGetLastError() == WSAEWOULDBLOCK)
|
||||
#define _getdns_EINPROGRESS (WSAGetLastError() == WSAEINPROGRESS)
|
||||
#define _getdns_EMFILE (WSAGetLastError() == WSAEMFILE)
|
||||
#else
|
||||
#define _getdns_EWOULDBLOCK (errno == EAGAIN || errno == EWOULDBLOCK)
|
||||
#define _getdns_EINPROGRESS (errno == EINPROGRESS)
|
||||
#define _getdns_EMFILE (errno == EMFILE)
|
||||
#endif
|
||||
|
||||
#endif
|
||||
/* util-internal.h */
|
||||
|
|
|
@ -45,6 +45,8 @@
|
|||
#define sec_status_insecure _getdns_sec_status_insecure
|
||||
#define sec_status_unchecked _getdns_sec_status_unchecked
|
||||
#define sec_status_bogus _getdns_sec_status_bogus
|
||||
#define fake_sha1 _getdns_fake_sha1
|
||||
#define fake_dsa _getdns_fake_dsa
|
||||
|
||||
enum sec_status { sec_status_bogus = 0
|
||||
, sec_status_unchecked = 0
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
Subproject commit 10f968b0e78b9aeee357d0de81a46b445c3fb27b
|
2
stubby
2
stubby
|
@ -1 +1 @@
|
|||
Subproject commit 6d97f4323f2706a2dfcffc7172bd3f71223974a8
|
||||
Subproject commit 6114230904d9413514d521358ca7956aac99e822
|
Loading…
Reference in New Issue