mirror of https://github.com/getdnsapi/getdns.git
Merge pull request #8 from wtoorop/features/mdns-client
Features/mdns client
This commit is contained in:
commit
d511ce24de
20
configure.ac
20
configure.ac
|
@ -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.
|
||||||
|
|
|
@ -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
|
||||||
|
|
390
src/Makefile.in
390
src/Makefile.in
|
@ -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
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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
|
||||||
|
|
53
src/mdns.c
53
src/mdns.c
|
@ -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;
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
#include "util/fptr_wlist.h"
|
|
@ -0,0 +1 @@
|
||||||
|
#include "util/log.h"
|
|
@ -0,0 +1 @@
|
||||||
|
#include "gldns/keyraw.h"
|
|
@ -0,0 +1 @@
|
||||||
|
#include "gldns/rrdef.h"
|
|
@ -0,0 +1 @@
|
||||||
|
#include "gldns/gbuffer.h"
|
|
@ -0,0 +1 @@
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
#include "util/lookup3.h"
|
|
@ -0,0 +1 @@
|
||||||
|
#include "util/lruhash.h"
|
|
@ -0,0 +1 @@
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
#include "util/val_secalgo.h"
|
|
@ -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
|
|
||||||
|
|
|
@ -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 */
|
|
@ -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
|
File diff suppressed because it is too large
Load Diff
|
@ -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 */
|
|
||||||
|
|
|
@ -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);
|
||||||
|
}
|
|
@ -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
|
|
@ -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 */
|
|
@ -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 */
|
|
@ -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 */
|
|
@ -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_ */
|
|
@ -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 */
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
@ -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 */
|
|
||||||
|
|
Loading…
Reference in New Issue