mirror of https://github.com/getdnsapi/getdns.git
Merge pull request #267 from wtoorop/features/mdns-client
Features/mdns client
This commit is contained in:
commit
1ad8047443
32
configure.ac
32
configure.ac
|
@ -311,6 +311,15 @@ AC_INCLUDES_DEFAULT
|
|||
fi
|
||||
|
||||
|
||||
AC_ARG_ENABLE(sha1, AC_HELP_STRING([--disable-sha1], [Disable SHA1 RRSIG support, does not disable nsec3 support]))
|
||||
case "$enable_sha1" in
|
||||
no)
|
||||
;;
|
||||
yes|*)
|
||||
AC_DEFINE([USE_SHA1], [1], [Define this to enable SHA1 support.])
|
||||
;;
|
||||
esac
|
||||
|
||||
AC_ARG_ENABLE(sha2, AC_HELP_STRING([--disable-sha2], [Disable SHA256 and SHA512 RRSIG support]))
|
||||
case "$enable_sha2" in
|
||||
no)
|
||||
|
@ -481,9 +490,10 @@ case "$enable_dsa" in
|
|||
;;
|
||||
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
|
||||
yes)
|
||||
AC_DEFINE_UNQUOTED([HAVE_MDNS_SUPPORT], [1], [Define this to enable the draft mdns client support.])
|
||||
;;
|
||||
no|*)
|
||||
;;
|
||||
|
@ -514,6 +524,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([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
|
||||
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
|
||||
|
@ -657,7 +676,7 @@ AC_TYPE_UINT16_T
|
|||
AC_TYPE_UINT32_T
|
||||
AC_TYPE_UINT64_T
|
||||
AC_TYPE_UINT8_T
|
||||
AC_CHECK_TYPE([u_char])
|
||||
AC_CHECK_TYPES([u_char])
|
||||
|
||||
AC_CHECK_FUNCS([fcntl])
|
||||
# check ioctlsocket
|
||||
|
@ -742,7 +761,7 @@ AS_IF([test x_$withval = x_no],
|
|||
[AC_MSG_ERROR([event2/event.h and event.h missing, try without libevent])]
|
||||
[have_libevent=0],
|
||||
[AC_INCLUDES_DEFAULT]
|
||||
[#if HAVE_U_CHAR == 0
|
||||
[#ifndef HAVE_U_CHAR
|
||||
typedef unsigned char u_char;
|
||||
#endif])],
|
||||
[AC_INCLUDES_DEFAULT])],
|
||||
|
@ -992,7 +1011,10 @@ fi
|
|||
|
||||
|
||||
#---- 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])
|
||||
LIBS="-lpthread $LIBS"
|
||||
], [AC_MSG_WARN([pthreads not available])])
|
||||
|
||||
AC_MSG_CHECKING([whether the C compiler (${CC-cc}) supports the __func__ variable])
|
||||
AC_LANG_PUSH(C)
|
||||
|
@ -1008,7 +1030,7 @@ dnl ----- Start of "Things needed for gldns" section
|
|||
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 result in HAVE_ATTR_FORMAT.
|
||||
|
|
196
src/Makefile.in
196
src/Makefile.in
|
@ -48,7 +48,7 @@ srcdir = @srcdir@
|
|||
LIBTOOL = ../libtool
|
||||
|
||||
CC=@CC@
|
||||
CFLAGS=-I$(srcdir) -I. @CFLAGS@ @CPPFLAGS@ $(XTRA_CFLAGS)
|
||||
CFLAGS=-I$(srcdir) -I. -I$(srcdir)/util/auxiliary @CFLAGS@ @CPPFLAGS@ $(XTRA_CFLAGS)
|
||||
WPEDANTICFLAG=@WPEDANTICFLAG@
|
||||
WNOERRORFLAG=@WNOERRORFLAG@
|
||||
LDFLAGS=@LDFLAGS@ @LIBS@
|
||||
|
@ -79,7 +79,7 @@ LIBOBJDIR=
|
|||
LIBOBJS=@LIBOBJS@
|
||||
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
|
||||
|
||||
|
@ -191,13 +191,14 @@ Makefile: $(srcdir)/Makefile.in ../config.status
|
|||
|
||||
depend:
|
||||
(cd $(srcdir) ; awk 'BEGIN{P=1}{if(P)print}/^# Dependencies/{P=0}' Makefile.in > Makefile.in.new )
|
||||
(blddir=`pwd`; cd $(srcdir) ; gcc -MM -I. -I"$$blddir" *.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" \
|
||||
-e 's?gldns/?$$(srcdir)/gldns/?g' \
|
||||
-e 's?compat/?$$(srcdir)/compat/?g' \
|
||||
-e 's?util/?$$(srcdir)/util/?g' \
|
||||
-e 's?jsmn/?$$(srcdir)/jsmn/?g' \
|
||||
-e 's?extension/?$$(srcdir)/extension/?g' \
|
||||
-e 's? gldns/? $$(srcdir)/gldns/?g' \
|
||||
-e 's? compat/? $$(srcdir)/compat/?g' \
|
||||
-e 's? util/auxiliary/util/? $$(srcdir)/util/auxiliary/util/?g' \
|
||||
-e 's? util/? $$(srcdir)/util/?g' \
|
||||
-e 's? jsmn/? $$(srcdir)/jsmn/?g' \
|
||||
-e 's? extension/? $$(srcdir)/extension/?g' \
|
||||
-e 's? \([a-z_-]*\)\.\([ch]\)? $$(srcdir)/\1.\2?g' \
|
||||
-e 's? \$$(srcdir)/config\.h? config.h?g' \
|
||||
-e 's? \$$(srcdir)/getdns/getdns_extra\.h? getdns/getdns_extra.h?g' \
|
||||
|
@ -224,95 +225,122 @@ context.lo context.o: $(srcdir)/context.c \
|
|||
$(srcdir)/debug.h $(srcdir)/gldns/str2wire.h $(srcdir)/gldns/rrdef.h $(srcdir)/gldns/wire2str.h $(srcdir)/context.h \
|
||||
getdns/getdns.h \
|
||||
getdns/getdns_extra.h \
|
||||
$(srcdir)/types-internal.h $(srcdir)/util/rbtree.h $(srcdir)/extension/default_eventloop.h \
|
||||
$(srcdir)/extension/poll_eventloop.h $(srcdir)/types-internal.h $(srcdir)/ub_loop.h $(srcdir)/server.h \
|
||||
$(srcdir)/util-internal.h $(srcdir)/rr-iter.h $(srcdir)/rr-dict.h $(srcdir)/gldns/gbuffer.h $(srcdir)/gldns/pkthdr.h \
|
||||
$(srcdir)/dnssec.h $(srcdir)/gldns/rrdef.h $(srcdir)/stub.h $(srcdir)/list.h $(srcdir)/dict.h $(srcdir)/pubkey-pinning.h
|
||||
$(srcdir)/types-internal.h $(srcdir)/util/rbtree.h $(srcdir)/util/orig-headers/rbtree.h \
|
||||
$(srcdir)/extension/default_eventloop.h $(srcdir)/extension/poll_eventloop.h \
|
||||
$(srcdir)/types-internal.h $(srcdir)/ub_loop.h $(srcdir)/server.h $(srcdir)/util/lruhash.h \
|
||||
$(srcdir)/util/orig-headers/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/orig-headers/locks.h \
|
||||
$(srcdir)/util/auxiliary/util/log.h $(srcdir)/debug.h $(srcdir)/util-internal.h $(srcdir)/rr-iter.h $(srcdir)/rr-dict.h \
|
||||
$(srcdir)/gldns/gbuffer.h $(srcdir)/gldns/pkthdr.h $(srcdir)/dnssec.h $(srcdir)/gldns/rrdef.h $(srcdir)/stub.h $(srcdir)/list.h \
|
||||
$(srcdir)/dict.h $(srcdir)/pubkey-pinning.h
|
||||
convert.lo convert.o: $(srcdir)/convert.c \
|
||||
config.h \
|
||||
getdns/getdns.h \
|
||||
getdns/getdns_extra.h \
|
||||
$(srcdir)/util-internal.h $(srcdir)/context.h $(srcdir)/types-internal.h $(srcdir)/util/rbtree.h \
|
||||
$(srcdir)/extension/default_eventloop.h $(srcdir)/extension/poll_eventloop.h \
|
||||
$(srcdir)/types-internal.h $(srcdir)/ub_loop.h $(srcdir)/debug.h $(srcdir)/server.h $(srcdir)/rr-iter.h $(srcdir)/rr-dict.h \
|
||||
$(srcdir)/gldns/gbuffer.h $(srcdir)/gldns/pkthdr.h $(srcdir)/gldns/wire2str.h $(srcdir)/gldns/str2wire.h \
|
||||
$(srcdir)/gldns/rrdef.h $(srcdir)/gldns/parseutil.h $(srcdir)/const-info.h $(srcdir)/dict.h $(srcdir)/list.h $(srcdir)/jsmn/jsmn.h \
|
||||
$(srcdir)/convert.h
|
||||
$(srcdir)/util/orig-headers/rbtree.h $(srcdir)/extension/default_eventloop.h \
|
||||
$(srcdir)/extension/poll_eventloop.h $(srcdir)/types-internal.h $(srcdir)/ub_loop.h $(srcdir)/debug.h $(srcdir)/server.h \
|
||||
$(srcdir)/util/lruhash.h $(srcdir)/util/orig-headers/lruhash.h $(srcdir)/util/locks.h \
|
||||
$(srcdir)/util/orig-headers/locks.h $(srcdir)/util/auxiliary/util/log.h $(srcdir)/debug.h $(srcdir)/rr-iter.h \
|
||||
$(srcdir)/rr-dict.h $(srcdir)/gldns/gbuffer.h $(srcdir)/gldns/pkthdr.h $(srcdir)/gldns/wire2str.h \
|
||||
$(srcdir)/gldns/str2wire.h $(srcdir)/gldns/rrdef.h $(srcdir)/gldns/parseutil.h $(srcdir)/const-info.h $(srcdir)/dict.h \
|
||||
$(srcdir)/list.h $(srcdir)/jsmn/jsmn.h $(srcdir)/convert.h
|
||||
dict.lo dict.o: $(srcdir)/dict.c \
|
||||
config.h \
|
||||
$(srcdir)/types-internal.h \
|
||||
getdns/getdns.h \
|
||||
getdns/getdns_extra.h \
|
||||
$(srcdir)/util/rbtree.h $(srcdir)/util-internal.h $(srcdir)/context.h $(srcdir)/extension/default_eventloop.h \
|
||||
$(srcdir)/extension/poll_eventloop.h $(srcdir)/types-internal.h $(srcdir)/ub_loop.h $(srcdir)/debug.h $(srcdir)/server.h \
|
||||
$(srcdir)/rr-iter.h $(srcdir)/rr-dict.h $(srcdir)/gldns/gbuffer.h $(srcdir)/gldns/pkthdr.h $(srcdir)/dict.h $(srcdir)/list.h \
|
||||
$(srcdir)/const-info.h $(srcdir)/gldns/wire2str.h
|
||||
$(srcdir)/util/rbtree.h $(srcdir)/util/orig-headers/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)/util/lruhash.h \
|
||||
$(srcdir)/util/orig-headers/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/orig-headers/locks.h \
|
||||
$(srcdir)/util/auxiliary/util/log.h $(srcdir)/debug.h $(srcdir)/rr-iter.h $(srcdir)/rr-dict.h $(srcdir)/gldns/gbuffer.h \
|
||||
$(srcdir)/gldns/pkthdr.h $(srcdir)/dict.h $(srcdir)/list.h $(srcdir)/const-info.h $(srcdir)/gldns/wire2str.h \
|
||||
$(srcdir)/gldns/parseutil.h
|
||||
dnssec.lo dnssec.o: $(srcdir)/dnssec.c \
|
||||
config.h \
|
||||
$(srcdir)/debug.h \
|
||||
getdns/getdns.h \
|
||||
$(srcdir)/context.h \
|
||||
getdns/getdns_extra.h \
|
||||
$(srcdir)/types-internal.h $(srcdir)/util/rbtree.h $(srcdir)/extension/default_eventloop.h \
|
||||
$(srcdir)/extension/poll_eventloop.h $(srcdir)/types-internal.h $(srcdir)/ub_loop.h $(srcdir)/server.h \
|
||||
$(srcdir)/util-internal.h $(srcdir)/rr-iter.h $(srcdir)/rr-dict.h $(srcdir)/gldns/gbuffer.h $(srcdir)/gldns/pkthdr.h \
|
||||
$(srcdir)/dnssec.h $(srcdir)/gldns/rrdef.h $(srcdir)/gldns/str2wire.h $(srcdir)/gldns/rrdef.h $(srcdir)/gldns/wire2str.h \
|
||||
$(srcdir)/gldns/keyraw.h $(srcdir)/gldns/parseutil.h $(srcdir)/general.h $(srcdir)/dict.h $(srcdir)/list.h \
|
||||
$(srcdir)/util/val_secalgo.h
|
||||
$(srcdir)/types-internal.h $(srcdir)/util/rbtree.h $(srcdir)/util/orig-headers/rbtree.h \
|
||||
$(srcdir)/extension/default_eventloop.h $(srcdir)/extension/poll_eventloop.h \
|
||||
$(srcdir)/types-internal.h $(srcdir)/ub_loop.h $(srcdir)/server.h $(srcdir)/util/lruhash.h \
|
||||
$(srcdir)/util/orig-headers/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/orig-headers/locks.h \
|
||||
$(srcdir)/util/auxiliary/util/log.h $(srcdir)/debug.h $(srcdir)/util-internal.h $(srcdir)/rr-iter.h $(srcdir)/rr-dict.h \
|
||||
$(srcdir)/gldns/gbuffer.h $(srcdir)/gldns/pkthdr.h $(srcdir)/dnssec.h $(srcdir)/gldns/rrdef.h $(srcdir)/gldns/str2wire.h \
|
||||
$(srcdir)/gldns/rrdef.h $(srcdir)/gldns/wire2str.h $(srcdir)/gldns/keyraw.h $(srcdir)/gldns/parseutil.h \
|
||||
$(srcdir)/general.h $(srcdir)/dict.h $(srcdir)/list.h $(srcdir)/util/val_secalgo.h \
|
||||
$(srcdir)/util/orig-headers/val_secalgo.h
|
||||
general.lo general.o: $(srcdir)/general.c \
|
||||
config.h \
|
||||
$(srcdir)/general.h \
|
||||
getdns/getdns.h \
|
||||
$(srcdir)/types-internal.h \
|
||||
getdns/getdns_extra.h \
|
||||
$(srcdir)/util/rbtree.h $(srcdir)/ub_loop.h $(srcdir)/debug.h $(srcdir)/gldns/wire2str.h $(srcdir)/context.h \
|
||||
$(srcdir)/extension/default_eventloop.h $(srcdir)/extension/poll_eventloop.h \
|
||||
$(srcdir)/types-internal.h $(srcdir)/server.h $(srcdir)/util-internal.h $(srcdir)/rr-iter.h $(srcdir)/rr-dict.h \
|
||||
$(srcdir)/util/rbtree.h $(srcdir)/util/orig-headers/rbtree.h $(srcdir)/ub_loop.h $(srcdir)/debug.h \
|
||||
$(srcdir)/gldns/wire2str.h $(srcdir)/context.h $(srcdir)/extension/default_eventloop.h \
|
||||
$(srcdir)/extension/poll_eventloop.h $(srcdir)/types-internal.h $(srcdir)/server.h $(srcdir)/util/lruhash.h \
|
||||
$(srcdir)/util/orig-headers/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/orig-headers/locks.h \
|
||||
$(srcdir)/util/auxiliary/util/log.h $(srcdir)/debug.h $(srcdir)/util-internal.h $(srcdir)/rr-iter.h $(srcdir)/rr-dict.h \
|
||||
$(srcdir)/gldns/gbuffer.h $(srcdir)/gldns/pkthdr.h $(srcdir)/dnssec.h $(srcdir)/gldns/rrdef.h $(srcdir)/stub.h $(srcdir)/dict.h \
|
||||
$(srcdir)/mdns.h
|
||||
list.lo list.o: $(srcdir)/list.c $(srcdir)/types-internal.h \
|
||||
getdns/getdns.h \
|
||||
getdns/getdns_extra.h \
|
||||
$(srcdir)/util/rbtree.h $(srcdir)/util-internal.h \
|
||||
$(srcdir)/util/rbtree.h $(srcdir)/util/orig-headers/rbtree.h $(srcdir)/util-internal.h \
|
||||
config.h \
|
||||
$(srcdir)/context.h $(srcdir)/extension/default_eventloop.h $(srcdir)/extension/poll_eventloop.h \
|
||||
$(srcdir)/types-internal.h $(srcdir)/ub_loop.h $(srcdir)/debug.h $(srcdir)/server.h $(srcdir)/rr-iter.h $(srcdir)/rr-dict.h \
|
||||
$(srcdir)/gldns/gbuffer.h $(srcdir)/gldns/pkthdr.h $(srcdir)/list.h $(srcdir)/dict.h
|
||||
$(srcdir)/types-internal.h $(srcdir)/ub_loop.h $(srcdir)/debug.h $(srcdir)/server.h $(srcdir)/util/lruhash.h \
|
||||
$(srcdir)/util/orig-headers/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/orig-headers/locks.h \
|
||||
$(srcdir)/util/auxiliary/util/log.h $(srcdir)/debug.h $(srcdir)/rr-iter.h $(srcdir)/rr-dict.h $(srcdir)/gldns/gbuffer.h \
|
||||
$(srcdir)/gldns/pkthdr.h $(srcdir)/list.h $(srcdir)/dict.h
|
||||
mdns.lo mdns.o: $(srcdir)/mdns.c \
|
||||
config.h \
|
||||
$(srcdir)/debug.h $(srcdir)/context.h \
|
||||
getdns/getdns.h \
|
||||
getdns/getdns_extra.h \
|
||||
$(srcdir)/types-internal.h $(srcdir)/util/rbtree.h $(srcdir)/extension/default_eventloop.h \
|
||||
$(srcdir)/extension/poll_eventloop.h $(srcdir)/types-internal.h $(srcdir)/ub_loop.h $(srcdir)/server.h $(srcdir)/general.h \
|
||||
$(srcdir)/gldns/pkthdr.h $(srcdir)/util-internal.h $(srcdir)/rr-iter.h $(srcdir)/rr-dict.h $(srcdir)/gldns/gbuffer.h \
|
||||
$(srcdir)/mdns.h
|
||||
$(srcdir)/types-internal.h $(srcdir)/util/rbtree.h $(srcdir)/util/orig-headers/rbtree.h \
|
||||
$(srcdir)/extension/default_eventloop.h $(srcdir)/extension/poll_eventloop.h \
|
||||
$(srcdir)/types-internal.h $(srcdir)/ub_loop.h $(srcdir)/server.h $(srcdir)/util/lruhash.h \
|
||||
$(srcdir)/util/orig-headers/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/orig-headers/locks.h \
|
||||
$(srcdir)/util/auxiliary/util/log.h $(srcdir)/debug.h $(srcdir)/general.h $(srcdir)/gldns/pkthdr.h $(srcdir)/gldns/rrdef.h \
|
||||
$(srcdir)/util-internal.h $(srcdir)/rr-iter.h $(srcdir)/rr-dict.h $(srcdir)/gldns/gbuffer.h $(srcdir)/mdns.h \
|
||||
$(srcdir)/util/auxiliary/util/fptr_wlist.h $(srcdir)/util/lookup3.h \
|
||||
$(srcdir)/util/orig-headers/lookup3.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
|
||||
$(srcdir)/types-internal.h $(srcdir)/util/rbtree.h $(srcdir)/util/orig-headers/rbtree.h \
|
||||
$(srcdir)/extension/default_eventloop.h $(srcdir)/extension/poll_eventloop.h \
|
||||
$(srcdir)/types-internal.h $(srcdir)/ub_loop.h $(srcdir)/server.h $(srcdir)/util/lruhash.h \
|
||||
$(srcdir)/util/orig-headers/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/orig-headers/locks.h \
|
||||
$(srcdir)/util/auxiliary/util/log.h $(srcdir)/debug.h $(srcdir)/util-internal.h $(srcdir)/rr-iter.h $(srcdir)/rr-dict.h \
|
||||
$(srcdir)/gldns/gbuffer.h $(srcdir)/gldns/pkthdr.h
|
||||
request-internal.lo request-internal.o: $(srcdir)/request-internal.c \
|
||||
config.h \
|
||||
$(srcdir)/types-internal.h \
|
||||
getdns/getdns.h \
|
||||
getdns/getdns_extra.h \
|
||||
$(srcdir)/util/rbtree.h $(srcdir)/util-internal.h $(srcdir)/context.h $(srcdir)/extension/default_eventloop.h \
|
||||
$(srcdir)/extension/poll_eventloop.h $(srcdir)/types-internal.h $(srcdir)/ub_loop.h $(srcdir)/debug.h $(srcdir)/server.h \
|
||||
$(srcdir)/rr-iter.h $(srcdir)/rr-dict.h $(srcdir)/gldns/gbuffer.h $(srcdir)/gldns/pkthdr.h $(srcdir)/gldns/rrdef.h \
|
||||
$(srcdir)/gldns/str2wire.h $(srcdir)/gldns/rrdef.h $(srcdir)/dict.h $(srcdir)/convert.h
|
||||
$(srcdir)/util/rbtree.h $(srcdir)/util/orig-headers/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)/util/lruhash.h \
|
||||
$(srcdir)/util/orig-headers/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/orig-headers/locks.h \
|
||||
$(srcdir)/util/auxiliary/util/log.h $(srcdir)/debug.h $(srcdir)/rr-iter.h $(srcdir)/rr-dict.h $(srcdir)/gldns/gbuffer.h \
|
||||
$(srcdir)/gldns/pkthdr.h $(srcdir)/gldns/rrdef.h $(srcdir)/gldns/str2wire.h $(srcdir)/gldns/rrdef.h $(srcdir)/dict.h \
|
||||
$(srcdir)/convert.h $(srcdir)/general.h
|
||||
rr-dict.lo rr-dict.o: $(srcdir)/rr-dict.c $(srcdir)/rr-dict.h \
|
||||
config.h \
|
||||
getdns/getdns.h \
|
||||
$(srcdir)/gldns/gbuffer.h $(srcdir)/util-internal.h $(srcdir)/context.h \
|
||||
getdns/getdns_extra.h \
|
||||
$(srcdir)/types-internal.h $(srcdir)/util/rbtree.h $(srcdir)/extension/default_eventloop.h \
|
||||
$(srcdir)/extension/poll_eventloop.h $(srcdir)/types-internal.h $(srcdir)/ub_loop.h $(srcdir)/debug.h $(srcdir)/server.h \
|
||||
$(srcdir)/rr-iter.h $(srcdir)/gldns/pkthdr.h $(srcdir)/dict.h
|
||||
$(srcdir)/types-internal.h $(srcdir)/util/rbtree.h $(srcdir)/util/orig-headers/rbtree.h \
|
||||
$(srcdir)/extension/default_eventloop.h $(srcdir)/extension/poll_eventloop.h \
|
||||
$(srcdir)/types-internal.h $(srcdir)/ub_loop.h $(srcdir)/debug.h $(srcdir)/server.h $(srcdir)/util/lruhash.h \
|
||||
$(srcdir)/util/orig-headers/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/orig-headers/locks.h \
|
||||
$(srcdir)/util/auxiliary/util/log.h $(srcdir)/debug.h $(srcdir)/rr-iter.h $(srcdir)/gldns/pkthdr.h $(srcdir)/dict.h
|
||||
rr-iter.lo rr-iter.o: $(srcdir)/rr-iter.c $(srcdir)/rr-iter.h $(srcdir)/rr-dict.h \
|
||||
config.h \
|
||||
getdns/getdns.h \
|
||||
|
@ -321,42 +349,52 @@ server.lo server.o: $(srcdir)/server.c \
|
|||
config.h \
|
||||
getdns/getdns_extra.h \
|
||||
getdns/getdns.h \
|
||||
$(srcdir)/context.h $(srcdir)/types-internal.h $(srcdir)/util/rbtree.h $(srcdir)/extension/default_eventloop.h \
|
||||
$(srcdir)/extension/poll_eventloop.h $(srcdir)/types-internal.h $(srcdir)/ub_loop.h $(srcdir)/debug.h $(srcdir)/server.h
|
||||
$(srcdir)/context.h $(srcdir)/types-internal.h $(srcdir)/util/rbtree.h $(srcdir)/util/orig-headers/rbtree.h \
|
||||
$(srcdir)/extension/default_eventloop.h $(srcdir)/extension/poll_eventloop.h \
|
||||
$(srcdir)/types-internal.h $(srcdir)/ub_loop.h $(srcdir)/debug.h $(srcdir)/server.h $(srcdir)/util/lruhash.h \
|
||||
$(srcdir)/util/orig-headers/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/orig-headers/locks.h \
|
||||
$(srcdir)/util/auxiliary/util/log.h $(srcdir)/debug.h
|
||||
stub.lo stub.o: $(srcdir)/stub.c \
|
||||
config.h \
|
||||
$(srcdir)/debug.h $(srcdir)/stub.h \
|
||||
getdns/getdns.h \
|
||||
$(srcdir)/types-internal.h \
|
||||
getdns/getdns_extra.h \
|
||||
$(srcdir)/util/rbtree.h $(srcdir)/gldns/gbuffer.h $(srcdir)/gldns/pkthdr.h $(srcdir)/gldns/rrdef.h \
|
||||
$(srcdir)/gldns/str2wire.h $(srcdir)/gldns/rrdef.h $(srcdir)/gldns/wire2str.h $(srcdir)/rr-iter.h $(srcdir)/rr-dict.h \
|
||||
$(srcdir)/context.h $(srcdir)/extension/default_eventloop.h $(srcdir)/extension/poll_eventloop.h \
|
||||
$(srcdir)/types-internal.h $(srcdir)/ub_loop.h $(srcdir)/server.h $(srcdir)/util-internal.h $(srcdir)/general.h \
|
||||
$(srcdir)/pubkey-pinning.h
|
||||
$(srcdir)/util/rbtree.h $(srcdir)/util/orig-headers/rbtree.h $(srcdir)/gldns/gbuffer.h $(srcdir)/gldns/pkthdr.h \
|
||||
$(srcdir)/gldns/rrdef.h $(srcdir)/gldns/str2wire.h $(srcdir)/gldns/rrdef.h $(srcdir)/gldns/wire2str.h $(srcdir)/rr-iter.h \
|
||||
$(srcdir)/rr-dict.h $(srcdir)/context.h $(srcdir)/extension/default_eventloop.h \
|
||||
$(srcdir)/extension/poll_eventloop.h $(srcdir)/types-internal.h $(srcdir)/ub_loop.h $(srcdir)/server.h \
|
||||
$(srcdir)/util/lruhash.h $(srcdir)/util/orig-headers/lruhash.h $(srcdir)/util/locks.h \
|
||||
$(srcdir)/util/orig-headers/locks.h $(srcdir)/util/auxiliary/util/log.h $(srcdir)/debug.h \
|
||||
$(srcdir)/util-internal.h $(srcdir)/general.h $(srcdir)/pubkey-pinning.h
|
||||
sync.lo sync.o: $(srcdir)/sync.c \
|
||||
getdns/getdns.h \
|
||||
config.h \
|
||||
$(srcdir)/context.h \
|
||||
getdns/getdns_extra.h \
|
||||
$(srcdir)/types-internal.h $(srcdir)/util/rbtree.h $(srcdir)/extension/default_eventloop.h \
|
||||
$(srcdir)/extension/poll_eventloop.h $(srcdir)/types-internal.h $(srcdir)/ub_loop.h $(srcdir)/debug.h $(srcdir)/server.h \
|
||||
$(srcdir)/general.h $(srcdir)/util-internal.h $(srcdir)/rr-iter.h $(srcdir)/rr-dict.h $(srcdir)/gldns/gbuffer.h \
|
||||
$(srcdir)/gldns/pkthdr.h $(srcdir)/dnssec.h $(srcdir)/gldns/rrdef.h $(srcdir)/stub.h $(srcdir)/gldns/wire2str.h
|
||||
$(srcdir)/types-internal.h $(srcdir)/util/rbtree.h $(srcdir)/util/orig-headers/rbtree.h \
|
||||
$(srcdir)/extension/default_eventloop.h $(srcdir)/extension/poll_eventloop.h \
|
||||
$(srcdir)/types-internal.h $(srcdir)/ub_loop.h $(srcdir)/debug.h $(srcdir)/server.h $(srcdir)/util/lruhash.h \
|
||||
$(srcdir)/util/orig-headers/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/orig-headers/locks.h \
|
||||
$(srcdir)/util/auxiliary/util/log.h $(srcdir)/debug.h $(srcdir)/general.h $(srcdir)/util-internal.h $(srcdir)/rr-iter.h \
|
||||
$(srcdir)/rr-dict.h $(srcdir)/gldns/gbuffer.h $(srcdir)/gldns/pkthdr.h $(srcdir)/dnssec.h $(srcdir)/gldns/rrdef.h $(srcdir)/stub.h \
|
||||
$(srcdir)/gldns/wire2str.h
|
||||
ub_loop.lo ub_loop.o: $(srcdir)/ub_loop.c $(srcdir)/ub_loop.h \
|
||||
config.h \
|
||||
getdns/getdns.h \
|
||||
getdns/getdns_extra.h \
|
||||
$(srcdir)/types-internal.h $(srcdir)/util/rbtree.h $(srcdir)/debug.h
|
||||
$(srcdir)/types-internal.h $(srcdir)/util/rbtree.h $(srcdir)/util/orig-headers/rbtree.h $(srcdir)/debug.h
|
||||
util-internal.lo util-internal.o: $(srcdir)/util-internal.c \
|
||||
config.h \
|
||||
getdns/getdns.h \
|
||||
$(srcdir)/dict.h $(srcdir)/util/rbtree.h $(srcdir)/types-internal.h \
|
||||
$(srcdir)/dict.h $(srcdir)/util/rbtree.h $(srcdir)/util/orig-headers/rbtree.h $(srcdir)/types-internal.h \
|
||||
getdns/getdns_extra.h \
|
||||
$(srcdir)/list.h $(srcdir)/util-internal.h $(srcdir)/context.h $(srcdir)/extension/default_eventloop.h \
|
||||
$(srcdir)/extension/poll_eventloop.h $(srcdir)/types-internal.h $(srcdir)/ub_loop.h $(srcdir)/debug.h $(srcdir)/server.h \
|
||||
$(srcdir)/rr-iter.h $(srcdir)/rr-dict.h $(srcdir)/gldns/gbuffer.h $(srcdir)/gldns/pkthdr.h $(srcdir)/gldns/str2wire.h \
|
||||
$(srcdir)/gldns/rrdef.h $(srcdir)/dnssec.h $(srcdir)/gldns/rrdef.h
|
||||
$(srcdir)/util/lruhash.h $(srcdir)/util/orig-headers/lruhash.h $(srcdir)/util/locks.h \
|
||||
$(srcdir)/util/orig-headers/locks.h $(srcdir)/util/auxiliary/util/log.h $(srcdir)/debug.h $(srcdir)/rr-iter.h \
|
||||
$(srcdir)/rr-dict.h $(srcdir)/gldns/gbuffer.h $(srcdir)/gldns/pkthdr.h $(srcdir)/gldns/str2wire.h $(srcdir)/gldns/rrdef.h \
|
||||
$(srcdir)/dnssec.h $(srcdir)/gldns/rrdef.h
|
||||
gbuffer.lo gbuffer.o: $(srcdir)/gldns/gbuffer.c \
|
||||
config.h \
|
||||
$(srcdir)/gldns/gbuffer.h
|
||||
|
@ -406,41 +444,59 @@ sha512.lo sha512.o: $(srcdir)/compat/sha512.c \
|
|||
config.h
|
||||
strlcpy.lo strlcpy.o: $(srcdir)/compat/strlcpy.c \
|
||||
config.h
|
||||
locks.lo locks.o: $(srcdir)/util/locks.c \
|
||||
config.h \
|
||||
$(srcdir)/util/locks.h $(srcdir)/util/orig-headers/locks.h $(srcdir)/util/auxiliary/util/log.h $(srcdir)/debug.h
|
||||
lookup3.lo lookup3.o: $(srcdir)/util/lookup3.c \
|
||||
config.h \
|
||||
$(srcdir)/util/auxiliary/util/storage/lookup3.h $(srcdir)/util/lookup3.h \
|
||||
$(srcdir)/util/orig-headers/lookup3.h
|
||||
lruhash.lo lruhash.o: $(srcdir)/util/lruhash.c \
|
||||
config.h \
|
||||
$(srcdir)/util/auxiliary/util/storage/lruhash.h $(srcdir)/util/lruhash.h \
|
||||
$(srcdir)/util/orig-headers/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/orig-headers/locks.h \
|
||||
$(srcdir)/util/auxiliary/util/log.h $(srcdir)/debug.h $(srcdir)/util/auxiliary/util/fptr_wlist.h
|
||||
rbtree.lo rbtree.o: $(srcdir)/util/rbtree.c \
|
||||
config.h \
|
||||
$(srcdir)/util/log.h $(srcdir)/debug.h $(srcdir)/util/fptr_wlist.h $(srcdir)/util/rbtree.h
|
||||
$(srcdir)/util/auxiliary/log.h $(srcdir)/util/auxiliary/util/log.h $(srcdir)/debug.h \
|
||||
$(srcdir)/util/auxiliary/fptr_wlist.h $(srcdir)/util/auxiliary/util/fptr_wlist.h \
|
||||
$(srcdir)/util/rbtree.h $(srcdir)/util/orig-headers/rbtree.h
|
||||
val_secalgo.lo val_secalgo.o: $(srcdir)/util/val_secalgo.c \
|
||||
config.h \
|
||||
$(srcdir)/util/val_secalgo.h $(srcdir)/util/log.h $(srcdir)/debug.h $(srcdir)/gldns/rrdef.h $(srcdir)/gldns/keyraw.h \
|
||||
$(srcdir)/gldns/gbuffer.h
|
||||
$(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 $(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
|
||||
libev.lo libev.o: $(srcdir)/extension/libev.c \
|
||||
config.h \
|
||||
$(srcdir)/types-internal.h \
|
||||
getdns/getdns.h \
|
||||
getdns/getdns_extra.h \
|
||||
$(srcdir)/util/rbtree.h $(srcdir)/getdns/getdns_ext_libev.h
|
||||
$(srcdir)/util/rbtree.h $(srcdir)/util/orig-headers/rbtree.h $(srcdir)/getdns/getdns_ext_libev.h
|
||||
libevent.lo libevent.o: $(srcdir)/extension/libevent.c \
|
||||
config.h \
|
||||
$(srcdir)/types-internal.h \
|
||||
getdns/getdns.h \
|
||||
getdns/getdns_extra.h \
|
||||
$(srcdir)/util/rbtree.h $(srcdir)/getdns/getdns_ext_libevent.h
|
||||
$(srcdir)/util/rbtree.h $(srcdir)/util/orig-headers/rbtree.h $(srcdir)/getdns/getdns_ext_libevent.h
|
||||
libuv.lo libuv.o: $(srcdir)/extension/libuv.c \
|
||||
config.h \
|
||||
$(srcdir)/debug.h $(srcdir)/types-internal.h \
|
||||
getdns/getdns.h \
|
||||
getdns/getdns_extra.h \
|
||||
$(srcdir)/util/rbtree.h $(srcdir)/getdns/getdns_ext_libuv.h
|
||||
$(srcdir)/util/rbtree.h $(srcdir)/util/orig-headers/rbtree.h $(srcdir)/getdns/getdns_ext_libuv.h
|
||||
poll_eventloop.lo poll_eventloop.o: $(srcdir)/extension/poll_eventloop.c \
|
||||
config.h \
|
||||
$(srcdir)/extension/poll_eventloop.h \
|
||||
getdns/getdns.h \
|
||||
getdns/getdns_extra.h \
|
||||
$(srcdir)/types-internal.h $(srcdir)/util/rbtree.h $(srcdir)/debug.h
|
||||
$(srcdir)/types-internal.h $(srcdir)/util/rbtree.h $(srcdir)/util/orig-headers/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
|
||||
$(srcdir)/debug.h $(srcdir)/types-internal.h $(srcdir)/util/rbtree.h $(srcdir)/util/orig-headers/rbtree.h
|
||||
|
|
|
@ -34,7 +34,7 @@
|
|||
#include "config.h"
|
||||
#define LOCKRET(func) func
|
||||
|
||||
#ifdef HAVE_PTHREADS
|
||||
#ifdef HAVE_PTHREAD
|
||||
#include "pthread.h"
|
||||
|
||||
static pthread_mutex_t arc_lock = PTHREAD_MUTEX_INITIALIZER;
|
||||
|
|
|
@ -62,7 +62,7 @@ typedef unsigned short in_port_t;
|
|||
#include <assert.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#ifdef HAVE_PTHREADS
|
||||
#ifdef HAVE_PTHREAD
|
||||
#include <pthread.h>
|
||||
#endif
|
||||
#include <stdbool.h>
|
||||
|
@ -93,11 +93,21 @@ typedef unsigned short in_port_t;
|
|||
upstream. Using 1 hour for all transports - based on RFC7858 value for for TLS.*/
|
||||
#define BACKOFF_RETRY 3600
|
||||
|
||||
#ifdef HAVE_PTHREADS
|
||||
#ifdef HAVE_PTHREAD
|
||||
static pthread_mutex_t ssl_init_lock = PTHREAD_MUTEX_INITIALIZER;
|
||||
#endif
|
||||
static bool ssl_init=false;
|
||||
|
||||
#ifdef HAVE_MDNS_SUPPORT
|
||||
/*
|
||||
* Forward declaration of MDNS context init and destroy function.
|
||||
* We do this here instead of including mdns.h, in order to
|
||||
* minimize dependencies.
|
||||
*/
|
||||
void _getdns_mdns_context_init(struct getdns_context *context);
|
||||
void _getdns_mdns_context_destroy(struct getdns_context *context);
|
||||
#endif
|
||||
|
||||
void *plain_mem_funcs_user_arg = MF_PLAIN;
|
||||
|
||||
typedef struct host_name_addrs {
|
||||
|
@ -817,9 +827,22 @@ tls_only_is_in_transports_list(getdns_context *context) {
|
|||
static int
|
||||
net_req_query_id_cmp(const void *id1, const void *id2)
|
||||
{
|
||||
return (intptr_t)id1 - (intptr_t)id2;
|
||||
/*
|
||||
* old code was:
|
||||
* return (intptr_t)id1 - (intptr_t)id2;
|
||||
*but this is incorrect on 64 bit architectures.
|
||||
*/
|
||||
int ret = 0;
|
||||
|
||||
if (id1 != id2)
|
||||
{
|
||||
ret = ((intptr_t)id1 < (intptr_t)id2) ? -1 : 1;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static getdns_tsig_info const tsig_info[] = {
|
||||
{ GETDNS_NO_TSIG, NULL, 0, NULL, 0, 0, 0 }
|
||||
, { GETDNS_HMAC_MD5 , "hmac-md5.sig-alg.reg.int", 24
|
||||
|
@ -1463,7 +1486,7 @@ getdns_context_create_with_extended_memory_functions(
|
|||
/* 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. */
|
||||
|
||||
#ifdef HAVE_PTHREADS
|
||||
#ifdef HAVE_PTHREAD
|
||||
pthread_mutex_lock(&ssl_init_lock);
|
||||
#else
|
||||
/* XXX implement Windows-style lock here */
|
||||
|
@ -1473,7 +1496,7 @@ getdns_context_create_with_extended_memory_functions(
|
|||
SSL_library_init();
|
||||
ssl_init = true;
|
||||
}
|
||||
#ifdef HAVE_PTHREADS
|
||||
#ifdef HAVE_PTHREAD
|
||||
pthread_mutex_unlock(&ssl_init_lock);
|
||||
#else
|
||||
/* XXX implement Windows-style unlock here */
|
||||
|
@ -1485,8 +1508,14 @@ getdns_context_create_with_extended_memory_functions(
|
|||
goto error;
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef HAVE_MDNS_SUPPORT
|
||||
_getdns_mdns_context_init(result);
|
||||
#endif
|
||||
|
||||
create_local_hosts(result);
|
||||
|
||||
|
||||
*context = result;
|
||||
return GETDNS_RETURN_GOOD;
|
||||
error:
|
||||
|
@ -1566,6 +1595,13 @@ getdns_context_destroy(struct getdns_context *context)
|
|||
ub_ctx_delete(context->unbound_ctx);
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_MDNS_SUPPORT
|
||||
/*
|
||||
* Release all ressource allocated for MDNS.
|
||||
*/
|
||||
_getdns_mdns_context_destroy(context);
|
||||
#endif
|
||||
|
||||
if (context->namespaces)
|
||||
GETDNS_FREE(context->my_mf, context->namespaces);
|
||||
|
||||
|
|
|
@ -45,6 +45,9 @@
|
|||
#include "util/rbtree.h"
|
||||
#include "ub_loop.h"
|
||||
#include "server.h"
|
||||
#ifdef HAVE_MDNS_SUPPORT
|
||||
#include "util/lruhash.h"
|
||||
#endif
|
||||
|
||||
struct getdns_dns_req;
|
||||
struct ub_ctx;
|
||||
|
@ -344,6 +347,23 @@ struct getdns_context {
|
|||
/* We need to run WSAStartup() to be able to use getaddrinfo() */
|
||||
WSADATA wsaData;
|
||||
#endif
|
||||
|
||||
/* MDNS */
|
||||
#ifdef HAVE_MDNS_SUPPORT
|
||||
/*
|
||||
* If supporting MDNS, context may be instantiated either in basic mode
|
||||
* or in full mode. If working in extended mode, two multicast sockets are
|
||||
* left open, for IPv4 and IPv6. Data can be received on either socket.
|
||||
* The context also keeps a list of open queries, characterized by a
|
||||
* name and an RR type, and a list of received answers, characterized
|
||||
* by name, RR type and data value.
|
||||
*/
|
||||
int mdns_extended_support; /* 0 = no support, 1 = supported, 2 = initialization needed */
|
||||
int mdns_connection_nb; /* typically 0 or 2 for IPv4 and IPv6 */
|
||||
struct mdns_network_connection * mdns_connection;
|
||||
struct lruhash * mdns_cache;
|
||||
|
||||
#endif /* HAVE_MDNS_SUPPORT */
|
||||
}; /* getdns_context */
|
||||
|
||||
/** internal functions **/
|
||||
|
|
10
src/debug.h
10
src/debug.h
|
@ -128,6 +128,7 @@
|
|||
|
||||
#define MDNS_DEBUG_ENTRY "-> MDNS ENTRY: "
|
||||
#define MDNS_DEBUG_READ "-- MDNS READ: "
|
||||
#define MDNS_DEBUG_MREAD "-- MDNS MREAD: "
|
||||
#define MDNS_DEBUG_WRITE "-- MDNS WRITE: "
|
||||
#define MDNS_DEBUG_CLEANUP "-- MDNS CLEANUP:"
|
||||
|
||||
|
@ -138,5 +139,14 @@
|
|||
#define DEBUG_MDNS(...) DEBUG_OFF(__VA_ARGS__)
|
||||
#endif
|
||||
|
||||
#if (defined(SCHED_DEBUG) && SCHED_DEBUG) || \
|
||||
(defined(STUB_DEBUG) && STUB_DEBUG) || \
|
||||
(defined(DAEMON_DEBUG) && DAEMON_DEBUG) || \
|
||||
(defined(SEC_DEBUG) && SEC_DEBUG) || \
|
||||
(defined(SERVER_DEBUG) && SERVER_DEBUG) || \
|
||||
(defined(MDNS_DEBUG) && MDNS_DEBUG)
|
||||
#define DEBUGGING 1
|
||||
#endif
|
||||
|
||||
#endif
|
||||
/* debug.h */
|
||||
|
|
|
@ -110,7 +110,8 @@ _getdns_check_dns_req_complete(getdns_dns_req *dns_req)
|
|||
|
||||
/* Do we have to check more suffixes on nxdomain/nodata?
|
||||
*/
|
||||
if (dns_req->suffix_appended && /* Something was appended */
|
||||
if (dns_req->is_dns_request &&
|
||||
dns_req->suffix_appended && /* Something was appended */
|
||||
dns_req->suffix_len > 1 && /* Next suffix available */
|
||||
no_answer(dns_req)) {
|
||||
/* Remove suffix from name */
|
||||
|
@ -146,6 +147,7 @@ _getdns_check_dns_req_complete(getdns_dns_req *dns_req)
|
|||
return;
|
||||
}
|
||||
} else if (
|
||||
dns_req->is_dns_request &&
|
||||
( dns_req->append_name ==
|
||||
GETDNS_APPEND_NAME_ONLY_TO_SINGLE_LABEL_AFTER_FAILURE ||
|
||||
dns_req->append_name ==
|
||||
|
@ -189,7 +191,9 @@ _getdns_check_dns_req_complete(getdns_dns_req *dns_req)
|
|||
dns_req->internal_cb(dns_req);
|
||||
} else if (! results_found)
|
||||
_getdns_call_user_callback(dns_req, NULL);
|
||||
else if (dns_req->dnssec_return_validation_chain
|
||||
else if (
|
||||
dns_req->is_dns_request &&
|
||||
(dns_req->dnssec_return_validation_chain
|
||||
#ifdef DNSSEC_ROADBLOCK_AVOIDANCE
|
||||
|| ( dns_req->dnssec_roadblock_avoidance
|
||||
&& !dns_req->avoid_dnssec_roadblocks)
|
||||
|
@ -202,7 +206,7 @@ _getdns_check_dns_req_complete(getdns_dns_req *dns_req)
|
|||
dns_req->dnssec_return_all_statuses
|
||||
))
|
||||
#endif
|
||||
)
|
||||
))
|
||||
_getdns_get_validation_chain(dns_req);
|
||||
else
|
||||
_getdns_call_user_callback(
|
||||
|
@ -301,7 +305,7 @@ _getdns_netreq_change_state(
|
|||
uint64_t now_ms;
|
||||
getdns_network_req *prev;
|
||||
|
||||
if (!netreq)
|
||||
if (!netreq || !netreq->owner->is_dns_request)
|
||||
return;
|
||||
|
||||
context = netreq->owner->context;
|
||||
|
@ -571,7 +575,7 @@ getdns_general_ns(getdns_context *context, getdns_eventloop *loop,
|
|||
|
||||
if (!(r = _getdns_context_local_namespace_resolve(
|
||||
req, &localnames_response))) {
|
||||
|
||||
req->is_dns_request = 0;
|
||||
_getdns_call_user_callback
|
||||
( req, localnames_response);
|
||||
break;
|
||||
|
@ -581,6 +585,7 @@ getdns_general_ns(getdns_context *context, getdns_eventloop *loop,
|
|||
/* Check whether the name belongs in the MDNS space */
|
||||
if (!(r = _getdns_mdns_namespace_check(req)))
|
||||
{
|
||||
req->is_dns_request = 0;
|
||||
// Submit the query to the MDNS transport.
|
||||
for (netreq_p = req->netreqs
|
||||
; !r && (netreq = *netreq_p)
|
||||
|
|
1852
src/mdns.c
1852
src/mdns.c
File diff suppressed because it is too large
Load Diff
86
src/mdns.h
86
src/mdns.h
|
@ -24,12 +24,98 @@
|
|||
#ifdef HAVE_MDNS_SUPPORT
|
||||
#include "getdns/getdns.h"
|
||||
#include "types-internal.h"
|
||||
#include "util/lruhash.h"
|
||||
#include "config.h"
|
||||
|
||||
#ifndef USE_WINSOCK
|
||||
#define SOCKADDR_STORAGE struct sockaddr_storage
|
||||
#endif
|
||||
|
||||
getdns_return_t
|
||||
_getdns_submit_mdns_request(getdns_network_req *netreq);
|
||||
|
||||
getdns_return_t
|
||||
_getdns_mdns_namespace_check(getdns_dns_req *dnsreq);
|
||||
|
||||
/*
|
||||
* data structure for continuous queries
|
||||
*/
|
||||
|
||||
typedef struct getdns_mdns_known_record
|
||||
{
|
||||
/* For storage in context->mdns_known_records_by_value */
|
||||
_getdns_rbnode_t node;
|
||||
uint64_t insertion_microsec;
|
||||
uint16_t record_type;
|
||||
uint16_t record_class;
|
||||
uint32_t ttl;
|
||||
int name_len;
|
||||
int record_data_len;
|
||||
uint8_t* name;
|
||||
uint8_t * record_data;
|
||||
} getdns_mdns_known_record;
|
||||
|
||||
/*
|
||||
* Each entry in the hash table is keyed by type, class and name.
|
||||
* The key structure also contains the LRU hash entry structure.
|
||||
* The data part contains:
|
||||
* - 64 bit time stamp
|
||||
* - 32 bit word describing the record size
|
||||
* - 32 bit word describing teh allocated memory size
|
||||
* - valid DNS response, including 1 query and N answers, 0 AUTH, 0 AD.
|
||||
* For economy, the names of all answers are encoded using header compression, pointing
|
||||
* to the name in the query, i.e. offset 12 from beginning of message.
|
||||
* For stability, the names included in the data part of records are not compressed.
|
||||
*/
|
||||
|
||||
typedef struct getdns_mdns_cached_key_header
|
||||
{
|
||||
/* embedded entry, for LRU hash */
|
||||
struct lruhash_entry entry;
|
||||
/* identification */
|
||||
uint16_t record_type;
|
||||
uint16_t record_class;
|
||||
int name_len;
|
||||
/* the octets following this structure contain the name */
|
||||
} getdns_mdns_cached_key_header;
|
||||
|
||||
typedef struct getdns_mdns_cached_record_header
|
||||
{
|
||||
uint64_t insertion_microsec;
|
||||
uint32_t content_len;
|
||||
uint32_t allocated_length;
|
||||
/* list of user queries */
|
||||
getdns_network_req *netreq_first;
|
||||
} getdns_mdns_cached_record_header;
|
||||
|
||||
typedef struct getdns_mdns_continuous_query
|
||||
{
|
||||
/* For storage in context->mdns_continuous_queries_by_name_rrtype */
|
||||
_getdns_rbnode_t node;
|
||||
uint8_t name[256]; /* binary representation of name being queried */
|
||||
int name_len;
|
||||
uint16_t request_class;
|
||||
uint16_t request_type;
|
||||
/* list of user queries */
|
||||
getdns_network_req *netreq_first;
|
||||
/* todo: do we need an expiration date, or a timer? */
|
||||
/* todo: do we need an update mark for showing last results? */
|
||||
} getdns_mdns_continuous_query;
|
||||
|
||||
typedef struct mdns_network_connection
|
||||
{
|
||||
struct getdns_context* context;
|
||||
int fd;
|
||||
int addr_mcast_len;
|
||||
SOCKADDR_STORAGE addr_mcast;
|
||||
getdns_eventloop_event event;
|
||||
uint8_t response[1500];
|
||||
} mdns_network_connection;
|
||||
|
||||
|
||||
void _getdns_mdns_context_init(struct getdns_context *context);
|
||||
void _getdns_mdns_context_destroy(struct getdns_context *context);
|
||||
|
||||
#endif /* HAVE_MDNS_SUPPORT */
|
||||
|
||||
#endif /* MDNS_H */
|
||||
|
|
|
@ -938,6 +938,7 @@ _getdns_dns_req_new(getdns_context *context, getdns_eventloop *loop,
|
|||
result->finished_next = NULL;
|
||||
result->freed = NULL;
|
||||
result->validating = 0;
|
||||
result->is_dns_request = 1;
|
||||
result->chain = NULL;
|
||||
|
||||
network_req_init(result->netreqs[0], result,
|
||||
|
|
26
src/server.c
26
src/server.c
|
@ -135,7 +135,11 @@ static void tcp_connection_destroy(tcp_connection *conn)
|
|||
loop->vmt->clear(loop, &conn->event);
|
||||
|
||||
if (conn->fd >= 0)
|
||||
#ifdef USE_WINSOCK
|
||||
(void) closesocket(conn->fd);
|
||||
#else
|
||||
(void) close(conn->fd);
|
||||
#endif
|
||||
GETDNS_FREE(*mf, conn->read_buf);
|
||||
|
||||
for (cur = conn->to_write; cur; cur = next) {
|
||||
|
@ -185,8 +189,8 @@ static void tcp_write_cb(void *userarg)
|
|||
}
|
||||
to_write = conn->to_write;
|
||||
if (conn->fd == -1 ||
|
||||
(written = write(conn->fd, &to_write->write_buf[to_write->written],
|
||||
to_write->write_buf_len - to_write->written)) == -1) {
|
||||
(written = send(conn->fd, &to_write->write_buf[to_write->written],
|
||||
to_write->write_buf_len - to_write->written, 0)) == -1) {
|
||||
|
||||
/* IO error, close connection */
|
||||
conn->event.read_cb = conn->event.write_cb =
|
||||
|
@ -280,7 +284,11 @@ getdns_reply(
|
|||
(struct sockaddr *)&conn->remote_in, conn->addrlen) == -1) {
|
||||
/* IO error, cleanup this listener */
|
||||
loop->vmt->clear(loop, &conn->l->event);
|
||||
#ifdef USE_WINSOCK
|
||||
closesocket(conn->l->fd);
|
||||
#else
|
||||
close(conn->l->fd);
|
||||
#endif
|
||||
conn->l->fd = -1;
|
||||
}
|
||||
/* Unlink this connection */
|
||||
|
@ -359,7 +367,7 @@ static void tcp_read_cb(void *userarg)
|
|||
(void) loop->vmt->schedule(loop, conn->fd,
|
||||
DOWNSTREAM_IDLE_TIMEOUT, &conn->event);
|
||||
|
||||
if ((bytes_read = read(conn->fd, conn->read_pos, conn->to_read)) < 0) {
|
||||
if ((bytes_read = recv(conn->fd, conn->read_pos, conn->to_read, 0)) < 0) {
|
||||
if (errno == EAGAIN || errno == EWOULDBLOCK)
|
||||
return; /* Come back to do the read later */
|
||||
|
||||
|
@ -473,7 +481,11 @@ static void tcp_accept_cb(void *userarg)
|
|||
&conn->super.remote_in, &conn->super.addrlen)) == -1) {
|
||||
/* IO error, cleanup this listener */
|
||||
loop->vmt->clear(loop, &l->event);
|
||||
#ifdef USE_WINSOCK
|
||||
closesocket(l->fd);
|
||||
#else
|
||||
close(l->fd);
|
||||
#endif
|
||||
l->fd = -1;
|
||||
GETDNS_FREE(*mf, conn);
|
||||
return;
|
||||
|
@ -543,7 +555,11 @@ static void udp_read_cb(void *userarg)
|
|||
(struct sockaddr *)&conn->remote_in, &conn->addrlen)) == -1) {
|
||||
/* IO error, cleanup this listener. */
|
||||
loop->vmt->clear(loop, &l->event);
|
||||
#ifdef USE_WINSOCK
|
||||
closesocket(l->fd);
|
||||
#else
|
||||
close(l->fd);
|
||||
#endif
|
||||
l->fd = -1;
|
||||
|
||||
#if 0 && defined(SERVER_DEBUG) && SERVER_DEBUG
|
||||
|
@ -692,7 +708,11 @@ static void remove_listeners(listen_set *set)
|
|||
continue;
|
||||
|
||||
loop->vmt->clear(loop, &l->event);
|
||||
#ifdef USE_WINSOCK
|
||||
closesocket(l->fd);
|
||||
#else
|
||||
close(l->fd);
|
||||
#endif
|
||||
l->fd = -1;
|
||||
|
||||
if (l->transport != GETDNS_TRANSPORT_TCP)
|
||||
|
|
|
@ -15,7 +15,8 @@ rm -f report.txt
|
|||
echo "*** running out of filedescriptors (sockets) and for the"
|
||||
echo "*** limit_outstanding_queries feature."
|
||||
echo "*** "
|
||||
grep '[^!=]=[ ][ ]*NET_REQ_' *.[ch] */*.[ch]
|
||||
grep -n '[^!=]=[ ][ ]*NET_REQ_' *.[ch] */*.[ch] | \
|
||||
grep -v '^request-internal.c:[12][0-9][0-9]: *net_req->state = NET_REQ_NOT_SENT;$'
|
||||
echo ""
|
||||
fi
|
||||
) >> report.txt
|
||||
|
@ -28,7 +29,7 @@ rm -f report.txt
|
|||
echo "*** __FUNC__ is aliases in config.h to name to be used"
|
||||
echo "*** for the system with a #define"
|
||||
echo "*** "
|
||||
grep '__FUNCION__' *.[ch] */*.[ch]
|
||||
grep -n '__FUNCTION__' *.[ch] */*.[ch]
|
||||
echo ""
|
||||
fi
|
||||
) >> report.txt
|
||||
|
|
|
@ -183,7 +183,6 @@ typedef struct getdns_tcp_state {
|
|||
|
||||
} getdns_tcp_state;
|
||||
|
||||
|
||||
/**
|
||||
* Request data
|
||||
**/
|
||||
|
@ -191,6 +190,12 @@ typedef struct getdns_network_req
|
|||
{
|
||||
/* For storage in upstream->netreq_by_query_id */
|
||||
_getdns_rbnode_t node;
|
||||
#ifdef HAVE_MDNS_SUPPORT
|
||||
/*
|
||||
* for storage of continuous query context in hash table of cached results.
|
||||
*/
|
||||
struct getdns_network_req * mdns_netreq_next;
|
||||
#endif /* HAVE_MDNS_SUPPORT */
|
||||
/* the async_id from unbound */
|
||||
int unbound_id;
|
||||
/* state var */
|
||||
|
@ -308,6 +313,7 @@ typedef struct getdns_dns_req {
|
|||
/* Internally used by return_validation_chain */
|
||||
unsigned dnssec_ok_checking_disabled : 1;
|
||||
unsigned is_sync_request : 1;
|
||||
unsigned is_dns_request : 1;
|
||||
|
||||
/* The validating and freed variables are used to make sure a single
|
||||
* code path is followed while processing a DNS request, even when
|
||||
|
|
|
@ -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
|
||||
|
||||
# Meant to be run from this directory
|
||||
REPO=http://unbound.net/svn/trunk
|
||||
|
||||
mkdir ub || true
|
||||
cd ub
|
||||
for f in rbtree.c rbtree.h
|
||||
do
|
||||
wget http://unbound.net/svn/trunk/util/$f || \
|
||||
ftp http://unbound.net/svn/trunk/util/$f || continue
|
||||
sed -e 's/event_/_getdns_event_/g' \
|
||||
-e 's/signal_add/_getdns_signal_add/g' \
|
||||
-e 's/signal_del/_getdns_signal_del/g' \
|
||||
-e 's/signal_set/_getdns_signal_set/g' \
|
||||
-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
|
||||
wget -O rbtree.c ${REPO}/util/rbtree.c
|
||||
wget -O orig-headers/rbtree.h ${REPO}/util/rbtree.h
|
||||
wget -O val_secalgo.c ${REPO}/validator/val_secalgo.c
|
||||
wget -O orig-headers/val_secalgo.h ${REPO}/validator/val_secalgo.h
|
||||
wget -O lruhash.c ${REPO}/util/storage/lruhash.c
|
||||
wget -O orig-headers/lruhash.h ${REPO}/util/storage/lruhash.h
|
||||
wget -O lookup3.c ${REPO}/util/storage/lookup3.c
|
||||
wget -O orig-headers/lookup3.h ${REPO}/util/storage/lookup3.h
|
||||
wget -O locks.c ${REPO}/util/locks.c
|
||||
wget -O orig-headers/locks.h ${REPO}/util/locks.h
|
||||
|
|
|
@ -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.
|
||||
*
|
||||
* 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
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#ifndef LOOKUP3_H_SYMBOLS
|
||||
#define LOOKUP3_H_SYMBOLS
|
||||
|
||||
#ifndef UTIL_LOG_H
|
||||
#define UTIL_LOG_H
|
||||
#define hashword _getdns_hashword
|
||||
#define hashlittle _getdns_hashlittle
|
||||
#define hash_set_raninit _getdns_hash_set_raninit
|
||||
|
||||
#include "config.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(...)
|
||||
#include "util/orig-headers/lookup3.h"
|
||||
#endif
|
||||
|
||||
#define log_assert(x)
|
||||
|
||||
#endif /* UTIL_LOG_H */
|
||||
|
|
@ -0,0 +1,631 @@
|
|||
/*
|
||||
* 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);
|
||||
}
|
||||
|
||||
/*
|
||||
* Demote: the opposite of touch, move an entry to the bottom
|
||||
* of the LRU pile.
|
||||
*/
|
||||
|
||||
void
|
||||
lru_demote(struct lruhash* table, struct lruhash_entry* entry)
|
||||
{
|
||||
log_assert(table && entry);
|
||||
if (entry == table->lru_end)
|
||||
return; /* nothing to do */
|
||||
/* remove from current lru position */
|
||||
lru_remove(table, entry);
|
||||
/* add at end */
|
||||
entry->lru_next = NULL;
|
||||
entry->lru_prev = table->lru_end;
|
||||
|
||||
if (table->lru_end == NULL)
|
||||
{
|
||||
table->lru_start = entry;
|
||||
}
|
||||
else
|
||||
{
|
||||
table->lru_end->lru_next = entry;
|
||||
}
|
||||
table->lru_end = entry;
|
||||
}
|
||||
|
||||
struct lruhash_entry*
|
||||
lruhash_insert_or_retrieve(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)) != NULL) {
|
||||
/* if so: keep the existing data - acquire a writelock */
|
||||
lock_rw_wrlock(&found->lock);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* 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;
|
||||
/* return the entry that was presented, and lock it */
|
||||
found = entry;
|
||||
lock_rw_wrlock(&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;
|
||||
}
|
||||
|
||||
/* return the entry that was selected */
|
||||
return found;
|
||||
}
|
||||
|
|
@ -0,0 +1,71 @@
|
|||
/**
|
||||
*
|
||||
* \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 lru_demote _getdns_lru_demote
|
||||
#define lruhash_insert_or_retrieve _getdns_lruhash_insert_or_retrieve
|
||||
|
||||
#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,446 @@
|
|||
/*
|
||||
* 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);
|
||||
|
||||
/************************* getdns functions ************************/
|
||||
/*** these are used by getdns only and not by unbound. ***/
|
||||
|
||||
/**
|
||||
* Demote entry, so it becomes the least 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 last in LRU.
|
||||
*/
|
||||
void lru_demote(struct lruhash* table, struct lruhash_entry* entry);
|
||||
|
||||
/**
|
||||
* Insert a new element into the hashtable, or retrieve the corresponding
|
||||
* element of it exits.
|
||||
*
|
||||
* If key is already present data pointer in that entry is kept.
|
||||
* If it is not present, a new entry is created. In that case,
|
||||
* 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.
|
||||
* @param data: the data.
|
||||
* @param cb_override: if not null overrides the cb_arg for the deletefunc.
|
||||
* @return: pointer to the existing entry if the key was already present,
|
||||
* or to the entry argument if it was not.
|
||||
*/
|
||||
struct lruhash_entry* lruhash_insert_or_retrieve(struct lruhash* table, hashvalue_type hash,
|
||||
struct lruhash_entry* entry, void* data, void* cb_arg);
|
||||
|
||||
/************************* 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 "util/log.h"
|
||||
#include "util/fptr_wlist.h"
|
||||
#include "log.h"
|
||||
#include "fptr_wlist.h"
|
||||
#include "util/rbtree.h"
|
||||
|
||||
/** Node colour black */
|
||||
|
@ -50,7 +50,7 @@
|
|||
#define RED 1
|
||||
|
||||
/** the NULL node, global alloc */
|
||||
_getdns_rbnode_t _getdns_rbtree_null_node = {
|
||||
rbnode_type rbtree_null_node = {
|
||||
RBTREE_NULL, /* Parent. */
|
||||
RBTREE_NULL, /* Left. */
|
||||
RBTREE_NULL, /* Right. */
|
||||
|
@ -59,13 +59,14 @@ _getdns_rbnode_t _getdns_rbtree_null_node = {
|
|||
};
|
||||
|
||||
/** 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) */
|
||||
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 */
|
||||
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 */
|
||||
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.
|
||||
|
@ -73,25 +74,25 @@ static void _getdns_rbtree_delete_fixup(_getdns_rbtree_t* rbtree, _getdns_rbnode
|
|||
* Return NULL on failure.
|
||||
*
|
||||
*/
|
||||
_getdns_rbtree_t *
|
||||
_getdns_rbtree_create (int (*cmpf)(const void *, const void *))
|
||||
rbtree_type *
|
||||
rbtree_create (int (*cmpf)(const void *, const void *))
|
||||
{
|
||||
_getdns_rbtree_t *rbtree;
|
||||
rbtree_type *rbtree;
|
||||
|
||||
/* Allocate memory for it */
|
||||
rbtree = (_getdns_rbtree_t *) malloc(sizeof(_getdns_rbtree_t));
|
||||
rbtree = (rbtree_type *) malloc(sizeof(rbtree_type));
|
||||
if (!rbtree) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Initialize it */
|
||||
_getdns_rbtree_init(rbtree, cmpf);
|
||||
rbtree_init(rbtree, cmpf);
|
||||
|
||||
return rbtree;
|
||||
}
|
||||
|
||||
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 */
|
||||
rbtree->root = RBTREE_NULL;
|
||||
|
@ -104,9 +105,9 @@ _getdns_rbtree_init(_getdns_rbtree_t *rbtree, int (*cmpf)(const void *, const vo
|
|||
*
|
||||
*/
|
||||
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;
|
||||
if (right->left != RBTREE_NULL)
|
||||
right->left->parent = node;
|
||||
|
@ -131,9 +132,9 @@ _getdns_rbtree_rotate_left(_getdns_rbtree_t *rbtree, _getdns_rbnode_t *node)
|
|||
*
|
||||
*/
|
||||
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;
|
||||
if (left->right != RBTREE_NULL)
|
||||
left->right->parent = node;
|
||||
|
@ -154,9 +155,9 @@ _getdns_rbtree_rotate_right(_getdns_rbtree_t *rbtree, _getdns_rbnode_t *node)
|
|||
}
|
||||
|
||||
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 (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? */
|
||||
if (node == node->parent->right) {
|
||||
node = node->parent;
|
||||
_getdns_rbtree_rotate_left(rbtree, node);
|
||||
rbtree_rotate_left(rbtree, node);
|
||||
}
|
||||
/* Now we're the left child, repaint and rotate... */
|
||||
node->parent->color = BLACK;
|
||||
node->parent->parent->color = RED;
|
||||
_getdns_rbtree_rotate_right(rbtree, node->parent->parent);
|
||||
rbtree_rotate_right(rbtree, node->parent->parent);
|
||||
}
|
||||
} else {
|
||||
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? */
|
||||
if (node == node->parent->left) {
|
||||
node = node->parent;
|
||||
_getdns_rbtree_rotate_right(rbtree, node);
|
||||
rbtree_rotate_right(rbtree, node);
|
||||
}
|
||||
/* Now we're the right child, repaint and rotate... */
|
||||
node->parent->color = BLACK;
|
||||
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
|
||||
* otherwise.
|
||||
*/
|
||||
_getdns_rbnode_t *
|
||||
_getdns_rbtree_insert (_getdns_rbtree_t *rbtree, _getdns_rbnode_t *data)
|
||||
rbnode_type *
|
||||
rbtree_insert (rbtree_type *rbtree, rbnode_type *data)
|
||||
{
|
||||
/* XXX Not necessary, but keeps compiler quiet... */
|
||||
int r = 0;
|
||||
|
||||
/* We start at the root of the tree */
|
||||
_getdns_rbnode_t *node = rbtree->root;
|
||||
_getdns_rbnode_t *parent = RBTREE_NULL;
|
||||
rbnode_type *node = rbtree->root;
|
||||
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... */
|
||||
while (node != RBTREE_NULL) {
|
||||
/* 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... */
|
||||
_getdns_rbtree_insert_fixup(rbtree, data);
|
||||
rbtree_insert_fixup(rbtree, 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.
|
||||
*
|
||||
*/
|
||||
_getdns_rbnode_t *
|
||||
_getdns_rbtree_search (_getdns_rbtree_t *rbtree, const void *key)
|
||||
rbnode_type *
|
||||
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;
|
||||
} else {
|
||||
return NULL;
|
||||
|
@ -295,13 +296,14 @@ static void swap_int8(uint8_t* x, uint8_t* y)
|
|||
}
|
||||
|
||||
/** 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' */
|
||||
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)
|
||||
{
|
||||
|
@ -315,30 +317,31 @@ static void change_parent_ptr(_getdns_rbtree_t* rbtree, _getdns_rbnode_t* parent
|
|||
if(parent->right == old) parent->right = new;
|
||||
}
|
||||
/** 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;
|
||||
log_assert(child->parent == old || child->parent == new);
|
||||
if(child->parent == old) child->parent = new;
|
||||
}
|
||||
|
||||
_getdns_rbnode_t*
|
||||
_getdns_rbtree_delete(_getdns_rbtree_t *rbtree, const void *key)
|
||||
rbnode_type*
|
||||
rbtree_delete(rbtree_type *rbtree, const void *key)
|
||||
{
|
||||
_getdns_rbnode_t *to_delete;
|
||||
_getdns_rbnode_t *child;
|
||||
if((to_delete = _getdns_rbtree_search(rbtree, key)) == 0) return 0;
|
||||
rbnode_type *to_delete;
|
||||
rbnode_type *child;
|
||||
if((to_delete = rbtree_search(rbtree, key)) == 0) return 0;
|
||||
rbtree->count--;
|
||||
|
||||
/* make sure we have at most one non-leaf child */
|
||||
if(to_delete->left != RBTREE_NULL && to_delete->right != RBTREE_NULL)
|
||||
{
|
||||
/* 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)
|
||||
smright = smright->left;
|
||||
/* 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
|
||||
* 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 */
|
||||
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 */
|
||||
to_delete->parent = RBTREE_NULL;
|
||||
|
@ -400,9 +403,10 @@ _getdns_rbtree_delete(_getdns_rbtree_t *rbtree, const void *key)
|
|||
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;
|
||||
|
||||
/* 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;
|
||||
sibling->color = BLACK;
|
||||
if(child_parent->right == child)
|
||||
_getdns_rbtree_rotate_right(rbtree, child_parent);
|
||||
else _getdns_rbtree_rotate_left(rbtree, child_parent);
|
||||
rbtree_rotate_right(rbtree, child_parent);
|
||||
else rbtree_rotate_left(rbtree, child_parent);
|
||||
/* new sibling after rotation */
|
||||
if(child_parent->right == child) sibling = child_parent->left;
|
||||
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->right->color = BLACK;
|
||||
_getdns_rbtree_rotate_left(rbtree, sibling);
|
||||
rbtree_rotate_left(rbtree, sibling);
|
||||
/* new sibling after rotation */
|
||||
if(child_parent->right == child) sibling = child_parent->left;
|
||||
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->left->color = BLACK;
|
||||
_getdns_rbtree_rotate_right(rbtree, sibling);
|
||||
rbtree_rotate_right(rbtree, sibling);
|
||||
/* new sibling after rotation */
|
||||
if(child_parent->right == child) sibling = child_parent->left;
|
||||
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);
|
||||
sibling->left->color = BLACK;
|
||||
_getdns_rbtree_rotate_right(rbtree, child_parent);
|
||||
rbtree_rotate_right(rbtree, child_parent);
|
||||
}
|
||||
else
|
||||
{
|
||||
log_assert(sibling->right->color == RED);
|
||||
sibling->right->color = BLACK;
|
||||
_getdns_rbtree_rotate_left(rbtree, child_parent);
|
||||
rbtree_rotate_left(rbtree, child_parent);
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
_getdns_rbnode_t *node;
|
||||
rbnode_type *node;
|
||||
|
||||
log_assert(result);
|
||||
|
||||
|
@ -515,7 +520,7 @@ _getdns_rbtree_find_less_equal(_getdns_rbtree_t *rbtree, const void *key, _getdn
|
|||
node = rbtree->root;
|
||||
|
||||
*result = NULL;
|
||||
fptr_ok(fptr_whitelist__getdns_rbtree_cmp(rbtree->cmp));
|
||||
fptr_ok(fptr_whitelist_rbtree_cmp(rbtree->cmp));
|
||||
|
||||
/* While there are children... */
|
||||
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
|
||||
*
|
||||
*/
|
||||
_getdns_rbnode_t *
|
||||
_getdns_rbtree_first (_getdns_rbtree_t *rbtree)
|
||||
rbnode_type *
|
||||
rbtree_first (rbtree_type *rbtree)
|
||||
{
|
||||
_getdns_rbnode_t *node;
|
||||
rbnode_type *node;
|
||||
|
||||
for (node = rbtree->root; node->left != RBTREE_NULL; node = node->left);
|
||||
return node;
|
||||
}
|
||||
|
||||
_getdns_rbnode_t *
|
||||
_getdns_rbtree_last (_getdns_rbtree_t *rbtree)
|
||||
rbnode_type *
|
||||
rbtree_last (rbtree_type *rbtree)
|
||||
{
|
||||
_getdns_rbnode_t *node;
|
||||
rbnode_type *node;
|
||||
|
||||
for (node = rbtree->root; node->right != RBTREE_NULL; node = node->right);
|
||||
return node;
|
||||
|
@ -562,10 +567,10 @@ _getdns_rbtree_last (_getdns_rbtree_t *rbtree)
|
|||
* Returns the next node...
|
||||
*
|
||||
*/
|
||||
_getdns_rbnode_t *
|
||||
_getdns_rbtree_next (_getdns_rbnode_t *node)
|
||||
rbnode_type *
|
||||
rbtree_next (rbnode_type *node)
|
||||
{
|
||||
_getdns_rbnode_t *parent;
|
||||
rbnode_type *parent;
|
||||
|
||||
if (node->right != RBTREE_NULL) {
|
||||
/* One right, then keep on going left... */
|
||||
|
@ -581,10 +586,10 @@ _getdns_rbtree_next (_getdns_rbnode_t *node)
|
|||
return node;
|
||||
}
|
||||
|
||||
_getdns_rbnode_t *
|
||||
_getdns_rbtree_previous(_getdns_rbnode_t *node)
|
||||
rbnode_type *
|
||||
rbtree_previous(rbnode_type *node)
|
||||
{
|
||||
_getdns_rbnode_t *parent;
|
||||
rbnode_type *parent;
|
||||
|
||||
if (node->left != RBTREE_NULL) {
|
||||
/* One left, then keep on going right... */
|
||||
|
@ -602,19 +607,20 @@ _getdns_rbtree_previous(_getdns_rbnode_t *node)
|
|||
|
||||
/** recursive descent traverse */
|
||||
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)
|
||||
return;
|
||||
/* recurse */
|
||||
_getdns_traverse_post(func, arg, node->left);
|
||||
_getdns_traverse_post(func, arg, node->right);
|
||||
traverse_post(func, arg, node->left);
|
||||
traverse_post(func, arg, node->right);
|
||||
/* call user func */
|
||||
(*func)(node, arg);
|
||||
}
|
||||
|
||||
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
|
||||
* 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.
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* \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 _getdns_rbnode_t and the
|
||||
* user data (poor man's inheritance).
|
||||
*/
|
||||
typedef struct _getdns_rbnode_t _getdns_rbnode_t;
|
||||
/**
|
||||
* The _getdns_rbnode_t struct definition.
|
||||
*/
|
||||
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_ */
|
||||
#ifndef RBTREE_H_SYMBOLS
|
||||
#define RBTREE_H_SYMBOLS
|
||||
#define rbnode_type _getdns_rbnode_t
|
||||
#define rbtree_null_node _getdns_rbtree_null_node
|
||||
#define rbtree_type _getdns_rbtree_t
|
||||
#define rbtree_create _getdns_rbtree_create
|
||||
#define rbtree_init _getdns_rbtree_init
|
||||
#define rbtree_insert _getdns_rbtree_insert
|
||||
#define rbtree_delete _getdns_rbtree_delete
|
||||
#define rbtree_search _getdns_rbtree_search
|
||||
#define rbtree_find_less_equal _getdns_rbtree_find_less_equal
|
||||
#define rbtree_first _getdns_rbtree_first
|
||||
#define rbtree_last _getdns_rbtree_last
|
||||
#define rbtree_next _getdns_rbtree_next
|
||||
#define rbtree_previous _getdns_rbtree_previous
|
||||
#define traverse_postorder _getdns_traverse_postorder
|
||||
#include "util/orig-headers/rbtree.h"
|
||||
#endif
|
||||
|
|
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
|
||||
* 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
|
||||
* 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 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
|
||||
|
||||
/**
|
||||
* \file
|
||||
*
|
||||
* This file contains helper functions for the validator module.
|
||||
* The functions take buffers with raw data and convert to library calls.
|
||||
*/
|
||||
enum sec_status { sec_status_bogus = 0
|
||||
, sec_status_unchecked = 0
|
||||
, sec_status_insecure = 0
|
||||
, sec_status_secure = 1 };
|
||||
#define NSEC3_HASH_SHA1 0x01
|
||||
|
||||
#ifndef VALIDATOR_VAL_SECALGO_H
|
||||
#define VALIDATOR_VAL_SECALGO_H
|
||||
struct gldns_buffer;
|
||||
|
||||
/** Return size of nsec3 hash algorithm, 0 if not supported */
|
||||
size_t _getdns_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 _getdns_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 _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 */
|
||||
#define LDNS_SHA1 GLDNS_SHA1
|
||||
#define LDNS_SHA256 GLDNS_SHA256
|
||||
#define LDNS_SHA384 GLDNS_SHA384
|
||||
#define LDNS_HASH_GOST GLDNS_HASH_GOST
|
||||
#define LDNS_RSAMD5 GLDNS_RSAMD5
|
||||
#define LDNS_DSA GLDNS_DSA
|
||||
#define LDNS_DSA_NSEC3 GLDNS_DSA_NSEC3
|
||||
#define LDNS_RSASHA1 GLDNS_RSASHA1
|
||||
#define LDNS_RSASHA1_NSEC3 GLDNS_RSASHA1_NSEC3
|
||||
#define LDNS_RSASHA256 GLDNS_RSASHA256
|
||||
#define LDNS_RSASHA512 GLDNS_RSASHA512
|
||||
#define LDNS_ECDSAP256SHA256 GLDNS_ECDSAP256SHA256
|
||||
#define LDNS_ECDSAP384SHA384 GLDNS_ECDSAP384SHA384
|
||||
#define LDNS_ECC_GOST GLDNS_ECC_GOST
|
||||
#define sldns_key_EVP_load_gost_id gldns_key_EVP_load_gost_id
|
||||
#define sldns_digest_evp gldns_digest_evp
|
||||
#define sldns_key_buf2dsa_raw gldns_key_buf2dsa_raw
|
||||
#define sldns_key_buf2rsa_raw gldns_key_buf2rsa_raw
|
||||
#define sldns_gost2pkey_raw gldns_gost2pkey_raw
|
||||
#define sldns_ecdsa2pkey_raw gldns_ecdsa2pkey_raw
|
||||
#define sldns_buffer_begin gldns_buffer_begin
|
||||
#define sldns_buffer_limit gldns_buffer_limit
|
||||
#include "util/orig-headers/val_secalgo.h"
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue