Merge pull request #8 from wtoorop/features/mdns-client

Features/mdns client
This commit is contained in:
huitema 2017-03-13 13:44:54 -07:00 committed by GitHub
commit d511ce24de
39 changed files with 3823 additions and 975 deletions

View File

@ -481,9 +481,10 @@ case "$enable_dsa" in
;; ;;
esac esac
AC_ARG_ENABLE(all-drafts, AC_HELP_STRING([--enable-all-drafts], [No drafts in this release])) AC_ARG_ENABLE(all-drafts, AC_HELP_STRING([--enable-all-drafts], [Enables the draft mdns client support]))
case "$enable_all_drafts" in case "$enable_all_drafts" in
yes) yes)
AC_DEFINE_UNQUOTED([HAVE_MDNS_SUPPORT], [1], [Define this to enable the draft mdns client support.])
;; ;;
no|*) no|*)
;; ;;
@ -514,6 +515,15 @@ AC_DEFINE_UNQUOTED([EDNS_COOKIE_ROLLOVER_TIME], [(24 * 60 * 60)], [How often the
AC_DEFINE_UNQUOTED([MAXIMUM_UPSTREAM_OPTION_SPACE], [3000], [limit for dynamically-generated DNS options]) AC_DEFINE_UNQUOTED([MAXIMUM_UPSTREAM_OPTION_SPACE], [3000], [limit for dynamically-generated DNS options])
AC_DEFINE_UNQUOTED([EDNS_PADDING_OPCODE], [12], [The edns padding option code.]) AC_DEFINE_UNQUOTED([EDNS_PADDING_OPCODE], [12], [The edns padding option code.])
AC_ARG_ENABLE(draft-mdns-support, AC_HELP_STRING([--enable-draft-mdns-support], [Enable draft mdns client support]))
case "$enable_draft_mdns_support" in
yes)
AC_DEFINE_UNQUOTED([HAVE_MDNS_SUPPORT], [1], [Define this to enable the draft mdns client support.])
;;
no|*)
;;
esac
my_with_libunbound=1 my_with_libunbound=1
AC_ARG_ENABLE(stub-only, AC_HELP_STRING([--enable-stub-only], [Restricts resolution modes to STUB (which will be the default mode). Removes the libunbound dependency.])) AC_ARG_ENABLE(stub-only, AC_HELP_STRING([--enable-stub-only], [Restricts resolution modes to STUB (which will be the default mode). Removes the libunbound dependency.]))
case "$enable_stub_only" in case "$enable_stub_only" in
@ -657,7 +667,7 @@ AC_TYPE_UINT16_T
AC_TYPE_UINT32_T AC_TYPE_UINT32_T
AC_TYPE_UINT64_T AC_TYPE_UINT64_T
AC_TYPE_UINT8_T AC_TYPE_UINT8_T
AC_CHECK_TYPE([u_char]) AC_CHECK_TYPES([u_char])
AC_CHECK_FUNCS([fcntl]) AC_CHECK_FUNCS([fcntl])
# check ioctlsocket # check ioctlsocket
@ -742,7 +752,7 @@ AS_IF([test x_$withval = x_no],
[AC_MSG_ERROR([event2/event.h and event.h missing, try without libevent])] [AC_MSG_ERROR([event2/event.h and event.h missing, try without libevent])]
[have_libevent=0], [have_libevent=0],
[AC_INCLUDES_DEFAULT] [AC_INCLUDES_DEFAULT]
[#if HAVE_U_CHAR == 0 [#ifndef HAVE_U_CHAR
typedef unsigned char u_char; typedef unsigned char u_char;
#endif])], #endif])],
[AC_INCLUDES_DEFAULT])], [AC_INCLUDES_DEFAULT])],
@ -992,7 +1002,7 @@ fi
#---- check for pthreads library #---- check for pthreads library
AC_SEARCH_LIBS([pthread_mutex_init],[pthread],[AC_DEFINE([HAVE_PTHREADS], [1], [Have pthreads library])], [AC_MSG_WARN([pthreads not available])]) AC_SEARCH_LIBS([pthread_mutex_init],[pthread],[AC_DEFINE([HAVE_PTHREAD], [1], [Have pthreads library])], [AC_MSG_WARN([pthreads not available])])
AC_MSG_CHECKING([whether the C compiler (${CC-cc}) supports the __func__ variable]) AC_MSG_CHECKING([whether the C compiler (${CC-cc}) supports the __func__ variable])
AC_LANG_PUSH(C) AC_LANG_PUSH(C)
@ -1008,7 +1018,7 @@ dnl ----- Start of "Things needed for gldns" section
dnl ----- dnl -----
dnl --------------------------------------------------------------------------- dnl ---------------------------------------------------------------------------
AC_CHECK_HEADERS([stdarg.h stdint.h netinet/in.h arpa/inet.h netdb.h sys/socket.h time.h sys/time.h sys/select.h],,, [AC_INCLUDES_DEFAULT]) AC_CHECK_HEADERS([stdarg.h stdint.h netinet/in.h arpa/inet.h netdb.h sys/socket.h time.h sys/time.h sys/select.h endian.h],,, [AC_INCLUDES_DEFAULT])
dnl Check the printf-format attribute (if any) dnl Check the printf-format attribute (if any)
dnl result in HAVE_ATTR_FORMAT. dnl result in HAVE_ATTR_FORMAT.

View File

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

View File

@ -48,7 +48,7 @@ srcdir = @srcdir@
LIBTOOL = ../libtool LIBTOOL = ../libtool
CC=@CC@ CC=@CC@
CFLAGS=-I$(srcdir) -I. @CFLAGS@ @CPPFLAGS@ $(XTRA_CFLAGS) CFLAGS=-I$(srcdir) -I. -I$(srcdir)/util/auxiliary @CFLAGS@ @CPPFLAGS@ $(XTRA_CFLAGS)
WPEDANTICFLAG=@WPEDANTICFLAG@ WPEDANTICFLAG=@WPEDANTICFLAG@
WNOERRORFLAG=@WNOERRORFLAG@ WNOERRORFLAG=@WNOERRORFLAG@
LDFLAGS=@LDFLAGS@ @LIBS@ LDFLAGS=@LDFLAGS@ @LIBS@
@ -79,7 +79,7 @@ LIBOBJDIR=
LIBOBJS=@LIBOBJS@ LIBOBJS=@LIBOBJS@
COMPAT_OBJ=$(LIBOBJS:.o=.lo) COMPAT_OBJ=$(LIBOBJS:.o=.lo)
UTIL_OBJ=rbtree.lo val_secalgo.lo UTIL_OBJ=rbtree.lo val_secalgo.lo lruhash.lo lookup3.lo locks.lo
JSMN_OBJ=jsmn.lo JSMN_OBJ=jsmn.lo
@ -191,13 +191,14 @@ Makefile: $(srcdir)/Makefile.in ../config.status
depend: depend:
(cd $(srcdir) ; awk 'BEGIN{P=1}{if(P)print}/^# Dependencies/{P=0}' Makefile.in > Makefile.in.new ) (cd $(srcdir) ; awk 'BEGIN{P=1}{if(P)print}/^# Dependencies/{P=0}' Makefile.in > Makefile.in.new )
(blddir=`pwd`; cd $(srcdir) ; gcc -MM -I. -I"$$blddir" *.c gldns/*.c compat/*.c util/*.c jsmn/*.c extension/*.c| \ (blddir=`pwd`; cd $(srcdir) ; gcc -MM -I. -I"$$blddir" -Iutil/auxiliary *.c gldns/*.c compat/*.c util/*.c jsmn/*.c extension/*.c| \
sed -e "s? $$blddir/? ?g" \ sed -e "s? $$blddir/? ?g" \
-e 's?gldns/?$$(srcdir)/gldns/?g' \ -e 's? gldns/? $$(srcdir)/gldns/?g' \
-e 's?compat/?$$(srcdir)/compat/?g' \ -e 's? compat/? $$(srcdir)/compat/?g' \
-e 's?util/?$$(srcdir)/util/?g' \ -e 's? util/auxiliary/util/? $$(srcdir)/util/auxiliary/util/?g' \
-e 's?jsmn/?$$(srcdir)/jsmn/?g' \ -e 's? util/? $$(srcdir)/util/?g' \
-e 's?extension/?$$(srcdir)/extension/?g' \ -e 's? jsmn/? $$(srcdir)/jsmn/?g' \
-e 's? extension/? $$(srcdir)/extension/?g' \
-e 's? \([a-z_-]*\)\.\([ch]\)? $$(srcdir)/\1.\2?g' \ -e 's? \([a-z_-]*\)\.\([ch]\)? $$(srcdir)/\1.\2?g' \
-e 's? \$$(srcdir)/config\.h? config.h?g' \ -e 's? \$$(srcdir)/config\.h? config.h?g' \
-e 's? \$$(srcdir)/getdns/getdns_extra\.h? getdns/getdns_extra.h?g' \ -e 's? \$$(srcdir)/getdns/getdns_extra\.h? getdns/getdns_extra.h?g' \
@ -215,232 +216,169 @@ depend:
FORCE: FORCE:
# Dependencies for gldns, utils, the extensions and compat functions # Dependencies for gldns, utils, the extensions and compat functions
const-info.lo const-info.o: $(srcdir)/const-info.c \ const-info.lo const-info.o: $(srcdir)/const-info.c getdns/getdns.h getdns/getdns_extra.h \
getdns/getdns.h \ getdns/getdns.h $(srcdir)/const-info.h
getdns/getdns_extra.h \ context.lo context.o: $(srcdir)/context.c config.h $(srcdir)/debug.h $(srcdir)/gldns/str2wire.h $(srcdir)/gldns/rrdef.h \
$(srcdir)/const-info.h $(srcdir)/gldns/wire2str.h $(srcdir)/context.h getdns/getdns.h getdns/getdns_extra.h \
context.lo context.o: $(srcdir)/context.c \ getdns/getdns.h $(srcdir)/types-internal.h $(srcdir)/util/rbtree.h \
config.h \ $(srcdir)/util/orig-headers/rbtree.h $(srcdir)/extension/default_eventloop.h config.h \
$(srcdir)/debug.h $(srcdir)/gldns/str2wire.h $(srcdir)/gldns/rrdef.h $(srcdir)/gldns/wire2str.h $(srcdir)/context.h \ $(srcdir)/extension/poll_eventloop.h getdns/getdns_extra.h $(srcdir)/types-internal.h \
getdns/getdns.h \ $(srcdir)/ub_loop.h $(srcdir)/server.h $(srcdir)/util-internal.h $(srcdir)/rr-iter.h $(srcdir)/rr-dict.h $(srcdir)/gldns/gbuffer.h \
getdns/getdns_extra.h \ $(srcdir)/gldns/pkthdr.h $(srcdir)/dnssec.h $(srcdir)/gldns/rrdef.h $(srcdir)/stub.h $(srcdir)/list.h $(srcdir)/dict.h \
$(srcdir)/types-internal.h $(srcdir)/util/rbtree.h $(srcdir)/extension/default_eventloop.h \ $(srcdir)/pubkey-pinning.h
$(srcdir)/extension/poll_eventloop.h $(srcdir)/types-internal.h $(srcdir)/ub_loop.h $(srcdir)/server.h \ convert.lo convert.o: $(srcdir)/convert.c config.h getdns/getdns.h getdns/getdns_extra.h \
$(srcdir)/util-internal.h $(srcdir)/rr-iter.h $(srcdir)/rr-dict.h $(srcdir)/gldns/gbuffer.h $(srcdir)/gldns/pkthdr.h \ getdns/getdns.h $(srcdir)/util-internal.h $(srcdir)/context.h $(srcdir)/types-internal.h $(srcdir)/util/rbtree.h \
$(srcdir)/dnssec.h $(srcdir)/gldns/rrdef.h $(srcdir)/stub.h $(srcdir)/list.h $(srcdir)/dict.h $(srcdir)/pubkey-pinning.h $(srcdir)/util/orig-headers/rbtree.h $(srcdir)/extension/default_eventloop.h config.h \
convert.lo convert.o: $(srcdir)/convert.c \ $(srcdir)/extension/poll_eventloop.h getdns/getdns_extra.h $(srcdir)/types-internal.h \
config.h \ $(srcdir)/ub_loop.h $(srcdir)/debug.h $(srcdir)/server.h $(srcdir)/rr-iter.h $(srcdir)/rr-dict.h $(srcdir)/gldns/gbuffer.h \
getdns/getdns.h \ $(srcdir)/gldns/pkthdr.h $(srcdir)/gldns/wire2str.h $(srcdir)/gldns/str2wire.h $(srcdir)/gldns/rrdef.h \
getdns/getdns_extra.h \ $(srcdir)/gldns/parseutil.h $(srcdir)/const-info.h $(srcdir)/dict.h $(srcdir)/list.h $(srcdir)/jsmn/jsmn.h $(srcdir)/convert.h
$(srcdir)/util-internal.h $(srcdir)/context.h $(srcdir)/types-internal.h $(srcdir)/util/rbtree.h \ dict.lo dict.o: $(srcdir)/dict.c config.h $(srcdir)/types-internal.h getdns/getdns.h \
$(srcdir)/extension/default_eventloop.h $(srcdir)/extension/poll_eventloop.h \ getdns/getdns_extra.h getdns/getdns.h $(srcdir)/util/rbtree.h \
$(srcdir)/types-internal.h $(srcdir)/ub_loop.h $(srcdir)/debug.h $(srcdir)/server.h $(srcdir)/rr-iter.h $(srcdir)/rr-dict.h \ $(srcdir)/util/orig-headers/rbtree.h $(srcdir)/util-internal.h $(srcdir)/context.h \
$(srcdir)/gldns/gbuffer.h $(srcdir)/gldns/pkthdr.h $(srcdir)/gldns/wire2str.h $(srcdir)/gldns/str2wire.h \ $(srcdir)/extension/default_eventloop.h config.h $(srcdir)/extension/poll_eventloop.h \
$(srcdir)/gldns/rrdef.h $(srcdir)/gldns/parseutil.h $(srcdir)/const-info.h $(srcdir)/dict.h $(srcdir)/list.h $(srcdir)/jsmn/jsmn.h \ getdns/getdns_extra.h $(srcdir)/types-internal.h $(srcdir)/ub_loop.h $(srcdir)/debug.h $(srcdir)/server.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)/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 $(srcdir)/const-info.h $(srcdir)/gldns/wire2str.h $(srcdir)/gldns/parseutil.h
dnssec.lo dnssec.o: $(srcdir)/dnssec.c \ dnssec.lo dnssec.o: $(srcdir)/dnssec.c config.h $(srcdir)/debug.h getdns/getdns.h $(srcdir)/context.h \
config.h \ getdns/getdns_extra.h getdns/getdns.h $(srcdir)/types-internal.h $(srcdir)/util/rbtree.h \
$(srcdir)/debug.h \ $(srcdir)/util/orig-headers/rbtree.h $(srcdir)/extension/default_eventloop.h config.h \
getdns/getdns.h \ $(srcdir)/extension/poll_eventloop.h getdns/getdns_extra.h $(srcdir)/types-internal.h \
$(srcdir)/context.h \ $(srcdir)/ub_loop.h $(srcdir)/server.h $(srcdir)/util-internal.h $(srcdir)/rr-iter.h $(srcdir)/rr-dict.h $(srcdir)/gldns/gbuffer.h \
getdns/getdns_extra.h \ $(srcdir)/gldns/pkthdr.h $(srcdir)/dnssec.h $(srcdir)/gldns/rrdef.h $(srcdir)/gldns/str2wire.h $(srcdir)/gldns/rrdef.h \
$(srcdir)/types-internal.h $(srcdir)/util/rbtree.h $(srcdir)/extension/default_eventloop.h \ $(srcdir)/gldns/wire2str.h $(srcdir)/gldns/keyraw.h $(srcdir)/gldns/parseutil.h $(srcdir)/general.h $(srcdir)/dict.h \
$(srcdir)/extension/poll_eventloop.h $(srcdir)/types-internal.h $(srcdir)/ub_loop.h $(srcdir)/server.h \ $(srcdir)/list.h $(srcdir)/util/val_secalgo.h $(srcdir)/util/orig-headers/val_secalgo.h
$(srcdir)/util-internal.h $(srcdir)/rr-iter.h $(srcdir)/rr-dict.h $(srcdir)/gldns/gbuffer.h $(srcdir)/gldns/pkthdr.h \ general.lo general.o: $(srcdir)/general.c config.h $(srcdir)/general.h getdns/getdns.h $(srcdir)/types-internal.h \
$(srcdir)/dnssec.h $(srcdir)/gldns/rrdef.h $(srcdir)/gldns/str2wire.h $(srcdir)/gldns/rrdef.h $(srcdir)/gldns/wire2str.h \ getdns/getdns_extra.h getdns/getdns.h $(srcdir)/util/rbtree.h \
$(srcdir)/gldns/keyraw.h $(srcdir)/gldns/parseutil.h $(srcdir)/general.h $(srcdir)/dict.h $(srcdir)/list.h \ $(srcdir)/util/orig-headers/rbtree.h $(srcdir)/ub_loop.h $(srcdir)/debug.h $(srcdir)/gldns/wire2str.h $(srcdir)/context.h \
$(srcdir)/util/val_secalgo.h $(srcdir)/extension/default_eventloop.h config.h $(srcdir)/extension/poll_eventloop.h \
general.lo general.o: $(srcdir)/general.c \ getdns/getdns_extra.h $(srcdir)/types-internal.h $(srcdir)/server.h $(srcdir)/util-internal.h \
config.h \ $(srcdir)/rr-iter.h $(srcdir)/rr-dict.h $(srcdir)/gldns/gbuffer.h $(srcdir)/gldns/pkthdr.h $(srcdir)/dnssec.h \
$(srcdir)/general.h \ $(srcdir)/gldns/rrdef.h $(srcdir)/stub.h $(srcdir)/dict.h $(srcdir)/mdns.h
getdns/getdns.h \ list.lo list.o: $(srcdir)/list.c $(srcdir)/types-internal.h getdns/getdns.h getdns/getdns_extra.h \
$(srcdir)/types-internal.h \ getdns/getdns.h $(srcdir)/util/rbtree.h $(srcdir)/util/orig-headers/rbtree.h $(srcdir)/util-internal.h \
getdns/getdns_extra.h \ config.h $(srcdir)/context.h $(srcdir)/extension/default_eventloop.h config.h \
$(srcdir)/util/rbtree.h $(srcdir)/ub_loop.h $(srcdir)/debug.h $(srcdir)/gldns/wire2str.h $(srcdir)/context.h \ $(srcdir)/extension/poll_eventloop.h getdns/getdns_extra.h $(srcdir)/types-internal.h \
$(srcdir)/extension/default_eventloop.h $(srcdir)/extension/poll_eventloop.h \ $(srcdir)/ub_loop.h $(srcdir)/debug.h $(srcdir)/server.h $(srcdir)/rr-iter.h $(srcdir)/rr-dict.h $(srcdir)/gldns/gbuffer.h \
$(srcdir)/types-internal.h $(srcdir)/server.h $(srcdir)/util-internal.h $(srcdir)/rr-iter.h $(srcdir)/rr-dict.h \ $(srcdir)/gldns/pkthdr.h $(srcdir)/list.h $(srcdir)/dict.h
$(srcdir)/gldns/gbuffer.h $(srcdir)/gldns/pkthdr.h $(srcdir)/dnssec.h $(srcdir)/gldns/rrdef.h $(srcdir)/stub.h $(srcdir)/dict.h \ mdns.lo mdns.o: $(srcdir)/mdns.c config.h $(srcdir)/debug.h $(srcdir)/context.h getdns/getdns.h \
$(srcdir)/mdns.h getdns/getdns_extra.h getdns/getdns.h $(srcdir)/types-internal.h $(srcdir)/util/rbtree.h \
list.lo list.o: $(srcdir)/list.c $(srcdir)/types-internal.h \ $(srcdir)/util/orig-headers/rbtree.h $(srcdir)/extension/default_eventloop.h config.h \
getdns/getdns.h \ $(srcdir)/extension/poll_eventloop.h getdns/getdns_extra.h $(srcdir)/types-internal.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)/util/rbtree.h $(srcdir)/util-internal.h \ $(srcdir)/rr-dict.h $(srcdir)/gldns/gbuffer.h $(srcdir)/mdns.h
config.h \ pubkey-pinning.lo pubkey-pinning.o: $(srcdir)/pubkey-pinning.c config.h $(srcdir)/debug.h getdns/getdns.h \
$(srcdir)/context.h $(srcdir)/extension/default_eventloop.h $(srcdir)/extension/poll_eventloop.h \ $(srcdir)/context.h getdns/getdns.h getdns/getdns_extra.h $(srcdir)/types-internal.h \
$(srcdir)/types-internal.h $(srcdir)/ub_loop.h $(srcdir)/debug.h $(srcdir)/server.h $(srcdir)/rr-iter.h $(srcdir)/rr-dict.h \ $(srcdir)/util/rbtree.h $(srcdir)/util/orig-headers/rbtree.h $(srcdir)/extension/default_eventloop.h \
$(srcdir)/gldns/gbuffer.h $(srcdir)/gldns/pkthdr.h $(srcdir)/list.h $(srcdir)/dict.h config.h $(srcdir)/extension/poll_eventloop.h getdns/getdns_extra.h \
mdns.lo mdns.o: $(srcdir)/mdns.c \ $(srcdir)/types-internal.h $(srcdir)/ub_loop.h $(srcdir)/server.h $(srcdir)/util-internal.h $(srcdir)/rr-iter.h $(srcdir)/rr-dict.h \
config.h \ $(srcdir)/gldns/gbuffer.h $(srcdir)/gldns/pkthdr.h
$(srcdir)/debug.h $(srcdir)/context.h \ request-internal.lo request-internal.o: $(srcdir)/request-internal.c config.h $(srcdir)/types-internal.h \
getdns/getdns.h \ getdns/getdns.h getdns/getdns_extra.h getdns/getdns.h $(srcdir)/util/rbtree.h \
getdns/getdns_extra.h \ $(srcdir)/util/orig-headers/rbtree.h $(srcdir)/util-internal.h $(srcdir)/context.h \
$(srcdir)/types-internal.h $(srcdir)/util/rbtree.h $(srcdir)/extension/default_eventloop.h \ $(srcdir)/extension/default_eventloop.h config.h $(srcdir)/extension/poll_eventloop.h \
$(srcdir)/extension/poll_eventloop.h $(srcdir)/types-internal.h $(srcdir)/ub_loop.h $(srcdir)/server.h $(srcdir)/general.h \ getdns/getdns_extra.h $(srcdir)/types-internal.h $(srcdir)/ub_loop.h $(srcdir)/debug.h $(srcdir)/server.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)/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 $(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 \ rr-dict.lo rr-dict.o: $(srcdir)/rr-dict.c $(srcdir)/rr-dict.h config.h getdns/getdns.h $(srcdir)/gldns/gbuffer.h \
config.h \ $(srcdir)/util-internal.h $(srcdir)/context.h getdns/getdns_extra.h getdns/getdns.h \
getdns/getdns.h \ $(srcdir)/types-internal.h $(srcdir)/util/rbtree.h $(srcdir)/util/orig-headers/rbtree.h \
$(srcdir)/gldns/gbuffer.h $(srcdir)/util-internal.h $(srcdir)/context.h \ $(srcdir)/extension/default_eventloop.h config.h $(srcdir)/extension/poll_eventloop.h \
getdns/getdns_extra.h \ getdns/getdns_extra.h $(srcdir)/types-internal.h $(srcdir)/ub_loop.h $(srcdir)/debug.h $(srcdir)/server.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 $(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 \ rr-iter.lo rr-iter.o: $(srcdir)/rr-iter.c $(srcdir)/rr-iter.h $(srcdir)/rr-dict.h config.h getdns/getdns.h \
config.h \
getdns/getdns.h \
$(srcdir)/gldns/gbuffer.h $(srcdir)/gldns/pkthdr.h $(srcdir)/gldns/rrdef.h $(srcdir)/gldns/gbuffer.h $(srcdir)/gldns/pkthdr.h $(srcdir)/gldns/rrdef.h
server.lo server.o: $(srcdir)/server.c \ server.lo server.o: $(srcdir)/server.c config.h getdns/getdns_extra.h getdns/getdns.h \
config.h \ $(srcdir)/context.h getdns/getdns.h $(srcdir)/types-internal.h $(srcdir)/util/rbtree.h \
getdns/getdns_extra.h \ $(srcdir)/util/orig-headers/rbtree.h $(srcdir)/extension/default_eventloop.h config.h \
getdns/getdns.h \ $(srcdir)/extension/poll_eventloop.h getdns/getdns_extra.h $(srcdir)/types-internal.h \
$(srcdir)/context.h $(srcdir)/types-internal.h $(srcdir)/util/rbtree.h $(srcdir)/extension/default_eventloop.h \ $(srcdir)/ub_loop.h $(srcdir)/debug.h $(srcdir)/server.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 \
stub.lo stub.o: $(srcdir)/stub.c \ getdns/getdns_extra.h getdns/getdns.h $(srcdir)/util/rbtree.h \
config.h \ $(srcdir)/util/orig-headers/rbtree.h $(srcdir)/gldns/gbuffer.h $(srcdir)/gldns/pkthdr.h $(srcdir)/gldns/rrdef.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)/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)/context.h $(srcdir)/extension/default_eventloop.h config.h \
$(srcdir)/types-internal.h $(srcdir)/ub_loop.h $(srcdir)/server.h $(srcdir)/util-internal.h $(srcdir)/general.h \ $(srcdir)/extension/poll_eventloop.h getdns/getdns_extra.h $(srcdir)/types-internal.h \
$(srcdir)/pubkey-pinning.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 \ sync.lo sync.o: $(srcdir)/sync.c getdns/getdns.h config.h $(srcdir)/context.h getdns/getdns_extra.h \
getdns/getdns.h \ getdns/getdns.h $(srcdir)/types-internal.h $(srcdir)/util/rbtree.h \
config.h \ $(srcdir)/util/orig-headers/rbtree.h $(srcdir)/extension/default_eventloop.h config.h \
$(srcdir)/context.h \ $(srcdir)/extension/poll_eventloop.h getdns/getdns_extra.h $(srcdir)/types-internal.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)/types-internal.h $(srcdir)/util/rbtree.h $(srcdir)/extension/default_eventloop.h \ $(srcdir)/gldns/gbuffer.h $(srcdir)/gldns/pkthdr.h $(srcdir)/dnssec.h $(srcdir)/gldns/rrdef.h $(srcdir)/stub.h \
$(srcdir)/extension/poll_eventloop.h $(srcdir)/types-internal.h $(srcdir)/ub_loop.h $(srcdir)/debug.h $(srcdir)/server.h \ $(srcdir)/gldns/wire2str.h
$(srcdir)/general.h $(srcdir)/util-internal.h $(srcdir)/rr-iter.h $(srcdir)/rr-dict.h $(srcdir)/gldns/gbuffer.h \ ub_loop.lo ub_loop.o: $(srcdir)/ub_loop.c $(srcdir)/ub_loop.h config.h getdns/getdns.h \
$(srcdir)/gldns/pkthdr.h $(srcdir)/dnssec.h $(srcdir)/gldns/rrdef.h $(srcdir)/stub.h $(srcdir)/gldns/wire2str.h getdns/getdns_extra.h getdns/getdns.h $(srcdir)/types-internal.h $(srcdir)/util/rbtree.h \
ub_loop.lo ub_loop.o: $(srcdir)/ub_loop.c $(srcdir)/ub_loop.h \ $(srcdir)/util/orig-headers/rbtree.h $(srcdir)/debug.h
config.h \ util-internal.lo util-internal.o: $(srcdir)/util-internal.c config.h getdns/getdns.h $(srcdir)/dict.h \
getdns/getdns.h \ $(srcdir)/util/rbtree.h $(srcdir)/util/orig-headers/rbtree.h $(srcdir)/types-internal.h \
getdns/getdns_extra.h \ getdns/getdns_extra.h getdns/getdns.h $(srcdir)/list.h $(srcdir)/util-internal.h $(srcdir)/context.h \
$(srcdir)/types-internal.h $(srcdir)/util/rbtree.h $(srcdir)/debug.h $(srcdir)/extension/default_eventloop.h config.h $(srcdir)/extension/poll_eventloop.h \
util-internal.lo util-internal.o: $(srcdir)/util-internal.c \ getdns/getdns_extra.h $(srcdir)/types-internal.h $(srcdir)/ub_loop.h $(srcdir)/debug.h $(srcdir)/server.h \
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)/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 $(srcdir)/gldns/rrdef.h $(srcdir)/dnssec.h $(srcdir)/gldns/rrdef.h
gbuffer.lo gbuffer.o: $(srcdir)/gldns/gbuffer.c \ version.lo version.o: version.c
config.h \ 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 \
$(srcdir)/gldns/gbuffer.h $(srcdir)/gldns/gbuffer.h
keyraw.lo keyraw.o: $(srcdir)/gldns/keyraw.c \ parseutil.lo parseutil.o: $(srcdir)/gldns/parseutil.c config.h $(srcdir)/gldns/parseutil.h
config.h \ rrdef.lo rrdef.o: $(srcdir)/gldns/rrdef.c config.h $(srcdir)/gldns/rrdef.h $(srcdir)/gldns/parseutil.h
$(srcdir)/gldns/keyraw.h $(srcdir)/gldns/rrdef.h str2wire.lo str2wire.o: $(srcdir)/gldns/str2wire.c config.h $(srcdir)/gldns/str2wire.h $(srcdir)/gldns/rrdef.h \
parse.lo parse.o: $(srcdir)/gldns/parse.c \ $(srcdir)/gldns/wire2str.h $(srcdir)/gldns/gbuffer.h $(srcdir)/gldns/parse.h $(srcdir)/gldns/parseutil.h
config.h \ wire2str.lo wire2str.o: $(srcdir)/gldns/wire2str.c config.h $(srcdir)/gldns/wire2str.h $(srcdir)/gldns/str2wire.h \
$(srcdir)/gldns/parse.h $(srcdir)/gldns/parseutil.h $(srcdir)/gldns/gbuffer.h $(srcdir)/gldns/rrdef.h $(srcdir)/gldns/pkthdr.h $(srcdir)/gldns/parseutil.h $(srcdir)/gldns/gbuffer.h \
parseutil.lo parseutil.o: $(srcdir)/gldns/parseutil.c \ $(srcdir)/gldns/keyraw.h
config.h \ arc4_lock.lo arc4_lock.o: $(srcdir)/compat/arc4_lock.c config.h
$(srcdir)/gldns/parseutil.h arc4random.lo arc4random.o: $(srcdir)/compat/arc4random.c config.h $(srcdir)/compat/chacha_private.h
rrdef.lo rrdef.o: $(srcdir)/gldns/rrdef.c \ arc4random_uniform.lo arc4random_uniform.o: $(srcdir)/compat/arc4random_uniform.c config.h
config.h \ explicit_bzero.lo explicit_bzero.o: $(srcdir)/compat/explicit_bzero.c config.h
$(srcdir)/gldns/rrdef.h $(srcdir)/gldns/parseutil.h getentropy_linux.lo getentropy_linux.o: $(srcdir)/compat/getentropy_linux.c config.h
str2wire.lo str2wire.o: $(srcdir)/gldns/str2wire.c \ getentropy_osx.lo getentropy_osx.o: $(srcdir)/compat/getentropy_osx.c config.h
config.h \ getentropy_solaris.lo getentropy_solaris.o: $(srcdir)/compat/getentropy_solaris.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 getentropy_win.lo getentropy_win.o: $(srcdir)/compat/getentropy_win.c
gettimeofday.lo gettimeofday.o: $(srcdir)/compat/gettimeofday.c \ gettimeofday.lo gettimeofday.o: $(srcdir)/compat/gettimeofday.c config.h
config.h inet_ntop.lo inet_ntop.o: $(srcdir)/compat/inet_ntop.c config.h
inet_ntop.lo inet_ntop.o: $(srcdir)/compat/inet_ntop.c \ inet_pton.lo inet_pton.o: $(srcdir)/compat/inet_pton.c config.h
config.h sha512.lo sha512.o: $(srcdir)/compat/sha512.c config.h
inet_pton.lo inet_pton.o: $(srcdir)/compat/inet_pton.c \ strlcpy.lo strlcpy.o: $(srcdir)/compat/strlcpy.c config.h
config.h locks.lo locks.o: $(srcdir)/util/locks.c config.h $(srcdir)/util/locks.h $(srcdir)/util/orig-headers/locks.h \
sha512.lo sha512.o: $(srcdir)/compat/sha512.c \ $(srcdir)/util/auxiliary/util/log.h $(srcdir)/debug.h config.h
config.h lookup3.lo lookup3.o: $(srcdir)/util/lookup3.c config.h $(srcdir)/util/auxiliary/util/storage/lookup3.h \
strlcpy.lo strlcpy.o: $(srcdir)/compat/strlcpy.c \ $(srcdir)/util/lookup3.h $(srcdir)/util/orig-headers/lookup3.h
config.h lruhash.lo lruhash.o: $(srcdir)/util/lruhash.c config.h $(srcdir)/util/auxiliary/util/storage/lruhash.h \
rbtree.lo rbtree.o: $(srcdir)/util/rbtree.c \ $(srcdir)/util/lruhash.h $(srcdir)/util/orig-headers/lruhash.h $(srcdir)/util/locks.h \
config.h \ $(srcdir)/util/orig-headers/locks.h $(srcdir)/util/auxiliary/util/log.h $(srcdir)/debug.h config.h \
$(srcdir)/util/log.h $(srcdir)/debug.h $(srcdir)/util/fptr_wlist.h $(srcdir)/util/rbtree.h $(srcdir)/util/auxiliary/util/fptr_wlist.h
val_secalgo.lo val_secalgo.o: $(srcdir)/util/val_secalgo.c \ rbtree.lo rbtree.o: $(srcdir)/util/rbtree.c config.h $(srcdir)/util/auxiliary/log.h \
config.h \ $(srcdir)/util/auxiliary/util/log.h $(srcdir)/debug.h config.h $(srcdir)/util/auxiliary/fptr_wlist.h \
$(srcdir)/util/val_secalgo.h $(srcdir)/util/log.h $(srcdir)/debug.h $(srcdir)/gldns/rrdef.h $(srcdir)/gldns/keyraw.h \ $(srcdir)/util/auxiliary/util/fptr_wlist.h $(srcdir)/util/rbtree.h \
$(srcdir)/gldns/gbuffer.h $(srcdir)/util/orig-headers/rbtree.h
val_secalgo.lo val_secalgo.o: $(srcdir)/util/val_secalgo.c config.h \
$(srcdir)/util/auxiliary/util/data/packed_rrset.h \
$(srcdir)/util/auxiliary/validator/val_secalgo.h $(srcdir)/util/val_secalgo.h \
$(srcdir)/util/orig-headers/val_secalgo.h $(srcdir)/util/auxiliary/validator/val_nsec3.h \
$(srcdir)/util/auxiliary/util/log.h $(srcdir)/debug.h config.h $(srcdir)/util/auxiliary/sldns/rrdef.h \
$(srcdir)/gldns/rrdef.h $(srcdir)/util/auxiliary/sldns/keyraw.h $(srcdir)/gldns/keyraw.h \
$(srcdir)/util/auxiliary/sldns/sbuffer.h $(srcdir)/gldns/gbuffer.h
jsmn.lo jsmn.o: $(srcdir)/jsmn/jsmn.c $(srcdir)/jsmn/jsmn.h jsmn.lo jsmn.o: $(srcdir)/jsmn/jsmn.c $(srcdir)/jsmn/jsmn.h
libev.lo libev.o: $(srcdir)/extension/libev.c \ libev.lo libev.o: $(srcdir)/extension/libev.c config.h $(srcdir)/types-internal.h getdns/getdns.h \
config.h \ getdns/getdns_extra.h getdns/getdns.h $(srcdir)/util/rbtree.h \
$(srcdir)/types-internal.h \ $(srcdir)/util/orig-headers/rbtree.h $(srcdir)/getdns/getdns_ext_libev.h \
getdns/getdns.h \ getdns/getdns_extra.h
getdns/getdns_extra.h \ libevent.lo libevent.o: $(srcdir)/extension/libevent.c config.h $(srcdir)/types-internal.h \
$(srcdir)/util/rbtree.h $(srcdir)/getdns/getdns_ext_libev.h getdns/getdns.h getdns/getdns_extra.h getdns/getdns.h $(srcdir)/util/rbtree.h \
libevent.lo libevent.o: $(srcdir)/extension/libevent.c \ $(srcdir)/util/orig-headers/rbtree.h $(srcdir)/getdns/getdns_ext_libevent.h \
config.h \ getdns/getdns_extra.h
$(srcdir)/types-internal.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.h getdns/getdns_extra.h getdns/getdns.h $(srcdir)/util/rbtree.h \
getdns/getdns_extra.h \ $(srcdir)/util/orig-headers/rbtree.h $(srcdir)/getdns/getdns_ext_libuv.h \
$(srcdir)/util/rbtree.h $(srcdir)/getdns/getdns_ext_libevent.h getdns/getdns_extra.h
libuv.lo libuv.o: $(srcdir)/extension/libuv.c \ poll_eventloop.lo poll_eventloop.o: $(srcdir)/extension/poll_eventloop.c config.h \
config.h \ $(srcdir)/extension/poll_eventloop.h getdns/getdns.h getdns/getdns_extra.h \
$(srcdir)/debug.h $(srcdir)/types-internal.h \ $(srcdir)/types-internal.h getdns/getdns.h getdns/getdns_extra.h $(srcdir)/util/rbtree.h \
getdns/getdns.h \ $(srcdir)/util/orig-headers/rbtree.h $(srcdir)/debug.h config.h
getdns/getdns_extra.h \ select_eventloop.lo select_eventloop.o: $(srcdir)/extension/select_eventloop.c config.h \
$(srcdir)/util/rbtree.h $(srcdir)/getdns/getdns_ext_libuv.h $(srcdir)/extension/select_eventloop.h getdns/getdns.h getdns/getdns_extra.h \
poll_eventloop.lo poll_eventloop.o: $(srcdir)/extension/poll_eventloop.c \ $(srcdir)/debug.h config.h $(srcdir)/types-internal.h getdns/getdns.h getdns/getdns_extra.h \
config.h \ $(srcdir)/util/rbtree.h $(srcdir)/util/orig-headers/rbtree.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

@ -34,7 +34,7 @@
#include "config.h" #include "config.h"
#define LOCKRET(func) func #define LOCKRET(func) func
#ifdef HAVE_PTHREADS #ifdef HAVE_PTHREAD
#include "pthread.h" #include "pthread.h"
static pthread_mutex_t arc_lock = PTHREAD_MUTEX_INITIALIZER; static pthread_mutex_t arc_lock = PTHREAD_MUTEX_INITIALIZER;

View File

@ -62,7 +62,7 @@ typedef unsigned short in_port_t;
#include <assert.h> #include <assert.h>
#include <ctype.h> #include <ctype.h>
#ifdef HAVE_PTHREADS #ifdef HAVE_PTHREAD
#include <pthread.h> #include <pthread.h>
#endif #endif
#include <stdbool.h> #include <stdbool.h>
@ -93,7 +93,7 @@ typedef unsigned short in_port_t;
upstream. Using 1 hour for all transports - based on RFC7858 value for for TLS.*/ upstream. Using 1 hour for all transports - based on RFC7858 value for for TLS.*/
#define BACKOFF_RETRY 3600 #define BACKOFF_RETRY 3600
#ifdef HAVE_PTHREADS #ifdef HAVE_PTHREAD
static pthread_mutex_t ssl_init_lock = PTHREAD_MUTEX_INITIALIZER; static pthread_mutex_t ssl_init_lock = PTHREAD_MUTEX_INITIALIZER;
#endif #endif
static bool ssl_init=false; static bool ssl_init=false;
@ -1457,7 +1457,7 @@ getdns_context_create_with_extended_memory_functions(
/* Unbound needs SSL to be init'ed this early when TLS is used. However we /* Unbound needs SSL to be init'ed this early when TLS is used. However we
* don't know that till later so we will have to do this every time. */ * don't know that till later so we will have to do this every time. */
#ifdef HAVE_PTHREADS #ifdef HAVE_PTHREAD
pthread_mutex_lock(&ssl_init_lock); pthread_mutex_lock(&ssl_init_lock);
#else #else
/* XXX implement Windows-style lock here */ /* XXX implement Windows-style lock here */
@ -1467,7 +1467,7 @@ getdns_context_create_with_extended_memory_functions(
SSL_library_init(); SSL_library_init();
ssl_init = true; ssl_init = true;
} }
#ifdef HAVE_PTHREADS #ifdef HAVE_PTHREAD
pthread_mutex_unlock(&ssl_init_lock); pthread_mutex_unlock(&ssl_init_lock);
#else #else
/* XXX implement Windows-style unlock here */ /* XXX implement Windows-style unlock here */

View File

@ -45,6 +45,9 @@
#include "util/rbtree.h" #include "util/rbtree.h"
#include "ub_loop.h" #include "ub_loop.h"
#include "server.h" #include "server.h"
#ifdef HAVE_MDNS_SUPPORT
#include "util/lruhash.h"
#endif
struct getdns_dns_req; struct getdns_dns_req;
struct ub_ctx; struct ub_ctx;

View File

@ -139,8 +139,13 @@
#define DEBUG_MDNS(...) DEBUG_OFF(__VA_ARGS__) #define DEBUG_MDNS(...) DEBUG_OFF(__VA_ARGS__)
#endif #endif
#ifndef log_info #if (defined(SCHED_DEBUG) && SCHED_DEBUG) || \
#define log_info(...) fprintf(stderr, __VA_ARGS__) (defined(STUB_DEBUG) && STUB_DEBUG) || \
(defined(DAEMON_DEBUG) && DAEMON_DEBUG) || \
(defined(SEC_DEBUG) && SEC_DEBUG) || \
(defined(SERVER_DEBUG) && SERVER_DEBUG) || \
(defined(MDNS_DEBUG) && MDNS_DEBUG)
#define DEBUGGING 1
#endif #endif
#endif #endif

View File

@ -38,17 +38,20 @@ typedef u_short sa_family_t;
#else #else
#define _getdns_EWOULDBLOCK (errno == EAGAIN || errno == EWOULDBLOCK) #define _getdns_EWOULDBLOCK (errno == EAGAIN || errno == EWOULDBLOCK)
#define _getdns_EINPROGRESS (errno == EINPROGRESS) #define _getdns_EINPROGRESS (errno == EINPROGRESS)
#define SOCKADDR struct sockaddr
#define SOCKADDR_IN struct sockaddr_in
#define SOCKADDR_IN6 struct sockaddr_in6
#define SOCKET int
#define IP_MREQ struct ip_mreq
#define IPV6_MREQ struct ipv6_mreq
#define BOOL int
#define TRUE 1
#endif #endif
uint64_t _getdns_get_time_as_uintt64(); uint64_t _getdns_get_time_as_uintt64();
#include "util/storage/lruhash.h" #include "util/fptr_wlist.h"
#include "util/storage/lookup3.h" #include "util/lookup3.h"
#ifndef HAVE_LIBUNBOUND
#include "util/storage/lruhash.c"
#include "util/storage/lookup3.c"
#endif
/* /*
* Constants defined in RFC 6762 * Constants defined in RFC 6762
@ -352,8 +355,6 @@ mdns_util_canonical_record(uint8_t *message, int message_length,
{ {
int ret = 0; int ret = 0;
int current_index = record_index; int current_index = record_index;
int buffer_index = 0;
int name_len = 0;
/* Check whether the record needs canonization */ /* Check whether the record needs canonization */
*actual_record = message + record_index; *actual_record = message + record_index;
*actual_length = record_length; *actual_length = record_length;
@ -781,7 +782,6 @@ mdns_update_cache_ttl_and_prune(struct getdns_context *context,
int current_record_data_len; int current_record_data_len;
uint32_t current_record_ttl; uint32_t current_record_ttl;
int not_matched_yet = (record_data == NULL) ? 0 : 1; int not_matched_yet = (record_data == NULL) ? 0 : 1;
int current_record_match;
int last_copied_index; int last_copied_index;
int current_hole_index = 0; int current_hole_index = 0;
int record_name_length = 0; int record_name_length = 0;
@ -819,15 +819,12 @@ mdns_update_cache_ttl_and_prune(struct getdns_context *context,
current_record_data_len == record_data_len && current_record_data_len == record_data_len &&
memcmp(old_record + record_ttl_index + 4 + 2, record_data, record_data_len) == 0) memcmp(old_record + record_ttl_index + 4 + 2, record_data, record_data_len) == 0)
{ {
current_record_match = 1;
not_matched_yet = 0; not_matched_yet = 0;
current_record_ttl = ttl; current_record_ttl = ttl;
} }
else else
{ {
/* Not a match */ /* Not a match */
current_record_match = 0;
if (current_record_ttl > delta_t_sec) if (current_record_ttl > delta_t_sec)
{ {
current_record_ttl -= delta_t_sec; current_record_ttl -= delta_t_sec;
@ -945,7 +942,6 @@ mdns_propose_entry_to_cache(
uint64_t current_time) uint64_t current_time)
{ {
int ret = 0; int ret = 0;
size_t required_memory = 0;
uint8_t temp_key[256 + sizeof(getdns_mdns_cached_key_header)]; uint8_t temp_key[256 + sizeof(getdns_mdns_cached_key_header)];
hashvalue_type hash; hashvalue_type hash;
struct lruhash_entry *entry, *new_entry; struct lruhash_entry *entry, *new_entry;
@ -988,7 +984,7 @@ mdns_propose_entry_to_cache(
new_entry = &((getdns_mdns_cached_key_header*)key)->entry; new_entry = &((getdns_mdns_cached_key_header*)key)->entry;
memset(new_entry, 0, sizeof(struct lruhash_entry)); memset(new_entry, 0, sizeof(struct lruhash_entry));
lock_rw_init(new_entry->lock); lock_rw_init(&new_entry->lock);
new_entry->hash = hash; new_entry->hash = hash;
new_entry->key = key; new_entry->key = key;
new_entry->data = data; new_entry->data = data;
@ -1036,7 +1032,7 @@ mdns_propose_entry_to_cache(
} }
/* then, unlock the entry */ /* then, unlock the entry */
lock_rw_unlock(entry->lock); lock_rw_unlock(&entry->lock);
} }
return ret; return ret;
@ -1139,7 +1135,6 @@ mdns_cache_complete_queries(
int record_type, int record_class) int record_type, int record_class)
{ {
int ret = 0; int ret = 0;
size_t required_memory = 0;
struct lruhash_entry *entry; struct lruhash_entry *entry;
getdns_mdns_cached_record_header * header; getdns_mdns_cached_record_header * header;
getdns_network_req * netreq; getdns_network_req * netreq;
@ -1157,7 +1152,7 @@ mdns_cache_complete_queries(
mdns_complete_query_from_cache_entry(netreq, entry); mdns_complete_query_from_cache_entry(netreq, entry);
} }
} }
lock_rw_unlock(entry->lock); lock_rw_unlock(&entry->lock);
} }
return ret; return ret;
@ -1173,8 +1168,6 @@ mdns_mcast_timeout_cb(void *userarg)
getdns_dns_req *dnsreq = netreq->owner; getdns_dns_req *dnsreq = netreq->owner;
getdns_context *context = dnsreq->context; getdns_context *context = dnsreq->context;
int ret = 0;
size_t required_memory = 0;
uint8_t temp_key[256 + sizeof(getdns_mdns_cached_key_header)]; uint8_t temp_key[256 + sizeof(getdns_mdns_cached_key_header)];
hashvalue_type hash; hashvalue_type hash;
struct lruhash_entry *entry; struct lruhash_entry *entry;
@ -1201,7 +1194,7 @@ mdns_mcast_timeout_cb(void *userarg)
found = 1; found = 1;
mdns_complete_query_from_cache_entry(netreq, entry); mdns_complete_query_from_cache_entry(netreq, entry);
} }
lock_rw_unlock(entry->lock); lock_rw_unlock(&entry->lock);
} }
if (!found) if (!found)
@ -1251,7 +1244,7 @@ mdns_udp_multicast_read_cb(void *userarg)
} }
else else
{ {
size_t current_index = 12; ssize_t current_index = 12;
uint8_t name[256]; uint8_t name[256];
int name_len; int name_len;
int record_type; int record_type;
@ -1388,7 +1381,8 @@ static int mdns_open_ipv4_multicast(SOCKADDR_STORAGE* mcast_dest, int* mcast_des
SOCKET fd4 = -1; SOCKET fd4 = -1;
SOCKADDR_IN ipv4_dest; SOCKADDR_IN ipv4_dest;
SOCKADDR_IN ipv4_port; SOCKADDR_IN ipv4_port;
uint8_t so_reuse_bool = 1; BOOL so_reuse_bool = TRUE;
int so_reuse_bool_OptLen = sizeof(BOOL);
uint8_t ttl = 255; uint8_t ttl = 255;
IP_MREQ mreq4; IP_MREQ mreq4;
@ -1398,9 +1392,11 @@ static int mdns_open_ipv4_multicast(SOCKADDR_STORAGE* mcast_dest, int* mcast_des
memset(&ipv4_port, 0, sizeof(ipv4_dest)); memset(&ipv4_port, 0, sizeof(ipv4_dest));
ipv4_dest.sin_family = AF_INET; ipv4_dest.sin_family = AF_INET;
ipv4_dest.sin_port = htons(MDNS_MCAST_PORT); ipv4_dest.sin_port = htons(MDNS_MCAST_PORT);
ipv4_dest.sin_addr.S_un.S_addr = htonl(MDNS_MCAST_IPV4_LONG); ipv4_dest.sin_addr.s_addr = htonl(MDNS_MCAST_IPV4_LONG);
ipv4_port.sin_family = AF_INET; ipv4_port.sin_family = AF_INET;
ipv4_port.sin_port = htons(MDNS_MCAST_PORT); ipv4_port.sin_port = htons(MDNS_MCAST_PORT);
/* memcpy(&ipv4_dest.sin_addr, mdns_mcast_ipv4, sizeof(mdns_mcast_ipv4)); */
fd4 = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); fd4 = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
@ -1412,7 +1408,7 @@ static int mdns_open_ipv4_multicast(SOCKADDR_STORAGE* mcast_dest, int* mcast_des
* since the only result that matters is that of bind. * since the only result that matters is that of bind.
*/ */
(void)setsockopt(fd4, SOL_SOCKET, SO_REUSEADDR (void)setsockopt(fd4, SOL_SOCKET, SO_REUSEADDR
, (const char*)&so_reuse_bool, (int) sizeof(BOOL)); , (const char*)&so_reuse_bool, so_reuse_bool_OptLen);
if (bind(fd4, (SOCKADDR*)&ipv4_port, sizeof(ipv4_port)) != 0) if (bind(fd4, (SOCKADDR*)&ipv4_port, sizeof(ipv4_port)) != 0)
{ {
@ -1633,7 +1629,6 @@ static getdns_return_t mdns_initialize_continuous_request(getdns_network_req *ne
getdns_dns_req *dnsreq = netreq->owner; getdns_dns_req *dnsreq = netreq->owner;
struct getdns_context *context = dnsreq->context; struct getdns_context *context = dnsreq->context;
size_t required_memory = 0;
uint8_t temp_key[256 + sizeof(getdns_mdns_cached_key_header)]; uint8_t temp_key[256 + sizeof(getdns_mdns_cached_key_header)];
hashvalue_type hash; hashvalue_type hash;
struct lruhash_entry *entry; struct lruhash_entry *entry;
@ -1697,7 +1692,7 @@ static getdns_return_t mdns_initialize_continuous_request(getdns_network_req *ne
, (SOCKADDR*)&context->mdns_connection[fd_index].addr_mcast , (SOCKADDR*)&context->mdns_connection[fd_index].addr_mcast
, context->mdns_connection[fd_index].addr_mcast_len); , context->mdns_connection[fd_index].addr_mcast_len);
if (pkt_len != sent) if (sent < 0 || pkt_len != (size_t)sent)
{ {
ret = GETDNS_RETURN_GENERIC_ERROR; ret = GETDNS_RETURN_GENERIC_ERROR;
} }
@ -1887,7 +1882,7 @@ mdns_udp_write_cb(void *userarg)
mdns_mcast_v4.sin_family = AF_INET; mdns_mcast_v4.sin_family = AF_INET;
mdns_mcast_v4.sin_port = htons(MDNS_MCAST_PORT); mdns_mcast_v4.sin_port = htons(MDNS_MCAST_PORT);
mdns_mcast_v4.sin_addr.s_addr = htonl(MDNS_MCAST_IPV4_LONG); mdns_mcast_v4.sin_addr.s_addr = htonl(MDNS_MCAST_IPV4_LONG);
/* memcpy(&mdns_mcast_v4.sin_addr.s_addr, mdns_mcast_ipv4, sizeof(mdns_mcast_ipv4)); */
/* Set TTL=255 for compliance with RFC 6762 */ /* Set TTL=255 for compliance with RFC 6762 */
r = setsockopt(netreq->fd, IPPROTO_IP, IP_TTL, (const char *)&ttl, sizeof(ttl)); r = setsockopt(netreq->fd, IPPROTO_IP, IP_TTL, (const char *)&ttl, sizeof(ttl));
@ -2143,7 +2138,7 @@ int mdns_finalize_lru_test(struct getdns_context* context,
} }
} }
lock_rw_unlock(entry->lock); lock_rw_unlock(&entry->lock);
} }
return ret; return ret;

View File

@ -24,7 +24,12 @@
#ifdef HAVE_MDNS_SUPPORT #ifdef HAVE_MDNS_SUPPORT
#include "getdns/getdns.h" #include "getdns/getdns.h"
#include "types-internal.h" #include "types-internal.h"
#include "util/storage/lruhash.h" #include "util/lruhash.h"
#include "config.h"
#ifndef USE_WINSOCK
#define SOCKADDR_STORAGE struct sockaddr_storage
#endif
getdns_return_t getdns_return_t
_getdns_submit_mdns_request(getdns_network_req *netreq); _getdns_submit_mdns_request(getdns_network_req *netreq);

View File

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

View File

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

View File

@ -0,0 +1 @@
#include "util/fptr_wlist.h"

1
src/util/auxiliary/log.h Normal file
View File

@ -0,0 +1 @@
#include "util/log.h"

View File

@ -0,0 +1 @@
#include "gldns/keyraw.h"

View File

@ -0,0 +1 @@
#include "gldns/rrdef.h"

View File

@ -0,0 +1 @@
#include "gldns/gbuffer.h"

View File

@ -0,0 +1 @@

View File

@ -0,0 +1,58 @@
/**
*
* /brief dummy prototypes for logging a la unbound
*
*/
/*
* 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 UTIL_LOG_H
#define UTIL_LOG_H
#include "config.h"
#include "debug.h"
#ifdef DEBUGGING
#define verbose(x, ...) DEBUG_NL(__VA_ARGS__)
#define log_err(...) DEBUG_NL(__VA_ARGS__)
#define log_info(...) DEBUG_NL(__VA_ARGS__)
#define fatal_exit(...) do { DEBUG_NL(__VA_ARGS__); exit(EXIT_FAILURE); } while(0)
#define log_assert(x) do { if(!(x)) fatal_exit("%s:%d: %s: assertion %s failed", \
__FILE__, __LINE__, __FUNC__, #x); \
} while(0)
#else
#define verbose(...) ((void)0)
#define log_err(...) ((void)0)
#define log_info(...) ((void)0)
#define fatal_exit(...) ((void)0)
#define log_assert(x) ((void)0)
#endif
#endif /* UTIL_LOG_H */

View File

@ -0,0 +1 @@
#include "util/lookup3.h"

View File

@ -0,0 +1 @@
#include "util/lruhash.h"

View File

@ -0,0 +1 @@

View File

@ -0,0 +1 @@
#include "util/val_secalgo.h"

View File

@ -1,60 +1,14 @@
#!/bin/sh #!/bin/sh
# Meant to be run from this directory REPO=http://unbound.net/svn/trunk
mkdir ub || true wget -O rbtree.c ${REPO}/util/rbtree.c
cd ub wget -O orig-headers/rbtree.h ${REPO}/util/rbtree.h
for f in rbtree.c rbtree.h wget -O val_secalgo.c ${REPO}/validator/val_secalgo.c
do wget -O orig-headers/val_secalgo.h ${REPO}/validator/val_secalgo.h
wget http://unbound.net/svn/trunk/util/$f || \ wget -O lruhash.c ${REPO}/util/storage/lruhash.c
ftp http://unbound.net/svn/trunk/util/$f || continue wget -O orig-headers/lruhash.h ${REPO}/util/storage/lruhash.h
sed -e 's/event_/_getdns_event_/g' \ wget -O lookup3.c ${REPO}/util/storage/lookup3.c
-e 's/signal_add/_getdns_signal_add/g' \ wget -O orig-headers/lookup3.h ${REPO}/util/storage/lookup3.h
-e 's/signal_del/_getdns_signal_del/g' \ wget -O locks.c ${REPO}/util/locks.c
-e 's/signal_set/_getdns_signal_set/g' \ wget -O orig-headers/locks.h ${REPO}/util/locks.h
-e 's/evtimer_/_getdns_evtimer_/g' \
-e 's/struct event/struct _getdns_event/g' \
-e 's/mini_ev_cmp/_getdns_mini_ev_cmp/g' \
-e 's/static void handle_timeouts/void handle_timeouts/g' \
-e 's/handle_timeouts/_getdns_handle_timeouts/g' \
-e 's/static int handle_select/int handle_select/g' \
-e 's/handle_select/_getdns_handle_select/g' \
-e 's/#include "rbtree\.h"/#include "util\/rbtree.h"/g' \
-e 's/rbnode_/_getdns_rbnode_/g' \
-e 's/rbtree_/_getdns_rbtree_/g' \
-e 's/traverse_post/_getdns_traverse_post/g' \
-e 's/#include "fptr_wlist\.h"/#include "util\/fptr_wlist.h"/g' \
-e 's/#include "log\.h"/#include "util\/log.h"/g' \
-e '/^#define _getdns_.* mini_getdns_/d' \
-e '/^\/\* redefine to use our own namespace so that on platforms where$/d' \
-e '/^ \* linkers crosslink library-private symbols with other symbols, it works \*\//d' \
$f > ../$f
done
for f in val_secalgo.h val_secalgo.c
do
wget http://unbound.net/svn/trunk/validator/$f || \
ftp http://unbound.net/svn/trunk/validator/$f || continue
sed -e 's/sldns/gldns/g' \
-e '/^\/\* packed_rrset on top to define enum types (forced by c99 standard) \*\/$/d' \
-e '/^#include "util\/data\/packed_rrset.h"$/d' \
-e 's/^#include "validator/#include "util/g' \
-e 's/^#include "gldns\/sbuffer/#include "gldns\/gbuffer/g' \
-e 's/^#include "util\/val_nsec3.h"/#define NSEC3_HASH_SHA1 0x01/g' \
-e 's/ds_digest_size_supported/_getdns_ds_digest_size_supported/g' \
-e 's/secalgo_ds_digest/_getdns_secalgo_ds_digest/g' \
-e 's/dnskey_algo_id_is_supported/_getdns_dnskey_algo_id_is_supported/g' \
-e 's/verify_canonrrset/_getdns_verify_canonrrset/g' \
-e 's/nsec3_hash_algo_size_supported/_getdns_nsec3_hash_algo_size_supported/g' \
-e 's/secalgo_nsec3_hash/_getdns_secalgo_nsec3_hash/g' \
-e 's/secalgo_hash_sha256/_getdns_secalgo_hash_sha256/g' \
-e 's/ecdsa_evp_workaround_init/_getdns_ecdsa_evp_workaround_init/g' \
-e 's/LDNS_/GLDNS_/g' \
-e 's/enum sec_status/int/g' \
-e 's/sec_status_bogus/0/g' \
-e 's/sec_status_unchecked/0/g' \
-e 's/sec_status_secure/1/g' \
$f > ../$f
done
cd ..
rm -r ub

264
src/util/locks.c Normal file
View File

@ -0,0 +1,264 @@
/**
* util/locks.c - unbound locking primitives
*
* Copyright (c) 2007, NLnet Labs. All rights reserved.
*
* This software is open source.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* Neither the name of the NLNET LABS nor the names of its contributors may
* be used to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* \file
* Implementation of locking and threading support.
* A place for locking debug code since most locking functions are macros.
*/
#include "config.h"
#include "util/locks.h"
#include <signal.h>
#ifdef HAVE_SYS_WAIT_H
#include <sys/wait.h>
#endif
/** block all signals, masks them away. */
void
ub_thread_blocksigs(void)
{
#if defined(HAVE_PTHREAD) || defined(HAVE_SOLARIS_THREADS) || defined(HAVE_SIGPROCMASK)
# if defined(HAVE_PTHREAD) || defined(HAVE_SOLARIS_THREADS)
int err;
# endif
sigset_t sigset;
sigfillset(&sigset);
#ifdef HAVE_PTHREAD
if((err=pthread_sigmask(SIG_SETMASK, &sigset, NULL)))
fatal_exit("pthread_sigmask: %s", strerror(err));
#else
# ifdef HAVE_SOLARIS_THREADS
if((err=thr_sigsetmask(SIG_SETMASK, &sigset, NULL)))
fatal_exit("thr_sigsetmask: %s", strerror(err));
# else
/* have nothing, do single process signal mask */
if(sigprocmask(SIG_SETMASK, &sigset, NULL))
fatal_exit("sigprocmask: %s", strerror(errno));
# endif /* HAVE_SOLARIS_THREADS */
#endif /* HAVE_PTHREAD */
#endif /* have signal stuff */
}
/** unblock one signal, so we can catch it */
void ub_thread_sig_unblock(int sig)
{
#if defined(HAVE_PTHREAD) || defined(HAVE_SOLARIS_THREADS) || defined(HAVE_SIGPROCMASK)
# if defined(HAVE_PTHREAD) || defined(HAVE_SOLARIS_THREADS)
int err;
# endif
sigset_t sigset;
sigemptyset(&sigset);
sigaddset(&sigset, sig);
#ifdef HAVE_PTHREAD
if((err=pthread_sigmask(SIG_UNBLOCK, &sigset, NULL)))
fatal_exit("pthread_sigmask: %s", strerror(err));
#else
# ifdef HAVE_SOLARIS_THREADS
if((err=thr_sigsetmask(SIG_UNBLOCK, &sigset, NULL)))
fatal_exit("thr_sigsetmask: %s", strerror(err));
# else
/* have nothing, do single thread case */
if(sigprocmask(SIG_UNBLOCK, &sigset, NULL))
fatal_exit("sigprocmask: %s", strerror(errno));
# endif /* HAVE_SOLARIS_THREADS */
#endif /* HAVE_PTHREAD */
#else
(void)sig;
#endif /* have signal stuff */
}
#if !defined(HAVE_PTHREAD) && !defined(HAVE_SOLARIS_THREADS) && !defined(HAVE_WINDOWS_THREADS)
/**
* No threading available: fork a new process.
* This means no shared data structure, and no locking.
* Only the main thread ever returns. Exits on errors.
* @param thr: the location where to store the thread-id.
* @param func: function body of the thread. Return value of func is lost.
* @param arg: user argument to func.
*/
void
ub_thr_fork_create(ub_thread_type* thr, void* (*func)(void*), void* arg)
{
pid_t pid = fork();
switch(pid) {
default: /* main */
*thr = (ub_thread_type)pid;
return;
case 0: /* child */
*thr = (ub_thread_type)getpid();
(void)(*func)(arg);
exit(0);
case -1: /* error */
fatal_exit("could not fork: %s", strerror(errno));
}
}
/**
* There is no threading. Wait for a process to terminate.
* Note that ub_thread_type is defined as pid_t.
* @param thread: the process id to wait for.
*/
void ub_thr_fork_wait(ub_thread_type thread)
{
int status = 0;
if(waitpid((pid_t)thread, &status, 0) == -1)
log_err("waitpid(%d): %s", (int)thread, strerror(errno));
if(status != 0)
log_warn("process %d abnormal exit with status %d",
(int)thread, status);
}
#endif /* !defined(HAVE_PTHREAD) && !defined(HAVE_SOLARIS_THREADS) && !defined(HAVE_WINDOWS_THREADS) */
#ifdef HAVE_SOLARIS_THREADS
void* ub_thread_key_get(ub_thread_key_type key)
{
void* ret=NULL;
LOCKRET(thr_getspecific(key, &ret));
return ret;
}
#endif
#ifdef HAVE_WINDOWS_THREADS
/** log a windows GetLastError message */
static void log_win_err(const char* str, DWORD err)
{
LPTSTR buf;
if(FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_ALLOCATE_BUFFER,
NULL, err, 0, (LPTSTR)&buf, 0, NULL) == 0) {
/* could not format error message */
log_err("%s, GetLastError=%d", str, (int)err);
return;
}
log_err("%s, (err=%d): %s", str, (int)err, buf);
LocalFree(buf);
}
void lock_basic_init(lock_basic_type* lock)
{
/* implement own lock, because windows HANDLE as Mutex usage
* uses too many handles and would bog down the whole system. */
(void)InterlockedExchange(lock, 0);
}
void lock_basic_destroy(lock_basic_type* lock)
{
(void)InterlockedExchange(lock, 0);
}
void lock_basic_lock(lock_basic_type* lock)
{
LONG wait = 1; /* wait 1 msec at first */
while(InterlockedExchange(lock, 1)) {
/* if the old value was 1 then if was already locked */
Sleep(wait); /* wait with sleep */
wait *= 2; /* exponential backoff for waiting */
}
/* the old value was 0, but we inserted 1, we locked it! */
}
void lock_basic_unlock(lock_basic_type* lock)
{
/* unlock it by inserting the value of 0. xchg for cache coherency. */
(void)InterlockedExchange(lock, 0);
}
void ub_thread_key_create(ub_thread_key_type* key, void* f)
{
*key = TlsAlloc();
if(*key == TLS_OUT_OF_INDEXES) {
*key = 0;
log_win_err("TlsAlloc Failed(OUT_OF_INDEXES)", GetLastError());
}
else ub_thread_key_set(*key, f);
}
void ub_thread_key_set(ub_thread_key_type key, void* v)
{
if(!TlsSetValue(key, v)) {
log_win_err("TlsSetValue failed", GetLastError());
}
}
void* ub_thread_key_get(ub_thread_key_type key)
{
void* ret = (void*)TlsGetValue(key);
if(ret == NULL && GetLastError() != ERROR_SUCCESS) {
log_win_err("TlsGetValue failed", GetLastError());
}
return ret;
}
void ub_thread_create(ub_thread_type* thr, void* (*func)(void*), void* arg)
{
#ifndef HAVE__BEGINTHREADEX
*thr = CreateThread(NULL, /* default security (no inherit handle) */
0, /* default stack size */
(LPTHREAD_START_ROUTINE)func, arg,
0, /* default flags, run immediately */
NULL); /* do not store thread identifier anywhere */
#else
/* the beginthreadex routine setups for the C lib; aligns stack */
*thr=(ub_thread_type)_beginthreadex(NULL, 0, (void*)func, arg, 0, NULL);
#endif
if(*thr == NULL) {
log_win_err("CreateThread failed", GetLastError());
fatal_exit("thread create failed");
}
}
ub_thread_type ub_thread_self(void)
{
return GetCurrentThread();
}
void ub_thread_join(ub_thread_type thr)
{
DWORD ret = WaitForSingleObject(thr, INFINITE);
if(ret == WAIT_FAILED) {
log_win_err("WaitForSingleObject(Thread):WAIT_FAILED",
GetLastError());
} else if(ret == WAIT_TIMEOUT) {
log_win_err("WaitForSingleObject(Thread):WAIT_TIMEOUT",
GetLastError());
}
/* and close the handle to the thread */
if(!CloseHandle(thr)) {
log_win_err("CloseHandle(Thread) failed", GetLastError());
}
}
#endif /* HAVE_WINDOWS_THREADS */

64
src/util/locks.h Normal file
View File

@ -0,0 +1,64 @@
/**
*
* \file locks.h
* /brief Alternative symbol names for unbound's locks.h
*
*/
/*
* Copyright (c) 2017, NLnet Labs, the getdns team
* 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 LOCKS_H_SYMBOLS
#define LOCKS_H_SYMBOLS
#include "config.h"
#define ub_thread_blocksigs _getdns_ub_thread_blocksigs
#define ub_thread_sig_unblock _getdns_ub_thread_sig_unblock
#define ub_thread_type _getdns_ub_thread_type
#define ub_thr_fork_create _getdns_ub_thr_fork_create
#define ub_thr_fork_wait _getdns_ub_thr_fork_wait
#if defined(HAVE_SOLARIS_THREADS) || defined(HAVE_WINDOWS_THREADS)
#define ub_thread_key_type _getdns_ub_thread_key_type
#define ub_thread_key_create _getdns_ub_thread_key_create
#define ub_thread_key_set _getdns_ub_thread_key_set
#define ub_thread_key_get _getdns_ub_thread_key_get
#endif
#ifdef HAVE_WINDOWS_THREADS
#define lock_basic_type _getdns_lock_basic_type
#define lock_basic_init _getdns_lock_basic_init
#define lock_basic_destroy _getdns_lock_basic_destroy
#define lock_basic_lock _getdns_lock_basic_lock_
#define lock_basic_unlock _getdns_lock_basic_unlock
#define ub_thread_create _getdns_ub_thread_create
#define ub_thread_self _getdns_ub_thread_self
#endif
#include "util/orig-headers/locks.h"
#endif

1032
src/util/lookup3.c Normal file

File diff suppressed because it is too large Load Diff

View File

@ -1,11 +1,11 @@
/** /**
* *
* /brief dummy prototypes for logging a la unbound * \file lookup3.h
* /brief Alternative symbol names for unbound's lookup3.h
* *
*/ */
/* /*
* Copyright (c) 2013, NLnet Labs, Verisign, Inc. * Copyright (c) 2017, NLnet Labs, the getdns team
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@ -30,22 +30,12 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#ifndef LOOKUP3_H_SYMBOLS
#define LOOKUP3_H_SYMBOLS
#ifndef UTIL_LOG_H #define hashword _getdns_hashword
#define UTIL_LOG_H #define hashlittle _getdns_hashlittle
#define hash_set_raninit _getdns_hash_set_raninit
#include "config.h" #include "util/orig-headers/lookup3.h"
#include "debug.h"
#if defined(SEC_DEBUG) && SEC_DEBUG
#define verbose(x, ...) DEBUG_NL(__VA_ARGS__)
#define log_err(...) DEBUG_NL(__VA_ARGS__)
#else
#define verbose(...)
#define log_err(...)
#endif #endif
#define log_assert(x)
#endif /* UTIL_LOG_H */

545
src/util/lruhash.c Normal file
View File

@ -0,0 +1,545 @@
/*
* util/storage/lruhash.c - hashtable, hash function, LRU keeping.
*
* Copyright (c) 2007, NLnet Labs. All rights reserved.
*
* This software is open source.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* Neither the name of the NLNET LABS nor the names of its contributors may
* be used to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* \file
*
* This file contains a hashtable with LRU keeping of entries.
*
*/
#include "config.h"
#include "util/storage/lruhash.h"
#include "util/fptr_wlist.h"
void
bin_init(struct lruhash_bin* array, size_t size)
{
size_t i;
#ifdef THREADS_DISABLED
(void)array;
#endif
for(i=0; i<size; i++) {
lock_quick_init(&array[i].lock);
lock_protect(&array[i].lock, &array[i],
sizeof(struct lruhash_bin));
}
}
struct lruhash*
lruhash_create(size_t start_size, size_t maxmem,
lruhash_sizefunc_type sizefunc, lruhash_compfunc_type compfunc,
lruhash_delkeyfunc_type delkeyfunc,
lruhash_deldatafunc_type deldatafunc, void* arg)
{
struct lruhash* table = (struct lruhash*)calloc(1,
sizeof(struct lruhash));
if(!table)
return NULL;
lock_quick_init(&table->lock);
table->sizefunc = sizefunc;
table->compfunc = compfunc;
table->delkeyfunc = delkeyfunc;
table->deldatafunc = deldatafunc;
table->cb_arg = arg;
table->size = start_size;
table->size_mask = (int)(start_size-1);
table->lru_start = NULL;
table->lru_end = NULL;
table->num = 0;
table->space_used = 0;
table->space_max = maxmem;
table->array = calloc(table->size, sizeof(struct lruhash_bin));
if(!table->array) {
lock_quick_destroy(&table->lock);
free(table);
return NULL;
}
bin_init(table->array, table->size);
lock_protect(&table->lock, table, sizeof(*table));
lock_protect(&table->lock, table->array,
table->size*sizeof(struct lruhash_bin));
return table;
}
void
bin_delete(struct lruhash* table, struct lruhash_bin* bin)
{
struct lruhash_entry* p, *np;
void *d;
if(!bin)
return;
lock_quick_destroy(&bin->lock);
p = bin->overflow_list;
bin->overflow_list = NULL;
while(p) {
np = p->overflow_next;
d = p->data;
(*table->delkeyfunc)(p->key, table->cb_arg);
(*table->deldatafunc)(d, table->cb_arg);
p = np;
}
}
void
bin_split(struct lruhash* table, struct lruhash_bin* newa,
int newmask)
{
size_t i;
struct lruhash_entry *p, *np;
struct lruhash_bin* newbin;
/* move entries to new table. Notice that since hash x is mapped to
* bin x & mask, and new mask uses one more bit, so all entries in
* one bin will go into the old bin or bin | newbit */
#ifndef THREADS_DISABLED
int newbit = newmask - table->size_mask;
#endif
/* so, really, this task could also be threaded, per bin. */
/* LRU list is not changed */
for(i=0; i<table->size; i++)
{
lock_quick_lock(&table->array[i].lock);
p = table->array[i].overflow_list;
/* lock both destination bins */
lock_quick_lock(&newa[i].lock);
lock_quick_lock(&newa[newbit|i].lock);
while(p) {
np = p->overflow_next;
/* link into correct new bin */
newbin = &newa[p->hash & newmask];
p->overflow_next = newbin->overflow_list;
newbin->overflow_list = p;
p=np;
}
lock_quick_unlock(&newa[i].lock);
lock_quick_unlock(&newa[newbit|i].lock);
lock_quick_unlock(&table->array[i].lock);
}
}
void
lruhash_delete(struct lruhash* table)
{
size_t i;
if(!table)
return;
/* delete lock on hashtable to force check its OK */
lock_quick_destroy(&table->lock);
for(i=0; i<table->size; i++)
bin_delete(table, &table->array[i]);
free(table->array);
free(table);
}
void
bin_overflow_remove(struct lruhash_bin* bin, struct lruhash_entry* entry)
{
struct lruhash_entry* p = bin->overflow_list;
struct lruhash_entry** prevp = &bin->overflow_list;
while(p) {
if(p == entry) {
*prevp = p->overflow_next;
return;
}
prevp = &p->overflow_next;
p = p->overflow_next;
}
}
void
reclaim_space(struct lruhash* table, struct lruhash_entry** list)
{
struct lruhash_entry* d;
struct lruhash_bin* bin;
log_assert(table);
/* does not delete MRU entry, so table will not be empty. */
while(table->num > 1 && table->space_used > table->space_max) {
/* notice that since we hold the hashtable lock, nobody
can change the lru chain. So it cannot be deleted underneath
us. We still need the hashbin and entry write lock to make
sure we flush all users away from the entry.
which is unlikely, since it is LRU, if someone got a rdlock
it would be moved to front, but to be sure. */
d = table->lru_end;
/* specialised, delete from end of double linked list,
and we know num>1, so there is a previous lru entry. */
log_assert(d && d->lru_prev);
table->lru_end = d->lru_prev;
d->lru_prev->lru_next = NULL;
/* schedule entry for deletion */
bin = &table->array[d->hash & table->size_mask];
table->num --;
lock_quick_lock(&bin->lock);
bin_overflow_remove(bin, d);
d->overflow_next = *list;
*list = d;
lock_rw_wrlock(&d->lock);
table->space_used -= table->sizefunc(d->key, d->data);
if(table->markdelfunc)
(*table->markdelfunc)(d->key);
lock_rw_unlock(&d->lock);
lock_quick_unlock(&bin->lock);
}
}
struct lruhash_entry*
bin_find_entry(struct lruhash* table,
struct lruhash_bin* bin, hashvalue_type hash, void* key)
{
struct lruhash_entry* p = bin->overflow_list;
while(p) {
if(p->hash == hash && table->compfunc(p->key, key) == 0)
return p;
p = p->overflow_next;
}
return NULL;
}
void
table_grow(struct lruhash* table)
{
struct lruhash_bin* newa;
int newmask;
size_t i;
if(table->size_mask == (int)(((size_t)-1)>>1)) {
log_err("hash array malloc: size_t too small");
return;
}
/* try to allocate new array, if not fail */
newa = calloc(table->size*2, sizeof(struct lruhash_bin));
if(!newa) {
log_err("hash grow: malloc failed");
/* continue with smaller array. Though its slower. */
return;
}
bin_init(newa, table->size*2);
newmask = (table->size_mask << 1) | 1;
bin_split(table, newa, newmask);
/* delete the old bins */
lock_unprotect(&table->lock, table->array);
for(i=0; i<table->size; i++) {
lock_quick_destroy(&table->array[i].lock);
}
free(table->array);
table->size *= 2;
table->size_mask = newmask;
table->array = newa;
lock_protect(&table->lock, table->array,
table->size*sizeof(struct lruhash_bin));
return;
}
void
lru_front(struct lruhash* table, struct lruhash_entry* entry)
{
entry->lru_prev = NULL;
entry->lru_next = table->lru_start;
if(!table->lru_start)
table->lru_end = entry;
else table->lru_start->lru_prev = entry;
table->lru_start = entry;
}
void
lru_remove(struct lruhash* table, struct lruhash_entry* entry)
{
if(entry->lru_prev)
entry->lru_prev->lru_next = entry->lru_next;
else table->lru_start = entry->lru_next;
if(entry->lru_next)
entry->lru_next->lru_prev = entry->lru_prev;
else table->lru_end = entry->lru_prev;
}
void
lru_touch(struct lruhash* table, struct lruhash_entry* entry)
{
log_assert(table && entry);
if(entry == table->lru_start)
return; /* nothing to do */
/* remove from current lru position */
lru_remove(table, entry);
/* add at front */
lru_front(table, entry);
}
void
lruhash_insert(struct lruhash* table, hashvalue_type hash,
struct lruhash_entry* entry, void* data, void* cb_arg)
{
struct lruhash_bin* bin;
struct lruhash_entry* found, *reclaimlist=NULL;
size_t need_size;
fptr_ok(fptr_whitelist_hash_sizefunc(table->sizefunc));
fptr_ok(fptr_whitelist_hash_delkeyfunc(table->delkeyfunc));
fptr_ok(fptr_whitelist_hash_deldatafunc(table->deldatafunc));
fptr_ok(fptr_whitelist_hash_compfunc(table->compfunc));
fptr_ok(fptr_whitelist_hash_markdelfunc(table->markdelfunc));
need_size = table->sizefunc(entry->key, data);
if(cb_arg == NULL) cb_arg = table->cb_arg;
/* find bin */
lock_quick_lock(&table->lock);
bin = &table->array[hash & table->size_mask];
lock_quick_lock(&bin->lock);
/* see if entry exists already */
if(!(found=bin_find_entry(table, bin, hash, entry->key))) {
/* if not: add to bin */
entry->overflow_next = bin->overflow_list;
bin->overflow_list = entry;
lru_front(table, entry);
table->num++;
table->space_used += need_size;
} else {
/* if so: update data - needs a writelock */
table->space_used += need_size -
(*table->sizefunc)(found->key, found->data);
(*table->delkeyfunc)(entry->key, cb_arg);
lru_touch(table, found);
lock_rw_wrlock(&found->lock);
(*table->deldatafunc)(found->data, cb_arg);
found->data = data;
lock_rw_unlock(&found->lock);
}
lock_quick_unlock(&bin->lock);
if(table->space_used > table->space_max)
reclaim_space(table, &reclaimlist);
if(table->num >= table->size)
table_grow(table);
lock_quick_unlock(&table->lock);
/* finish reclaim if any (outside of critical region) */
while(reclaimlist) {
struct lruhash_entry* n = reclaimlist->overflow_next;
void* d = reclaimlist->data;
(*table->delkeyfunc)(reclaimlist->key, cb_arg);
(*table->deldatafunc)(d, cb_arg);
reclaimlist = n;
}
}
struct lruhash_entry*
lruhash_lookup(struct lruhash* table, hashvalue_type hash, void* key, int wr)
{
struct lruhash_entry* entry;
struct lruhash_bin* bin;
fptr_ok(fptr_whitelist_hash_compfunc(table->compfunc));
lock_quick_lock(&table->lock);
bin = &table->array[hash & table->size_mask];
lock_quick_lock(&bin->lock);
if((entry=bin_find_entry(table, bin, hash, key)))
lru_touch(table, entry);
lock_quick_unlock(&table->lock);
if(entry) {
if(wr) { lock_rw_wrlock(&entry->lock); }
else { lock_rw_rdlock(&entry->lock); }
}
lock_quick_unlock(&bin->lock);
return entry;
}
void
lruhash_remove(struct lruhash* table, hashvalue_type hash, void* key)
{
struct lruhash_entry* entry;
struct lruhash_bin* bin;
void *d;
fptr_ok(fptr_whitelist_hash_sizefunc(table->sizefunc));
fptr_ok(fptr_whitelist_hash_delkeyfunc(table->delkeyfunc));
fptr_ok(fptr_whitelist_hash_deldatafunc(table->deldatafunc));
fptr_ok(fptr_whitelist_hash_compfunc(table->compfunc));
fptr_ok(fptr_whitelist_hash_markdelfunc(table->markdelfunc));
lock_quick_lock(&table->lock);
bin = &table->array[hash & table->size_mask];
lock_quick_lock(&bin->lock);
if((entry=bin_find_entry(table, bin, hash, key))) {
bin_overflow_remove(bin, entry);
lru_remove(table, entry);
} else {
lock_quick_unlock(&table->lock);
lock_quick_unlock(&bin->lock);
return;
}
table->num--;
table->space_used -= (*table->sizefunc)(entry->key, entry->data);
lock_quick_unlock(&table->lock);
lock_rw_wrlock(&entry->lock);
if(table->markdelfunc)
(*table->markdelfunc)(entry->key);
lock_rw_unlock(&entry->lock);
lock_quick_unlock(&bin->lock);
/* finish removal */
d = entry->data;
(*table->delkeyfunc)(entry->key, table->cb_arg);
(*table->deldatafunc)(d, table->cb_arg);
}
/** clear bin, respecting locks, does not do space, LRU */
static void
bin_clear(struct lruhash* table, struct lruhash_bin* bin)
{
struct lruhash_entry* p, *np;
void *d;
lock_quick_lock(&bin->lock);
p = bin->overflow_list;
while(p) {
lock_rw_wrlock(&p->lock);
np = p->overflow_next;
d = p->data;
if(table->markdelfunc)
(*table->markdelfunc)(p->key);
lock_rw_unlock(&p->lock);
(*table->delkeyfunc)(p->key, table->cb_arg);
(*table->deldatafunc)(d, table->cb_arg);
p = np;
}
bin->overflow_list = NULL;
lock_quick_unlock(&bin->lock);
}
void
lruhash_clear(struct lruhash* table)
{
size_t i;
if(!table)
return;
fptr_ok(fptr_whitelist_hash_delkeyfunc(table->delkeyfunc));
fptr_ok(fptr_whitelist_hash_deldatafunc(table->deldatafunc));
fptr_ok(fptr_whitelist_hash_markdelfunc(table->markdelfunc));
lock_quick_lock(&table->lock);
for(i=0; i<table->size; i++) {
bin_clear(table, &table->array[i]);
}
table->lru_start = NULL;
table->lru_end = NULL;
table->num = 0;
table->space_used = 0;
lock_quick_unlock(&table->lock);
}
void
lruhash_status(struct lruhash* table, const char* id, int extended)
{
lock_quick_lock(&table->lock);
log_info("%s: %u entries, memory %u / %u",
id, (unsigned)table->num, (unsigned)table->space_used,
(unsigned)table->space_max);
log_info(" itemsize %u, array %u, mask %d",
(unsigned)(table->num? table->space_used/table->num : 0),
(unsigned)table->size, table->size_mask);
if(extended) {
size_t i;
int min=(int)table->size*2, max=-2;
for(i=0; i<table->size; i++) {
int here = 0;
struct lruhash_entry *en;
lock_quick_lock(&table->array[i].lock);
en = table->array[i].overflow_list;
while(en) {
here ++;
en = en->overflow_next;
}
lock_quick_unlock(&table->array[i].lock);
if(extended >= 2)
log_info("bin[%d] %d", (int)i, here);
if(here > max) max = here;
if(here < min) min = here;
}
log_info(" bin min %d, avg %.2lf, max %d", min,
(double)table->num/(double)table->size, max);
}
lock_quick_unlock(&table->lock);
}
size_t
lruhash_get_mem(struct lruhash* table)
{
size_t s;
lock_quick_lock(&table->lock);
s = sizeof(struct lruhash) + table->space_used;
#ifdef USE_THREAD_DEBUG
if(table->size != 0) {
size_t i;
for(i=0; i<table->size; i++)
s += sizeof(struct lruhash_bin) +
lock_get_mem(&table->array[i].lock);
}
#else /* no THREAD_DEBUG */
if(table->size != 0)
s += (table->size)*(sizeof(struct lruhash_bin) +
lock_get_mem(&table->array[0].lock));
#endif
lock_quick_unlock(&table->lock);
s += lock_get_mem(&table->lock);
return s;
}
void
lruhash_setmarkdel(struct lruhash* table, lruhash_markdelfunc_type md)
{
lock_quick_lock(&table->lock);
table->markdelfunc = md;
lock_quick_unlock(&table->lock);
}
void
lruhash_traverse(struct lruhash* h, int wr,
void (*func)(struct lruhash_entry*, void*), void* arg)
{
size_t i;
struct lruhash_entry* e;
lock_quick_lock(&h->lock);
for(i=0; i<h->size; i++) {
lock_quick_lock(&h->array[i].lock);
for(e = h->array[i].overflow_list; e; e = e->overflow_next) {
if(wr) {
lock_rw_wrlock(&e->lock);
} else {
lock_rw_rdlock(&e->lock);
}
(*func)(e, arg);
lock_rw_unlock(&e->lock);
}
lock_quick_unlock(&h->array[i].lock);
}
lock_quick_unlock(&h->lock);
}

68
src/util/lruhash.h Normal file
View File

@ -0,0 +1,68 @@
/**
*
* \file lruhash.h
* /brief Alternative symbol names for unbound's lruhash.h
*
*/
/*
* Copyright (c) 2017, NLnet Labs, the getdns team
* 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 LRUHASH_H_SYMBOLS
#define LRUHASH_H_SYMBOLS
#define lruhash _getdns_lruhash
#define lruhash_bin _getdns_lruhash_bin
#define lruhash_entry _getdns_lruhash_entry
#define hashvalue_type _getdns_hashvalue_type
#define lruhash_sizefunc_type _getdns_lruhash_sizefunc_type
#define lruhash_compfunc_type _getdns_lruhash_compfunc_type
#define lruhash_delkeyfunc_type _getdns_lruhash_delkeyfunc_type
#define lruhash_deldatafunc_type _getdns_lruhash_deldatafunc_type
#define lruhash_markdelfunc_type _getdns_lruhash_markdelfunc_type
#define lruhash_create _getdns_lruhash_create
#define lruhash_delete _getdns_lruhash_delete
#define lruhash_clear _getdns_lruhash_clear
#define lruhash_insert _getdns_lruhash_insert
#define lruhash_lookup _getdns_lruhash_lookup
#define lru_touch _getdns_lru_touch
#define lruhash_setmarkdel _getdns_lruhash_setmarkdel
#define lruhash_remove _getdns_lruhash_remove
#define bin_init _getdns_bin_init
#define bin_delete _getdns_bin_delete
#define bin_find_entry _getdns_bin_find_entry
#define bin_overflow_remove _getdns_bin_overflow_remove
#define bin_split _getdns_bin_split
#define reclaim_space _getdns_reclaim_space
#define table_grow _getdns_table_grow
#define lru_front _getdns_lru_front
#define lru_remove _getdns_lru_remove
#define lruhash_status _getdns_lruhash_status
#define lruhash_get_mem _getdns_lruhash_get_mem
#define lruhash_traverse _getdns_lruhash_traverse
#include "util/orig-headers/lruhash.h"
#endif

View File

@ -0,0 +1,313 @@
/**
* util/locks.h - unbound locking primitives
*
* Copyright (c) 2007, NLnet Labs. All rights reserved.
*
* This software is open source.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* Neither the name of the NLNET LABS nor the names of its contributors may
* be used to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef UTIL_LOCKS_H
#define UTIL_LOCKS_H
/**
* \file
* Locking primitives.
* If pthreads is available, these are used.
* If no locking exists, they do nothing.
*
* The idea is to have different sorts of locks for different tasks.
* This allows the locking code to be ported more easily.
*
* Types of locks that are supported.
* o lock_rw: lock that has many readers and one writer (to a data entry).
* o lock_basic: simple mutex. Blocking, one person has access only.
* This lock is meant for non performance sensitive uses.
* o lock_quick: speed lock. For performance sensitive locking of critical
* sections. Could be implemented by a mutex or a spinlock.
*
* Also thread creation and deletion functions are defined here.
*/
/* if you define your own LOCKRET before including locks.h, you can get most
* locking functions without the dependency on log_err. */
#ifndef LOCKRET
#include "util/log.h"
/**
* The following macro is used to check the return value of the
* pthread calls. They return 0 on success and an errno on error.
* The errno is logged to the logfile with a descriptive comment.
*/
#define LOCKRET(func) do {\
int lockret_err; \
if( (lockret_err=(func)) != 0) \
log_err("%s at %d could not " #func ": %s", \
__FILE__, __LINE__, strerror(lockret_err)); \
} while(0)
#endif
/** DEBUG: use thread debug whenever possible */
#if defined(HAVE_PTHREAD) && defined(HAVE_PTHREAD_SPINLOCK_T) && defined(ENABLE_LOCK_CHECKS)
# define USE_THREAD_DEBUG
#endif
#ifdef USE_THREAD_DEBUG
/******************* THREAD DEBUG ************************/
/* (some) checking; to detect races and deadlocks. */
#include "testcode/checklocks.h"
#else /* USE_THREAD_DEBUG */
#define lock_protect(lock, area, size) /* nop */
#define lock_unprotect(lock, area) /* nop */
#define lock_get_mem(lock) (0) /* nothing */
#define checklock_start() /* nop */
#define checklock_stop() /* nop */
#ifdef HAVE_PTHREAD
#include <pthread.h>
/******************* PTHREAD ************************/
/** use pthread mutex for basic lock */
typedef pthread_mutex_t lock_basic_type;
/** small front for pthread init func, NULL is default attrs. */
#define lock_basic_init(lock) LOCKRET(pthread_mutex_init(lock, NULL))
#define lock_basic_destroy(lock) LOCKRET(pthread_mutex_destroy(lock))
#define lock_basic_lock(lock) LOCKRET(pthread_mutex_lock(lock))
#define lock_basic_unlock(lock) LOCKRET(pthread_mutex_unlock(lock))
#ifndef HAVE_PTHREAD_RWLOCK_T
/** in case rwlocks are not supported, use a mutex. */
typedef pthread_mutex_t lock_rw_type;
#define lock_rw_init(lock) LOCKRET(pthread_mutex_init(lock, NULL))
#define lock_rw_destroy(lock) LOCKRET(pthread_mutex_destroy(lock))
#define lock_rw_rdlock(lock) LOCKRET(pthread_mutex_lock(lock))
#define lock_rw_wrlock(lock) LOCKRET(pthread_mutex_lock(lock))
#define lock_rw_unlock(lock) LOCKRET(pthread_mutex_unlock(lock))
#else /* HAVE_PTHREAD_RWLOCK_T */
/** we use the pthread rwlock */
typedef pthread_rwlock_t lock_rw_type;
/** small front for pthread init func, NULL is default attrs. */
#define lock_rw_init(lock) LOCKRET(pthread_rwlock_init(lock, NULL))
#define lock_rw_destroy(lock) LOCKRET(pthread_rwlock_destroy(lock))
#define lock_rw_rdlock(lock) LOCKRET(pthread_rwlock_rdlock(lock))
#define lock_rw_wrlock(lock) LOCKRET(pthread_rwlock_wrlock(lock))
#define lock_rw_unlock(lock) LOCKRET(pthread_rwlock_unlock(lock))
#endif /* HAVE_PTHREAD_RWLOCK_T */
#ifndef HAVE_PTHREAD_SPINLOCK_T
/** in case spinlocks are not supported, use a mutex. */
typedef pthread_mutex_t lock_quick_type;
/** small front for pthread init func, NULL is default attrs. */
#define lock_quick_init(lock) LOCKRET(pthread_mutex_init(lock, NULL))
#define lock_quick_destroy(lock) LOCKRET(pthread_mutex_destroy(lock))
#define lock_quick_lock(lock) LOCKRET(pthread_mutex_lock(lock))
#define lock_quick_unlock(lock) LOCKRET(pthread_mutex_unlock(lock))
#else /* HAVE_PTHREAD_SPINLOCK_T */
/** use pthread spinlock for the quick lock */
typedef pthread_spinlock_t lock_quick_type;
/**
* allocate process private since this is available whether
* Thread Process-Shared Synchronization is supported or not.
* This means only threads inside this process may access the lock.
* (not threads from another process that shares memory).
* spinlocks are not supported on all pthread platforms.
*/
#define lock_quick_init(lock) LOCKRET(pthread_spin_init(lock, PTHREAD_PROCESS_PRIVATE))
#define lock_quick_destroy(lock) LOCKRET(pthread_spin_destroy(lock))
#define lock_quick_lock(lock) LOCKRET(pthread_spin_lock(lock))
#define lock_quick_unlock(lock) LOCKRET(pthread_spin_unlock(lock))
#endif /* HAVE SPINLOCK */
/** Thread creation */
typedef pthread_t ub_thread_type;
/** On alpine linux default thread stack size is 80 Kb. See
http://wiki.musl-libc.org/wiki/Functional_differences_from_glibc#Thread_stack_size
This is not enough and cause segfault. Other linux distros have 2 Mb at least.
Wrapper for set up thread stack size */
#define PTHREADSTACKSIZE 2*1024*1024
#define PTHREADCREATE(thr, stackrequired, func, arg) do {\
pthread_attr_t attr; \
size_t stacksize; \
LOCKRET(pthread_attr_init(&attr)); \
LOCKRET(pthread_attr_getstacksize(&attr, &stacksize)); \
if (stacksize < stackrequired) { \
LOCKRET(pthread_attr_setstacksize(&attr, stackrequired)); \
LOCKRET(pthread_create(thr, &attr, func, arg)); \
LOCKRET(pthread_attr_getstacksize(&attr, &stacksize)); \
verbose(VERB_ALGO, "Thread stack size set to %u", (unsigned)stacksize); \
} else {LOCKRET(pthread_create(thr, NULL, func, arg));} \
} while(0)
/** Use wrapper for set thread stack size on attributes. */
#define ub_thread_create(thr, func, arg) PTHREADCREATE(thr, PTHREADSTACKSIZE, func, arg)
/** get self id. */
#define ub_thread_self() pthread_self()
/** wait for another thread to terminate */
#define ub_thread_join(thread) LOCKRET(pthread_join(thread, NULL))
typedef pthread_key_t ub_thread_key_type;
#define ub_thread_key_create(key, f) LOCKRET(pthread_key_create(key, f))
#define ub_thread_key_set(key, v) LOCKRET(pthread_setspecific(key, v))
#define ub_thread_key_get(key) pthread_getspecific(key)
#else /* we do not HAVE_PTHREAD */
#ifdef HAVE_SOLARIS_THREADS
/******************* SOLARIS THREADS ************************/
#include <synch.h>
#include <thread.h>
typedef rwlock_t lock_rw_type;
#define lock_rw_init(lock) LOCKRET(rwlock_init(lock, USYNC_THREAD, NULL))
#define lock_rw_destroy(lock) LOCKRET(rwlock_destroy(lock))
#define lock_rw_rdlock(lock) LOCKRET(rw_rdlock(lock))
#define lock_rw_wrlock(lock) LOCKRET(rw_wrlock(lock))
#define lock_rw_unlock(lock) LOCKRET(rw_unlock(lock))
/** use basic mutex */
typedef mutex_t lock_basic_type;
#define lock_basic_init(lock) LOCKRET(mutex_init(lock, USYNC_THREAD, NULL))
#define lock_basic_destroy(lock) LOCKRET(mutex_destroy(lock))
#define lock_basic_lock(lock) LOCKRET(mutex_lock(lock))
#define lock_basic_unlock(lock) LOCKRET(mutex_unlock(lock))
/** No spinlocks in solaris threads API. Use a mutex. */
typedef mutex_t lock_quick_type;
#define lock_quick_init(lock) LOCKRET(mutex_init(lock, USYNC_THREAD, NULL))
#define lock_quick_destroy(lock) LOCKRET(mutex_destroy(lock))
#define lock_quick_lock(lock) LOCKRET(mutex_lock(lock))
#define lock_quick_unlock(lock) LOCKRET(mutex_unlock(lock))
/** Thread creation, create a default thread. */
typedef thread_t ub_thread_type;
#define ub_thread_create(thr, func, arg) LOCKRET(thr_create(NULL, NULL, func, arg, NULL, thr))
#define ub_thread_self() thr_self()
#define ub_thread_join(thread) LOCKRET(thr_join(thread, NULL, NULL))
typedef thread_key_t ub_thread_key_type;
#define ub_thread_key_create(key, f) LOCKRET(thr_keycreate(key, f))
#define ub_thread_key_set(key, v) LOCKRET(thr_setspecific(key, v))
void* ub_thread_key_get(ub_thread_key_type key);
#else /* we do not HAVE_SOLARIS_THREADS and no PTHREADS */
/******************* WINDOWS THREADS ************************/
#ifdef HAVE_WINDOWS_THREADS
#include <windows.h>
/* Use a mutex */
typedef LONG lock_rw_type;
#define lock_rw_init(lock) lock_basic_init(lock)
#define lock_rw_destroy(lock) lock_basic_destroy(lock)
#define lock_rw_rdlock(lock) lock_basic_lock(lock)
#define lock_rw_wrlock(lock) lock_basic_lock(lock)
#define lock_rw_unlock(lock) lock_basic_unlock(lock)
/** the basic lock is a mutex, implemented opaquely, for error handling. */
typedef LONG lock_basic_type;
void lock_basic_init(lock_basic_type* lock);
void lock_basic_destroy(lock_basic_type* lock);
void lock_basic_lock(lock_basic_type* lock);
void lock_basic_unlock(lock_basic_type* lock);
/** on windows no spinlock, use mutex too. */
typedef LONG lock_quick_type;
#define lock_quick_init(lock) lock_basic_init(lock)
#define lock_quick_destroy(lock) lock_basic_destroy(lock)
#define lock_quick_lock(lock) lock_basic_lock(lock)
#define lock_quick_unlock(lock) lock_basic_unlock(lock)
/** Thread creation, create a default thread. */
typedef HANDLE ub_thread_type;
void ub_thread_create(ub_thread_type* thr, void* (*func)(void*), void* arg);
ub_thread_type ub_thread_self(void);
void ub_thread_join(ub_thread_type thr);
typedef DWORD ub_thread_key_type;
void ub_thread_key_create(ub_thread_key_type* key, void* f);
void ub_thread_key_set(ub_thread_key_type key, void* v);
void* ub_thread_key_get(ub_thread_key_type key);
#else /* we do not HAVE_SOLARIS_THREADS, PTHREADS or WINDOWS_THREADS */
/******************* NO THREADS ************************/
#define THREADS_DISABLED 1
/** In case there is no thread support, define locks to do nothing */
typedef int lock_rw_type;
#define lock_rw_init(lock) /* nop */
#define lock_rw_destroy(lock) /* nop */
#define lock_rw_rdlock(lock) /* nop */
#define lock_rw_wrlock(lock) /* nop */
#define lock_rw_unlock(lock) /* nop */
/** define locks to do nothing */
typedef int lock_basic_type;
#define lock_basic_init(lock) /* nop */
#define lock_basic_destroy(lock) /* nop */
#define lock_basic_lock(lock) /* nop */
#define lock_basic_unlock(lock) /* nop */
/** define locks to do nothing */
typedef int lock_quick_type;
#define lock_quick_init(lock) /* nop */
#define lock_quick_destroy(lock) /* nop */
#define lock_quick_lock(lock) /* nop */
#define lock_quick_unlock(lock) /* nop */
/** Thread creation, threads do not exist */
typedef pid_t ub_thread_type;
/** ub_thread_create is simulated with fork (extremely heavy threads,
* with no shared memory). */
#define ub_thread_create(thr, func, arg) \
ub_thr_fork_create(thr, func, arg)
#define ub_thread_self() getpid()
#define ub_thread_join(thread) ub_thr_fork_wait(thread)
void ub_thr_fork_wait(ub_thread_type thread);
void ub_thr_fork_create(ub_thread_type* thr, void* (*func)(void*), void* arg);
typedef void* ub_thread_key_type;
#define ub_thread_key_create(key, f) (*(key)) = NULL
#define ub_thread_key_set(key, v) (key) = (v)
#define ub_thread_key_get(key) (key)
#endif /* HAVE_WINDOWS_THREADS */
#endif /* HAVE_SOLARIS_THREADS */
#endif /* HAVE_PTHREAD */
#endif /* USE_THREAD_DEBUG */
/**
* Block all signals for this thread.
* fatal exit on error.
*/
void ub_thread_blocksigs(void);
/**
* unblock one signal for this thread.
*/
void ub_thread_sig_unblock(int sig);
#endif /* UTIL_LOCKS_H */

View File

@ -0,0 +1,71 @@
/*
* util/storage/lookup3.h - header file for hashing functions.
*
* Copyright (c) 2007, NLnet Labs. All rights reserved.
*
* This software is open source.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* Neither the name of the NLNET LABS nor the names of its contributors may
* be used to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* \file
*
* This file contains header definitions for the hash functions we use.
* The hash functions are public domain (see lookup3.c).
*/
#ifndef UTIL_STORAGE_LOOKUP3_H
#define UTIL_STORAGE_LOOKUP3_H
/**
* Hash key made of 4byte chunks.
* @param k: the key, an array of uint32_t values
* @param length: the length of the key, in uint32_ts
* @param initval: the previous hash, or an arbitrary value
* @return: hash value.
*/
uint32_t hashword(const uint32_t *k, size_t length, uint32_t initval);
/**
* Hash key data.
* @param k: the key, array of uint8_t
* @param length: the length of the key, in uint8_ts
* @param initval: the previous hash, or an arbitrary value
* @return: hash value.
*/
uint32_t hashlittle(const void *k, size_t length, uint32_t initval);
/**
* Set the randomisation initial value, set this before threads start,
* and before hashing stuff (because it changes subsequent results).
* @param v: value
*/
void hash_set_raninit(uint32_t v);
#endif /* UTIL_STORAGE_LOOKUP3_H */

View File

@ -0,0 +1,414 @@
/*
* util/storage/lruhash.h - hashtable, hash function, LRU keeping.
*
* Copyright (c) 2007, NLnet Labs. All rights reserved.
*
* This software is open source.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* Neither the name of the NLNET LABS nor the names of its contributors may
* be used to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* \file
*
* This file contains a hashtable with LRU keeping of entries.
*
* The hash table keeps a maximum memory size. Old entries are removed
* to make space for new entries.
*
* The locking strategy is as follows:
* o since (almost) every read also implies a LRU update, the
* hashtable lock is a spinlock, not rwlock.
* o the idea is to move every thread through the hash lock quickly,
* so that the next thread can access the lookup table.
* o User performs hash function.
*
* For read:
* o lock hashtable.
* o lookup hash bin.
* o lock hash bin.
* o find entry (if failed, unlock hash, unl bin, exit).
* o swizzle pointers for LRU update.
* o unlock hashtable.
* o lock entry (rwlock).
* o unlock hash bin.
* o work on entry.
* o unlock entry.
*
* To update an entry, gain writelock and change the entry.
* (the entry must keep the same hashvalue, so a data update.)
* (you cannot upgrade a readlock to a writelock, because the item may
* be deleted, it would cause race conditions. So instead, unlock and
* relookup it in the hashtable.)
*
* To delete an entry:
* o unlock the entry if you hold the lock already.
* o lock hashtable.
* o lookup hash bin.
* o lock hash bin.
* o find entry (if failed, unlock hash, unl bin, exit).
* o remove entry from hashtable bin overflow chain.
* o unlock hashtable.
* o lock entry (writelock).
* o unlock hash bin.
* o unlock entry (nobody else should be waiting for this lock,
* since you removed it from hashtable, and you got writelock while
* holding the hashbinlock so you are the only one.)
* Note you are only allowed to obtain a lock while holding hashbinlock.
* o delete entry.
*
* The above sequence is:
* o race free, works with read, write and delete.
* o but has a queue, imagine someone needing a writelock on an item.
* but there are still readlocks. The writelocker waits, but holds
* the hashbinlock. The next thread that comes in and needs the same
* hashbin will wait for the lock while holding the hashtable lock.
* thus halting the entire system on hashtable.
* This is because of the delete protection.
* Readlocks will be easier on the rwlock on entries.
* While the writer is holding writelock, similar problems happen with
* a reader or writer needing the same item.
* the scenario requires more than three threads.
* o so the queue length is 3 threads in a bad situation. The fourth is
* unable to use the hashtable.
*
* If you need to acquire locks on multiple items from the hashtable.
* o you MUST release all locks on items from the hashtable before
* doing the next lookup/insert/delete/whatever.
* o To acquire multiple items you should use a special routine that
* obtains the locks on those multiple items in one go.
*/
#ifndef UTIL_STORAGE_LRUHASH_H
#define UTIL_STORAGE_LRUHASH_H
#include "util/locks.h"
struct lruhash_bin;
struct lruhash_entry;
/** default start size for hash arrays */
#define HASH_DEFAULT_STARTARRAY 1024 /* entries in array */
/** default max memory for hash arrays */
#define HASH_DEFAULT_MAXMEM 4*1024*1024 /* bytes */
/** the type of a hash value */
typedef uint32_t hashvalue_type;
/**
* Type of function that calculates the size of an entry.
* Result must include the size of struct lruhash_entry.
* Keys that are identical must also calculate to the same size.
* size = func(key, data).
*/
typedef size_t (*lruhash_sizefunc_type)(void*, void*);
/** type of function that compares two keys. return 0 if equal. */
typedef int (*lruhash_compfunc_type)(void*, void*);
/** old keys are deleted.
* The RRset type has to revoke its ID number, markdel() is used first.
* This function is called: func(key, userarg) */
typedef void (*lruhash_delkeyfunc_type)(void*, void*);
/** old data is deleted. This function is called: func(data, userarg). */
typedef void (*lruhash_deldatafunc_type)(void*, void*);
/** mark a key as pending to be deleted (and not to be used by anyone).
* called: func(key) */
typedef void (*lruhash_markdelfunc_type)(void*);
/**
* Hash table that keeps LRU list of entries.
*/
struct lruhash {
/** lock for exclusive access, to the lookup array */
lock_quick_type lock;
/** the size function for entries in this table */
lruhash_sizefunc_type sizefunc;
/** the compare function for entries in this table. */
lruhash_compfunc_type compfunc;
/** how to delete keys. */
lruhash_delkeyfunc_type delkeyfunc;
/** how to delete data. */
lruhash_deldatafunc_type deldatafunc;
/** how to mark a key pending deletion */
lruhash_markdelfunc_type markdelfunc;
/** user argument for user functions */
void* cb_arg;
/** the size of the lookup array */
size_t size;
/** size bitmask - since size is a power of 2 */
int size_mask;
/** lookup array of bins */
struct lruhash_bin* array;
/** the lru list, start and end, noncyclical double linked list. */
struct lruhash_entry* lru_start;
/** lru list end item (least recently used) */
struct lruhash_entry* lru_end;
/** the number of entries in the hash table. */
size_t num;
/** the amount of space used, roughly the number of bytes in use. */
size_t space_used;
/** the amount of space the hash table is maximally allowed to use. */
size_t space_max;
};
/**
* A single bin with a linked list of entries in it.
*/
struct lruhash_bin {
/**
* Lock for exclusive access to the linked list
* This lock makes deletion of items safe in this overflow list.
*/
lock_quick_type lock;
/** linked list of overflow entries */
struct lruhash_entry* overflow_list;
};
/**
* An entry into the hash table.
* To change overflow_next you need to hold the bin lock.
* To change the lru items you need to hold the hashtable lock.
* This structure is designed as part of key struct. And key pointer helps
* to get the surrounding structure. Data should be allocated on its own.
*/
struct lruhash_entry {
/**
* rwlock for access to the contents of the entry
* Note that it does _not_ cover the lru_ and overflow_ ptrs.
* Even with a writelock, you cannot change hash and key.
* You need to delete it to change hash or key.
*/
lock_rw_type lock;
/** next entry in overflow chain. Covered by hashlock and binlock. */
struct lruhash_entry* overflow_next;
/** next entry in lru chain. covered by hashlock. */
struct lruhash_entry* lru_next;
/** prev entry in lru chain. covered by hashlock. */
struct lruhash_entry* lru_prev;
/** hash value of the key. It may not change, until entry deleted. */
hashvalue_type hash;
/** key */
void* key;
/** data */
void* data;
};
/**
* Create new hash table.
* @param start_size: size of hashtable array at start, must be power of 2.
* @param maxmem: maximum amount of memory this table is allowed to use.
* @param sizefunc: calculates memory usage of entries.
* @param compfunc: compares entries, 0 on equality.
* @param delkeyfunc: deletes key.
* Calling both delkey and deldata will also free the struct lruhash_entry.
* Make it part of the key structure and delete it in delkeyfunc.
* @param deldatafunc: deletes data.
* @param arg: user argument that is passed to user function calls.
* @return: new hash table or NULL on malloc failure.
*/
struct lruhash* lruhash_create(size_t start_size, size_t maxmem,
lruhash_sizefunc_type sizefunc, lruhash_compfunc_type compfunc,
lruhash_delkeyfunc_type delkeyfunc,
lruhash_deldatafunc_type deldatafunc, void* arg);
/**
* Delete hash table. Entries are all deleted.
* @param table: to delete.
*/
void lruhash_delete(struct lruhash* table);
/**
* Clear hash table. Entries are all deleted, while locking them before
* doing so. At end the table is empty.
* @param table: to make empty.
*/
void lruhash_clear(struct lruhash* table);
/**
* Insert a new element into the hashtable.
* If key is already present data pointer in that entry is updated.
* The space calculation function is called with the key, data.
* If necessary the least recently used entries are deleted to make space.
* If necessary the hash array is grown up.
*
* @param table: hash table.
* @param hash: hash value. User calculates the hash.
* @param entry: identifies the entry.
* If key already present, this entry->key is deleted immediately.
* But entry->data is set to NULL before deletion, and put into
* the existing entry. The data is then freed.
* @param data: the data.
* @param cb_override: if not null overrides the cb_arg for the deletefunc.
*/
void lruhash_insert(struct lruhash* table, hashvalue_type hash,
struct lruhash_entry* entry, void* data, void* cb_override);
/**
* Lookup an entry in the hashtable.
* At the end of the function you hold a (read/write)lock on the entry.
* The LRU is updated for the entry (if found).
* @param table: hash table.
* @param hash: hash of key.
* @param key: what to look for, compared against entries in overflow chain.
* the hash value must be set, and must work with compare function.
* @param wr: set to true if you desire a writelock on the entry.
* with a writelock you can update the data part.
* @return: pointer to the entry or NULL. The entry is locked.
* The user must unlock the entry when done.
*/
struct lruhash_entry* lruhash_lookup(struct lruhash* table,
hashvalue_type hash, void* key, int wr);
/**
* Touch entry, so it becomes the most recently used in the LRU list.
* Caller must hold hash table lock. The entry must be inserted already.
* @param table: hash table.
* @param entry: entry to make first in LRU.
*/
void lru_touch(struct lruhash* table, struct lruhash_entry* entry);
/**
* Set the markdelfunction (or NULL)
*/
void lruhash_setmarkdel(struct lruhash* table, lruhash_markdelfunc_type md);
/************************* Internal functions ************************/
/*** these are only exposed for unit tests. ***/
/**
* Remove entry from hashtable. Does nothing if not found in hashtable.
* Delfunc is called for the entry.
* @param table: hash table.
* @param hash: hash of key.
* @param key: what to look for.
*/
void lruhash_remove(struct lruhash* table, hashvalue_type hash, void* key);
/** init the hash bins for the table */
void bin_init(struct lruhash_bin* array, size_t size);
/** delete the hash bin and entries inside it */
void bin_delete(struct lruhash* table, struct lruhash_bin* bin);
/**
* Find entry in hash bin. You must have locked the bin.
* @param table: hash table with function pointers.
* @param bin: hash bin to look into.
* @param hash: hash value to look for.
* @param key: key to look for.
* @return: the entry or NULL if not found.
*/
struct lruhash_entry* bin_find_entry(struct lruhash* table,
struct lruhash_bin* bin, hashvalue_type hash, void* key);
/**
* Remove entry from bin overflow chain.
* You must have locked the bin.
* @param bin: hash bin to look into.
* @param entry: entry ptr that needs removal.
*/
void bin_overflow_remove(struct lruhash_bin* bin,
struct lruhash_entry* entry);
/**
* Split hash bin into two new ones. Based on increased size_mask.
* Caller must hold hash table lock.
* At the end the routine acquires all hashbin locks (in the old array).
* This makes it wait for other threads to finish with the bins.
* So the bins are ready to be deleted after this function.
* @param table: hash table with function pointers.
* @param newa: new increased array.
* @param newmask: new lookup mask.
*/
void bin_split(struct lruhash* table, struct lruhash_bin* newa,
int newmask);
/**
* Try to make space available by deleting old entries.
* Assumes that the lock on the hashtable is being held by caller.
* Caller must not hold bin locks.
* @param table: hash table.
* @param list: list of entries that are to be deleted later.
* Entries have been removed from the hash table and writelock is held.
*/
void reclaim_space(struct lruhash* table, struct lruhash_entry** list);
/**
* Grow the table lookup array. Becomes twice as large.
* Caller must hold the hash table lock. Must not hold any bin locks.
* Tries to grow, on malloc failure, nothing happened.
* @param table: hash table.
*/
void table_grow(struct lruhash* table);
/**
* Put entry at front of lru. entry must be unlinked from lru.
* Caller must hold hash table lock.
* @param table: hash table with lru head and tail.
* @param entry: entry to make most recently used.
*/
void lru_front(struct lruhash* table, struct lruhash_entry* entry);
/**
* Remove entry from lru list.
* Caller must hold hash table lock.
* @param table: hash table with lru head and tail.
* @param entry: entry to remove from lru.
*/
void lru_remove(struct lruhash* table, struct lruhash_entry* entry);
/**
* Output debug info to the log as to state of the hash table.
* @param table: hash table.
* @param id: string printed with table to identify the hash table.
* @param extended: set to true to print statistics on overflow bin lengths.
*/
void lruhash_status(struct lruhash* table, const char* id, int extended);
/**
* Get memory in use now by the lruhash table.
* @param table: hash table. Will be locked before use. And unlocked after.
* @return size in bytes.
*/
size_t lruhash_get_mem(struct lruhash* table);
/**
* Traverse a lruhash. Call back for every element in the table.
* @param h: hash table. Locked before use.
* @param wr: if true writelock is obtained on element, otherwise readlock.
* @param func: function for every element. Do not lock or unlock elements.
* @param arg: user argument to func.
*/
void lruhash_traverse(struct lruhash* h, int wr,
void (*func)(struct lruhash_entry*, void*), void* arg);
#endif /* UTIL_STORAGE_LRUHASH_H */

View File

@ -0,0 +1,192 @@
/*
* rbtree.h -- generic red-black tree
*
* Copyright (c) 2001-2007, NLnet Labs. All rights reserved.
*
* This software is open source.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* Neither the name of the NLNET LABS nor the names of its contributors may
* be used to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
/**
* \file
* Red black tree. Implementation taken from NSD 3.0.5, adjusted for use
* in unbound (memory allocation, logging and so on).
*/
#ifndef UTIL_RBTREE_H_
#define UTIL_RBTREE_H_
/**
* This structure must be the first member of the data structure in
* the rbtree. This allows easy casting between an rbnode_type and the
* user data (poor man's inheritance).
*/
typedef struct rbnode_type rbnode_type;
/**
* The rbnode_type struct definition.
*/
struct rbnode_type {
/** parent in rbtree, RBTREE_NULL for root */
rbnode_type *parent;
/** left node (smaller items) */
rbnode_type *left;
/** right node (larger items) */
rbnode_type *right;
/** pointer to sorting key */
const void *key;
/** colour of this node */
uint8_t color;
};
/** The nullpointer, points to empty node */
#define RBTREE_NULL &rbtree_null_node
/** the global empty node */
extern rbnode_type rbtree_null_node;
/** An entire red black tree */
typedef struct rbtree_type rbtree_type;
/** definition for tree struct */
struct rbtree_type {
/** The root of the red-black tree */
rbnode_type *root;
/** The number of the nodes in the tree */
size_t count;
/**
* Key compare function. <0,0,>0 like strcmp.
* Return 0 on two NULL ptrs.
*/
int (*cmp) (const void *, const void *);
};
/**
* Create new tree (malloced) with given key compare function.
* @param cmpf: compare function (like strcmp) takes pointers to two keys.
* @return: new tree, empty.
*/
rbtree_type *rbtree_create(int (*cmpf)(const void *, const void *));
/**
* Init a new tree (malloced by caller) with given key compare function.
* @param rbtree: uninitialised memory for new tree, returned empty.
* @param cmpf: compare function (like strcmp) takes pointers to two keys.
*/
void rbtree_init(rbtree_type *rbtree, int (*cmpf)(const void *, const void *));
/**
* Insert data into the tree.
* @param rbtree: tree to insert to.
* @param data: element to insert.
* @return: data ptr or NULL if key already present.
*/
rbnode_type *rbtree_insert(rbtree_type *rbtree, rbnode_type *data);
/**
* Delete element from tree.
* @param rbtree: tree to delete from.
* @param key: key of item to delete.
* @return: node that is now unlinked from the tree. User to delete it.
* returns 0 if node not present
*/
rbnode_type *rbtree_delete(rbtree_type *rbtree, const void *key);
/**
* Find key in tree. Returns NULL if not found.
* @param rbtree: tree to find in.
* @param key: key that must match.
* @return: node that fits or NULL.
*/
rbnode_type *rbtree_search(rbtree_type *rbtree, const void *key);
/**
* Find, but match does not have to be exact.
* @param rbtree: tree to find in.
* @param key: key to find position of.
* @param result: set to the exact node if present, otherwise to element that
* precedes the position of key in the tree. NULL if no smaller element.
* @return: true if exact match in result. Else result points to <= element,
* or NULL if key is smaller than the smallest key.
*/
int rbtree_find_less_equal(rbtree_type *rbtree, const void *key,
rbnode_type **result);
/**
* Returns first (smallest) node in the tree
* @param rbtree: tree
* @return: smallest element or NULL if tree empty.
*/
rbnode_type *rbtree_first(rbtree_type *rbtree);
/**
* Returns last (largest) node in the tree
* @param rbtree: tree
* @return: largest element or NULL if tree empty.
*/
rbnode_type *rbtree_last(rbtree_type *rbtree);
/**
* Returns next larger node in the tree
* @param rbtree: tree
* @return: next larger element or NULL if no larger in tree.
*/
rbnode_type *rbtree_next(rbnode_type *rbtree);
/**
* Returns previous smaller node in the tree
* @param rbtree: tree
* @return: previous smaller element or NULL if no previous in tree.
*/
rbnode_type *rbtree_previous(rbnode_type *rbtree);
/**
* Call with node=variable of struct* with rbnode_type as first element.
* with type is the type of a pointer to that struct.
*/
#define RBTREE_FOR(node, type, rbtree) \
for(node=(type)rbtree_first(rbtree); \
(rbnode_type*)node != RBTREE_NULL; \
node = (type)rbtree_next((rbnode_type*)node))
/**
* Call function for all elements in the redblack tree, such that
* leaf elements are called before parent elements. So that all
* elements can be safely free()d.
* Note that your function must not remove the nodes from the tree.
* Since that may trigger rebalances of the rbtree.
* @param tree: the tree
* @param func: function called with element and user arg.
* The function must not alter the rbtree.
* @param arg: user argument.
*/
void traverse_postorder(rbtree_type* tree, void (*func)(rbnode_type*, void*),
void* arg);
#endif /* UTIL_RBTREE_H_ */

View File

@ -0,0 +1,107 @@
/*
* validator/val_secalgo.h - validator security algorithm functions.
*
* Copyright (c) 2012, NLnet Labs. All rights reserved.
*
* This software is open source.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* Neither the name of the NLNET LABS nor the names of its contributors may
* be used to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* \file
*
* This file contains helper functions for the validator module.
* The functions take buffers with raw data and convert to library calls.
*/
#ifndef VALIDATOR_VAL_SECALGO_H
#define VALIDATOR_VAL_SECALGO_H
struct sldns_buffer;
/** Return size of nsec3 hash algorithm, 0 if not supported */
size_t nsec3_hash_algo_size_supported(int id);
/**
* Hash a single hash call of an NSEC3 hash algorithm.
* Iterations and salt are done by the caller.
* @param algo: nsec3 hash algorithm.
* @param buf: the buffer to digest
* @param len: length of buffer to digest.
* @param res: result stored here (must have sufficient space).
* @return false on failure.
*/
int secalgo_nsec3_hash(int algo, unsigned char* buf, size_t len,
unsigned char* res);
/**
* Calculate the sha256 hash for the data buffer into the result.
* @param buf: buffer to digest.
* @param len: length of the buffer to digest.
* @param res: result is stored here (space 256/8 bytes).
*/
void secalgo_hash_sha256(unsigned char* buf, size_t len, unsigned char* res);
/**
* Return size of DS digest according to its hash algorithm.
* @param algo: DS digest algo.
* @return size in bytes of digest, or 0 if not supported.
*/
size_t ds_digest_size_supported(int algo);
/**
* @param algo: the DS digest algo
* @param buf: the buffer to digest
* @param len: length of buffer to digest.
* @param res: result stored here (must have sufficient space).
* @return false on failure.
*/
int secalgo_ds_digest(int algo, unsigned char* buf, size_t len,
unsigned char* res);
/** return true if DNSKEY algorithm id is supported */
int dnskey_algo_id_is_supported(int id);
/**
* Check a canonical sig+rrset and signature against a dnskey
* @param buf: buffer with data to verify, the first rrsig part and the
* canonicalized rrset.
* @param algo: DNSKEY algorithm.
* @param sigblock: signature rdata field from RRSIG
* @param sigblock_len: length of sigblock data.
* @param key: public key data from DNSKEY RR.
* @param keylen: length of keydata.
* @param reason: bogus reason in more detail.
* @return secure if verification succeeded, bogus on crypto failure,
* unchecked on format errors and alloc failures.
*/
enum sec_status verify_canonrrset(struct sldns_buffer* buf, int algo,
unsigned char* sigblock, unsigned int sigblock_len,
unsigned char* key, unsigned int keylen, char** reason);
#endif /* VALIDATOR_VAL_SECALGO_H */

View File

@ -40,8 +40,8 @@
*/ */
#include "config.h" #include "config.h"
#include "util/log.h" #include "log.h"
#include "util/fptr_wlist.h" #include "fptr_wlist.h"
#include "util/rbtree.h" #include "util/rbtree.h"
/** Node colour black */ /** Node colour black */
@ -50,7 +50,7 @@
#define RED 1 #define RED 1
/** the NULL node, global alloc */ /** the NULL node, global alloc */
_getdns_rbnode_t _getdns_rbtree_null_node = { rbnode_type rbtree_null_node = {
RBTREE_NULL, /* Parent. */ RBTREE_NULL, /* Parent. */
RBTREE_NULL, /* Left. */ RBTREE_NULL, /* Left. */
RBTREE_NULL, /* Right. */ RBTREE_NULL, /* Right. */
@ -59,13 +59,14 @@ _getdns_rbnode_t _getdns_rbtree_null_node = {
}; };
/** rotate subtree left (to preserve redblack property) */ /** rotate subtree left (to preserve redblack property) */
static void _getdns_rbtree_rotate_left(_getdns_rbtree_t *rbtree, _getdns_rbnode_t *node); static void rbtree_rotate_left(rbtree_type *rbtree, rbnode_type *node);
/** rotate subtree right (to preserve redblack property) */ /** rotate subtree right (to preserve redblack property) */
static void _getdns_rbtree_rotate_right(_getdns_rbtree_t *rbtree, _getdns_rbnode_t *node); static void rbtree_rotate_right(rbtree_type *rbtree, rbnode_type *node);
/** Fixup node colours when insert happened */ /** Fixup node colours when insert happened */
static void _getdns_rbtree_insert_fixup(_getdns_rbtree_t *rbtree, _getdns_rbnode_t *node); static void rbtree_insert_fixup(rbtree_type *rbtree, rbnode_type *node);
/** Fixup node colours when delete happened */ /** Fixup node colours when delete happened */
static void _getdns_rbtree_delete_fixup(_getdns_rbtree_t* rbtree, _getdns_rbnode_t* child, _getdns_rbnode_t* child_parent); static void rbtree_delete_fixup(rbtree_type* rbtree, rbnode_type* child,
rbnode_type* child_parent);
/* /*
* Creates a new red black tree, initializes and returns a pointer to it. * Creates a new red black tree, initializes and returns a pointer to it.
@ -73,25 +74,25 @@ static void _getdns_rbtree_delete_fixup(_getdns_rbtree_t* rbtree, _getdns_rbnode
* Return NULL on failure. * Return NULL on failure.
* *
*/ */
_getdns_rbtree_t * rbtree_type *
_getdns_rbtree_create (int (*cmpf)(const void *, const void *)) rbtree_create (int (*cmpf)(const void *, const void *))
{ {
_getdns_rbtree_t *rbtree; rbtree_type *rbtree;
/* Allocate memory for it */ /* Allocate memory for it */
rbtree = (_getdns_rbtree_t *) malloc(sizeof(_getdns_rbtree_t)); rbtree = (rbtree_type *) malloc(sizeof(rbtree_type));
if (!rbtree) { if (!rbtree) {
return NULL; return NULL;
} }
/* Initialize it */ /* Initialize it */
_getdns_rbtree_init(rbtree, cmpf); rbtree_init(rbtree, cmpf);
return rbtree; return rbtree;
} }
void void
_getdns_rbtree_init(_getdns_rbtree_t *rbtree, int (*cmpf)(const void *, const void *)) rbtree_init(rbtree_type *rbtree, int (*cmpf)(const void *, const void *))
{ {
/* Initialize it */ /* Initialize it */
rbtree->root = RBTREE_NULL; rbtree->root = RBTREE_NULL;
@ -104,9 +105,9 @@ _getdns_rbtree_init(_getdns_rbtree_t *rbtree, int (*cmpf)(const void *, const vo
* *
*/ */
static void static void
_getdns_rbtree_rotate_left(_getdns_rbtree_t *rbtree, _getdns_rbnode_t *node) rbtree_rotate_left(rbtree_type *rbtree, rbnode_type *node)
{ {
_getdns_rbnode_t *right = node->right; rbnode_type *right = node->right;
node->right = right->left; node->right = right->left;
if (right->left != RBTREE_NULL) if (right->left != RBTREE_NULL)
right->left->parent = node; right->left->parent = node;
@ -131,9 +132,9 @@ _getdns_rbtree_rotate_left(_getdns_rbtree_t *rbtree, _getdns_rbnode_t *node)
* *
*/ */
static void static void
_getdns_rbtree_rotate_right(_getdns_rbtree_t *rbtree, _getdns_rbnode_t *node) rbtree_rotate_right(rbtree_type *rbtree, rbnode_type *node)
{ {
_getdns_rbnode_t *left = node->left; rbnode_type *left = node->left;
node->left = left->right; node->left = left->right;
if (left->right != RBTREE_NULL) if (left->right != RBTREE_NULL)
left->right->parent = node; left->right->parent = node;
@ -154,9 +155,9 @@ _getdns_rbtree_rotate_right(_getdns_rbtree_t *rbtree, _getdns_rbnode_t *node)
} }
static void static void
_getdns_rbtree_insert_fixup(_getdns_rbtree_t *rbtree, _getdns_rbnode_t *node) rbtree_insert_fixup(rbtree_type *rbtree, rbnode_type *node)
{ {
_getdns_rbnode_t *uncle; rbnode_type *uncle;
/* While not at the root and need fixing... */ /* While not at the root and need fixing... */
while (node != rbtree->root && node->parent->color == RED) { while (node != rbtree->root && node->parent->color == RED) {
@ -179,12 +180,12 @@ _getdns_rbtree_insert_fixup(_getdns_rbtree_t *rbtree, _getdns_rbnode_t *node)
/* Are we the right child? */ /* Are we the right child? */
if (node == node->parent->right) { if (node == node->parent->right) {
node = node->parent; node = node->parent;
_getdns_rbtree_rotate_left(rbtree, node); rbtree_rotate_left(rbtree, node);
} }
/* Now we're the left child, repaint and rotate... */ /* Now we're the left child, repaint and rotate... */
node->parent->color = BLACK; node->parent->color = BLACK;
node->parent->parent->color = RED; node->parent->parent->color = RED;
_getdns_rbtree_rotate_right(rbtree, node->parent->parent); rbtree_rotate_right(rbtree, node->parent->parent);
} }
} else { } else {
uncle = node->parent->parent->left; uncle = node->parent->parent->left;
@ -204,12 +205,12 @@ _getdns_rbtree_insert_fixup(_getdns_rbtree_t *rbtree, _getdns_rbnode_t *node)
/* Are we the right child? */ /* Are we the right child? */
if (node == node->parent->left) { if (node == node->parent->left) {
node = node->parent; node = node->parent;
_getdns_rbtree_rotate_right(rbtree, node); rbtree_rotate_right(rbtree, node);
} }
/* Now we're the right child, repaint and rotate... */ /* Now we're the right child, repaint and rotate... */
node->parent->color = BLACK; node->parent->color = BLACK;
node->parent->parent->color = RED; node->parent->parent->color = RED;
_getdns_rbtree_rotate_left(rbtree, node->parent->parent); rbtree_rotate_left(rbtree, node->parent->parent);
} }
} }
} }
@ -223,17 +224,17 @@ _getdns_rbtree_insert_fixup(_getdns_rbtree_t *rbtree, _getdns_rbnode_t *node)
* Returns NULL on failure or the pointer to the newly added node * Returns NULL on failure or the pointer to the newly added node
* otherwise. * otherwise.
*/ */
_getdns_rbnode_t * rbnode_type *
_getdns_rbtree_insert (_getdns_rbtree_t *rbtree, _getdns_rbnode_t *data) rbtree_insert (rbtree_type *rbtree, rbnode_type *data)
{ {
/* XXX Not necessary, but keeps compiler quiet... */ /* XXX Not necessary, but keeps compiler quiet... */
int r = 0; int r = 0;
/* We start at the root of the tree */ /* We start at the root of the tree */
_getdns_rbnode_t *node = rbtree->root; rbnode_type *node = rbtree->root;
_getdns_rbnode_t *parent = RBTREE_NULL; rbnode_type *parent = RBTREE_NULL;
fptr_ok(fptr_whitelist__getdns_rbtree_cmp(rbtree->cmp)); fptr_ok(fptr_whitelist_rbtree_cmp(rbtree->cmp));
/* Lets find the new parent... */ /* Lets find the new parent... */
while (node != RBTREE_NULL) { while (node != RBTREE_NULL) {
/* Compare two keys, do we have a duplicate? */ /* Compare two keys, do we have a duplicate? */
@ -267,7 +268,7 @@ _getdns_rbtree_insert (_getdns_rbtree_t *rbtree, _getdns_rbnode_t *data)
} }
/* Fix up the red-black properties... */ /* Fix up the red-black properties... */
_getdns_rbtree_insert_fixup(rbtree, data); rbtree_insert_fixup(rbtree, data);
return data; return data;
} }
@ -276,12 +277,12 @@ _getdns_rbtree_insert (_getdns_rbtree_t *rbtree, _getdns_rbnode_t *data)
* Searches the red black tree, returns the data if key is found or NULL otherwise. * Searches the red black tree, returns the data if key is found or NULL otherwise.
* *
*/ */
_getdns_rbnode_t * rbnode_type *
_getdns_rbtree_search (_getdns_rbtree_t *rbtree, const void *key) rbtree_search (rbtree_type *rbtree, const void *key)
{ {
_getdns_rbnode_t *node; rbnode_type *node;
if (_getdns_rbtree_find_less_equal(rbtree, key, &node)) { if (rbtree_find_less_equal(rbtree, key, &node)) {
return node; return node;
} else { } else {
return NULL; return NULL;
@ -295,13 +296,14 @@ static void swap_int8(uint8_t* x, uint8_t* y)
} }
/** helpers for delete: swap node pointers */ /** helpers for delete: swap node pointers */
static void swap_np(_getdns_rbnode_t** x, _getdns_rbnode_t** y) static void swap_np(rbnode_type** x, rbnode_type** y)
{ {
_getdns_rbnode_t* t = *x; *x = *y; *y = t; rbnode_type* t = *x; *x = *y; *y = t;
} }
/** Update parent pointers of child trees of 'parent' */ /** Update parent pointers of child trees of 'parent' */
static void change_parent_ptr(_getdns_rbtree_t* rbtree, _getdns_rbnode_t* parent, _getdns_rbnode_t* old, _getdns_rbnode_t* new) static void change_parent_ptr(rbtree_type* rbtree, rbnode_type* parent,
rbnode_type* old, rbnode_type* new)
{ {
if(parent == RBTREE_NULL) if(parent == RBTREE_NULL)
{ {
@ -315,30 +317,31 @@ static void change_parent_ptr(_getdns_rbtree_t* rbtree, _getdns_rbnode_t* parent
if(parent->right == old) parent->right = new; if(parent->right == old) parent->right = new;
} }
/** Update parent pointer of a node 'child' */ /** Update parent pointer of a node 'child' */
static void change_child_ptr(_getdns_rbnode_t* child, _getdns_rbnode_t* old, _getdns_rbnode_t* new) static void change_child_ptr(rbnode_type* child, rbnode_type* old,
rbnode_type* new)
{ {
if(child == RBTREE_NULL) return; if(child == RBTREE_NULL) return;
log_assert(child->parent == old || child->parent == new); log_assert(child->parent == old || child->parent == new);
if(child->parent == old) child->parent = new; if(child->parent == old) child->parent = new;
} }
_getdns_rbnode_t* rbnode_type*
_getdns_rbtree_delete(_getdns_rbtree_t *rbtree, const void *key) rbtree_delete(rbtree_type *rbtree, const void *key)
{ {
_getdns_rbnode_t *to_delete; rbnode_type *to_delete;
_getdns_rbnode_t *child; rbnode_type *child;
if((to_delete = _getdns_rbtree_search(rbtree, key)) == 0) return 0; if((to_delete = rbtree_search(rbtree, key)) == 0) return 0;
rbtree->count--; rbtree->count--;
/* make sure we have at most one non-leaf child */ /* make sure we have at most one non-leaf child */
if(to_delete->left != RBTREE_NULL && to_delete->right != RBTREE_NULL) if(to_delete->left != RBTREE_NULL && to_delete->right != RBTREE_NULL)
{ {
/* swap with smallest from right subtree (or largest from left) */ /* swap with smallest from right subtree (or largest from left) */
_getdns_rbnode_t *smright = to_delete->right; rbnode_type *smright = to_delete->right;
while(smright->left != RBTREE_NULL) while(smright->left != RBTREE_NULL)
smright = smright->left; smright = smright->left;
/* swap the smright and to_delete elements in the tree, /* swap the smright and to_delete elements in the tree,
* but the _getdns_rbnode_t is first part of user data struct * but the rbnode_type is first part of user data struct
* so cannot just swap the keys and data pointers. Instead * so cannot just swap the keys and data pointers. Instead
* readjust the pointers left,right,parent */ * readjust the pointers left,right,parent */
@ -390,7 +393,7 @@ _getdns_rbtree_delete(_getdns_rbtree_t *rbtree, const void *key)
/* change child to BLACK, removing a RED node is no problem */ /* change child to BLACK, removing a RED node is no problem */
if(child!=RBTREE_NULL) child->color = BLACK; if(child!=RBTREE_NULL) child->color = BLACK;
} }
else _getdns_rbtree_delete_fixup(rbtree, child, to_delete->parent); else rbtree_delete_fixup(rbtree, child, to_delete->parent);
/* unlink completely */ /* unlink completely */
to_delete->parent = RBTREE_NULL; to_delete->parent = RBTREE_NULL;
@ -400,9 +403,10 @@ _getdns_rbtree_delete(_getdns_rbtree_t *rbtree, const void *key)
return to_delete; return to_delete;
} }
static void _getdns_rbtree_delete_fixup(_getdns_rbtree_t* rbtree, _getdns_rbnode_t* child, _getdns_rbnode_t* child_parent) static void rbtree_delete_fixup(rbtree_type* rbtree, rbnode_type* child,
rbnode_type* child_parent)
{ {
_getdns_rbnode_t* sibling; rbnode_type* sibling;
int go_up = 1; int go_up = 1;
/* determine sibling to the node that is one-black short */ /* determine sibling to the node that is one-black short */
@ -422,8 +426,8 @@ static void _getdns_rbtree_delete_fixup(_getdns_rbtree_t* rbtree, _getdns_rbnode
child_parent->color = RED; child_parent->color = RED;
sibling->color = BLACK; sibling->color = BLACK;
if(child_parent->right == child) if(child_parent->right == child)
_getdns_rbtree_rotate_right(rbtree, child_parent); rbtree_rotate_right(rbtree, child_parent);
else _getdns_rbtree_rotate_left(rbtree, child_parent); else rbtree_rotate_left(rbtree, child_parent);
/* new sibling after rotation */ /* new sibling after rotation */
if(child_parent->right == child) sibling = child_parent->left; if(child_parent->right == child) sibling = child_parent->left;
else sibling = child_parent->right; else sibling = child_parent->right;
@ -468,7 +472,7 @@ static void _getdns_rbtree_delete_fixup(_getdns_rbtree_t* rbtree, _getdns_rbnode
{ {
sibling->color = RED; sibling->color = RED;
sibling->right->color = BLACK; sibling->right->color = BLACK;
_getdns_rbtree_rotate_left(rbtree, sibling); rbtree_rotate_left(rbtree, sibling);
/* new sibling after rotation */ /* new sibling after rotation */
if(child_parent->right == child) sibling = child_parent->left; if(child_parent->right == child) sibling = child_parent->left;
else sibling = child_parent->right; else sibling = child_parent->right;
@ -480,7 +484,7 @@ static void _getdns_rbtree_delete_fixup(_getdns_rbtree_t* rbtree, _getdns_rbnode
{ {
sibling->color = RED; sibling->color = RED;
sibling->left->color = BLACK; sibling->left->color = BLACK;
_getdns_rbtree_rotate_right(rbtree, sibling); rbtree_rotate_right(rbtree, sibling);
/* new sibling after rotation */ /* new sibling after rotation */
if(child_parent->right == child) sibling = child_parent->left; if(child_parent->right == child) sibling = child_parent->left;
else sibling = child_parent->right; else sibling = child_parent->right;
@ -493,21 +497,22 @@ static void _getdns_rbtree_delete_fixup(_getdns_rbtree_t* rbtree, _getdns_rbnode
{ {
log_assert(sibling->left->color == RED); log_assert(sibling->left->color == RED);
sibling->left->color = BLACK; sibling->left->color = BLACK;
_getdns_rbtree_rotate_right(rbtree, child_parent); rbtree_rotate_right(rbtree, child_parent);
} }
else else
{ {
log_assert(sibling->right->color == RED); log_assert(sibling->right->color == RED);
sibling->right->color = BLACK; sibling->right->color = BLACK;
_getdns_rbtree_rotate_left(rbtree, child_parent); rbtree_rotate_left(rbtree, child_parent);
} }
} }
int int
_getdns_rbtree_find_less_equal(_getdns_rbtree_t *rbtree, const void *key, _getdns_rbnode_t **result) rbtree_find_less_equal(rbtree_type *rbtree, const void *key,
rbnode_type **result)
{ {
int r; int r;
_getdns_rbnode_t *node; rbnode_type *node;
log_assert(result); log_assert(result);
@ -515,7 +520,7 @@ _getdns_rbtree_find_less_equal(_getdns_rbtree_t *rbtree, const void *key, _getdn
node = rbtree->root; node = rbtree->root;
*result = NULL; *result = NULL;
fptr_ok(fptr_whitelist__getdns_rbtree_cmp(rbtree->cmp)); fptr_ok(fptr_whitelist_rbtree_cmp(rbtree->cmp));
/* While there are children... */ /* While there are children... */
while (node != RBTREE_NULL) { while (node != RBTREE_NULL) {
@ -540,19 +545,19 @@ _getdns_rbtree_find_less_equal(_getdns_rbtree_t *rbtree, const void *key, _getdn
* Finds the first element in the red black tree * Finds the first element in the red black tree
* *
*/ */
_getdns_rbnode_t * rbnode_type *
_getdns_rbtree_first (_getdns_rbtree_t *rbtree) rbtree_first (rbtree_type *rbtree)
{ {
_getdns_rbnode_t *node; rbnode_type *node;
for (node = rbtree->root; node->left != RBTREE_NULL; node = node->left); for (node = rbtree->root; node->left != RBTREE_NULL; node = node->left);
return node; return node;
} }
_getdns_rbnode_t * rbnode_type *
_getdns_rbtree_last (_getdns_rbtree_t *rbtree) rbtree_last (rbtree_type *rbtree)
{ {
_getdns_rbnode_t *node; rbnode_type *node;
for (node = rbtree->root; node->right != RBTREE_NULL; node = node->right); for (node = rbtree->root; node->right != RBTREE_NULL; node = node->right);
return node; return node;
@ -562,10 +567,10 @@ _getdns_rbtree_last (_getdns_rbtree_t *rbtree)
* Returns the next node... * Returns the next node...
* *
*/ */
_getdns_rbnode_t * rbnode_type *
_getdns_rbtree_next (_getdns_rbnode_t *node) rbtree_next (rbnode_type *node)
{ {
_getdns_rbnode_t *parent; rbnode_type *parent;
if (node->right != RBTREE_NULL) { if (node->right != RBTREE_NULL) {
/* One right, then keep on going left... */ /* One right, then keep on going left... */
@ -581,10 +586,10 @@ _getdns_rbtree_next (_getdns_rbnode_t *node)
return node; return node;
} }
_getdns_rbnode_t * rbnode_type *
_getdns_rbtree_previous(_getdns_rbnode_t *node) rbtree_previous(rbnode_type *node)
{ {
_getdns_rbnode_t *parent; rbnode_type *parent;
if (node->left != RBTREE_NULL) { if (node->left != RBTREE_NULL) {
/* One left, then keep on going right... */ /* One left, then keep on going right... */
@ -602,19 +607,20 @@ _getdns_rbtree_previous(_getdns_rbnode_t *node)
/** recursive descent traverse */ /** recursive descent traverse */
static void static void
_getdns_traverse_post(void (*func)(_getdns_rbnode_t*, void*), void* arg, _getdns_rbnode_t* node) traverse_post(void (*func)(rbnode_type*, void*), void* arg, rbnode_type* node)
{ {
if(!node || node == RBTREE_NULL) if(!node || node == RBTREE_NULL)
return; return;
/* recurse */ /* recurse */
_getdns_traverse_post(func, arg, node->left); traverse_post(func, arg, node->left);
_getdns_traverse_post(func, arg, node->right); traverse_post(func, arg, node->right);
/* call user func */ /* call user func */
(*func)(node, arg); (*func)(node, arg);
} }
void void
_getdns_traverse_postorder(_getdns_rbtree_t* tree, void (*func)(_getdns_rbnode_t*, void*), void* arg) traverse_postorder(rbtree_type* tree, void (*func)(rbnode_type*, void*),
void* arg)
{ {
_getdns_traverse_post(func, arg, tree->root); traverse_post(func, arg, tree->root);
} }

View File

@ -1,192 +1,50 @@
/**
*
* \file rbtree.h
* /brief Alternative symbol names for unbound's rbtree.h
*
*/
/* /*
* rbtree.h -- generic red-black tree * Copyright (c) 2017, NLnet Labs, the getdns team
* All rights reserved.
* *
* Copyright (c) 2001-2007, NLnet Labs. All rights reserved.
*
* This software is open source.
*
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions are met:
* are met: * * Redistributions of source code must retain the above copyright
* * notice, this list of conditions and the following disclaimer.
* Redistributions of source code must retain the above copyright notice, * * Redistributions in binary form must reproduce the above copyright
* this list of conditions and the following disclaimer. * notice, this list of conditions and the following disclaimer in the
* * documentation and/or other materials provided with the distribution.
* Redistributions in binary form must reproduce the above copyright notice, * * Neither the names of the copyright holders nor the
* this list of conditions and the following disclaimer in the documentation * names of its contributors may be used to endorse or promote products
* and/or other materials provided with the distribution. * derived from this software without specific prior written permission.
*
* Neither the name of the NLNET LABS nor the names of its contributors may
* be used to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* *
* 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 RBTREE_H_SYMBOLS
/** #define RBTREE_H_SYMBOLS
* \file #define rbnode_type _getdns_rbnode_t
* Red black tree. Implementation taken from NSD 3.0.5, adjusted for use #define rbtree_null_node _getdns_rbtree_null_node
* in unbound (memory allocation, logging and so on). #define rbtree_type _getdns_rbtree_t
*/ #define rbtree_create _getdns_rbtree_create
#define rbtree_init _getdns_rbtree_init
#ifndef UTIL_RBTREE_H_ #define rbtree_insert _getdns_rbtree_insert
#define UTIL_RBTREE_H_ #define rbtree_delete _getdns_rbtree_delete
#define rbtree_search _getdns_rbtree_search
/** #define rbtree_find_less_equal _getdns_rbtree_find_less_equal
* This structure must be the first member of the data structure in #define rbtree_first _getdns_rbtree_first
* the rbtree. This allows easy casting between an _getdns_rbnode_t and the #define rbtree_last _getdns_rbtree_last
* user data (poor man's inheritance). #define rbtree_next _getdns_rbtree_next
*/ #define rbtree_previous _getdns_rbtree_previous
typedef struct _getdns_rbnode_t _getdns_rbnode_t; #define traverse_postorder _getdns_traverse_postorder
/** #include "util/orig-headers/rbtree.h"
* The _getdns_rbnode_t struct definition. #endif
*/
struct _getdns_rbnode_t {
/** parent in rbtree, RBTREE_NULL for root */
_getdns_rbnode_t *parent;
/** left node (smaller items) */
_getdns_rbnode_t *left;
/** right node (larger items) */
_getdns_rbnode_t *right;
/** pointer to sorting key */
const void *key;
/** colour of this node */
uint8_t color;
};
/** The nullpointer, points to empty node */
#define RBTREE_NULL &_getdns_rbtree_null_node
/** the global empty node */
extern _getdns_rbnode_t _getdns_rbtree_null_node;
/** An entire red black tree */
typedef struct _getdns_rbtree_t _getdns_rbtree_t;
/** definition for tree struct */
struct _getdns_rbtree_t {
/** The root of the red-black tree */
_getdns_rbnode_t *root;
/** The number of the nodes in the tree */
size_t count;
/**
* Key compare function. <0,0,>0 like strcmp.
* Return 0 on two NULL ptrs.
*/
int (*cmp) (const void *, const void *);
};
/**
* Create new tree (malloced) with given key compare function.
* @param cmpf: compare function (like strcmp) takes pointers to two keys.
* @return: new tree, empty.
*/
_getdns_rbtree_t *_getdns_rbtree_create(int (*cmpf)(const void *, const void *));
/**
* Init a new tree (malloced by caller) with given key compare function.
* @param rbtree: uninitialised memory for new tree, returned empty.
* @param cmpf: compare function (like strcmp) takes pointers to two keys.
*/
void _getdns_rbtree_init(_getdns_rbtree_t *rbtree, int (*cmpf)(const void *, const void *));
/**
* Insert data into the tree.
* @param rbtree: tree to insert to.
* @param data: element to insert.
* @return: data ptr or NULL if key already present.
*/
_getdns_rbnode_t *_getdns_rbtree_insert(_getdns_rbtree_t *rbtree, _getdns_rbnode_t *data);
/**
* Delete element from tree.
* @param rbtree: tree to delete from.
* @param key: key of item to delete.
* @return: node that is now unlinked from the tree. User to delete it.
* returns 0 if node not present
*/
_getdns_rbnode_t *_getdns_rbtree_delete(_getdns_rbtree_t *rbtree, const void *key);
/**
* Find key in tree. Returns NULL if not found.
* @param rbtree: tree to find in.
* @param key: key that must match.
* @return: node that fits or NULL.
*/
_getdns_rbnode_t *_getdns_rbtree_search(_getdns_rbtree_t *rbtree, const void *key);
/**
* Find, but match does not have to be exact.
* @param rbtree: tree to find in.
* @param key: key to find position of.
* @param result: set to the exact node if present, otherwise to element that
* precedes the position of key in the tree. NULL if no smaller element.
* @return: true if exact match in result. Else result points to <= element,
* or NULL if key is smaller than the smallest key.
*/
int _getdns_rbtree_find_less_equal(_getdns_rbtree_t *rbtree, const void *key,
_getdns_rbnode_t **result);
/**
* Returns first (smallest) node in the tree
* @param rbtree: tree
* @return: smallest element or NULL if tree empty.
*/
_getdns_rbnode_t *_getdns_rbtree_first(_getdns_rbtree_t *rbtree);
/**
* Returns last (largest) node in the tree
* @param rbtree: tree
* @return: largest element or NULL if tree empty.
*/
_getdns_rbnode_t *_getdns_rbtree_last(_getdns_rbtree_t *rbtree);
/**
* Returns next larger node in the tree
* @param rbtree: tree
* @return: next larger element or NULL if no larger in tree.
*/
_getdns_rbnode_t *_getdns_rbtree_next(_getdns_rbnode_t *rbtree);
/**
* Returns previous smaller node in the tree
* @param rbtree: tree
* @return: previous smaller element or NULL if no previous in tree.
*/
_getdns_rbnode_t *_getdns_rbtree_previous(_getdns_rbnode_t *rbtree);
/**
* Call with node=variable of struct* with _getdns_rbnode_t as first element.
* with type is the type of a pointer to that struct.
*/
#define RBTREE_FOR(node, type, rbtree) \
for(node=(type)_getdns_rbtree_first(rbtree); \
(_getdns_rbnode_t*)node != RBTREE_NULL; \
node = (type)_getdns_rbtree_next((_getdns_rbnode_t*)node))
/**
* Call function for all elements in the redblack tree, such that
* leaf elements are called before parent elements. So that all
* elements can be safely free()d.
* Note that your function must not remove the nodes from the tree.
* Since that may trigger rebalances of the rbtree.
* @param tree: the tree
* @param func: function called with element and user arg.
* The function must not alter the rbtree.
* @param arg: user argument.
*/
void _getdns_traverse_postorder(_getdns_rbtree_t* tree, void (*func)(_getdns_rbnode_t*, void*),
void* arg);
#endif /* UTIL_RBTREE_H_ */

File diff suppressed because it is too large Load Diff

View File

@ -1,107 +1,78 @@
/**
*
* \file rbtree.h
* /brief Alternative symbol names for unbound's rbtree.h
*
*/
/* /*
* validator/val_secalgo.h - validator security algorithm functions. * Copyright (c) 2017, NLnet Labs, the getdns team
* All rights reserved.
* *
* Copyright (c) 2012, NLnet Labs. All rights reserved.
*
* This software is open source.
*
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions are met:
* are met: * * Redistributions of source code must retain the above copyright
* * notice, this list of conditions and the following disclaimer.
* Redistributions of source code must retain the above copyright notice, * * Redistributions in binary form must reproduce the above copyright
* this list of conditions and the following disclaimer. * notice, this list of conditions and the following disclaimer in the
* * documentation and/or other materials provided with the distribution.
* Redistributions in binary form must reproduce the above copyright notice, * * Neither the names of the copyright holders nor the
* this list of conditions and the following disclaimer in the documentation * names of its contributors may be used to endorse or promote products
* and/or other materials provided with the distribution. * derived from this software without specific prior written permission.
* *
* Neither the name of the NLNET LABS nor the names of its contributors may * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* be used to endorse or promote products derived from this software without * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* specific prior written permission. * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* * DISCLAIMED. IN NO EVENT SHALL Verisign, Inc. BE LIABLE FOR ANY
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* 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. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#ifndef VAL_SECALGO_H_SYMBOLS
#define VAL_SECALGO_H_SYMBOLS
#define sldns_buffer gldns_buffer
#define nsec3_hash_algo_size_supported _getdns_nsec3_hash_algo_size_supported
#define secalgo_nsec3_hash _getdns_secalgo_nsec3_hash
#define secalgo_hash_sha256 _getdns_secalgo_hash_sha256
#define ds_digest_size_supported _getdns_ds_digest_size_supported
#define secalgo_ds_digest _getdns_secalgo_ds_digest
#define dnskey_algo_id_is_supported _getdns_dnskey_algo_id_is_supported
#define verify_canonrrset _getdns_verify_canonrrset
#define sec_status _getdns_sec_status
#define sec_status_secure _getdns_sec_status_secure
#define sec_status_insecure _getdns_sec_status_insecure
#define sec_status_unchecked _getdns_sec_status_unchecked
#define sec_status_bogus _getdns_sec_status_bogus
/** enum sec_status { sec_status_bogus = 0
* \file , sec_status_unchecked = 0
* , sec_status_insecure = 0
* This file contains helper functions for the validator module. , sec_status_secure = 1 };
* The functions take buffers with raw data and convert to library calls. #define NSEC3_HASH_SHA1 0x01
*/
#ifndef VALIDATOR_VAL_SECALGO_H #define LDNS_SHA1 GLDNS_SHA1
#define VALIDATOR_VAL_SECALGO_H #define LDNS_SHA256 GLDNS_SHA256
struct gldns_buffer; #define LDNS_SHA384 GLDNS_SHA384
#define LDNS_HASH_GOST GLDNS_HASH_GOST
/** Return size of nsec3 hash algorithm, 0 if not supported */ #define LDNS_RSAMD5 GLDNS_RSAMD5
size_t _getdns_nsec3_hash_algo_size_supported(int id); #define LDNS_DSA GLDNS_DSA
#define LDNS_DSA_NSEC3 GLDNS_DSA_NSEC3
/** #define LDNS_RSASHA1 GLDNS_RSASHA1
* Hash a single hash call of an NSEC3 hash algorithm. #define LDNS_RSASHA1_NSEC3 GLDNS_RSASHA1_NSEC3
* Iterations and salt are done by the caller. #define LDNS_RSASHA256 GLDNS_RSASHA256
* @param algo: nsec3 hash algorithm. #define LDNS_RSASHA512 GLDNS_RSASHA512
* @param buf: the buffer to digest #define LDNS_ECDSAP256SHA256 GLDNS_ECDSAP256SHA256
* @param len: length of buffer to digest. #define LDNS_ECDSAP384SHA384 GLDNS_ECDSAP384SHA384
* @param res: result stored here (must have sufficient space). #define LDNS_ECC_GOST GLDNS_ECC_GOST
* @return false on failure. #define sldns_key_EVP_load_gost_id gldns_key_EVP_load_gost_id
*/ #define sldns_digest_evp gldns_digest_evp
int _getdns_secalgo_nsec3_hash(int algo, unsigned char* buf, size_t len, #define sldns_key_buf2dsa_raw gldns_key_buf2dsa_raw
unsigned char* res); #define sldns_key_buf2rsa_raw gldns_key_buf2rsa_raw
#define sldns_gost2pkey_raw gldns_gost2pkey_raw
/** #define sldns_ecdsa2pkey_raw gldns_ecdsa2pkey_raw
* Calculate the sha256 hash for the data buffer into the result. #define sldns_buffer_begin gldns_buffer_begin
* @param buf: buffer to digest. #define sldns_buffer_limit gldns_buffer_limit
* @param len: length of the buffer to digest. #include "util/orig-headers/val_secalgo.h"
* @param res: result is stored here (space 256/8 bytes). #endif
*/
void _getdns_secalgo_hash_sha256(unsigned char* buf, size_t len, unsigned char* res);
/**
* Return size of DS digest according to its hash algorithm.
* @param algo: DS digest algo.
* @return size in bytes of digest, or 0 if not supported.
*/
size_t _getdns_ds_digest_size_supported(int algo);
/**
* @param algo: the DS digest algo
* @param buf: the buffer to digest
* @param len: length of buffer to digest.
* @param res: result stored here (must have sufficient space).
* @return false on failure.
*/
int _getdns_secalgo_ds_digest(int algo, unsigned char* buf, size_t len,
unsigned char* res);
/** return true if DNSKEY algorithm id is supported */
int _getdns_dnskey_algo_id_is_supported(int id);
/**
* Check a canonical sig+rrset and signature against a dnskey
* @param buf: buffer with data to verify, the first rrsig part and the
* canonicalized rrset.
* @param algo: DNSKEY algorithm.
* @param sigblock: signature rdata field from RRSIG
* @param sigblock_len: length of sigblock data.
* @param key: public key data from DNSKEY RR.
* @param keylen: length of keydata.
* @param reason: bogus reason in more detail.
* @return secure if verification succeeded, bogus on crypto failure,
* unchecked on format errors and alloc failures.
*/
int _getdns_verify_canonrrset(struct gldns_buffer* buf, int algo,
unsigned char* sigblock, unsigned int sigblock_len,
unsigned char* key, unsigned int keylen, char** reason);
#endif /* VALIDATOR_VAL_SECALGO_H */