Merge branch 'develop' into huitema-develop

This commit is contained in:
Willem Toorop 2017-03-06 16:07:12 +01:00
commit de1ab4c8a4
33 changed files with 1510 additions and 509 deletions

9
.gitignore vendored
View File

@ -55,6 +55,13 @@ m4/ltsugar.m4
m4/ltversion.m4
m4/lt~obsolete.m4
src/config.h.in
build/
getdns.pc
getdns_ext_event.pc
/src/test/tpkg/result.*
/src/test/tpkg/.done-*
/src/test/tpkg/.tpkg.var.master
/src/test/tpkg/scan-build-reports/
/src/test/tpkg/install/
/src/test/tpkg/build/
/src/test/tpkg/build-stub-only/
/src/test/tpkg/build-event-loops/

View File

@ -214,6 +214,30 @@ case "$enable_debug_keep_connections_open" in
;;
esac
DEFAULT_EVENTLOOP=select_eventloop
AC_CHECK_HEADERS([sys/poll.h poll.h sys/resource.h],,, [AC_INCLUDES_DEFAULT])
AC_ARG_ENABLE(poll-eventloop, AC_HELP_STRING([--disable-poll-eventloop], [Disable default eventloop based on poll (default=enabled if available)]))
case "$enable_poll_eventloop" in
no)
;;
yes|*)
AC_MSG_CHECKING(for poll)
AC_LINK_IFELSE([AC_LANG_PROGRAM([
#ifdef HAVE_SYS_POLL_H
#include <sys/poll.h>
#else
#include <poll.h>
#endif
], [int rc; rc = poll((struct pollfd *)(0), 0, 0);])], [
AC_MSG_RESULT(yes)
AC_DEFINE_UNQUOTED([USE_POLL_DEFAULT_EVENTLOOP], [1], [Define this to enable a default eventloop based on poll().])
DEFAULT_EVENTLOOP=poll_eventloop
],[AC_MSG_RESULT(no)])
;;
esac
AC_SUBST(DEFAULT_EVENTLOOP)
AC_ARG_ENABLE(tcp-fastopen, AC_HELP_STRING([--disable-tcp-fastopen], Disable TCP Fast Open (default=enabled if available)),
enable_tcp_fastopen="$enableval", enable_tcp_fastopen=yes)
if test "x$enable_tcp_fastopen" = xno; then
@ -1076,8 +1100,6 @@ if test "$ac_cv_func_arc4random" = "no"; then
])
fi
AC_DEFINE(USE_MINI_EVENT, 1, [Needed for sync stub resolver functions])
AC_TYPE_SIGNAL
case `uname` in
@ -1108,7 +1130,6 @@ AH_BOTTOM([
# ifndef FD_SETSIZE
# define FD_SETSIZE 1024
# endif
# define PRIsz "%Iu"
#else
# define PRIsz "%zu"
@ -1148,8 +1169,6 @@ AH_BOTTOM([
#define FD_SET_T
#endif
#ifdef __cplusplus
extern "C" {
#endif
@ -1204,6 +1223,12 @@ int inet_pton(int af, const char* src, void* dst);
const char *inet_ntop(int af, const void *src, char *dst, size_t size);
#endif
#ifdef USE_WINSOCK
static inline int _gldns_custom_vsnprintf(char *str, size_t size, const char *format, va_list ap)
{ int r = vsnprintf(str, size, format, ap); return r == -1 ? _vscprintf(format, ap) : r; }
# define vsnprintf _gldns_custom_vsnprintf
#endif
#ifdef __cplusplus
}
#endif

View File

@ -149,16 +149,24 @@ depend:
# Dependencies for the examples
example-all-functions.lo example-all-functions.o: $(srcdir)/example-all-functions.c $(srcdir)/getdns_libevent.h \
../../src/config.h ../../src/getdns/getdns.h \
$(srcdir)/../../src/getdns/getdns_ext_libevent.h ../../src/getdns/getdns_extra.h
example-reverse.lo example-reverse.o: $(srcdir)/example-reverse.c $(srcdir)/getdns_libevent.h ../../src/config.h \
../../src/getdns/getdns.h $(srcdir)/../../src/getdns/getdns_ext_libevent.h \
../../src/config.h \
../../src/getdns/getdns.h \
$(srcdir)/../../src/getdns/getdns_ext_libevent.h \
../../src/getdns/getdns_extra.h
example-reverse.lo example-reverse.o: $(srcdir)/example-reverse.c $(srcdir)/getdns_libevent.h \
../../src/config.h \
../../src/getdns/getdns.h \
$(srcdir)/../../src/getdns/getdns_ext_libevent.h \
../../src/getdns/getdns_extra.h
example-simple-answers.lo example-simple-answers.o: $(srcdir)/example-simple-answers.c $(srcdir)/getdns_libevent.h \
../../src/config.h ../../src/getdns/getdns.h \
$(srcdir)/../../src/getdns/getdns_ext_libevent.h ../../src/getdns/getdns_extra.h
../../src/config.h \
../../src/getdns/getdns.h \
$(srcdir)/../../src/getdns/getdns_ext_libevent.h \
../../src/getdns/getdns_extra.h
example-synchronous.lo example-synchronous.o: $(srcdir)/example-synchronous.c $(srcdir)/getdns_core_only.h \
../../src/getdns/getdns.h
example-tree.lo example-tree.o: $(srcdir)/example-tree.c $(srcdir)/getdns_libevent.h ../../src/config.h \
../../src/getdns/getdns.h $(srcdir)/../../src/getdns/getdns_ext_libevent.h \
example-tree.lo example-tree.o: $(srcdir)/example-tree.c $(srcdir)/getdns_libevent.h \
../../src/config.h \
../../src/getdns/getdns.h \
$(srcdir)/../../src/getdns/getdns_ext_libevent.h \
../../src/getdns/getdns_extra.h

View File

@ -65,6 +65,8 @@ EXTENSION_LIBUV_LDFLAGS=@EXTENSION_LIBUV_LDFLAGS@
C99COMPATFLAGS=@C99COMPATFLAGS@
DEFAULT_EVENTLOOP_OBJ=@DEFAULT_EVENTLOOP@.lo
GETDNS_OBJ=const-info.lo convert.lo dict.lo dnssec.lo general.lo \
list.lo request-internal.lo pubkey-pinning.lo rr-dict.lo \
rr-iter.lo server.lo stub.lo sync.lo ub_loop.lo util-internal.lo \
@ -81,7 +83,7 @@ UTIL_OBJ=rbtree.lo val_secalgo.lo
JSMN_OBJ=jsmn.lo
EXTENSION_OBJ=default_eventloop.lo libevent.lo libev.lo
EXTENSION_OBJ=$(DEFAULT_EVENTLOOP_OBJ) libevent.lo libev.lo
NON_C99_OBJS=context.lo libuv.lo
@ -152,8 +154,8 @@ 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.lo $(GLDNS_OBJ) $(COMPAT_OBJ) $(UTIL_OBJ) $(JSMN_OBJ)
$(LIBTOOL) --tag=CC --mode=link $(CC) -o $@ $(GETDNS_OBJ) version.lo context.lo default_eventloop.lo $(GLDNS_OBJ) $(COMPAT_OBJ) $(UTIL_OBJ) $(JSMN_OBJ) $(LDFLAGS) -rpath $(libdir) -version-info $(libversion) -no-undefined -export-symbols $(srcdir)/libgetdns.symbols
libgetdns.la: $(GETDNS_OBJ) version.lo context.lo $(DEFAULT_EVENTLOOP_OBJ) $(GLDNS_OBJ) $(COMPAT_OBJ) $(UTIL_OBJ) $(JSMN_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) $(LDFLAGS) -rpath $(libdir) -version-info $(libversion) -no-undefined -export-symbols $(srcdir)/libgetdns.symbols
test: all
cd test && $(MAKE) $@
@ -213,132 +215,232 @@ depend:
FORCE:
# Dependencies for gldns, utils, the extensions and compat functions
const-info.lo const-info.o: $(srcdir)/const-info.c getdns/getdns.h getdns/getdns_extra.h \
getdns/getdns.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 getdns/getdns.h getdns/getdns_extra.h \
getdns/getdns.h $(srcdir)/types-internal.h $(srcdir)/util/rbtree.h \
$(srcdir)/extension/default_eventloop.h config.h getdns/getdns_extra.h $(srcdir)/ub_loop.h \
$(srcdir)/server.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)/dict.h \
$(srcdir)/pubkey-pinning.h
convert.lo convert.o: $(srcdir)/convert.c config.h getdns/getdns.h getdns/getdns_extra.h \
getdns/getdns.h $(srcdir)/util-internal.h $(srcdir)/context.h $(srcdir)/types-internal.h $(srcdir)/util/rbtree.h \
$(srcdir)/extension/default_eventloop.h config.h getdns/getdns_extra.h $(srcdir)/ub_loop.h \
$(srcdir)/debug.h $(srcdir)/server.h $(srcdir)/rr-iter.h $(srcdir)/rr-dict.h $(srcdir)/gldns/gbuffer.h $(srcdir)/gldns/pkthdr.h \
$(srcdir)/gldns/wire2str.h $(srcdir)/gldns/str2wire.h $(srcdir)/gldns/rrdef.h $(srcdir)/gldns/parseutil.h \
$(srcdir)/const-info.h $(srcdir)/dict.h $(srcdir)/list.h $(srcdir)/jsmn/jsmn.h $(srcdir)/convert.h
dict.lo dict.o: $(srcdir)/dict.c config.h $(srcdir)/types-internal.h getdns/getdns.h \
getdns/getdns_extra.h getdns/getdns.h $(srcdir)/util/rbtree.h $(srcdir)/util-internal.h \
$(srcdir)/context.h $(srcdir)/extension/default_eventloop.h config.h getdns/getdns_extra.h \
$(srcdir)/ub_loop.h $(srcdir)/debug.h $(srcdir)/server.h $(srcdir)/rr-iter.h $(srcdir)/rr-dict.h $(srcdir)/gldns/gbuffer.h \
$(srcdir)/gldns/pkthdr.h $(srcdir)/dict.h $(srcdir)/list.h $(srcdir)/const-info.h $(srcdir)/gldns/wire2str.h
dnssec.lo dnssec.o: $(srcdir)/dnssec.c config.h $(srcdir)/debug.h getdns/getdns.h $(srcdir)/context.h \
getdns/getdns_extra.h getdns/getdns.h $(srcdir)/types-internal.h $(srcdir)/util/rbtree.h \
$(srcdir)/extension/default_eventloop.h config.h getdns/getdns_extra.h $(srcdir)/ub_loop.h \
$(srcdir)/server.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)/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
general.lo general.o: $(srcdir)/general.c config.h $(srcdir)/general.h getdns/getdns.h $(srcdir)/types-internal.h \
getdns/getdns_extra.h getdns/getdns.h $(srcdir)/util/rbtree.h $(srcdir)/ub_loop.h $(srcdir)/debug.h \
$(srcdir)/gldns/wire2str.h $(srcdir)/context.h $(srcdir)/extension/default_eventloop.h config.h \
getdns/getdns_extra.h $(srcdir)/server.h $(srcdir)/util-internal.h $(srcdir)/rr-iter.h $(srcdir)/rr-dict.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 \
getdns/getdns.h \
getdns/getdns_extra.h \
$(srcdir)/types-internal.h $(srcdir)/util/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-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)/dict.h $(srcdir)/pubkey-pinning.h
convert.lo convert.o: $(srcdir)/convert.c \
config.h \
getdns/getdns.h \
getdns/getdns_extra.h \
$(srcdir)/util-internal.h $(srcdir)/context.h $(srcdir)/types-internal.h $(srcdir)/util/rbtree.h \
$(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)/rr-iter.h $(srcdir)/rr-dict.h \
$(srcdir)/gldns/gbuffer.h $(srcdir)/gldns/pkthdr.h $(srcdir)/gldns/wire2str.h $(srcdir)/gldns/str2wire.h \
$(srcdir)/gldns/rrdef.h $(srcdir)/gldns/parseutil.h $(srcdir)/const-info.h $(srcdir)/dict.h $(srcdir)/list.h $(srcdir)/jsmn/jsmn.h \
$(srcdir)/convert.h
dict.lo dict.o: $(srcdir)/dict.c \
config.h \
$(srcdir)/types-internal.h \
getdns/getdns.h \
getdns/getdns_extra.h \
$(srcdir)/util/rbtree.h $(srcdir)/util-internal.h $(srcdir)/context.h $(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)/rr-iter.h $(srcdir)/rr-dict.h $(srcdir)/gldns/gbuffer.h $(srcdir)/gldns/pkthdr.h $(srcdir)/dict.h $(srcdir)/list.h \
$(srcdir)/const-info.h $(srcdir)/gldns/wire2str.h
dnssec.lo dnssec.o: $(srcdir)/dnssec.c \
config.h \
$(srcdir)/debug.h \
getdns/getdns.h \
$(srcdir)/context.h \
getdns/getdns_extra.h \
$(srcdir)/types-internal.h $(srcdir)/util/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-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)/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
general.lo general.o: $(srcdir)/general.c \
config.h \
$(srcdir)/general.h \
getdns/getdns.h \
$(srcdir)/types-internal.h \
getdns/getdns_extra.h \
$(srcdir)/util/rbtree.h $(srcdir)/ub_loop.h $(srcdir)/debug.h $(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-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
list.lo list.o: $(srcdir)/list.c $(srcdir)/types-internal.h getdns/getdns.h getdns/getdns_extra.h \
getdns/getdns.h $(srcdir)/util/rbtree.h $(srcdir)/util-internal.h config.h $(srcdir)/context.h \
$(srcdir)/extension/default_eventloop.h config.h getdns/getdns_extra.h $(srcdir)/ub_loop.h \
$(srcdir)/debug.h $(srcdir)/server.h $(srcdir)/rr-iter.h $(srcdir)/rr-dict.h $(srcdir)/gldns/gbuffer.h $(srcdir)/gldns/pkthdr.h \
$(srcdir)/list.h $(srcdir)/dict.h
mdns.lo mdns.o: $(srcdir)/mdns.c config.h $(srcdir)/debug.h $(srcdir)/context.h getdns/getdns.h \
getdns/getdns_extra.h getdns/getdns.h $(srcdir)/types-internal.h $(srcdir)/util/rbtree.h \
$(srcdir)/extension/default_eventloop.h config.h getdns/getdns_extra.h $(srcdir)/ub_loop.h \
$(srcdir)/server.h $(srcdir)/general.h $(srcdir)/gldns/pkthdr.h $(srcdir)/util-internal.h $(srcdir)/rr-iter.h $(srcdir)/rr-dict.h \
$(srcdir)/gldns/gbuffer.h $(srcdir)/mdns.h
pubkey-pinning.lo pubkey-pinning.o: $(srcdir)/pubkey-pinning.c config.h $(srcdir)/debug.h getdns/getdns.h \
$(srcdir)/context.h getdns/getdns.h getdns/getdns_extra.h $(srcdir)/types-internal.h \
$(srcdir)/util/rbtree.h $(srcdir)/extension/default_eventloop.h config.h \
getdns/getdns_extra.h $(srcdir)/ub_loop.h $(srcdir)/server.h $(srcdir)/util-internal.h $(srcdir)/rr-iter.h \
$(srcdir)/rr-dict.h $(srcdir)/gldns/gbuffer.h $(srcdir)/gldns/pkthdr.h
request-internal.lo request-internal.o: $(srcdir)/request-internal.c config.h $(srcdir)/types-internal.h \
getdns/getdns.h getdns/getdns_extra.h getdns/getdns.h $(srcdir)/util/rbtree.h \
$(srcdir)/util-internal.h $(srcdir)/context.h $(srcdir)/extension/default_eventloop.h config.h \
getdns/getdns_extra.h $(srcdir)/ub_loop.h $(srcdir)/debug.h $(srcdir)/server.h $(srcdir)/rr-iter.h $(srcdir)/rr-dict.h \
$(srcdir)/gldns/gbuffer.h $(srcdir)/gldns/pkthdr.h $(srcdir)/gldns/rrdef.h $(srcdir)/gldns/str2wire.h \
$(srcdir)/gldns/rrdef.h $(srcdir)/dict.h $(srcdir)/convert.h
rr-dict.lo rr-dict.o: $(srcdir)/rr-dict.c $(srcdir)/rr-dict.h config.h getdns/getdns.h $(srcdir)/gldns/gbuffer.h \
$(srcdir)/util-internal.h $(srcdir)/context.h getdns/getdns_extra.h getdns/getdns.h \
$(srcdir)/types-internal.h $(srcdir)/util/rbtree.h $(srcdir)/extension/default_eventloop.h config.h \
getdns/getdns_extra.h $(srcdir)/ub_loop.h $(srcdir)/debug.h $(srcdir)/server.h $(srcdir)/rr-iter.h \
$(srcdir)/gldns/pkthdr.h $(srcdir)/dict.h
rr-iter.lo rr-iter.o: $(srcdir)/rr-iter.c $(srcdir)/rr-iter.h $(srcdir)/rr-dict.h config.h getdns/getdns.h \
list.lo list.o: $(srcdir)/list.c $(srcdir)/types-internal.h \
getdns/getdns.h \
getdns/getdns_extra.h \
$(srcdir)/util/rbtree.h $(srcdir)/util-internal.h \
config.h \
$(srcdir)/context.h $(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)/rr-iter.h $(srcdir)/rr-dict.h \
$(srcdir)/gldns/gbuffer.h $(srcdir)/gldns/pkthdr.h $(srcdir)/list.h $(srcdir)/dict.h
mdns.lo mdns.o: $(srcdir)/mdns.c \
config.h \
$(srcdir)/debug.h $(srcdir)/context.h \
getdns/getdns.h \
getdns/getdns_extra.h \
$(srcdir)/types-internal.h $(srcdir)/util/rbtree.h $(srcdir)/extension/default_eventloop.h \
$(srcdir)/extension/poll_eventloop.h $(srcdir)/types-internal.h $(srcdir)/ub_loop.h $(srcdir)/server.h $(srcdir)/general.h \
$(srcdir)/gldns/pkthdr.h $(srcdir)/util-internal.h $(srcdir)/rr-iter.h $(srcdir)/rr-dict.h $(srcdir)/gldns/gbuffer.h \
$(srcdir)/mdns.h
pubkey-pinning.lo pubkey-pinning.o: $(srcdir)/pubkey-pinning.c \
config.h \
$(srcdir)/debug.h \
getdns/getdns.h \
$(srcdir)/context.h \
getdns/getdns_extra.h \
$(srcdir)/types-internal.h $(srcdir)/util/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-internal.h $(srcdir)/rr-iter.h $(srcdir)/rr-dict.h $(srcdir)/gldns/gbuffer.h $(srcdir)/gldns/pkthdr.h
request-internal.lo request-internal.o: $(srcdir)/request-internal.c \
config.h \
$(srcdir)/types-internal.h \
getdns/getdns.h \
getdns/getdns_extra.h \
$(srcdir)/util/rbtree.h $(srcdir)/util-internal.h $(srcdir)/context.h $(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)/rr-iter.h $(srcdir)/rr-dict.h $(srcdir)/gldns/gbuffer.h $(srcdir)/gldns/pkthdr.h $(srcdir)/gldns/rrdef.h \
$(srcdir)/gldns/str2wire.h $(srcdir)/gldns/rrdef.h $(srcdir)/dict.h $(srcdir)/convert.h
rr-dict.lo rr-dict.o: $(srcdir)/rr-dict.c $(srcdir)/rr-dict.h \
config.h \
getdns/getdns.h \
$(srcdir)/gldns/gbuffer.h $(srcdir)/util-internal.h $(srcdir)/context.h \
getdns/getdns_extra.h \
$(srcdir)/types-internal.h $(srcdir)/util/rbtree.h $(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)/rr-iter.h $(srcdir)/gldns/pkthdr.h $(srcdir)/dict.h
rr-iter.lo rr-iter.o: $(srcdir)/rr-iter.c $(srcdir)/rr-iter.h $(srcdir)/rr-dict.h \
config.h \
getdns/getdns.h \
$(srcdir)/gldns/gbuffer.h $(srcdir)/gldns/pkthdr.h $(srcdir)/gldns/rrdef.h
server.lo server.o: $(srcdir)/server.c config.h getdns/getdns_extra.h getdns/getdns.h \
$(srcdir)/context.h getdns/getdns.h $(srcdir)/types-internal.h $(srcdir)/util/rbtree.h \
$(srcdir)/extension/default_eventloop.h config.h getdns/getdns_extra.h $(srcdir)/ub_loop.h \
$(srcdir)/debug.h $(srcdir)/server.h
stub.lo stub.o: $(srcdir)/stub.c config.h $(srcdir)/debug.h $(srcdir)/stub.h getdns/getdns.h $(srcdir)/types-internal.h \
getdns/getdns_extra.h getdns/getdns.h $(srcdir)/util/rbtree.h $(srcdir)/gldns/gbuffer.h \
$(srcdir)/gldns/pkthdr.h $(srcdir)/gldns/rrdef.h $(srcdir)/gldns/str2wire.h $(srcdir)/gldns/rrdef.h \
$(srcdir)/gldns/wire2str.h $(srcdir)/rr-iter.h $(srcdir)/rr-dict.h $(srcdir)/context.h \
$(srcdir)/extension/default_eventloop.h config.h getdns/getdns_extra.h $(srcdir)/ub_loop.h \
$(srcdir)/server.h $(srcdir)/util-internal.h $(srcdir)/general.h $(srcdir)/pubkey-pinning.h
sync.lo sync.o: $(srcdir)/sync.c getdns/getdns.h config.h $(srcdir)/context.h getdns/getdns_extra.h \
getdns/getdns.h $(srcdir)/types-internal.h $(srcdir)/util/rbtree.h \
$(srcdir)/extension/default_eventloop.h config.h getdns/getdns_extra.h $(srcdir)/ub_loop.h \
$(srcdir)/debug.h $(srcdir)/server.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)/gldns/wire2str.h
ub_loop.lo ub_loop.o: $(srcdir)/ub_loop.c $(srcdir)/ub_loop.h config.h getdns/getdns.h \
getdns/getdns_extra.h getdns/getdns.h $(srcdir)/types-internal.h $(srcdir)/util/rbtree.h \
$(srcdir)/debug.h
util-internal.lo util-internal.o: $(srcdir)/util-internal.c config.h getdns/getdns.h $(srcdir)/dict.h \
$(srcdir)/util/rbtree.h $(srcdir)/types-internal.h getdns/getdns_extra.h getdns/getdns.h \
$(srcdir)/list.h $(srcdir)/util-internal.h $(srcdir)/context.h $(srcdir)/extension/default_eventloop.h config.h \
getdns/getdns_extra.h $(srcdir)/ub_loop.h $(srcdir)/debug.h $(srcdir)/server.h $(srcdir)/rr-iter.h $(srcdir)/rr-dict.h \
$(srcdir)/gldns/gbuffer.h $(srcdir)/gldns/pkthdr.h $(srcdir)/gldns/str2wire.h $(srcdir)/gldns/rrdef.h $(srcdir)/dnssec.h \
$(srcdir)/gldns/rrdef.h
version.lo version.o: version.c
gbuffer.lo gbuffer.o: $(srcdir)/gldns/gbuffer.c config.h $(srcdir)/gldns/gbuffer.h
keyraw.lo keyraw.o: $(srcdir)/gldns/keyraw.c config.h $(srcdir)/gldns/keyraw.h $(srcdir)/gldns/rrdef.h
parse.lo parse.o: $(srcdir)/gldns/parse.c config.h $(srcdir)/gldns/parse.h $(srcdir)/gldns/parseutil.h \
server.lo server.o: $(srcdir)/server.c \
config.h \
getdns/getdns_extra.h \
getdns/getdns.h \
$(srcdir)/context.h $(srcdir)/types-internal.h $(srcdir)/util/rbtree.h $(srcdir)/extension/default_eventloop.h \
$(srcdir)/extension/poll_eventloop.h $(srcdir)/types-internal.h $(srcdir)/ub_loop.h $(srcdir)/debug.h $(srcdir)/server.h
stub.lo stub.o: $(srcdir)/stub.c \
config.h \
$(srcdir)/debug.h $(srcdir)/stub.h \
getdns/getdns.h \
$(srcdir)/types-internal.h \
getdns/getdns_extra.h \
$(srcdir)/util/rbtree.h $(srcdir)/gldns/gbuffer.h $(srcdir)/gldns/pkthdr.h $(srcdir)/gldns/rrdef.h \
$(srcdir)/gldns/str2wire.h $(srcdir)/gldns/rrdef.h $(srcdir)/gldns/wire2str.h $(srcdir)/rr-iter.h $(srcdir)/rr-dict.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-internal.h $(srcdir)/general.h \
$(srcdir)/pubkey-pinning.h
sync.lo sync.o: $(srcdir)/sync.c \
getdns/getdns.h \
config.h \
$(srcdir)/context.h \
getdns/getdns_extra.h \
$(srcdir)/types-internal.h $(srcdir)/util/rbtree.h $(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)/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)/gldns/wire2str.h
ub_loop.lo ub_loop.o: $(srcdir)/ub_loop.c $(srcdir)/ub_loop.h \
config.h \
getdns/getdns.h \
getdns/getdns_extra.h \
$(srcdir)/types-internal.h $(srcdir)/util/rbtree.h $(srcdir)/debug.h
util-internal.lo util-internal.o: $(srcdir)/util-internal.c \
config.h \
getdns/getdns.h \
$(srcdir)/dict.h $(srcdir)/util/rbtree.h $(srcdir)/types-internal.h \
getdns/getdns_extra.h \
$(srcdir)/list.h $(srcdir)/util-internal.h $(srcdir)/context.h $(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)/rr-iter.h $(srcdir)/rr-dict.h $(srcdir)/gldns/gbuffer.h $(srcdir)/gldns/pkthdr.h $(srcdir)/gldns/str2wire.h \
$(srcdir)/gldns/rrdef.h $(srcdir)/dnssec.h $(srcdir)/gldns/rrdef.h
gbuffer.lo gbuffer.o: $(srcdir)/gldns/gbuffer.c \
config.h \
$(srcdir)/gldns/gbuffer.h
parseutil.lo parseutil.o: $(srcdir)/gldns/parseutil.c config.h $(srcdir)/gldns/parseutil.h
rrdef.lo rrdef.o: $(srcdir)/gldns/rrdef.c config.h $(srcdir)/gldns/rrdef.h $(srcdir)/gldns/parseutil.h
str2wire.lo str2wire.o: $(srcdir)/gldns/str2wire.c config.h $(srcdir)/gldns/str2wire.h $(srcdir)/gldns/rrdef.h \
$(srcdir)/gldns/wire2str.h $(srcdir)/gldns/gbuffer.h $(srcdir)/gldns/parse.h $(srcdir)/gldns/parseutil.h
wire2str.lo wire2str.o: $(srcdir)/gldns/wire2str.c config.h $(srcdir)/gldns/wire2str.h $(srcdir)/gldns/str2wire.h \
$(srcdir)/gldns/rrdef.h $(srcdir)/gldns/pkthdr.h $(srcdir)/gldns/parseutil.h $(srcdir)/gldns/gbuffer.h \
$(srcdir)/gldns/keyraw.h
arc4_lock.lo arc4_lock.o: $(srcdir)/compat/arc4_lock.c config.h
arc4random.lo arc4random.o: $(srcdir)/compat/arc4random.c config.h $(srcdir)/compat/chacha_private.h
arc4random_uniform.lo arc4random_uniform.o: $(srcdir)/compat/arc4random_uniform.c config.h
explicit_bzero.lo explicit_bzero.o: $(srcdir)/compat/explicit_bzero.c config.h
getentropy_linux.lo getentropy_linux.o: $(srcdir)/compat/getentropy_linux.c config.h
getentropy_osx.lo getentropy_osx.o: $(srcdir)/compat/getentropy_osx.c config.h
getentropy_solaris.lo getentropy_solaris.o: $(srcdir)/compat/getentropy_solaris.c config.h
keyraw.lo keyraw.o: $(srcdir)/gldns/keyraw.c \
config.h \
$(srcdir)/gldns/keyraw.h $(srcdir)/gldns/rrdef.h
parse.lo parse.o: $(srcdir)/gldns/parse.c \
config.h \
$(srcdir)/gldns/parse.h $(srcdir)/gldns/parseutil.h $(srcdir)/gldns/gbuffer.h
parseutil.lo parseutil.o: $(srcdir)/gldns/parseutil.c \
config.h \
$(srcdir)/gldns/parseutil.h
rrdef.lo rrdef.o: $(srcdir)/gldns/rrdef.c \
config.h \
$(srcdir)/gldns/rrdef.h $(srcdir)/gldns/parseutil.h
str2wire.lo str2wire.o: $(srcdir)/gldns/str2wire.c \
config.h \
$(srcdir)/gldns/str2wire.h $(srcdir)/gldns/rrdef.h $(srcdir)/gldns/wire2str.h $(srcdir)/gldns/gbuffer.h \
$(srcdir)/gldns/parse.h $(srcdir)/gldns/parseutil.h
wire2str.lo wire2str.o: $(srcdir)/gldns/wire2str.c \
config.h \
$(srcdir)/gldns/wire2str.h $(srcdir)/gldns/str2wire.h $(srcdir)/gldns/rrdef.h $(srcdir)/gldns/pkthdr.h \
$(srcdir)/gldns/parseutil.h $(srcdir)/gldns/gbuffer.h $(srcdir)/gldns/keyraw.h
arc4_lock.lo arc4_lock.o: $(srcdir)/compat/arc4_lock.c \
config.h
arc4random.lo arc4random.o: $(srcdir)/compat/arc4random.c \
config.h \
$(srcdir)/compat/chacha_private.h
arc4random_uniform.lo arc4random_uniform.o: $(srcdir)/compat/arc4random_uniform.c \
config.h
explicit_bzero.lo explicit_bzero.o: $(srcdir)/compat/explicit_bzero.c \
config.h
getentropy_linux.lo getentropy_linux.o: $(srcdir)/compat/getentropy_linux.c \
config.h
getentropy_osx.lo getentropy_osx.o: $(srcdir)/compat/getentropy_osx.c \
config.h
getentropy_solaris.lo getentropy_solaris.o: $(srcdir)/compat/getentropy_solaris.c \
config.h
getentropy_win.lo getentropy_win.o: $(srcdir)/compat/getentropy_win.c
gettimeofday.lo gettimeofday.o: $(srcdir)/compat/gettimeofday.c config.h
inet_ntop.lo inet_ntop.o: $(srcdir)/compat/inet_ntop.c config.h
inet_pton.lo inet_pton.o: $(srcdir)/compat/inet_pton.c config.h
sha512.lo sha512.o: $(srcdir)/compat/sha512.c config.h
strlcpy.lo strlcpy.o: $(srcdir)/compat/strlcpy.c config.h
rbtree.lo rbtree.o: $(srcdir)/util/rbtree.c config.h $(srcdir)/util/log.h $(srcdir)/debug.h config.h \
$(srcdir)/util/fptr_wlist.h $(srcdir)/util/rbtree.h
val_secalgo.lo val_secalgo.o: $(srcdir)/util/val_secalgo.c config.h $(srcdir)/util/val_secalgo.h $(srcdir)/util/log.h \
$(srcdir)/debug.h config.h $(srcdir)/gldns/rrdef.h $(srcdir)/gldns/keyraw.h $(srcdir)/gldns/gbuffer.h
gettimeofday.lo gettimeofday.o: $(srcdir)/compat/gettimeofday.c \
config.h
inet_ntop.lo inet_ntop.o: $(srcdir)/compat/inet_ntop.c \
config.h
inet_pton.lo inet_pton.o: $(srcdir)/compat/inet_pton.c \
config.h
sha512.lo sha512.o: $(srcdir)/compat/sha512.c \
config.h
strlcpy.lo strlcpy.o: $(srcdir)/compat/strlcpy.c \
config.h
rbtree.lo rbtree.o: $(srcdir)/util/rbtree.c \
config.h \
$(srcdir)/util/log.h $(srcdir)/debug.h $(srcdir)/util/fptr_wlist.h $(srcdir)/util/rbtree.h
val_secalgo.lo val_secalgo.o: $(srcdir)/util/val_secalgo.c \
config.h \
$(srcdir)/util/val_secalgo.h $(srcdir)/util/log.h $(srcdir)/debug.h $(srcdir)/gldns/rrdef.h $(srcdir)/gldns/keyraw.h \
$(srcdir)/gldns/gbuffer.h
jsmn.lo jsmn.o: $(srcdir)/jsmn/jsmn.c $(srcdir)/jsmn/jsmn.h
default_eventloop.lo default_eventloop.o: $(srcdir)/extension/default_eventloop.c config.h \
$(srcdir)/extension/default_eventloop.h getdns/getdns.h getdns/getdns_extra.h \
$(srcdir)/debug.h config.h $(srcdir)/types-internal.h getdns/getdns.h getdns/getdns_extra.h \
$(srcdir)/util/rbtree.h
libev.lo libev.o: $(srcdir)/extension/libev.c config.h $(srcdir)/types-internal.h getdns/getdns.h \
getdns/getdns_extra.h getdns/getdns.h $(srcdir)/util/rbtree.h \
$(srcdir)/getdns/getdns_ext_libev.h getdns/getdns_extra.h
libevent.lo libevent.o: $(srcdir)/extension/libevent.c config.h $(srcdir)/types-internal.h \
getdns/getdns.h getdns/getdns_extra.h getdns/getdns.h $(srcdir)/util/rbtree.h \
$(srcdir)/getdns/getdns_ext_libevent.h getdns/getdns_extra.h
libuv.lo libuv.o: $(srcdir)/extension/libuv.c config.h $(srcdir)/debug.h config.h $(srcdir)/types-internal.h \
getdns/getdns.h getdns/getdns_extra.h getdns/getdns.h $(srcdir)/util/rbtree.h \
$(srcdir)/getdns/getdns_ext_libuv.h getdns/getdns_extra.h
libev.lo libev.o: $(srcdir)/extension/libev.c \
config.h \
$(srcdir)/types-internal.h \
getdns/getdns.h \
getdns/getdns_extra.h \
$(srcdir)/util/rbtree.h $(srcdir)/getdns/getdns_ext_libev.h
libevent.lo libevent.o: $(srcdir)/extension/libevent.c \
config.h \
$(srcdir)/types-internal.h \
getdns/getdns.h \
getdns/getdns_extra.h \
$(srcdir)/util/rbtree.h $(srcdir)/getdns/getdns_ext_libevent.h
libuv.lo libuv.o: $(srcdir)/extension/libuv.c \
config.h \
$(srcdir)/debug.h $(srcdir)/types-internal.h \
getdns/getdns.h \
getdns/getdns_extra.h \
$(srcdir)/util/rbtree.h $(srcdir)/getdns/getdns_ext_libuv.h
poll_eventloop.lo poll_eventloop.o: $(srcdir)/extension/poll_eventloop.c \
config.h \
$(srcdir)/extension/poll_eventloop.h \
getdns/getdns.h \
getdns/getdns_extra.h \
$(srcdir)/types-internal.h $(srcdir)/util/rbtree.h $(srcdir)/debug.h
select_eventloop.lo select_eventloop.o: $(srcdir)/extension/select_eventloop.c \
config.h \
$(srcdir)/extension/select_eventloop.h \
getdns/getdns.h \
getdns/getdns_extra.h \
$(srcdir)/debug.h $(srcdir)/types-internal.h $(srcdir)/util/rbtree.h

View File

@ -24,6 +24,7 @@ static struct const_info consts_info[] = {
{ 310, "GETDNS_RETURN_MEMORY_ERROR", GETDNS_RETURN_MEMORY_ERROR_TEXT },
{ 311, "GETDNS_RETURN_INVALID_PARAMETER", GETDNS_RETURN_INVALID_PARAMETER_TEXT },
{ 312, "GETDNS_RETURN_NOT_IMPLEMENTED", GETDNS_RETURN_NOT_IMPLEMENTED_TEXT },
{ 398, "GETDNS_RETURN_NO_UPSTREAM_AVAILABLE", GETDNS_RETURN_NO_UPSTREAM_AVAILABLE_TEXT },
{ 399, "GETDNS_RETURN_NEED_MORE_SPACE", GETDNS_RETURN_NEED_MORE_SPACE_TEXT },
{ 400, "GETDNS_DNSSEC_SECURE", GETDNS_DNSSEC_SECURE_TEXT },
{ 401, "GETDNS_DNSSEC_BOGUS", GETDNS_DNSSEC_BOGUS_TEXT },
@ -223,6 +224,7 @@ static struct const_name_info consts_name_info[] = {
{ "GETDNS_RETURN_NO_SUCH_DICT_NAME", 305 },
{ "GETDNS_RETURN_NO_SUCH_EXTENSION", 307 },
{ "GETDNS_RETURN_NO_SUCH_LIST_ITEM", 304 },
{ "GETDNS_RETURN_NO_UPSTREAM_AVAILABLE", 398 },
{ "GETDNS_RETURN_UNKNOWN_TRANSACTION", 303 },
{ "GETDNS_RETURN_WRONG_TYPE_REQUESTED", 306 },
{ "GETDNS_RRCLASS_ANY", 255 },

View File

@ -145,8 +145,7 @@ static getdns_return_t create_default_namespaces(struct getdns_context *context)
static getdns_return_t create_default_dns_transports(struct getdns_context *context);
static int transaction_id_cmp(const void *, const void *);
static void dispatch_updated(struct getdns_context *, uint16_t);
static void cancel_dns_req(getdns_dns_req *);
static void cancel_outstanding_requests(struct getdns_context*, int);
static void cancel_outstanding_requests(getdns_context*);
/* unbound helpers */
#ifdef HAVE_LIBUNBOUND
@ -692,8 +691,7 @@ _getdns_upstreams_dereference(getdns_upstreams *upstreams)
while (upstream->finished_dnsreqs) {
dnsreq = upstream->finished_dnsreqs;
upstream->finished_dnsreqs = dnsreq->finished_next;
(void) _getdns_context_cancel_request(dnsreq->context,
dnsreq->trans_id, 1);
_getdns_context_cancel_request(dnsreq);
}
if (upstream->tls_obj != NULL) {
if (upstream->tls_session != NULL)
@ -1377,7 +1375,7 @@ getdns_context_create_with_extended_memory_functions(
result->suffixes = no_suffixes;
result->suffixes_len = sizeof(no_suffixes);
gldns_buffer_init_frm_data(&gbuf, result->trust_anchors_spc
gldns_buffer_init_vfixed_frm_data(&gbuf, result->trust_anchors_spc
, sizeof(result->trust_anchors_spc));
if (!_getdns_parse_ta_file(NULL, &gbuf)) {
@ -1411,8 +1409,8 @@ getdns_context_create_with_extended_memory_functions(
result->tls_ctx = NULL;
result->extension = &result->default_eventloop.loop;
_getdns_default_eventloop_init(&result->default_eventloop);
_getdns_default_eventloop_init(&result->sync_eventloop);
_getdns_default_eventloop_init(&result->mf, &result->default_eventloop);
_getdns_default_eventloop_init(&result->mf, &result->sync_eventloop);
/* request extension defaults
*/
@ -1550,7 +1548,7 @@ getdns_context_destroy(struct getdns_context *context)
context->destroying = 1;
/* cancel all outstanding requests */
cancel_outstanding_requests(context, 1);
cancel_outstanding_requests(context);
/* Destroy listening addresses */
(void) getdns_context_set_listen_addresses(context, NULL, NULL, NULL);
@ -1741,7 +1739,7 @@ static getdns_return_t
rebuild_ub_ctx(struct getdns_context* context) {
if (context->unbound_ctx != NULL) {
/* cancel all requests and delete */
cancel_outstanding_requests(context, 1);
cancel_outstanding_requests(context);
ub_ctx_delete(context->unbound_ctx);
context->unbound_ctx = NULL;
}
@ -2369,7 +2367,7 @@ getdns_context_set_suffix(getdns_context *context, getdns_list *value)
context->suffixes_len = sizeof(no_suffixes);
return GETDNS_RETURN_GOOD;
}
gldns_buffer_init_frm_data(&gbuf, buf_spc, sizeof(buf_spc));
gldns_buffer_init_vfixed_frm_data(&gbuf, buf_spc, sizeof(buf_spc));
for (;;) {
for ( i = 0
; !(r = getdns_list_get_bindata(value, i, &bindata))
@ -2918,28 +2916,68 @@ getdns_context_set_memory_functions(struct getdns_context *context,
context, MF_PLAIN, mf.ext.malloc, mf.ext.realloc, mf.ext.free);
} /* getdns_context_set_memory_functions*/
/* cancel the request */
static void
cancel_dns_req(getdns_dns_req *req)
void
_getdns_context_track_outbound_request(getdns_dns_req *dnsreq)
{
/* Called only by getdns_general_ns() after successful allocation */
assert(dnsreq);
dnsreq->node.key = &(dnsreq->trans_id);
if (_getdns_rbtree_insert(
&dnsreq->context->outbound_requests, &dnsreq->node))
getdns_context_request_count_changed(dnsreq->context);
}
void
_getdns_context_clear_outbound_request(getdns_dns_req *dnsreq)
{
if (!dnsreq) return;
if (dnsreq->loop && dnsreq->loop->vmt && dnsreq->timeout.timeout_cb) {
dnsreq->loop->vmt->clear(dnsreq->loop, &dnsreq->timeout);
dnsreq->timeout.timeout_cb = NULL;
}
/* delete the node from the tree */
if (_getdns_rbtree_delete(
&dnsreq->context->outbound_requests, &dnsreq->trans_id))
getdns_context_request_count_changed(dnsreq->context);
if (dnsreq->chain)
_getdns_cancel_validation_chain(dnsreq);
}
void
_getdns_context_cancel_request(getdns_dns_req *dnsreq)
{
getdns_network_req *netreq, **netreq_p;
for (netreq_p = req->netreqs; (netreq = *netreq_p); netreq_p++)
DEBUG_SCHED("%s(%p)\n", __FUNC__, (void *)dnsreq);
if (!dnsreq) return;
_getdns_context_clear_outbound_request(dnsreq);
/* cancel network requests */
for (netreq_p = dnsreq->netreqs; (netreq = *netreq_p); netreq_p++)
#ifdef HAVE_LIBUNBOUND
if (netreq->unbound_id != -1) {
ub_cancel(req->context->unbound_ctx,
ub_cancel(dnsreq->context->unbound_ctx,
netreq->unbound_id);
netreq->unbound_id = -1;
} else
#endif
_getdns_cancel_stub_request(netreq);
req->canceled = 1;
/* clean up */
_getdns_dns_req_free(dnsreq);
}
/*
* getdns_cancel_callback
*
*/
getdns_return_t
_getdns_context_cancel_request(getdns_context *context,
getdns_transaction_t transaction_id, int fire_callback)
getdns_cancel_callback(getdns_context *context,
getdns_transaction_t transaction_id)
{
getdns_dns_req *dnsreq;
@ -2951,37 +2989,65 @@ _getdns_context_cancel_request(getdns_context *context,
&context->outbound_requests, &transaction_id)))
return GETDNS_RETURN_UNKNOWN_TRANSACTION;
/* do the cancel */
cancel_dns_req(dnsreq);
if (fire_callback) {
context->processing = 1;
dnsreq->user_callback(context, GETDNS_CALLBACK_CANCEL,
NULL, dnsreq->user_pointer, transaction_id);
context->processing = 0;
}
/* clean up */
_getdns_dns_req_free(dnsreq);
return GETDNS_RETURN_GOOD;
}
/*
* getdns_cancel_callback
*
*/
getdns_return_t
getdns_cancel_callback(getdns_context *context,
getdns_transaction_t transaction_id)
{
if (!context)
return GETDNS_RETURN_INVALID_PARAMETER;
getdns_return_t r = _getdns_context_cancel_request(context, transaction_id, 1);
getdns_context_request_count_changed(context);
return r;
if (dnsreq->user_callback) {
dnsreq->context->processing = 1;
dnsreq->user_callback(dnsreq->context, GETDNS_CALLBACK_CANCEL,
NULL, dnsreq->user_pointer, dnsreq->trans_id);
dnsreq->context->processing = 0;
}
_getdns_context_cancel_request(dnsreq);
return GETDNS_RETURN_GOOD;
} /* getdns_cancel_callback */
void
_getdns_context_request_timed_out(getdns_dns_req *dnsreq)
{
DEBUG_SCHED("%s(%p)\n", __FUNC__, (void *)dnsreq);
if (dnsreq->user_callback) {
dnsreq->context->processing = 1;
dnsreq->user_callback(dnsreq->context, GETDNS_CALLBACK_TIMEOUT,
_getdns_create_getdns_response(dnsreq),
dnsreq->user_pointer, dnsreq->trans_id);
dnsreq->context->processing = 0;
}
_getdns_context_cancel_request(dnsreq);
}
static void
accumulate_outstanding_transactions(_getdns_rbnode_t *node, void* arg)
{
*(*(getdns_transaction_t**)arg)++ = ((getdns_dns_req*)node)->trans_id;
}
static void
cancel_outstanding_requests(getdns_context* context)
{
getdns_transaction_t *trans_ids, *tids_a, *tids_i;
if (context->outbound_requests.count == 0)
return;
tids_i = tids_a = trans_ids = GETDNS_XMALLOC(context->my_mf,
getdns_transaction_t, context->outbound_requests.count);
_getdns_traverse_postorder(&context->outbound_requests,
accumulate_outstanding_transactions, &tids_a);
while (tids_i < tids_a) {
/* We have to cancel by transaction_id because we do not know
* what happens when the user_callback is called. It might
* delete getdns_dns_req's that were scheduled to be canceled.
* The extra lookup with transaction_id makes sure we do not
* access freed memory.
*/
(void) getdns_cancel_callback(context, *tids_i++);
}
GETDNS_FREE(context->my_mf, trans_ids);
}
#ifndef STUB_NATIVE_DNSSEC
@ -3267,54 +3333,6 @@ _getdns_context_prepare_for_resolution(struct getdns_context *context,
return r;
} /* _getdns_context_prepare_for_resolution */
getdns_return_t
_getdns_context_track_outbound_request(getdns_dns_req *dnsreq)
{
if (!dnsreq)
return GETDNS_RETURN_INVALID_PARAMETER;
dnsreq->node.key = &(dnsreq->trans_id);
if (!_getdns_rbtree_insert(
&dnsreq->context->outbound_requests, &dnsreq->node))
return GETDNS_RETURN_GENERIC_ERROR;
getdns_context_request_count_changed(dnsreq->context);
return GETDNS_RETURN_GOOD;
}
getdns_return_t
_getdns_context_clear_outbound_request(getdns_dns_req *dnsreq)
{
if (!dnsreq)
return GETDNS_RETURN_INVALID_PARAMETER;
if (!_getdns_rbtree_delete(
&dnsreq->context->outbound_requests, &dnsreq->trans_id))
return GETDNS_RETURN_GENERIC_ERROR;
getdns_context_request_count_changed(dnsreq->context);
return GETDNS_RETURN_GOOD;
}
getdns_return_t
_getdns_context_request_timed_out(getdns_dns_req *req)
{
/* Don't use req after callback */
getdns_context* context = req->context;
getdns_transaction_t trans_id = req->trans_id;
getdns_callback_t cb = req->user_callback;
void *user_arg = req->user_pointer;
getdns_dict *response = _getdns_create_getdns_response(req);
/* cancel the req - also clears it from outbound and cleans up*/
_getdns_context_cancel_request(context, trans_id, 0);
context->processing = 1;
cb(context, GETDNS_CALLBACK_TIMEOUT, response, user_arg, trans_id);
context->processing = 0;
getdns_context_request_count_changed(context);
return GETDNS_RETURN_GOOD;
}
char *
_getdns_strdup(const struct mem_funcs *mfs, const char *s)
{
@ -3396,33 +3414,6 @@ getdns_context_run(getdns_context *context)
context->extension->vmt->run(context->extension);
}
typedef struct timeout_accumulator {
getdns_transaction_t* ids;
int idx;
} timeout_accumulator;
static void
accumulate_outstanding_transactions(_getdns_rbnode_t* node, void* arg) {
timeout_accumulator* acc = (timeout_accumulator*) arg;
acc->ids[acc->idx] = *((getdns_transaction_t*) node->key);
acc->idx++;
}
static void
cancel_outstanding_requests(struct getdns_context* context, int fire_callback) {
if (context->outbound_requests.count > 0) {
timeout_accumulator acc;
int i;
acc.idx = 0;
acc.ids = GETDNS_XMALLOC(context->my_mf, getdns_transaction_t, context->outbound_requests.count);
_getdns_traverse_postorder(&context->outbound_requests, accumulate_outstanding_transactions, &acc);
for (i = 0; i < acc.idx; ++i) {
_getdns_context_cancel_request(context, acc.ids[i], fire_callback);
}
GETDNS_FREE(context->my_mf, acc.ids);
}
}
getdns_return_t
getdns_context_detach_eventloop(struct getdns_context* context)
{
@ -3436,10 +3427,10 @@ getdns_context_detach_eventloop(struct getdns_context* context)
* and they may destroy the context )
*/
/* cancel all outstanding requests */
cancel_outstanding_requests(context, 1);
cancel_outstanding_requests(context);
context->extension->vmt->cleanup(context->extension);
context->extension = &context->default_eventloop.loop;
_getdns_default_eventloop_init(&context->default_eventloop);
_getdns_default_eventloop_init(&context->mf, &context->default_eventloop);
#ifdef HAVE_UNBOUND_EVENT_API
if (_getdns_ub_loop_enabled(&context->ub_loop))
context->ub_loop.extension = context->extension;
@ -3454,7 +3445,7 @@ getdns_context_set_eventloop(getdns_context* context, getdns_eventloop* loop)
return GETDNS_RETURN_INVALID_PARAMETER;
if (context->extension) {
cancel_outstanding_requests(context, 1);
cancel_outstanding_requests(context);
context->extension->vmt->cleanup(context->extension);
}
context->extension = loop;

View File

@ -366,19 +366,34 @@ struct getdns_context {
getdns_return_t _getdns_context_prepare_for_resolution(struct getdns_context *context,
int usenamespaces);
/* track an outbound request */
getdns_return_t _getdns_context_track_outbound_request(struct getdns_dns_req
*req);
/* clear the outbound request from being tracked - does not cancel it */
getdns_return_t _getdns_context_clear_outbound_request(struct getdns_dns_req
*req);
/* Register a getdns_dns_req with context.
* - Without pluggable unbound event API,
* ub_fd() is scheduled when this was the first request.
*/
void _getdns_context_track_outbound_request(getdns_dns_req *dnsreq);
getdns_return_t _getdns_context_request_timed_out(struct getdns_dns_req
*req);
/* Deregister getdns_dns_req from the context.
* - Without pluggable unbound event API,
* ub_fd() is scheduled when this was the first request.
* - Potential timeout events will be cleared.
* - All associated getdns_dns_reqs (to get the validation chain)
* will be canceled.
*/
void _getdns_context_clear_outbound_request(getdns_dns_req *dnsreq);
/* cancel callback internal - flag to indicate if req should be freed and callback fired */
getdns_return_t _getdns_context_cancel_request(struct getdns_context *context,
getdns_transaction_t transaction_id, int fire_callback);
/* Cancels and frees a getdns_dns_req (without calling user callbacks)
* - Deregisters getdns_dns_req with _getdns_context_clear_outbound_request()
* - Cancels associated getdns_network_reqs
* (by calling ub_cancel() or _getdns_cancel_stub_request())
* - Frees the getdns_dns_req
*/
void _getdns_context_cancel_request(getdns_dns_req *dnsreq);
/* Calls user callback (with GETDNS_CALLBACK_TIMEOUT + response dict), then
* cancels and frees the getdns_dns_req with _getdns_context_cancel_request()
*/
void _getdns_context_request_timed_out(getdns_dns_req *dnsreq);
char *_getdns_strdup(const struct mem_funcs *mfs, const char *str);

View File

@ -297,7 +297,7 @@ getdns_rr_dict2wire_scan(
return GETDNS_RETURN_INVALID_PARAMETER;
gldns_buffer_init_frm_data(&gbuf, *wire, *wire_sz);
gldns_buffer_init_vfixed_frm_data(&gbuf, *wire, *wire_sz);
if ((r = _getdns_rr_dict2wire(rr_dict, &gbuf)))
return r;
@ -447,7 +447,7 @@ getdns_rr_dict2str_scan(
if (!rr_dict || !str || !*str || !str_len)
return GETDNS_RETURN_INVALID_PARAMETER;
gldns_buffer_init_frm_data(&gbuf, buf, sizeof(buf_spc));
gldns_buffer_init_vfixed_frm_data(&gbuf, buf, sizeof(buf_spc));
r = _getdns_rr_dict2wire(rr_dict, &gbuf);
if (gldns_buffer_position(&gbuf) > sizeof(buf_spc)) {
if (!(buf = GETDNS_XMALLOC(
@ -960,7 +960,7 @@ getdns_msg_dict2wire_scan(
if (!msg_dict || !wire || !wire_sz || (!*wire && *wire_sz))
return GETDNS_RETURN_INVALID_PARAMETER;
gldns_buffer_init_frm_data(&gbuf, *wire, *wire_sz);
gldns_buffer_init_vfixed_frm_data(&gbuf, *wire, *wire_sz);
if ((r = _getdns_msg_dict2wire_buf(msg_dict, &gbuf)))
return r;
@ -1036,7 +1036,7 @@ getdns_msg_dict2str_scan(
if (!msg_dict || !str || !*str || !str_len)
return GETDNS_RETURN_INVALID_PARAMETER;
gldns_buffer_init_frm_data(&gbuf, buf, sizeof(buf_spc));
gldns_buffer_init_vfixed_frm_data(&gbuf, buf, sizeof(buf_spc));
r = _getdns_msg_dict2wire_buf(msg_dict, &gbuf);
if (gldns_buffer_position(&gbuf) > sizeof(buf_spc)) {
if (!(buf = GETDNS_XMALLOC(
@ -1204,6 +1204,63 @@ static int _jsmn_get_ipdict(struct mem_funcs *mf, const char *js, jsmntok_t *t,
return *value != NULL;
}
static int _jsmn_get_base64_data(struct mem_funcs *mf, const char *js, jsmntok_t *t,
getdns_bindata **value)
{
int e, i;
int size = t->end - t->start;
char value_str_buf[1025];
char *value_str;
size_t target_buf_size;
assert(size >= 4);
if (size % 4 != 0)
return 0;
e = t->end;
if (js[e - 1] == '=') e -= 1;
if (js[e - 1] == '=') e -= 1;
for (i = t->start; i < e; i++)
if (!((js[i] >= '0' && js[i] <= '9')
||(js[i] >= 'a' && js[i] <= 'z')
||(js[i] >= 'A' && js[i] <= 'Z')
|| js[i] == '+' || js[i] == '/'))
return 0;
target_buf_size = gldns_b64_pton_calculate_size(size);
if (!(*value = GETDNS_MALLOC(*mf, getdns_bindata)))
return 0;
else if (!((*value)->data = GETDNS_XMALLOC(
*mf, uint8_t, target_buf_size))) {
GETDNS_FREE(*mf, *value);
return 0;
}
if ((size_t)size >= sizeof(value_str_buf))
value_str = GETDNS_XMALLOC(*mf, char, size + 1);
else value_str = value_str_buf;
if (value_str) {
(void) memcpy(value_str, js + t->start, size);
value_str[size] = '\0';
e = gldns_b64_pton(value_str, (*value)->data, target_buf_size);
if (value_str != value_str_buf)
GETDNS_FREE(*mf, value_str);
if (e > 0) {
(*value)->size = e;
return 1;
}
}
GETDNS_FREE(*mf, (*value)->data);
GETDNS_FREE(*mf, *value);
return 0;
}
static int _jsmn_get_data(struct mem_funcs *mf, const char *js, jsmntok_t *t,
getdns_bindata **value)
{
@ -1211,15 +1268,17 @@ static int _jsmn_get_data(struct mem_funcs *mf, const char *js, jsmntok_t *t,
size_t j;
uint8_t h, l;
if ((t->end - t->start) < 4 || (t->end - t->start) % 2 == 1 ||
js[t->start] != '0' || js[t->start + 1] != 'x')
if ((t->end - t->start) < 4 || (t->end - t->start) % 2 == 1)
return 0;
if (js[t->start] != '0' || js[t->start + 1] != 'x')
return _jsmn_get_base64_data(mf, js, t, value);
for (i = t->start + 2; i < t->end; i++)
if (!((js[i] >= '0' && js[i] <= '9')
||(js[i] >= 'a' && js[i] <= 'f')
||(js[i] >= 'A' && js[i] <= 'F')))
return 0;
return _jsmn_get_base64_data(mf, js, t, value);
if (!(*value = GETDNS_MALLOC(*mf, getdns_bindata)))
return 0;

View File

@ -51,6 +51,7 @@
#include "const-info.h"
#include "gldns/gbuffer.h"
#include "gldns/wire2str.h"
#include "gldns/parseutil.h"
static char *_json_ptr_first(const struct mem_funcs *mf,
@ -731,6 +732,33 @@ _getdns_bindata_is_dname(getdns_bindata *bindata)
bindata->data[bindata->size - 1] == 0;
}
static int
getdns_pp_base64(gldns_buffer *buf, getdns_bindata *bindata)
{
size_t p = gldns_buffer_position(buf);
size_t base64str_sz;
char *target;
size_t avail;
if (gldns_buffer_printf(buf, " <bindata of ") < 0)
return -1;
base64str_sz = gldns_b64_ntop_calculate_size(bindata->size);
target = (char *)gldns_buffer_current(buf);
avail = gldns_buffer_remaining(buf);
if (avail >= base64str_sz)
gldns_buffer_skip(buf, gldns_b64_ntop(
bindata->data, bindata->size,
target, base64str_sz));
else
gldns_buffer_skip(buf, base64str_sz);
if (gldns_buffer_printf(buf, ">") < 0)
return -1;
return gldns_buffer_position(buf) - p;
}
/*---------------------------------------- getdns_pp_bindata */
/**
* private function to pretty print bindata to a gldns_buffer
@ -1094,6 +1122,16 @@ getdns_pp_dict(gldns_buffer * buf, size_t indent,
)) < 0)
return -1;
} else if (!json &&
(strcmp(item->node.key, "pin-sha256") == 0 ||
strcmp(item->node.key, "value") == 0) &&
item->i.data.bindata->size > 0 &&
item->i.data.bindata->size % 4 == 0) {
if (getdns_pp_base64(buf,
item->i.data.bindata) < 0)
return -1;
} else if (getdns_pp_bindata(
buf, item->i.data.bindata,
(strcmp(item->node.key, "rdata_raw") == 0),
@ -1186,7 +1224,7 @@ getdns_pretty_snprint_dict(char *str, size_t size, const getdns_dict *dict)
if (!dict) return -1;
gldns_buffer_init_frm_data(&buf, str, size);
gldns_buffer_init_vfixed_frm_data(&buf, str, size);
return getdns_pp_dict(&buf, 0, dict, 0) < 0
? -1 : (int)gldns_buffer_position(&buf);
}
@ -1220,7 +1258,7 @@ getdns_pretty_snprint_list(char *str, size_t size, const getdns_list *list)
if (!list) return -1;
gldns_buffer_init_frm_data(&buf, str, size);
gldns_buffer_init_vfixed_frm_data(&buf, str, size);
return getdns_pp_list(&buf, 0, list, 0, 0) < 0
? -1 : (int)gldns_buffer_position(&buf);
}
@ -1255,7 +1293,7 @@ getdns_snprint_json_dict(
if (!dict) return -1;
gldns_buffer_init_frm_data(&buf, str, size);
gldns_buffer_init_vfixed_frm_data(&buf, str, size);
return getdns_pp_dict(&buf, 0, dict, pretty ? 1 : 2) < 0
? -1 : (int)gldns_buffer_position(&buf);
}
@ -1290,7 +1328,7 @@ getdns_snprint_json_list(
if (!list) return -1;
gldns_buffer_init_frm_data(&buf, str, size);
gldns_buffer_init_vfixed_frm_data(&buf, str, size);
return getdns_pp_list(&buf, 0, list, 0, pretty ? 1 : 2) < 0
? -1 : (int)gldns_buffer_position(&buf);
}

View File

@ -1044,7 +1044,6 @@ static void val_chain_node_cb(getdns_dns_req *dnsreq)
_getdns_rrsig_iter *rrsig, rrsig_spc;
size_t n_signers;
_getdns_context_clear_outbound_request(dnsreq);
switch (netreq->request_type) {
case GETDNS_RRTYPE_DS : node->ds.pkt = netreq->response;
node->ds.pkt_len = netreq->response_len;
@ -1094,7 +1093,6 @@ static void val_chain_node_soa_cb(getdns_dns_req *dnsreq)
_getdns_rrset_iter i_spc, *i;
_getdns_rrset *rrset;
_getdns_context_clear_outbound_request(dnsreq);
/* A SOA query is always scheduled with a node as the user argument.
*/
assert(node != NULL);
@ -1121,9 +1119,11 @@ static void val_chain_node_soa_cb(getdns_dns_req *dnsreq)
} else {
/* SOA for a different name */
node = (chain_node *)dnsreq->user_pointer;
if (node->parent) {
node->lock++;
val_chain_sched_soa_node(node->parent);
}
}
} else if (node->parent) {
node->lock++;
@ -3049,7 +3049,10 @@ static void check_chain_complete(chain_head *chain)
val_chain_list = dnsreq->dnssec_return_validation_chain
? getdns_list_create_with_context(context) : NULL;
/* Walk chain to add values to val_chain_list and to cleanup */
/* Walk chain to add values to val_chain_list. We do not cleanup yet.
* The chain will eventually be freed when the dns request is descheduled
* with getdns_context_clear_outbound_request().
*/
for ( head = chain; head ; head = next ) {
next = head->next;
if (dnsreq->dnssec_return_full_validation_chain &&
@ -3076,7 +3079,6 @@ static void check_chain_complete(chain_head *chain)
context, val_chain_list,
node->dnskey_req,
node->dnskey_signer);
_getdns_dns_req_free(node->dnskey_req->owner);
}
if (node->ds_req) {
if (val_chain_list)
@ -3094,13 +3096,8 @@ static void check_chain_complete(chain_head *chain)
context, val_chain_list,
&node->ds);
}
_getdns_dns_req_free(node->ds_req->owner);
}
if (node->soa_req) {
_getdns_dns_req_free(node->soa_req->owner);
}
}
GETDNS_FREE(head->my_mf, head);
}
response_dict = _getdns_create_getdns_response(dnsreq);
@ -3115,6 +3112,36 @@ static void check_chain_complete(chain_head *chain)
_getdns_call_user_callback(dnsreq, response_dict);
}
void _getdns_cancel_validation_chain(getdns_dns_req *dnsreq)
{
chain_head *head = dnsreq->chain, *next;
chain_node *node;
size_t node_count;
dnsreq->chain = NULL;
while (head) {
next = head->next;
for ( node_count = head->node_count, node = head->parent
; node_count
; node_count--, node = node->parent ) {
if (node->dnskey_req)
_getdns_context_cancel_request(
node->dnskey_req->owner);
if (node->ds_req)
_getdns_context_cancel_request(
node->ds_req->owner);
if (node->soa_req)
_getdns_context_cancel_request(
node->soa_req->owner);
}
GETDNS_FREE(head->my_mf, head);
head = next;
}
}
void _getdns_get_validation_chain(getdns_dns_req *dnsreq)
{
@ -3152,6 +3179,7 @@ void _getdns_get_validation_chain(getdns_dns_req *dnsreq)
for (chain_p = chain; chain_p; chain_p = chain_p->next) {
if (chain_p->lock) chain_p->lock--;
}
dnsreq->chain = chain;
check_chain_complete(chain);
} else {
dnsreq->validating = 0;

View File

@ -46,6 +46,7 @@
/* Do some additional requests to fetch the complete validation chain */
void _getdns_get_validation_chain(getdns_dns_req *dns_req);
void _getdns_cancel_validation_chain(getdns_dns_req *dns_req);
uint16_t _getdns_parse_ta_file(time_t *ta_mtime, gldns_buffer *gbuf);

View File

@ -1,6 +1,6 @@
/*
* \file default_eventloop.h
* @brief Build in default eventloop extension that uses select.
* @brief Build in default eventloop extension that uses either poll or select.
*
*/
/*
@ -32,28 +32,13 @@
#ifndef DEFAULT_EVENTLOOP_H_
#define DEFAULT_EVENTLOOP_H_
#include "config.h"
#include "getdns/getdns.h"
#include "getdns/getdns_extra.h"
/* No more than select's capability queries can be outstanding,
* The number of outstanding timeouts should be less or equal then
* the number of outstanding queries, so MAX_TIMEOUTS equal to
* FD_SETSIZE should be safe.
*/
#define MAX_TIMEOUTS FD_SETSIZE
/* Eventloop based on select */
typedef struct _getdns_default_eventloop {
getdns_eventloop loop;
getdns_eventloop_event *fd_events[FD_SETSIZE];
uint64_t fd_timeout_times[FD_SETSIZE];
getdns_eventloop_event *timeout_events[MAX_TIMEOUTS];
uint64_t timeout_times[MAX_TIMEOUTS];
} _getdns_default_eventloop;
void
_getdns_default_eventloop_init(_getdns_default_eventloop *loop);
#ifdef USE_POLL_DEFAULT_EVENTLOOP
#include "extension/poll_eventloop.h"
#define _getdns_default_eventloop _getdns_poll_eventloop
#define _getdns_default_eventloop_init _getdns_poll_eventloop_init
#else
#include "extension/select_eventloop.h"
#define _getdns_default_eventloop _getdns_select_eventloop
#define _getdns_default_eventloop_init _getdns_select_eventloop_init
#endif
#endif

View File

@ -0,0 +1,545 @@
/*
* Copyright (c) 2013, NLNet Labs, Verisign, Inc.
* 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.
*/
#include "config.h"
#ifdef HAVE_SYS_POLL_H
#include <sys/poll.h>
#else
#include <poll.h>
#endif
#ifdef HAVE_SYS_RESOURCE_H
#include <sys/resource.h>
#endif
#include "extension/poll_eventloop.h"
#include "debug.h"
enum { init_fd_events_capacity = 64
, init_to_events_capacity = 64 };
static void *get_to_event(_getdns_poll_eventloop *loop,
getdns_eventloop_event *event, uint64_t timeout_time)
{
if (loop->to_events_free == loop->to_events_capacity) {
if (loop->to_events_free) {
_getdns_poll_event *to_events = GETDNS_XREALLOC(
loop->mf, loop->to_events, _getdns_poll_event,
loop->to_events_free * 2);
if (!to_events)
return NULL;
(void) memset(&to_events[loop->to_events_free],
0, sizeof(_getdns_poll_event)
* loop->to_events_free);
loop->to_events_capacity = loop->to_events_free * 2;
loop->to_events = to_events;
} else {
if (!(loop->to_events = GETDNS_XMALLOC(loop->mf,
_getdns_poll_event, init_to_events_capacity)))
return NULL;
(void) memset(loop->to_events, 0,
sizeof(_getdns_poll_event)
* init_to_events_capacity);
loop->to_events_capacity = init_to_events_capacity;
}
}
loop->to_events[loop->to_events_free].event = event;
loop->to_events[loop->to_events_free].timeout_time = timeout_time;
loop->to_events_n_used++;
return (void *) (intptr_t) (++loop->to_events_free);
}
static void *get_fd_event(_getdns_poll_eventloop *loop, int fd,
getdns_eventloop_event *event, uint64_t timeout_time)
{
size_t i;
if (loop->fd_events_free == loop->fd_events_capacity) {
if (loop->fd_events_free) {
_getdns_poll_event *fd_events = GETDNS_XREALLOC(
loop->mf, loop->fd_events, _getdns_poll_event,
loop->fd_events_free * 2);
struct pollfd *pfds = GETDNS_XREALLOC(
loop->mf, loop->pfds, struct pollfd,
loop->fd_events_free * 2);
if (!fd_events || !pfds) {
if (fd_events)
GETDNS_FREE(loop->mf, fd_events);
if (pfds)
GETDNS_FREE(loop->mf, pfds);
return NULL;
}
(void) memset(&fd_events[loop->fd_events_free],
0, sizeof(_getdns_poll_event)
* loop->fd_events_free);
for ( i = loop->fd_events_free
; i < loop->fd_events_free * 2
; i++) {
pfds[i].fd = -1;
pfds[i].events = 0;
pfds[i].revents = 0;
}
loop->fd_events_capacity = loop->fd_events_free * 2;
loop->fd_events = fd_events;
loop->pfds = pfds;
} else {
if (!(loop->fd_events = GETDNS_XMALLOC(loop->mf,
_getdns_poll_event, init_fd_events_capacity)) ||
!(loop->pfds = GETDNS_XMALLOC(loop->mf,
struct pollfd, init_fd_events_capacity))) {
GETDNS_NULL_FREE(loop->mf, loop->fd_events);
return NULL;
}
(void) memset(loop->fd_events, 0,
sizeof(_getdns_poll_event)
* init_fd_events_capacity);
for (i = 0; i < init_fd_events_capacity; i++) {
loop->pfds[i].fd = -1;
loop->pfds[i].events = 0;
loop->pfds[i].revents = 0;
}
loop->fd_events_capacity = init_fd_events_capacity;
}
}
loop->pfds[loop->fd_events_free].fd = fd;
loop->pfds[loop->fd_events_free].events = 0;
if (event->read_cb)
loop->pfds[loop->fd_events_free].events |= POLLIN;
if (event->write_cb)
loop->pfds[loop->fd_events_free].events |= POLLOUT;
loop->fd_events[loop->fd_events_free].event = event;
loop->fd_events[loop->fd_events_free].timeout_time = timeout_time;
loop->fd_events_n_used++;
return (void *) (intptr_t) (++loop->fd_events_free);
}
static uint64_t get_now_plus(uint64_t amount)
{
struct timeval tv;
uint64_t now;
if (gettimeofday(&tv, NULL)) {
perror("gettimeofday() failed");
exit(EXIT_FAILURE);
}
now = tv.tv_sec * 1000000 + tv.tv_usec;
return (now + amount * 1000) >= now
? now + amount * 1000 : TIMEOUT_FOREVER;
}
static getdns_return_t
poll_eventloop_schedule(getdns_eventloop *loop,
int fd, uint64_t timeout, getdns_eventloop_event *event)
{
_getdns_poll_eventloop *poll_loop = (_getdns_poll_eventloop *)loop;
DEBUG_SCHED( "%s(loop: %p, fd: %d, timeout: %"PRIu64", event: %p)\n"
, __FUNC__, (void *)loop, fd, timeout, (void *)event);
if (!loop || !event)
return GETDNS_RETURN_INVALID_PARAMETER;
if (fd >= 0 && !(event->read_cb || event->write_cb)) {
DEBUG_SCHED("WARNING: fd event without "
"read or write cb!\n");
fd = -1;
}
if (fd >= 0) {
if (!(event->ev = get_fd_event(
poll_loop, fd, event, get_now_plus(timeout)))) {
DEBUG_SCHED("ERROR: scheduled read/write slots!\n");
return GETDNS_RETURN_GENERIC_ERROR;
}
DEBUG_SCHED( "scheduled read/write at for %d at %p\n"
, fd, (void *)event->ev);
return GETDNS_RETURN_GOOD;
}
if (!event->timeout_cb) {
DEBUG_SCHED("ERROR: fd < 0 without timeout_cb!\n");
return GETDNS_RETURN_GENERIC_ERROR;
}
if (event->read_cb) {
DEBUG_SCHED("ERROR: timeout event with read_cb! Clearing.\n");
event->read_cb = NULL;
}
if (event->write_cb) {
DEBUG_SCHED("ERROR: timeout event with write_cb! Clearing.\n");
event->write_cb = NULL;
}
if (!(event->ev = get_to_event(poll_loop, event, get_now_plus(timeout)))) {
DEBUG_SCHED("ERROR: Out of timeout slots!\n");
return GETDNS_RETURN_GENERIC_ERROR;
}
DEBUG_SCHED("scheduled timeout at slot %p\n", (void *)event->ev);
return GETDNS_RETURN_GOOD;
}
static getdns_return_t
poll_eventloop_clear(getdns_eventloop *loop, getdns_eventloop_event *event)
{
_getdns_poll_eventloop *poll_loop = (_getdns_poll_eventloop *)loop;
if (!loop || !event)
return GETDNS_RETURN_INVALID_PARAMETER;
DEBUG_SCHED( "%s(loop: %p, event: %p)\n", __FUNC__, (void *)loop, (void *)event);
if (!event->ev)
return GETDNS_RETURN_GOOD;
else if (event->timeout_cb && !event->read_cb && !event->write_cb) {
size_t i = ((size_t) (intptr_t) event->ev) - 1;
/* This may happen with full recursive synchronous requests
* with the unbound pluggable event API, because the default
* poll_eventloop is temporarily replaced by a poll_eventloop
* used only in synchronous calls. When the synchronous request
* had an answer, the poll_eventloop for the synchronous is
* cleaned, however it could still have outstanding events.
*/
if (i >= poll_loop->to_events_capacity ||
poll_loop->to_events[i].event != event) {
event->ev = NULL;
DEBUG_SCHED( "ERROR: Event mismatch %p\n", (void *)event->ev);
return GETDNS_RETURN_GENERIC_ERROR;
}
poll_loop->to_events[i].event = NULL;
if (--poll_loop->to_events_n_used == 0) {
poll_loop->to_events_free = 0;
}
DEBUG_SCHED( "cleared timeout at slot %p\n", (void *)event->ev);
} else {
size_t i = ((size_t) (intptr_t) event->ev) - 1;
/* This may happen with full recursive synchronous requests
* with the unbound pluggable event API, because the default
* poll_eventloop is temporarily replaced by a poll_eventloop
* used only in synchronous calls. When the synchronous request
* had an answer, the poll_eventloop for the synchronous is
* cleaned, however it could still have outstanding events.
*/
if (i >= poll_loop->fd_events_capacity ||
poll_loop->fd_events[i].event != event) {
event->ev = NULL;
DEBUG_SCHED( "ERROR: Event mismatch %p\n", (void *)event->ev);
return GETDNS_RETURN_GENERIC_ERROR;
}
poll_loop->fd_events[i].event = NULL;
if (--poll_loop->fd_events_n_used == 0) {
poll_loop->fd_events_free = 0;
}
DEBUG_SCHED( "cleared read/write for %d at slot %p\n"
, poll_loop->pfds[i].fd, (void *)event->ev);
poll_loop->pfds[i].fd = -1; /* Not necessary, but to be sure */
}
event->ev = NULL;
return GETDNS_RETURN_GOOD;
}
static void
poll_eventloop_cleanup(getdns_eventloop *loop)
{
_getdns_poll_eventloop *poll_loop = (_getdns_poll_eventloop *)loop;
struct mem_funcs *mf = &poll_loop->mf;
GETDNS_NULL_FREE(*mf, poll_loop->pfds);
if (poll_loop->fd_events) {
GETDNS_FREE(*mf, poll_loop->fd_events);
poll_loop->fd_events = NULL;
poll_loop->fd_events_capacity = 0;
poll_loop->fd_events_free = 0;
poll_loop->fd_events_n_used = 0;
}
if (poll_loop->to_events) {
GETDNS_FREE(*mf, poll_loop->to_events);
poll_loop->to_events = NULL;
poll_loop->to_events_capacity = 0;
poll_loop->to_events_free = 0;
poll_loop->to_events_n_used = 0;
}
}
static void
poll_read_cb(int fd, getdns_eventloop_event *event)
{
#if !defined(SCHED_DEBUG) || !SCHED_DEBUG
(void)fd;
#endif
DEBUG_SCHED( "%s(fd: %d, event: %p)\n", __FUNC__, fd, (void *)event);
event->read_cb(event->userarg);
}
static void
poll_write_cb(int fd, getdns_eventloop_event *event)
{
#if !defined(SCHED_DEBUG) || !SCHED_DEBUG
(void)fd;
#endif
DEBUG_SCHED( "%s(fd: %d, event: %p)\n", __FUNC__, fd, (void *)event);
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);
}
static void
poll_eventloop_run_once(getdns_eventloop *loop, int blocking)
{
_getdns_poll_eventloop *poll_loop = (_getdns_poll_eventloop *)loop;
uint64_t now, timeout = TIMEOUT_FOREVER;
size_t i = 0, j;
int poll_timeout = 0;
if (!loop)
return;
now = get_now_plus(0);
for (i = 0, j = 0; i < poll_loop->to_events_free; i++, j++) {
while (poll_loop->to_events[i].event == NULL) {
if (++i == poll_loop->to_events_free) {
poll_loop->to_events_free = j;
break;
}
}
if (j < i) {
if (j >= poll_loop->to_events_free)
break;
poll_loop->to_events[j] = poll_loop->to_events[i];
poll_loop->to_events[i].event = NULL;
poll_loop->to_events[j].event->ev =
(void *) (intptr_t) (j + 1);
}
if (poll_loop->to_events[j].timeout_time < now)
poll_timeout_cb(poll_loop->to_events[j].event);
}
for (i = 0, j = 0; i < poll_loop->to_events_free; i++, j++) {
while (poll_loop->to_events[i].event == NULL) {
if (++i == poll_loop->to_events_free) {
poll_loop->to_events_free = j;
break;
}
}
if (j < i) {
if (j >= poll_loop->to_events_free)
break;
poll_loop->to_events[j] = poll_loop->to_events[i];
poll_loop->to_events[i].event = NULL;
poll_loop->to_events[j].event->ev =
(void *) (intptr_t) (j + 1);
}
if (poll_loop->to_events[j].timeout_time < timeout)
timeout = poll_loop->to_events[j].timeout_time;
}
if ((timeout == TIMEOUT_FOREVER) && (poll_loop->fd_events_free == 0))
return;
for (i = 0, j = 0; i < poll_loop->fd_events_free; i++, j++) {
while (poll_loop->fd_events[i].event == NULL) {
if (++i == poll_loop->fd_events_free) {
poll_loop->fd_events_free = j;
break;
}
}
if (j < i) {
if (j >= poll_loop->fd_events_free)
break;
poll_loop->fd_events[j] = poll_loop->fd_events[i];
poll_loop->fd_events[i].event = NULL;
poll_loop->fd_events[j].event->ev =
(void *) (intptr_t) (j + 1);
poll_loop->pfds[j] = poll_loop->pfds[i];
poll_loop->pfds[i].fd = -1;
}
if (poll_loop->fd_events[j].timeout_time < timeout)
timeout = poll_loop->fd_events[j].timeout_time;
}
if (timeout == TIMEOUT_FOREVER) {
poll_timeout = -1;
} else if (! blocking || now > timeout) {
poll_timeout = 0;
} else {
/* turn microseconds into milliseconds */
poll_timeout = (timeout - now) / 1000;
}
DEBUG_SCHED( "poll(fd_free: %d, fd_used: %d, to_free: %d, to_used: %d, timeout: %d)\n"
, (int)poll_loop->fd_events_free, (int)poll_loop->fd_events_n_used
, (int)poll_loop->to_events_free, (int)poll_loop->to_events_n_used
, poll_timeout
);
#ifdef USE_WINSOCK
if (WSAPoll(poll_loop->pfds, poll_loop->fd_events_free, poll_timeout) < 0) {
#else
if (poll(poll_loop->pfds, poll_loop->fd_events_free, poll_timeout) < 0) {
#endif
perror("poll() failed");
exit(EXIT_FAILURE);
}
now = get_now_plus(0);
for (i = 0, j = 0; i < poll_loop->fd_events_free; i++, j++) {
while (poll_loop->fd_events[i].event == NULL) {
if (++i == poll_loop->fd_events_free) {
poll_loop->fd_events_free = j;
break;
}
}
if (j < i) {
if (j >= poll_loop->fd_events_free)
break;
poll_loop->fd_events[j] = poll_loop->fd_events[i];
poll_loop->fd_events[i].event = NULL;
poll_loop->fd_events[j].event->ev =
(void *) (intptr_t) (j + 1);
poll_loop->pfds[j] = poll_loop->pfds[i];
poll_loop->pfds[i].fd = -1;
}
if (poll_loop->fd_events[j].event->write_cb &&
poll_loop->pfds[j].revents & POLLOUT)
poll_write_cb( poll_loop->pfds[j].fd
, poll_loop->fd_events[j].event);
if (poll_loop->fd_events[j].event &&
poll_loop->fd_events[j].event->read_cb &&
poll_loop->pfds[j].revents & POLLIN)
poll_read_cb( poll_loop->pfds[j].fd
, poll_loop->fd_events[j].event);
}
for (i = 0, j = 0; i < poll_loop->fd_events_free; i++, j++) {
while (poll_loop->fd_events[i].event == NULL) {
if (++i == poll_loop->fd_events_free) {
poll_loop->fd_events_free = j;
break;
}
}
if (j < i) {
if (j >= poll_loop->fd_events_free)
break;
poll_loop->fd_events[j] = poll_loop->fd_events[i];
poll_loop->fd_events[i].event = NULL;
poll_loop->fd_events[j].event->ev =
(void *) (intptr_t) (j + 1);
poll_loop->pfds[j] = poll_loop->pfds[i];
poll_loop->pfds[i].fd = -1;
}
if (poll_loop->fd_events[j].timeout_time < now)
poll_timeout_cb(poll_loop->fd_events[j].event);
}
for (i = 0, j = 0; i < poll_loop->to_events_free; i++, j++) {
while (poll_loop->to_events[i].event == NULL) {
if (++i == poll_loop->to_events_free) {
poll_loop->to_events_free = j;
break;
}
}
if (j < i) {
if (j >= poll_loop->to_events_free)
break;
poll_loop->to_events[j] = poll_loop->to_events[i];
poll_loop->to_events[i].event = NULL;
poll_loop->to_events[j].event->ev =
(void *) (intptr_t) (j + 1);
}
if (poll_loop->to_events[j].timeout_time < now)
poll_timeout_cb(poll_loop->to_events[j].event);
}
}
static void
poll_eventloop_run(getdns_eventloop *loop)
{
_getdns_poll_eventloop *poll_loop = (_getdns_poll_eventloop *)loop;
if (!loop)
return;
/* keep going until all the events are cleared */
while (poll_loop->fd_events_n_used || poll_loop->to_events_n_used) {
poll_eventloop_run_once(loop, 1);
}
}
void
_getdns_poll_eventloop_init(struct mem_funcs *mf, _getdns_poll_eventloop *loop)
{
static getdns_eventloop_vmt poll_eventloop_vmt = {
poll_eventloop_cleanup,
poll_eventloop_schedule,
poll_eventloop_clear,
poll_eventloop_run,
poll_eventloop_run_once
};
loop->loop.vmt = &poll_eventloop_vmt;
loop->mf = *mf;
loop->to_events_capacity = init_to_events_capacity;
if ((loop->to_events = GETDNS_XMALLOC(
*mf, _getdns_poll_event, init_to_events_capacity)))
(void) memset(loop->to_events, 0,
sizeof(_getdns_poll_event) * init_to_events_capacity);
else
loop->to_events_capacity = 0;
loop->to_events_free = 0;
loop->to_events_n_used = 0;
loop->fd_events_capacity = init_fd_events_capacity;
if ((loop->fd_events = GETDNS_XMALLOC(
*mf, _getdns_poll_event, init_fd_events_capacity)) &&
(loop->pfds = GETDNS_XMALLOC(
*mf, struct pollfd, init_fd_events_capacity))) {
size_t i;
(void) memset(loop->fd_events, 0,
sizeof(_getdns_poll_event) * init_fd_events_capacity);
for (i = 0; i < init_fd_events_capacity; i++) {
loop->pfds[i].fd = -1;
loop->pfds[i].events = 0;
loop->pfds[i].revents = 0;
}
} else {
loop->fd_events_capacity = 0;
if (loop->fd_events) {
GETDNS_FREE(*mf, loop->fd_events);
loop->fd_events = NULL;
}
}
loop->fd_events_free = 0;
loop->fd_events_n_used = 0;
}

View File

@ -0,0 +1,66 @@
/*
* \file poll_eventloop.h
* @brief Build in default eventloop extension that uses select.
*
*/
/*
* Copyright (c) 2013, NLNet Labs, Verisign, Inc.
* 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 POLL_EVENTLOOP_H_
#define POLL_EVENTLOOP_H_
#include "config.h"
#include "getdns/getdns.h"
#include "getdns/getdns_extra.h"
#include "types-internal.h"
/* Eventloop based on poll */
typedef struct _getdns_poll_event {
getdns_eventloop_event *event;
uint64_t timeout_time;
} _getdns_poll_event;
typedef struct _getdns_poll_eventloop {
getdns_eventloop loop;
struct mem_funcs mf;
struct pollfd *pfds;
size_t fd_events_capacity;
_getdns_poll_event *fd_events;
size_t fd_events_free;
size_t fd_events_n_used;
size_t to_events_capacity;
_getdns_poll_event *to_events;
size_t to_events_free;
size_t to_events_n_used;
} _getdns_poll_eventloop;
void
_getdns_poll_eventloop_init(struct mem_funcs *mf, _getdns_poll_eventloop *loop);
#endif

View File

@ -27,7 +27,7 @@
#include "config.h"
#include "extension/default_eventloop.h"
#include "extension/select_eventloop.h"
#include "debug.h"
#include "types-internal.h"
@ -47,10 +47,10 @@ static uint64_t get_now_plus(uint64_t amount)
}
static getdns_return_t
default_eventloop_schedule(getdns_eventloop *loop,
select_eventloop_schedule(getdns_eventloop *loop,
int fd, uint64_t timeout, getdns_eventloop_event *event)
{
_getdns_default_eventloop *default_loop = (_getdns_default_eventloop *)loop;
_getdns_select_eventloop *select_loop = (_getdns_select_eventloop *)loop;
size_t i;
DEBUG_SCHED( "%s(loop: %p, fd: %d, timeout: %"PRIu64", event: %p, FD_SETSIZE: %d)\n"
@ -71,20 +71,20 @@ default_eventloop_schedule(getdns_eventloop *loop,
}
if (fd >= 0) {
#if defined(SCHED_DEBUG) && SCHED_DEBUG
if (default_loop->fd_events[fd]) {
if (default_loop->fd_events[fd] == event) {
if (select_loop->fd_events[fd]) {
if (select_loop->fd_events[fd] == event) {
DEBUG_SCHED("WARNING: Event %p not cleared "
"before being rescheduled!\n"
, (void *)default_loop->fd_events[fd]);
, (void *)select_loop->fd_events[fd]);
} else {
DEBUG_SCHED("ERROR: A different event is "
"already present at fd slot: %p!\n"
, (void *)default_loop->fd_events[fd]);
, (void *)select_loop->fd_events[fd]);
}
}
#endif
default_loop->fd_events[fd] = event;
default_loop->fd_timeout_times[fd] = get_now_plus(timeout);
select_loop->fd_events[fd] = event;
select_loop->fd_timeout_times[fd] = get_now_plus(timeout);
event->ev = (void *)(intptr_t)(fd + 1);
DEBUG_SCHED( "scheduled read/write at %d\n", fd);
return GETDNS_RETURN_GOOD;
@ -102,9 +102,9 @@ default_eventloop_schedule(getdns_eventloop *loop,
event->write_cb = NULL;
}
for (i = 0; i < MAX_TIMEOUTS; i++) {
if (default_loop->timeout_events[i] == NULL) {
default_loop->timeout_events[i] = event;
default_loop->timeout_times[i] = get_now_plus(timeout);
if (select_loop->timeout_events[i] == NULL) {
select_loop->timeout_events[i] = event;
select_loop->timeout_times[i] = get_now_plus(timeout);
event->ev = (void *)(intptr_t)(i + 1);
DEBUG_SCHED( "scheduled timeout at %d\n", (int)i);
return GETDNS_RETURN_GOOD;
@ -115,9 +115,9 @@ default_eventloop_schedule(getdns_eventloop *loop,
}
static getdns_return_t
default_eventloop_clear(getdns_eventloop *loop, getdns_eventloop_event *event)
select_eventloop_clear(getdns_eventloop *loop, getdns_eventloop_event *event)
{
_getdns_default_eventloop *default_loop = (_getdns_default_eventloop *)loop;
_getdns_select_eventloop *select_loop = (_getdns_select_eventloop *)loop;
ssize_t i;
if (!loop || !event)
@ -131,33 +131,33 @@ default_eventloop_clear(getdns_eventloop *loop, getdns_eventloop_event *event)
}
if (event->timeout_cb && !event->read_cb && !event->write_cb) {
#if defined(SCHED_DEBUG) && SCHED_DEBUG
if (default_loop->timeout_events[i] != event)
if (select_loop->timeout_events[i] != event)
DEBUG_SCHED( "ERROR: Different/wrong event present at "
"timeout slot: %p!\n"
, (void *)default_loop->timeout_events[i]);
, (void *)select_loop->timeout_events[i]);
#endif
default_loop->timeout_events[i] = NULL;
select_loop->timeout_events[i] = NULL;
} else {
#if defined(SCHED_DEBUG) && SCHED_DEBUG
if (default_loop->fd_events[i] != event)
if (select_loop->fd_events[i] != event)
DEBUG_SCHED( "ERROR: Different/wrong event present at "
"fd slot: %p!\n"
, (void *)default_loop->fd_events[i]);
, (void *)select_loop->fd_events[i]);
#endif
default_loop->fd_events[i] = NULL;
select_loop->fd_events[i] = NULL;
}
event->ev = NULL;
return GETDNS_RETURN_GOOD;
}
static void
default_eventloop_cleanup(getdns_eventloop *loop)
select_eventloop_cleanup(getdns_eventloop *loop)
{
(void)loop;
}
static void
default_read_cb(int fd, getdns_eventloop_event *event)
select_read_cb(int fd, getdns_eventloop_event *event)
{
#if !defined(SCHED_DEBUG) || !SCHED_DEBUG
(void)fd;
@ -167,7 +167,7 @@ default_read_cb(int fd, getdns_eventloop_event *event)
}
static void
default_write_cb(int fd, getdns_eventloop_event *event)
select_write_cb(int fd, getdns_eventloop_event *event)
{
#if !defined(SCHED_DEBUG) || !SCHED_DEBUG
(void)fd;
@ -177,7 +177,7 @@ default_write_cb(int fd, getdns_eventloop_event *event)
}
static void
default_timeout_cb(int fd, getdns_eventloop_event *event)
select_timeout_cb(int fd, getdns_eventloop_event *event)
{
#if !defined(SCHED_DEBUG) || !SCHED_DEBUG
(void)fd;
@ -187,9 +187,9 @@ default_timeout_cb(int fd, getdns_eventloop_event *event)
}
static void
default_eventloop_run_once(getdns_eventloop *loop, int blocking)
select_eventloop_run_once(getdns_eventloop *loop, int blocking)
{
_getdns_default_eventloop *default_loop = (_getdns_default_eventloop *)loop;
_getdns_select_eventloop *select_loop = (_getdns_select_eventloop *)loop;
fd_set readfds, writefds;
int fd, max_fd = -1;
@ -205,24 +205,24 @@ default_eventloop_run_once(getdns_eventloop *loop, int blocking)
now = get_now_plus(0);
for (i = 0; i < MAX_TIMEOUTS; i++) {
if (!default_loop->timeout_events[i])
if (!select_loop->timeout_events[i])
continue;
if (now > default_loop->timeout_times[i])
default_timeout_cb(-1, default_loop->timeout_events[i]);
else if (default_loop->timeout_times[i] < timeout)
timeout = default_loop->timeout_times[i];
if (now > select_loop->timeout_times[i])
select_timeout_cb(-1, select_loop->timeout_events[i]);
else if (select_loop->timeout_times[i] < timeout)
timeout = select_loop->timeout_times[i];
}
for (fd = 0; fd < (int)FD_SETSIZE; fd++) {
if (!default_loop->fd_events[fd])
if (!select_loop->fd_events[fd])
continue;
if (default_loop->fd_events[fd]->read_cb)
if (select_loop->fd_events[fd]->read_cb)
FD_SET(fd, &readfds);
if (default_loop->fd_events[fd]->write_cb)
if (select_loop->fd_events[fd]->write_cb)
FD_SET(fd, &writefds);
if (fd > max_fd)
max_fd = fd;
if (default_loop->fd_timeout_times[fd] < timeout)
timeout = default_loop->fd_timeout_times[fd];
if (select_loop->fd_timeout_times[fd] < timeout)
timeout = select_loop->fd_timeout_times[fd];
}
if (max_fd == -1 && timeout == TIMEOUT_FOREVER)
return;
@ -241,33 +241,33 @@ default_eventloop_run_once(getdns_eventloop *loop, int blocking)
}
now = get_now_plus(0);
for (fd = 0; fd < (int)FD_SETSIZE; fd++) {
if (default_loop->fd_events[fd] &&
default_loop->fd_events[fd]->read_cb &&
if (select_loop->fd_events[fd] &&
select_loop->fd_events[fd]->read_cb &&
FD_ISSET(fd, &readfds))
default_read_cb(fd, default_loop->fd_events[fd]);
select_read_cb(fd, select_loop->fd_events[fd]);
if (default_loop->fd_events[fd] &&
default_loop->fd_events[fd]->write_cb &&
if (select_loop->fd_events[fd] &&
select_loop->fd_events[fd]->write_cb &&
FD_ISSET(fd, &writefds))
default_write_cb(fd, default_loop->fd_events[fd]);
select_write_cb(fd, select_loop->fd_events[fd]);
if (default_loop->fd_events[fd] &&
default_loop->fd_events[fd]->timeout_cb &&
now > default_loop->fd_timeout_times[fd])
default_timeout_cb(fd, default_loop->fd_events[fd]);
if (select_loop->fd_events[fd] &&
select_loop->fd_events[fd]->timeout_cb &&
now > select_loop->fd_timeout_times[fd])
select_timeout_cb(fd, select_loop->fd_events[fd]);
i = fd;
if (default_loop->timeout_events[i] &&
default_loop->timeout_events[i]->timeout_cb &&
now > default_loop->timeout_times[i])
default_timeout_cb(-1, default_loop->timeout_events[i]);
if (select_loop->timeout_events[i] &&
select_loop->timeout_events[i]->timeout_cb &&
now > select_loop->timeout_times[i])
select_timeout_cb(-1, select_loop->timeout_events[i]);
}
}
static void
default_eventloop_run(getdns_eventloop *loop)
select_eventloop_run(getdns_eventloop *loop)
{
_getdns_default_eventloop *default_loop = (_getdns_default_eventloop *)loop;
_getdns_select_eventloop *select_loop = (_getdns_select_eventloop *)loop;
size_t i;
if (!loop)
@ -275,8 +275,8 @@ default_eventloop_run(getdns_eventloop *loop)
i = 0;
while (i < MAX_TIMEOUTS) {
if (default_loop->fd_events[i] || default_loop->timeout_events[i]) {
default_eventloop_run_once(loop, 1);
if (select_loop->fd_events[i] || select_loop->timeout_events[i]) {
select_eventloop_run_once(loop, 1);
i = 0;
} else {
i++;
@ -285,16 +285,16 @@ default_eventloop_run(getdns_eventloop *loop)
}
void
_getdns_default_eventloop_init(_getdns_default_eventloop *loop)
_getdns_select_eventloop_init(struct mem_funcs *mf, _getdns_select_eventloop *loop)
{
static getdns_eventloop_vmt default_eventloop_vmt = {
default_eventloop_cleanup,
default_eventloop_schedule,
default_eventloop_clear,
default_eventloop_run,
default_eventloop_run_once
static getdns_eventloop_vmt select_eventloop_vmt = {
select_eventloop_cleanup,
select_eventloop_schedule,
select_eventloop_clear,
select_eventloop_run,
select_eventloop_run_once
};
(void) memset(loop, 0, sizeof(_getdns_default_eventloop));
loop->loop.vmt = &default_eventloop_vmt;
(void) mf;
(void) memset(loop, 0, sizeof(_getdns_select_eventloop));
loop->loop.vmt = &select_eventloop_vmt;
}

View File

@ -0,0 +1,58 @@
/*
* \file select_eventloop.h
* @brief Build in default eventloop extension that uses select.
*
*/
/*
* Copyright (c) 2013, NLNet Labs, Verisign, Inc.
* 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 SELECT_EVENTLOOP_H_
#define SELECT_EVENTLOOP_H_
#include "config.h"
#include "getdns/getdns.h"
#include "getdns/getdns_extra.h"
/* No more than select's capability queries can be outstanding,
* The number of outstanding timeouts should be less or equal then
* the number of outstanding queries, so MAX_TIMEOUTS equal to
* FD_SETSIZE should be safe.
*/
#define MAX_TIMEOUTS FD_SETSIZE
/* Eventloop based on select */
typedef struct _getdns_select_eventloop {
getdns_eventloop loop;
getdns_eventloop_event *fd_events[FD_SETSIZE];
uint64_t fd_timeout_times[FD_SETSIZE];
getdns_eventloop_event *timeout_events[MAX_TIMEOUTS];
uint64_t timeout_times[MAX_TIMEOUTS];
} _getdns_select_eventloop;
void
_getdns_select_eventloop_init(struct mem_funcs *mf, _getdns_select_eventloop *loop);
#endif

View File

@ -54,31 +54,19 @@
#include "dict.h"
#include "mdns.h"
/* cancel, cleanup and send timeout to callback */
static void
ub_resolve_timeout(void *arg)
void _getdns_call_user_callback(getdns_dns_req *dnsreq, getdns_dict *response)
{
getdns_dns_req *dns_req = (getdns_dns_req *) arg;
(void) _getdns_context_request_timed_out(dns_req);
_getdns_context_clear_outbound_request(dnsreq);
if (dnsreq->user_callback) {
dnsreq->context->processing = 1;
dnsreq->user_callback(dnsreq->context,
(response ? GETDNS_CALLBACK_COMPLETE
: GETDNS_CALLBACK_ERROR),
response, dnsreq->user_pointer, dnsreq->trans_id);
dnsreq->context->processing = 0;
}
void _getdns_call_user_callback(getdns_dns_req *dns_req,
struct getdns_dict *response)
{
struct getdns_context *context = dns_req->context;
getdns_transaction_t trans_id = dns_req->trans_id;
getdns_callback_t cb = dns_req->user_callback;
void *user_arg = dns_req->user_pointer;
/* clean up */
_getdns_context_clear_outbound_request(dns_req);
_getdns_dns_req_free(dns_req);
context->processing = 1;
cb(context,
(response ? GETDNS_CALLBACK_COMPLETE : GETDNS_CALLBACK_ERROR),
response, user_arg, trans_id);
context->processing = 0;
_getdns_dns_req_free(dnsreq);
}
static int
@ -186,9 +174,10 @@ _getdns_check_dns_req_complete(getdns_dns_req *dns_req)
return;
}
}
if (dns_req->internal_cb)
if (dns_req->internal_cb) {
_getdns_context_clear_outbound_request(dns_req);
dns_req->internal_cb(dns_req);
else if (! results_found)
} else if (! results_found)
_getdns_call_user_callback(dns_req, NULL);
else if (dns_req->dnssec_return_validation_chain
#ifdef DNSSEC_ROADBLOCK_AVOIDANCE
@ -290,7 +279,9 @@ _getdns_submit_netreq(getdns_network_req *netreq)
dns_req->timeout.userarg = dns_req;
dns_req->timeout.read_cb = NULL;
dns_req->timeout.write_cb = NULL;
dns_req->timeout.timeout_cb = ub_resolve_timeout;
dns_req->timeout.timeout_cb =
(getdns_eventloop_callback)
_getdns_context_request_timed_out;
dns_req->timeout.ev = NULL;
if ((r = dns_req->loop->vmt->schedule(dns_req->loop, -1,
dns_req->context->timeout, &dns_req->timeout)))

View File

@ -56,6 +56,8 @@ extern "C" {
* \defgroup Ureturnvaluesandtext Additional return values and texts
* @{
*/
#define GETDNS_RETURN_NO_UPSTREAM_AVAILABLE ((getdns_return_t) 398 )
#define GETDNS_RETURN_NO_UPSTREAM_AVAILABLE_TEXT "None of the configured upstreams could be used to send queries on the specified transports"
#define GETDNS_RETURN_NEED_MORE_SPACE ((getdns_return_t) 399 )
#define GETDNS_RETURN_NEED_MORE_SPACE_TEXT "The buffer was too small"
/** @}

View File

@ -33,6 +33,7 @@ gldns_buffer_new(size_t capacity)
buffer->_position = 0;
buffer->_limit = buffer->_capacity = capacity;
buffer->_fixed = 0;
buffer->_vfixed = 0;
buffer->_status_err = 0;
gldns_buffer_invariant(buffer);
@ -48,6 +49,7 @@ gldns_buffer_new_frm_data(gldns_buffer *buffer, void *data, size_t size)
buffer->_position = 0;
buffer->_limit = buffer->_capacity = size;
buffer->_fixed = 0;
buffer->_vfixed = 0;
buffer->_data = malloc(size);
if(!buffer->_data) {
buffer->_status_err = 1;
@ -66,6 +68,17 @@ gldns_buffer_init_frm_data(gldns_buffer *buffer, void *data, size_t size)
buffer->_data = data;
buffer->_capacity = buffer->_limit = size;
buffer->_fixed = 1;
buffer->_vfixed = 0;
}
void
gldns_buffer_init_vfixed_frm_data(gldns_buffer *buffer, void *data, size_t size)
{
memset(buffer, 0, sizeof(*buffer));
buffer->_data = data;
buffer->_capacity = buffer->_limit = size;
buffer->_fixed = 1;
buffer->_vfixed = 1;
}
int
@ -120,20 +133,19 @@ gldns_buffer_printf(gldns_buffer *buffer, const char *format, ...)
remaining = gldns_buffer_remaining(buffer);
va_start(args, format);
written = _gldns_vsnprintf((char*)gldns_buffer_current(buffer),
remaining, format, args);
written = vsnprintf((char *) gldns_buffer_current(buffer), remaining,
format, args);
va_end(args);
if (written == -1) {
buffer->_status_err = 1;
return -1;
} else if (!buffer->_fixed && (size_t) written >= remaining) {
} else if (!buffer->_vfixed && (size_t) written >= remaining) {
if (!gldns_buffer_reserve(buffer, (size_t) written + 1)) {
buffer->_status_err = 1;
return -1;
}
va_start(args, format);
written = _gldns_vsnprintf(
(char *) gldns_buffer_current(buffer),
written = vsnprintf((char *) gldns_buffer_current(buffer),
gldns_buffer_remaining(buffer), format, args);
va_end(args);
if (written == -1) {

View File

@ -27,21 +27,6 @@ extern "C" {
# endif
#endif
#ifndef USE_WINSOCK
#define _gldns_vsnprintf vsnprintf
#else
/* Unlike Linux and BSD, vsnprintf on Windows returns -1 on overflow.
* Here it is redefined to always return the amount printed
* if enough space had been available.
*/
INLINE int
_gldns_vsnprintf(char *str, size_t size, const char *format, va_list ap)
{
int r = vsnprintf(str, size, format, ap);
return r == -1 ? _vscprintf(format, ap) : r;
}
#endif
/*
* Copy data allowing for unaligned accesses in network byte order
* (big endian).
@ -145,6 +130,17 @@ struct gldns_buffer
/** If the buffer is fixed it cannot be resized */
unsigned _fixed : 1;
/** If the buffer is vfixed, no more than capacity bytes willl be
* written to _data, however the _position counter will be updated
* with the amount that would have been written in consecutive
* writes. This allows for a modus operandi in which a sequence is
* written on a fixed capacity buffer (perhaps with _data on stack).
* When everything could be written, then the _data is immediately
* usable, if not, then a buffer could be allocated sized precisely
* to fit the data for a second attempt.
*/
unsigned _vfixed : 1;
/** The current state of the buffer. If writing to the buffer fails
* for any reason, this value is changed. This way, you can perform
* multiple writes in sequence and check for success afterwards. */
@ -162,9 +158,9 @@ INLINE void
gldns_buffer_invariant(gldns_buffer *buffer)
{
assert(buffer != NULL);
assert(buffer->_position <= buffer->_limit || buffer->_fixed);
assert(buffer->_position <= buffer->_limit || buffer->_vfixed);
assert(buffer->_limit <= buffer->_capacity);
assert(buffer->_data != NULL || (buffer->_capacity == 0 && buffer->_fixed));
assert(buffer->_data != NULL || (buffer->_vfixed && buffer->_capacity == 0));
}
#endif
@ -196,6 +192,19 @@ void gldns_buffer_new_frm_data(gldns_buffer *buffer, void *data, size_t size);
*/
void gldns_buffer_init_frm_data(gldns_buffer *buffer, void *data, size_t size);
/**
* Setup a buffer with the data pointed to. No data copied, no memory allocs.
* The buffer is "virtually" fixed. Writes beyond size (the capacity) will
* only update position, but no data will be written beyond capacity. This
* allows to determine how big the buffer should have been to contain all the
* written data, by looking at the position with gldns_buffer_position(),
* similarly to the return value of POSIX's snprintf.
* \param[in] buffer pointer to the buffer to put the data in
* \param[in] data the data to encapsulate in the buffer
* \param[in] size the size of the data
*/
void gldns_buffer_init_vfixed_frm_data(gldns_buffer *buffer, void *data, size_t size);
/**
* clears the buffer and make it ready for writing. The buffer's limit
* is set to the capacity and the position is set to 0.
@ -259,7 +268,7 @@ gldns_buffer_position(gldns_buffer *buffer)
INLINE void
gldns_buffer_set_position(gldns_buffer *buffer, size_t mark)
{
assert(mark <= buffer->_limit || buffer->_fixed);
assert(mark <= buffer->_limit || buffer->_vfixed);
buffer->_position = mark;
}
@ -273,7 +282,7 @@ gldns_buffer_set_position(gldns_buffer *buffer, size_t mark)
INLINE void
gldns_buffer_skip(gldns_buffer *buffer, ssize_t count)
{
assert(buffer->_position + count <= buffer->_limit || buffer->_fixed);
assert(buffer->_position + count <= buffer->_limit || buffer->_vfixed);
buffer->_position += count;
}
@ -345,7 +354,7 @@ int gldns_buffer_reserve(gldns_buffer *buffer, size_t amount);
INLINE uint8_t *
gldns_buffer_at(const gldns_buffer *buffer, size_t at)
{
assert(at <= buffer->_limit || buffer->_fixed);
assert(at <= buffer->_limit || buffer->_vfixed);
return buffer->_data + at;
}
@ -395,6 +404,7 @@ INLINE size_t
gldns_buffer_remaining_at(gldns_buffer *buffer, size_t at)
{
gldns_buffer_invariant(buffer);
assert(at <= buffer->_limit || buffer->_vfixed);
return at < buffer->_limit ? buffer->_limit - at : 0;
}
@ -447,7 +457,7 @@ gldns_buffer_available(gldns_buffer *buffer, size_t count)
INLINE void
gldns_buffer_write_at(gldns_buffer *buffer, size_t at, const void *data, size_t count)
{
if (!buffer->_fixed)
if (!buffer->_vfixed)
assert(gldns_buffer_available_at(buffer, at, count));
else if (gldns_buffer_remaining_at(buffer, at) == 0)
return;
@ -504,7 +514,7 @@ gldns_buffer_write_string(gldns_buffer *buffer, const char *str)
INLINE void
gldns_buffer_write_u8_at(gldns_buffer *buffer, size_t at, uint8_t data)
{
if (buffer->_fixed && at + sizeof(data) > buffer->_limit) return;
if (buffer->_vfixed && at + sizeof(data) > buffer->_limit) return;
assert(gldns_buffer_available_at(buffer, at, sizeof(data)));
buffer->_data[at] = data;
}
@ -530,7 +540,7 @@ gldns_buffer_write_u8(gldns_buffer *buffer, uint8_t data)
INLINE void
gldns_buffer_write_u16_at(gldns_buffer *buffer, size_t at, uint16_t data)
{
if (buffer->_fixed && at + sizeof(data) > buffer->_limit) return;
if (buffer->_vfixed && at + sizeof(data) > buffer->_limit) return;
assert(gldns_buffer_available_at(buffer, at, sizeof(data)));
gldns_write_uint16(buffer->_data + at, data);
}
@ -556,7 +566,7 @@ gldns_buffer_write_u16(gldns_buffer *buffer, uint16_t data)
INLINE void
gldns_buffer_write_u32_at(gldns_buffer *buffer, size_t at, uint32_t data)
{
if (buffer->_fixed && at + sizeof(data) > buffer->_limit) return;
if (buffer->_vfixed && at + sizeof(data) > buffer->_limit) return;
assert(gldns_buffer_available_at(buffer, at, sizeof(data)));
gldns_write_uint32(buffer->_data + at, data);
}
@ -570,7 +580,7 @@ gldns_buffer_write_u32_at(gldns_buffer *buffer, size_t at, uint32_t data)
INLINE void
gldns_buffer_write_u48_at(gldns_buffer *buffer, size_t at, uint64_t data)
{
if (buffer->_fixed && at + 6 > buffer->_limit) return;
if (buffer->_vfixed && at + 6 > buffer->_limit) return;
assert(gldns_buffer_available_at(buffer, at, 6));
gldns_write_uint48(buffer->_data + at, data);
}

View File

@ -372,6 +372,8 @@ enum gldns_enum_algorithm
GLDNS_ECC_GOST = 12, /* RFC 5933 */
GLDNS_ECDSAP256SHA256 = 13, /* RFC 6605 */
GLDNS_ECDSAP384SHA384 = 14, /* RFC 6605 */
GLDNS_ED25519 = 15, /* RFC 8080 */
GLDNS_ED448 = 16, /* RFC 8080 */
GLDNS_INDIRECT = 252,
GLDNS_PRIVATEDNS = 253,
GLDNS_PRIVATEOID = 254

View File

@ -47,6 +47,8 @@ static gldns_lookup_table gldns_algorithms_data[] = {
{ GLDNS_ECC_GOST, "ECC-GOST"},
{ GLDNS_ECDSAP256SHA256, "ECDSAP256SHA256"},
{ GLDNS_ECDSAP384SHA384, "ECDSAP384SHA384"},
{ GLDNS_ED25519, "ED25519"},
{ GLDNS_ED448, "ED448"},
{ GLDNS_INDIRECT, "INDIRECT" },
{ GLDNS_PRIVATEDNS, "PRIVATEDNS" },
{ GLDNS_PRIVATEOID, "PRIVATEOID" },
@ -279,7 +281,7 @@ int gldns_wire2str_dname_buf(uint8_t* d, size_t dlen, char* s, size_t slen)
int gldns_str_vprint(char** str, size_t* slen, const char* format, va_list args)
{
int w = _gldns_vsnprintf(*str, *slen, format, args);
int w = vsnprintf(*str, *slen, format, args);
if(w < 0) {
/* error in printout */
return 0;

1
src/jsmn Submodule

@ -0,0 +1 @@
Subproject commit 868c22e35ec223fc26ddefdb9ca83901dc6e2534

View File

@ -1757,7 +1757,7 @@ static void
mdns_cleanup(getdns_network_req *netreq)
{
DEBUG_MDNS("%s %-35s: MSG: %p\n",
MDNS_DEBUG_CLEANUP, __FUNCTION__, netreq);
MDNS_DEBUG_CLEANUP, __FUNC__, netreq);
getdns_dns_req *dnsreq = netreq->owner;
GETDNS_CLEAR_EVENT(dnsreq->loop, &netreq->event);
@ -1781,7 +1781,7 @@ mdns_timeout_cb(void *userarg)
{
getdns_network_req *netreq = (getdns_network_req *)userarg;
DEBUG_MDNS("%s %-35s: MSG: %p\n",
MDNS_DEBUG_CLEANUP, __FUNCTION__, netreq);
MDNS_DEBUG_CLEANUP, __FUNC__, netreq);
/* TODO: do we need a retry logic here? */
@ -1815,7 +1815,7 @@ mdns_udp_read_cb(void *userarg)
getdns_dns_req *dnsreq = netreq->owner;
ssize_t read;
DEBUG_MDNS("%s %-35s: MSG: %p \n", MDNS_DEBUG_READ,
__FUNCTION__, netreq);
__FUNC__, netreq);
GETDNS_CLEAR_EVENT(dnsreq->loop, &netreq->event);
@ -1869,7 +1869,7 @@ mdns_udp_write_cb(void *userarg)
int r;
DEBUG_MDNS("%s %-35s: MSG: %p \n", MDNS_DEBUG_WRITE,
__FUNCTION__, netreq);
__FUNC__, netreq);
GETDNS_CLEAR_EVENT(dnsreq->loop, &netreq->event);
@ -1917,7 +1917,7 @@ mdns_udp_write_cb(void *userarg)
getdns_return_t
_getdns_submit_mdns_request(getdns_network_req *netreq)
{
DEBUG_MDNS("%s %-35s: MSG: %p TYPE: %d\n", MDNS_DEBUG_ENTRY, __FUNCTION__,
DEBUG_MDNS("%s %-35s: MSG: %p TYPE: %d\n", MDNS_DEBUG_ENTRY, __FUNC__,
netreq, netreq->request_type);
int fd = -1;
getdns_dns_req *dnsreq = netreq->owner;

View File

@ -383,7 +383,7 @@ _getdns_network_req_add_tsig(getdns_network_req *req)
#endif
tsig_info = _getdns_get_tsig_info(upstream->tsig_alg);
gldns_buffer_init_frm_data(&gbuf, req->response, MAXIMUM_TSIG_SPACE);
gldns_buffer_init_vfixed_frm_data(&gbuf, req->response, MAXIMUM_TSIG_SPACE);
gldns_buffer_write(&gbuf,
upstream->tsig_dname, upstream->tsig_dname_len); /* Name */
gldns_buffer_write_u16(&gbuf, GETDNS_RRCLASS_ANY); /* Class */
@ -644,7 +644,7 @@ _getdns_dns_req_free(getdns_dns_req * req)
network_req_cleanup(*net_req);
/* clear timeout event */
if (req->timeout.timeout_cb) {
if (req->loop && req->loop->vmt && req->timeout.timeout_cb) {
req->loop->vmt->clear(req->loop, &req->timeout);
req->timeout.timeout_cb = NULL;
}
@ -896,9 +896,7 @@ _getdns_dns_req_new(getdns_context *context, getdns_eventloop *loop,
}
result->context = context;
result->loop = loop;
result->canceled = 0;
result->trans_id = (((uint64_t)arc4random()) << 32) |
((uint64_t)arc4random());
result->trans_id = (uint64_t) (intptr_t) result;
result->dnssec_return_status = dnssec_return_status;
result->dnssec_return_only_secure = dnssec_return_only_secure;
result->dnssec_return_all_statuses = dnssec_return_all_statuses;
@ -934,6 +932,7 @@ _getdns_dns_req_new(getdns_context *context, getdns_eventloop *loop,
result->finished_next = NULL;
result->freed = NULL;
result->validating = 0;
result->chain = NULL;
network_req_init(result->netreqs[0], result,
request_type, dnssec_extension_set, with_opt,

View File

@ -520,7 +520,7 @@ stub_cleanup(getdns_network_req *netreq)
static void
upstream_failed(getdns_upstream *upstream, int during_setup)
{
DEBUG_STUB("%s %-35s: FD: %d During setup = %d\n",
DEBUG_STUB("%s %-35s: FD: %d Failure during connection setup = %d\n",
STUB_DEBUG_CLEANUP, __FUNC__, upstream->fd, during_setup);
/* Fallback code should take care of queue queries and then close conn
when idle.*/
@ -602,7 +602,7 @@ stub_timeout_cb(void *userarg)
if (netreq->owner->user_callback) {
netreq->debug_end_time = _getdns_get_time_as_uintt64();
/* Note this calls cancel_request which calls stub_cleanup again....!*/
(void) _getdns_context_request_timed_out(netreq->owner);
_getdns_context_request_timed_out(netreq->owner);
} else
_getdns_check_dns_req_complete(netreq->owner);
}
@ -868,13 +868,21 @@ tls_verify_callback(int preverify_ok, X509_STORE_CTX *ctx)
STUB_DEBUG_SETUP_TLS, __FUNC__, upstream->fd, err,
X509_verify_cert_error_string(err));
#endif
#if defined(DAEMON_DEBUG) && DAEMON_DEBUG
if (!preverify_ok && !upstream->tls_fallback_ok)
DEBUG_DAEMON("%s %s : Conn failed : Transport=TLS - *Failure* - (%d) \"%s\"\n",
STUB_DEBUG_DAEMON, upstream->addr_str, err,
X509_verify_cert_error_string(err));
#endif
/* First deal with the hostname authentication done by OpenSSL. */
#ifdef X509_V_ERR_HOSTNAME_MISMATCH
# if defined(STUB_DEBUG) && STUB_DEBUG
/*Report if error is hostname mismatch*/
if (err == X509_V_ERR_HOSTNAME_MISMATCH && upstream->tls_fallback_ok)
DEBUG_STUB("%s %-35s: FD: %d WARNING: Proceeding even though hostname validation failed!\n",
STUB_DEBUG_SETUP_TLS, __FUNC__, upstream->fd);
# endif
#else
/* if we weren't built against OpenSSL with hostname matching we
* could not have matched the hostname, so this would be an automatic
@ -897,9 +905,15 @@ tls_verify_callback(int preverify_ok, X509_STORE_CTX *ctx)
if (upstream->tls_fallback_ok)
DEBUG_STUB("%s %-35s: FD: %d, WARNING: Proceeding even though pinset validation failed!\n",
STUB_DEBUG_SETUP_TLS, __FUNC__, upstream->fd);
#if defined(DAEMON_DEBUG) && DAEMON_DEBUG
else
DEBUG_DAEMON("%s %s : Conn failed : Transport=TLS - *Failure* - Pinset validation failure\n",
STUB_DEBUG_DAEMON, upstream->addr_str);
#endif
} else {
/* If we _only_ had a pinset and it is good then force succesful
authentication when the cert self-signed */
authentication when the cert self-signed
TODO: We need to check for other error cases here, not blindly accept the cert!! */
if ((upstream->tls_pubkey_pinset && upstream->tls_auth_name[0] == '\0') &&
(err == X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN ||
err == X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT)) {
@ -915,6 +929,7 @@ tls_verify_callback(int preverify_ok, X509_STORE_CTX *ctx)
else if (upstream->tls_auth_state == GETDNS_AUTH_NONE &&
(upstream->tls_pubkey_pinset || upstream->tls_auth_name[0]))
upstream->tls_auth_state = GETDNS_AUTH_OK;
/* If fallback is allowed, proceed regardless of what the auth error is
(might not be hostname or pinset related) */
return (upstream->tls_fallback_ok) ? 1 : preverify_ok;
@ -1299,8 +1314,6 @@ stub_udp_read_cb(void *userarg)
DEBUG_STUB("%s %-35s: MSG: %p \n", STUB_DEBUG_READ,
__FUNC__, (void*)netreq);
GETDNS_CLEAR_EVENT(dnsreq->loop, &netreq->event);
read = recvfrom(netreq->fd, (void *)netreq->response,
netreq->max_udp_payload_size + 1, /* If read == max_udp_payload_size
* then all is good. If read ==
@ -1322,6 +1335,8 @@ stub_udp_read_cb(void *userarg)
upstream, netreq->response, read))
return; /* Client cookie didn't match? */
GETDNS_CLEAR_EVENT(dnsreq->loop, &netreq->event);
#ifdef USE_WINSOCK
closesocket(netreq->fd);
#else
@ -2023,8 +2038,7 @@ _getdns_submit_stub_request(getdns_network_req *netreq)
* All other set up is done async*/
fd = upstream_find_for_netreq(netreq);
if (fd == -1)
/* Handle better, will give unhelpful error is some cases */
return GETDNS_RETURN_GENERIC_ERROR;
return GETDNS_RETURN_NO_UPSTREAM_AVAILABLE;
getdns_transport_list_t transport =
netreq->transports[netreq->transport_current];

View File

@ -216,10 +216,13 @@ depend:
.PHONY: clean test
# Dependencies for the unit tests
check_getdns.lo check_getdns.o: $(srcdir)/check_getdns.c ../getdns/getdns.h $(srcdir)/check_getdns_common.h \
../getdns/getdns_extra.h $(srcdir)/check_getdns_address.h \
$(srcdir)/check_getdns_address_sync.h $(srcdir)/check_getdns_cancel_callback.h \
$(srcdir)/check_getdns_context_create.h $(srcdir)/check_getdns_context_destroy.h \
check_getdns.lo check_getdns.o: $(srcdir)/check_getdns.c \
../getdns/getdns.h \
$(srcdir)/check_getdns_common.h \
../getdns/getdns_extra.h \
$(srcdir)/check_getdns_address.h $(srcdir)/check_getdns_address_sync.h \
$(srcdir)/check_getdns_cancel_callback.h $(srcdir)/check_getdns_context_create.h \
$(srcdir)/check_getdns_context_destroy.h \
$(srcdir)/check_getdns_context_set_context_update_callback.h \
$(srcdir)/check_getdns_context_set_dns_transport.h \
$(srcdir)/check_getdns_context_set_timeout.h \
@ -239,34 +242,58 @@ check_getdns.lo check_getdns.o: $(srcdir)/check_getdns.c ../getdns/getdns.h $(sr
$(srcdir)/check_getdns_list_get_list.h $(srcdir)/check_getdns_pretty_print_dict.h \
$(srcdir)/check_getdns_service.h $(srcdir)/check_getdns_service_sync.h \
$(srcdir)/check_getdns_transport.h
check_getdns_common.lo check_getdns_common.o: $(srcdir)/check_getdns_common.c ../getdns/getdns.h \
../config.h $(srcdir)/check_getdns_common.h ../getdns/getdns_extra.h \
check_getdns_common.lo check_getdns_common.o: $(srcdir)/check_getdns_common.c \
../getdns/getdns.h \
../config.h \
$(srcdir)/check_getdns_common.h \
../getdns/getdns_extra.h \
$(srcdir)/check_getdns_eventloop.h
check_getdns_context_set_timeout.lo check_getdns_context_set_timeout.o: $(srcdir)/check_getdns_context_set_timeout.c \
$(srcdir)/check_getdns_context_set_timeout.h $(srcdir)/check_getdns_common.h \
../getdns/getdns.h ../getdns/getdns_extra.h
../getdns/getdns.h \
../getdns/getdns_extra.h
check_getdns_libev.lo check_getdns_libev.o: $(srcdir)/check_getdns_libev.c $(srcdir)/check_getdns_eventloop.h \
../config.h ../getdns/getdns.h $(srcdir)/../getdns/getdns_ext_libev.h \
../getdns/getdns_extra.h $(srcdir)/check_getdns_common.h
../config.h \
../getdns/getdns.h \
$(srcdir)/../getdns/getdns_ext_libev.h \
../getdns/getdns_extra.h \
$(srcdir)/check_getdns_common.h
check_getdns_libevent.lo check_getdns_libevent.o: $(srcdir)/check_getdns_libevent.c $(srcdir)/check_getdns_eventloop.h \
../config.h ../getdns/getdns.h $(srcdir)/../getdns/getdns_ext_libevent.h \
../getdns/getdns_extra.h $(srcdir)/check_getdns_libevent.h $(srcdir)/check_getdns_common.h
../config.h \
../getdns/getdns.h \
$(srcdir)/../getdns/getdns_ext_libevent.h \
../getdns/getdns_extra.h \
$(srcdir)/check_getdns_libevent.h $(srcdir)/check_getdns_common.h
check_getdns_libuv.lo check_getdns_libuv.o: $(srcdir)/check_getdns_libuv.c $(srcdir)/check_getdns_eventloop.h \
../config.h ../getdns/getdns.h $(srcdir)/../getdns/getdns_ext_libuv.h \
../getdns/getdns_extra.h $(srcdir)/check_getdns_common.h
../config.h \
../getdns/getdns.h \
$(srcdir)/../getdns/getdns_ext_libuv.h \
../getdns/getdns_extra.h \
$(srcdir)/check_getdns_common.h
check_getdns_selectloop.lo check_getdns_selectloop.o: $(srcdir)/check_getdns_selectloop.c \
$(srcdir)/check_getdns_eventloop.h ../config.h ../getdns/getdns.h \
$(srcdir)/check_getdns_eventloop.h \
../config.h \
../getdns/getdns.h \
../getdns/getdns_extra.h
check_getdns_transport.lo check_getdns_transport.o: $(srcdir)/check_getdns_transport.c \
$(srcdir)/check_getdns_transport.h $(srcdir)/check_getdns_common.h ../getdns/getdns.h \
$(srcdir)/check_getdns_transport.h $(srcdir)/check_getdns_common.h \
../getdns/getdns.h \
../getdns/getdns_extra.h
scratchpad.template.lo scratchpad.template.o: scratchpad.template.c ../getdns/getdns.h \
scratchpad.template.lo scratchpad.template.o: scratchpad.template.c \
../getdns/getdns.h \
../getdns/getdns_extra.h
testmessages.lo testmessages.o: $(srcdir)/testmessages.c $(srcdir)/testmessages.h
tests_dict.lo tests_dict.o: $(srcdir)/tests_dict.c $(srcdir)/testmessages.h ../getdns/getdns.h
tests_list.lo tests_list.o: $(srcdir)/tests_list.c $(srcdir)/testmessages.h ../getdns/getdns.h
tests_namespaces.lo tests_namespaces.o: $(srcdir)/tests_namespaces.c $(srcdir)/testmessages.h ../getdns/getdns.h
tests_stub_async.lo tests_stub_async.o: $(srcdir)/tests_stub_async.c ../config.h $(srcdir)/testmessages.h \
../getdns/getdns.h ../getdns/getdns_extra.h
tests_stub_sync.lo tests_stub_sync.o: $(srcdir)/tests_stub_sync.c $(srcdir)/testmessages.h ../getdns/getdns.h \
tests_dict.lo tests_dict.o: $(srcdir)/tests_dict.c $(srcdir)/testmessages.h \
../getdns/getdns.h
tests_list.lo tests_list.o: $(srcdir)/tests_list.c $(srcdir)/testmessages.h \
../getdns/getdns.h
tests_namespaces.lo tests_namespaces.o: $(srcdir)/tests_namespaces.c $(srcdir)/testmessages.h \
../getdns/getdns.h
tests_stub_async.lo tests_stub_async.o: $(srcdir)/tests_stub_async.c \
../config.h \
$(srcdir)/testmessages.h \
../getdns/getdns.h \
../getdns/getdns_extra.h
tests_stub_sync.lo tests_stub_sync.o: $(srcdir)/tests_stub_sync.c $(srcdir)/testmessages.h \
../getdns/getdns.h \
../getdns/getdns_extra.h

7
src/test/tpkg/clean.sh Executable file
View File

@ -0,0 +1,7 @@
#!/bin/sh
export SRCDIR=`dirname $0`
( cd $SRCDIR
./tpkg clean
rm -fr build build-stub-only build-event-loops install scan-build-reports .tpkg.var.master
)

View File

@ -113,5 +113,8 @@ depend:
.PHONY: clean test
# Dependencies for getdns_query
getdns_query.lo getdns_query.o: $(srcdir)/getdns_query.c ../config.h $(srcdir)/../debug.h ../config.h \
../getdns/getdns.h ../getdns/getdns_extra.h
getdns_query.lo getdns_query.o: $(srcdir)/getdns_query.c \
../config.h \
$(srcdir)/../debug.h \
../getdns/getdns.h \
../getdns/getdns_extra.h

View File

@ -215,7 +215,7 @@ print_usage(FILE *out, const char *progname)
fprintf(out, "\t\tThe file must be in json dict format.\n");
if (i_am_stubby) {
fprintf(out, "\t\tBy default, configuration is first read from");
fprintf(out, "\t\t\"/etc/stubby.conf\" and then from \"$HOME/.stubby.conf\"");
fprintf(out, "\n\t\t\"/etc/stubby.conf\" and then from \"$HOME/.stubby.conf\"\n");
}
fprintf(out, "\t-D\tSet edns0 do bit\n");
fprintf(out, "\t-d\tclear edns0 do bit\n");

View File

@ -5,54 +5,54 @@
, tls_auth_name: "dnsovertls.sinodun.com"
, tls_pubkey_pinset:
[ { digest: "sha256"
, value: 0xA132D34D34C181765337C70B83E3697B9524DDDB05A7118B43C0284033D5A0CC
, value: 62lKu9HsDVbyiPenApnc4sfmSYTHOVfFgL3pyB+cBL4=
} ]
},
{ address_data: 145.100.185.16
, tls_auth_name: "dnsovertls1.sinodun.com"
, tls_pubkey_pinset:
[ { digest: "sha256"
, value: 0x659B41EB08DCC70EE9D624E6219C76EE31954DA1548B0C8519EAE5228CB24150
, value: cE2ecALeE5B+urJhDrJlVFmf38cJLAvqekONvjvpqUA=
} ]
},
{ address_data: 185.49.141.38
, tls_auth_name: "getdnsapi.net"
, tls_pubkey_pinset:
[ { digest: "sha256"
, value: 0x7e8c59467221f606695a797ecc488a6b4109dab7421aba0c5a6d3681ac5273d4
, value: foxZRnIh9gZpWnl+zEiKa0EJ2rdCGroMWm02gaxSc9Q=
} ]
},
{ address_data: 2001:610:1:40ba:145:100:185:15
, tls_auth_name: "dnsovertls.sinodun.com"
, tls_pubkey_pinset:
[ { digest: "sha256"
, value: 0xA132D34D34C181765337C70B83E3697B9524DDDB05A7118B43C0284033D5A0CC
, value: 62lKu9HsDVbyiPenApnc4sfmSYTHOVfFgL3pyB+cBL4=
} ]
},
{ address_data: 2001:610:1:40ba:145:100:185:16
, tls_auth_name: "dnsovertls1.sinodun.com"
, tls_pubkey_pinset:
[ { digest: "sha256"
, value: 0x659B41EB08DCC70EE9D624E6219C76EE31954DA1548B0C8519EAE5228CB24150
, value: cE2ecALeE5B+urJhDrJlVFmf38cJLAvqekONvjvpqUA=
} ]
},
{ address_data: 2a04:b900:0:100::38
, tls_auth_name: "getdnsapi.net"
, tls_pubkey_pinset:
[ { digest: "sha256"
, value: 0x7e8c59467221f606695a797ecc488a6b4109dab7421aba0c5a6d3681ac5273d4
, value: foxZRnIh9gZpWnl+zEiKa0EJ2rdCGroMWm02gaxSc9Q=
} ]
},
{ address_data: 184.105.193.78
, tls_pubkey_pinset:
[ { digest: "sha256"
, value: 0xA4E5EBA54B7D9203E06D6C411457014DB447DA17A8DB01F05E9D5F7780045572
, value: pOXrpUt9kgPgbWxBFFcBTbRH2heo2wHwXp1fd4AEVXI=
} ]
},
{ address_data: 2620:ff:c000:0:1::64:25
, tls_pubkey_pinset:
[ { digest: "sha256"
, value: 0xA4E5EBA54B7D9203E06D6C411457014DB447DA17A8DB01F05E9D5F7780045572
, value: pOXrpUt9kgPgbWxBFFcBTbRH2heo2wHwXp1fd4AEVXI=
} ]
}
]

View File

@ -272,6 +272,7 @@ typedef struct getdns_network_req
static inline int _getdns_netreq_finished(getdns_network_req *req)
{ return !req || (req->state & NET_REQ_FINISHED); }
struct chain_head;
/**
* dns request - manages a number of network requests and
* the initial data passed to getdns_general
@ -294,9 +295,6 @@ typedef struct getdns_dns_req {
size_t suffix_len;
unsigned suffix_appended : 1;
/* canceled flag */
unsigned canceled : 1;
/* request extensions */
unsigned dnssec_return_status : 1;
unsigned dnssec_return_only_secure : 1;
@ -327,6 +325,9 @@ typedef struct getdns_dns_req {
unsigned validating : 1;
int *freed;
/* Validation chain to be canceled when this request is canceled */
struct chain_head *chain;
uint16_t tls_query_padding_blocksize;
/* internally scheduled request */

View File

@ -1510,7 +1510,7 @@ uint8_t *_getdns_list2wire(
gldns_buffer gbuf;
size_t sz;
gldns_buffer_init_frm_data(&gbuf, buf, *buf_len);
gldns_buffer_init_vfixed_frm_data(&gbuf, buf, *buf_len);
_getdns_list2wire_buf(&gbuf, l);
if ((sz = gldns_buffer_position(&gbuf)) <= *buf_len) {
@ -1531,7 +1531,7 @@ uint8_t *_getdns_reply2wire(
gldns_buffer gbuf;
size_t sz;
gldns_buffer_init_frm_data(&gbuf, buf, *buf_len);
gldns_buffer_init_vfixed_frm_data(&gbuf, buf, *buf_len);
_getdns_reply2wire_buf(&gbuf, r);
if ((sz = gldns_buffer_position(&gbuf)) <= *buf_len) {