mirror of https://github.com/getdnsapi/getdns.git
Merge in stock unbound
This commit is contained in:
commit
07dcd6cc0e
12
Makefile.in
12
Makefile.in
|
@ -18,7 +18,7 @@ VPATH = @srcdir@
|
|||
default:
|
||||
cd src && $(MAKE) $@
|
||||
|
||||
all : default
|
||||
all : default
|
||||
|
||||
install: all
|
||||
cd src && $(MAKE) $@
|
||||
|
@ -28,7 +28,7 @@ uninstall:
|
|||
cd src && $(MAKE) $@
|
||||
cd doc && $(MAKE) $@
|
||||
|
||||
doc:
|
||||
doc:
|
||||
cd doc && $(MAKE) $@
|
||||
|
||||
example:
|
||||
|
@ -37,6 +37,9 @@ example:
|
|||
test:
|
||||
cd src && $(MAKE) $@
|
||||
|
||||
example:
|
||||
cd src && $(MAKE) $@
|
||||
|
||||
clean:
|
||||
cd src && $(MAKE) $@
|
||||
cd doc && $(MAKE) $@
|
||||
|
@ -53,7 +56,7 @@ $(distdir).tar.gz: $(distdir)
|
|||
tar chof - $(distdir) | gzip -9 -c > $@
|
||||
rm -rf $(distdir)
|
||||
|
||||
$(distdir):
|
||||
$(distdir):
|
||||
mkdir -p $(distdir)/src
|
||||
mkdir -p $(distdir)/src/getdns
|
||||
mkdir -p $(distdir)/src/test
|
||||
|
@ -68,6 +71,7 @@ $(distdir):
|
|||
cp $(srcdir)/ltmain.sh $(distdir)
|
||||
cp $(srcdir)/src/*.in $(distdir)/src
|
||||
cp $(srcdir)/src/*.[ch] $(distdir)/src
|
||||
cp $(srcdir)/src/extension/*.[ch] $(distdir)/src/extension
|
||||
cp $(srcdir)/src/getdns/*.in $(distdir)/src/getdns
|
||||
cp $(srcdir)/src/getdns/*.h $(distdir)/src/getdns
|
||||
cp $(srcdir)/src/test/Makefile.in $(distdir)/src/test
|
||||
|
@ -98,7 +102,7 @@ distcheck: $(distdir).tar.gz
|
|||
|
||||
Makefile: Makefile.in config.status
|
||||
./config.status $@
|
||||
|
||||
|
||||
configure.status: configure
|
||||
./config.status --recheck
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
# Guess values for system-dependent variables and create Makefiles.
|
||||
# Generated by GNU Autoconf 2.69 for getdns 0.1.0.
|
||||
#
|
||||
# Report bugs to <melinda.shore@nomountain.net>.
|
||||
# Report bugs to <stub-resolver@verisignlabs.com>.
|
||||
#
|
||||
#
|
||||
# Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc.
|
||||
|
@ -275,7 +275,7 @@ fi
|
|||
$as_echo "$0: be upgraded to zsh 4.3.4 or later."
|
||||
else
|
||||
$as_echo "$0: Please tell bug-autoconf@gnu.org and
|
||||
$0: melinda.shore@nomountain.net about your system,
|
||||
$0: stub-resolver@verisignlabs.com about your system,
|
||||
$0: including any error possibly output before this
|
||||
$0: message. Then install a modern shell, or manually run
|
||||
$0: the script under such a shell if you do have one."
|
||||
|
@ -592,7 +592,7 @@ PACKAGE_NAME='getdns'
|
|||
PACKAGE_TARNAME='getdns'
|
||||
PACKAGE_VERSION='0.1.0'
|
||||
PACKAGE_STRING='getdns 0.1.0'
|
||||
PACKAGE_BUGREPORT='melinda.shore@nomountain.net'
|
||||
PACKAGE_BUGREPORT='stub-resolver@verisignlabs.com'
|
||||
PACKAGE_URL=''
|
||||
|
||||
ac_unique_file="src/getdns/getdns.h"
|
||||
|
@ -634,6 +634,7 @@ ac_includes_default="\
|
|||
|
||||
ac_subst_vars='LTLIBOBJS
|
||||
LIBOBJS
|
||||
have_libevent
|
||||
DOXYGEN
|
||||
INSTALL_DATA
|
||||
INSTALL_SCRIPT
|
||||
|
@ -1386,7 +1387,7 @@ Some influential environment variables:
|
|||
Use these variables to override the choices made by `configure' or to help
|
||||
it to find libraries and programs with nonstandard names/locations.
|
||||
|
||||
Report bugs to <melinda.shore@nomountain.net>.
|
||||
Report bugs to <stub-resolver@verisignlabs.com>.
|
||||
_ACEOF
|
||||
ac_status=$?
|
||||
fi
|
||||
|
@ -10853,127 +10854,8 @@ fi
|
|||
|
||||
# Checks for libraries.
|
||||
found_all_libs=1
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: Checking for dependencies libevent, ldns" >&5
|
||||
$as_echo "$as_me: Checking for dependencies libevent, ldns" >&6;}
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing event_loop" >&5
|
||||
$as_echo_n "checking for library containing event_loop... " >&6; }
|
||||
if ${ac_cv_search_event_loop+:} false; then :
|
||||
$as_echo_n "(cached) " >&6
|
||||
else
|
||||
ac_func_search_save_LIBS=$LIBS
|
||||
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||
/* end confdefs.h. */
|
||||
|
||||
/* Override any GCC internal prototype to avoid an error.
|
||||
Use char because int might match the return type of a GCC
|
||||
builtin and then its argument prototype would still apply. */
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
#endif
|
||||
char event_loop ();
|
||||
int
|
||||
main ()
|
||||
{
|
||||
return event_loop ();
|
||||
;
|
||||
return 0;
|
||||
}
|
||||
_ACEOF
|
||||
for ac_lib in '' event_core event; do
|
||||
if test -z "$ac_lib"; then
|
||||
ac_res="none required"
|
||||
else
|
||||
ac_res=-l$ac_lib
|
||||
LIBS="-l$ac_lib $ac_func_search_save_LIBS"
|
||||
fi
|
||||
if ac_fn_c_try_link "$LINENO"; then :
|
||||
ac_cv_search_event_loop=$ac_res
|
||||
fi
|
||||
rm -f core conftest.err conftest.$ac_objext \
|
||||
conftest$ac_exeext
|
||||
if ${ac_cv_search_event_loop+:} false; then :
|
||||
break
|
||||
fi
|
||||
done
|
||||
if ${ac_cv_search_event_loop+:} false; then :
|
||||
|
||||
else
|
||||
ac_cv_search_event_loop=no
|
||||
fi
|
||||
rm conftest.$ac_ext
|
||||
LIBS=$ac_func_search_save_LIBS
|
||||
fi
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_event_loop" >&5
|
||||
$as_echo "$ac_cv_search_event_loop" >&6; }
|
||||
ac_res=$ac_cv_search_event_loop
|
||||
if test "$ac_res" != no; then :
|
||||
test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
|
||||
|
||||
else
|
||||
|
||||
ac_cv_search_event_loop=''
|
||||
LDFLAGS="$LDFLAGS -L/usr/local/lib/event"
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing event_loop" >&5
|
||||
$as_echo_n "checking for library containing event_loop... " >&6; }
|
||||
if ${ac_cv_search_event_loop+:} false; then :
|
||||
$as_echo_n "(cached) " >&6
|
||||
else
|
||||
ac_func_search_save_LIBS=$LIBS
|
||||
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||
/* end confdefs.h. */
|
||||
|
||||
/* Override any GCC internal prototype to avoid an error.
|
||||
Use char because int might match the return type of a GCC
|
||||
builtin and then its argument prototype would still apply. */
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
#endif
|
||||
char event_loop ();
|
||||
int
|
||||
main ()
|
||||
{
|
||||
return event_loop ();
|
||||
;
|
||||
return 0;
|
||||
}
|
||||
_ACEOF
|
||||
for ac_lib in '' event_core event; do
|
||||
if test -z "$ac_lib"; then
|
||||
ac_res="none required"
|
||||
else
|
||||
ac_res=-l$ac_lib
|
||||
LIBS="-l$ac_lib $ac_func_search_save_LIBS"
|
||||
fi
|
||||
if ac_fn_c_try_link "$LINENO"; then :
|
||||
ac_cv_search_event_loop=$ac_res
|
||||
fi
|
||||
rm -f core conftest.err conftest.$ac_objext \
|
||||
conftest$ac_exeext
|
||||
if ${ac_cv_search_event_loop+:} false; then :
|
||||
break
|
||||
fi
|
||||
done
|
||||
if ${ac_cv_search_event_loop+:} false; then :
|
||||
|
||||
else
|
||||
ac_cv_search_event_loop=no
|
||||
fi
|
||||
rm conftest.$ac_ext
|
||||
LIBS=$ac_func_search_save_LIBS
|
||||
fi
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_event_loop" >&5
|
||||
$as_echo "$ac_cv_search_event_loop" >&6; }
|
||||
ac_res=$ac_cv_search_event_loop
|
||||
if test "$ac_res" != no; then :
|
||||
test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
|
||||
|
||||
else
|
||||
found_all_libs=0
|
||||
fi
|
||||
|
||||
|
||||
fi
|
||||
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: Checking for dependencies ldns" >&5
|
||||
$as_echo "$as_me: Checking for dependencies ldns" >&6;}
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ldns_dname_new_frm_str in -lldns" >&5
|
||||
$as_echo_n "checking for ldns_dname_new_frm_str in -lldns... " >&6; }
|
||||
if ${ac_cv_lib_ldns_ldns_dname_new_frm_str+:} false; then :
|
||||
|
@ -11079,9 +10961,9 @@ fi
|
|||
found_libunbound=1
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: Checking for dependency libunbound" >&5
|
||||
$as_echo "$as_me: Checking for dependency libunbound" >&6;}
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ub_ctx_set_event in -lunbound" >&5
|
||||
$as_echo_n "checking for ub_ctx_set_event in -lunbound... " >&6; }
|
||||
if ${ac_cv_lib_unbound_ub_ctx_set_event+:} false; then :
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ub_fd in -lunbound" >&5
|
||||
$as_echo_n "checking for ub_fd in -lunbound... " >&6; }
|
||||
if ${ac_cv_lib_unbound_ub_fd+:} false; then :
|
||||
$as_echo_n "(cached) " >&6
|
||||
else
|
||||
ac_check_lib_save_LIBS=$LIBS
|
||||
|
@ -11095,27 +10977,27 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
|||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
#endif
|
||||
char ub_ctx_set_event ();
|
||||
char ub_fd ();
|
||||
int
|
||||
main ()
|
||||
{
|
||||
return ub_ctx_set_event ();
|
||||
return ub_fd ();
|
||||
;
|
||||
return 0;
|
||||
}
|
||||
_ACEOF
|
||||
if ac_fn_c_try_link "$LINENO"; then :
|
||||
ac_cv_lib_unbound_ub_ctx_set_event=yes
|
||||
ac_cv_lib_unbound_ub_fd=yes
|
||||
else
|
||||
ac_cv_lib_unbound_ub_ctx_set_event=no
|
||||
ac_cv_lib_unbound_ub_fd=no
|
||||
fi
|
||||
rm -f core conftest.err conftest.$ac_objext \
|
||||
conftest$ac_exeext conftest.$ac_ext
|
||||
LIBS=$ac_check_lib_save_LIBS
|
||||
fi
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_unbound_ub_ctx_set_event" >&5
|
||||
$as_echo "$ac_cv_lib_unbound_ub_ctx_set_event" >&6; }
|
||||
if test "x$ac_cv_lib_unbound_ub_ctx_set_event" = xyes; then :
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_unbound_ub_fd" >&5
|
||||
$as_echo "$ac_cv_lib_unbound_ub_fd" >&6; }
|
||||
if test "x$ac_cv_lib_unbound_ub_fd" = xyes; then :
|
||||
cat >>confdefs.h <<_ACEOF
|
||||
#define HAVE_LIBUNBOUND 1
|
||||
_ACEOF
|
||||
|
@ -11128,7 +11010,7 @@ fi
|
|||
|
||||
if test $found_libunbound == 0
|
||||
then
|
||||
as_fn_error $? "libunbound is missing or does not incude event code, you may need to patch your libunbound sources and rebuild. See the getdns build instructions" "$LINENO" 5
|
||||
as_fn_error $? "libunbound is missing." "$LINENO" 5
|
||||
fi
|
||||
|
||||
for ac_prog in doxygen
|
||||
|
@ -11261,7 +11143,64 @@ _ACEOF
|
|||
esac
|
||||
|
||||
|
||||
for ac_func in event_base_new event_base_free
|
||||
have_libevent=1
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing event_loop" >&5
|
||||
$as_echo_n "checking for library containing event_loop... " >&6; }
|
||||
if ${ac_cv_search_event_loop+:} false; then :
|
||||
$as_echo_n "(cached) " >&6
|
||||
else
|
||||
ac_func_search_save_LIBS=$LIBS
|
||||
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||
/* end confdefs.h. */
|
||||
|
||||
/* Override any GCC internal prototype to avoid an error.
|
||||
Use char because int might match the return type of a GCC
|
||||
builtin and then its argument prototype would still apply. */
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
#endif
|
||||
char event_loop ();
|
||||
int
|
||||
main ()
|
||||
{
|
||||
return event_loop ();
|
||||
;
|
||||
return 0;
|
||||
}
|
||||
_ACEOF
|
||||
for ac_lib in '' event_core event; do
|
||||
if test -z "$ac_lib"; then
|
||||
ac_res="none required"
|
||||
else
|
||||
ac_res=-l$ac_lib
|
||||
LIBS="-l$ac_lib $ac_func_search_save_LIBS"
|
||||
fi
|
||||
if ac_fn_c_try_link "$LINENO"; then :
|
||||
ac_cv_search_event_loop=$ac_res
|
||||
fi
|
||||
rm -f core conftest.err conftest.$ac_objext \
|
||||
conftest$ac_exeext
|
||||
if ${ac_cv_search_event_loop+:} false; then :
|
||||
break
|
||||
fi
|
||||
done
|
||||
if ${ac_cv_search_event_loop+:} false; then :
|
||||
|
||||
else
|
||||
ac_cv_search_event_loop=no
|
||||
fi
|
||||
rm conftest.$ac_ext
|
||||
LIBS=$ac_func_search_save_LIBS
|
||||
fi
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_event_loop" >&5
|
||||
$as_echo "$ac_cv_search_event_loop" >&6; }
|
||||
ac_res=$ac_cv_search_event_loop
|
||||
if test "$ac_res" != no; then :
|
||||
test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
|
||||
|
||||
$as_echo "#define HAVE_LIBEVENT 1" >>confdefs.h
|
||||
|
||||
for ac_func in event_base_new event_base_free
|
||||
do :
|
||||
as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
|
||||
ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
|
||||
|
@ -11274,6 +11213,11 @@ fi
|
|||
done
|
||||
|
||||
|
||||
else
|
||||
have_libevent=0
|
||||
fi
|
||||
|
||||
|
||||
|
||||
ac_config_files="$ac_config_files Makefile src/Makefile src/getdns/Makefile src/example/Makefile src/test/Makefile doc/Makefile"
|
||||
|
||||
|
@ -11849,7 +11793,7 @@ $config_headers
|
|||
Configuration commands:
|
||||
$config_commands
|
||||
|
||||
Report bugs to <melinda.shore@nomountain.net>."
|
||||
Report bugs to <stub-resolver@verisignlabs.com>."
|
||||
|
||||
_ACEOF
|
||||
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
|
||||
|
|
39
configure.ac
39
configure.ac
|
@ -6,7 +6,7 @@
|
|||
#
|
||||
|
||||
AC_PREREQ([2.56])
|
||||
AC_INIT([getdns], [0.1.0], [melinda.shore@nomountain.net])
|
||||
AC_INIT([getdns], [0.1.0], [stub-resolver@verisignlabs.com])
|
||||
AC_CONFIG_SRCDIR([src/getdns/getdns.h])
|
||||
# AM_INIT_AUTOMAKE
|
||||
# LT_INIT
|
||||
|
@ -128,12 +128,7 @@ fi
|
|||
|
||||
# Checks for libraries.
|
||||
found_all_libs=1
|
||||
AC_MSG_NOTICE([Checking for dependencies libevent, ldns])
|
||||
AC_SEARCH_LIBS([event_loop], [event_core event], [], [
|
||||
ac_cv_search_event_loop=''
|
||||
LDFLAGS="$LDFLAGS -L/usr/local/lib/event"
|
||||
AC_SEARCH_LIBS([event_loop], [event_core event], [], [found_all_libs=0])
|
||||
])
|
||||
AC_MSG_NOTICE([Checking for dependencies ldns])
|
||||
AC_CHECK_LIB([ldns], [ldns_dname_new_frm_str], [], [found_all_libs=0])
|
||||
AC_CHECK_LIB([idn], [idna_to_ascii_8z], [], [found_all_libs=0])
|
||||
|
||||
|
@ -142,14 +137,14 @@ then
|
|||
AC_MSG_ERROR([One more dependencies is missing])
|
||||
fi
|
||||
|
||||
# break out libunbound from other libraries since we are currently using a
|
||||
# break out libunbound from other libraries since we are currently using a
|
||||
# patch to the sources
|
||||
found_libunbound=1
|
||||
AC_MSG_NOTICE([Checking for dependency libunbound])
|
||||
AC_CHECK_LIB([unbound], [ub_ctx_set_event], [], [found_libunbound=0])
|
||||
AC_CHECK_LIB([unbound], [ub_fd], [], [found_libunbound=0])
|
||||
if test $found_libunbound == 0
|
||||
then
|
||||
AC_MSG_ERROR([libunbound is missing or does not incude event code, you may need to patch your libunbound sources and rebuild. See the getdns build instructions])
|
||||
AC_MSG_ERROR([libunbound is missing.])
|
||||
fi
|
||||
|
||||
AC_CHECK_PROGS([DOXYGEN], [doxygen])
|
||||
|
@ -167,16 +162,22 @@ AC_TYPE_UINT32_T
|
|||
AC_TYPE_UINT64_T
|
||||
AC_TYPE_UINT8_T
|
||||
|
||||
AC_CHECK_FUNCS([event_base_new event_base_free])
|
||||
AH_BOTTOM([
|
||||
#ifndef HAVE_EVENT_BASE_FREE
|
||||
#define event_base_free(x) /* nop */
|
||||
#endif
|
||||
#ifndef HAVE_EVENT_BASE_NEW
|
||||
#define event_base_new event_init
|
||||
#endif
|
||||
])
|
||||
have_libevent=1
|
||||
AC_SEARCH_LIBS([event_loop],
|
||||
[event_core event],
|
||||
[AC_DEFINE([HAVE_LIBEVENT], [1], [Define to 1 to enable the libevent extension])]
|
||||
[AC_CHECK_FUNCS([event_base_new event_base_free])]
|
||||
[AH_BOTTOM([
|
||||
#ifndef HAVE_EVENT_BASE_FREE
|
||||
#define event_base_free(x) /* nop */
|
||||
#endif
|
||||
#ifndef HAVE_EVENT_BASE_NEW
|
||||
#define event_base_new event_init
|
||||
#endif
|
||||
])],
|
||||
[have_libevent=0])
|
||||
|
||||
AC_SUBST(have_libevent)
|
||||
AC_CONFIG_FILES([Makefile src/Makefile src/getdns/Makefile src/example/Makefile src/test/Makefile doc/Makefile])
|
||||
if [ test -n "$DOXYGEN" ]
|
||||
then AC_CONFIG_FILES([src/Doxyfile])
|
||||
|
|
|
@ -20,6 +20,7 @@ exec_prefix = @exec_prefix@
|
|||
bindir = @bindir@
|
||||
libdir = @libdir@
|
||||
includedir = @includedir@
|
||||
have_libevent = @have_libevent@
|
||||
# datarootdir is here to please some checkers
|
||||
datarootdir=@datarootdir@
|
||||
INSTALL = @INSTALL@
|
||||
|
@ -35,6 +36,10 @@ GETDNS_OBJ=sync.lo context.lo list.lo dict.lo convert.lo general.lo \
|
|||
hostname.lo service.lo request-internal.lo validate_dnssec.lo \
|
||||
util-internal.lo getdns_error.lo rr-dict.lo validation-chain.lo
|
||||
|
||||
ifeq ($(have_libevent),1)
|
||||
GETDNS_OBJ += extension/libevent.lo
|
||||
endif
|
||||
|
||||
.SUFFIXES: .c .o .a .lo .h
|
||||
|
||||
.c.o:
|
||||
|
@ -54,24 +59,31 @@ install: libgetdns.la
|
|||
$(INSTALL) -m 755 -d $(DESTDIR)$(includedir)
|
||||
$(INSTALL) -m 755 -d $(DESTDIR)$(includedir)/getdns
|
||||
$(INSTALL) -m 644 $(srcdir)/getdns/getdns.h $(DESTDIR)$(includedir)/getdns/getdns.h
|
||||
ifeq ($(have_libevent),1)
|
||||
$(INSTALL) -m 644 $(srcdir)/getdns/getdns_ext_libevent.h $(DESTDIR)$(includedir)/getdns/
|
||||
endif
|
||||
$(INSTALL) -m 755 -d $(DESTDIR)$(libdir)
|
||||
$(LIBTOOL) --mode=install cp libgetdns.la $(DESTDIR)$(libdir)
|
||||
$(LIBTOOL) --mode=finish $(DESTDIR)$(libdir)
|
||||
|
||||
uninstall:
|
||||
rm -f $(DESTDIR)$(includedir)/getdns/getdns.h
|
||||
rm -rf $(DESTDIR)$(includedir)/getdns
|
||||
$(LIBTOOL) --mode=uninstall rm -f $(DESTDIR)$(libdir)/libgetdns.la
|
||||
|
||||
libgetdns.la: $(GETDNS_OBJ)
|
||||
$(LIBTOOL) --tag=CC --mode=link $(CC) $(CFLAGS) -o $@ $(GETDNS_OBJ) $(LDFLAGS) -rpath $(libdir) -version-info $(libversion) -no-undefined
|
||||
|
||||
test: libgetdns.la
|
||||
test:
|
||||
cd test && $(MAKE) $@
|
||||
|
||||
example:
|
||||
cd example && $(MAKE) $@
|
||||
|
||||
|
||||
clean:
|
||||
cd test && $(MAKE) $@
|
||||
cd example && $(MAKE) $@
|
||||
rm -f *.o *.lo $(PROGRAMS) libgetdns.la
|
||||
rm -f *.o *.lo extension/*.lo $(PROGRAMS) libgetdns.la
|
||||
rm -rf .libs
|
||||
|
||||
distclean : clean
|
||||
|
|
|
@ -15,6 +15,9 @@
|
|||
/* Define to 1 if you have the <inttypes.h> header file. */
|
||||
#undef HAVE_INTTYPES_H
|
||||
|
||||
/* Define to 1 to enable the libevent extension */
|
||||
#undef HAVE_LIBEVENT
|
||||
|
||||
/* Define to 1 if you have the `idn' library (-lidn). */
|
||||
#undef HAVE_LIBIDN
|
||||
|
||||
|
@ -111,10 +114,10 @@
|
|||
#undef uint8_t
|
||||
|
||||
|
||||
#ifndef HAVE_EVENT_BASE_FREE
|
||||
#define event_base_free(x) /* nop */
|
||||
#endif
|
||||
#ifndef HAVE_EVENT_BASE_NEW
|
||||
#define event_base_new event_init
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_EVENT_BASE_FREE
|
||||
#define event_base_free(x) /* nop */
|
||||
#endif
|
||||
#ifndef HAVE_EVENT_BASE_NEW
|
||||
#define event_base_new event_init
|
||||
#endif
|
||||
|
||||
|
|
368
src/context.c
368
src/context.c
|
@ -35,17 +35,12 @@
|
|||
*/
|
||||
|
||||
#include "config.h"
|
||||
#ifdef HAVE_EVENT2_EVENT_H
|
||||
# include <event2/event.h>
|
||||
#else
|
||||
# include <event.h>
|
||||
#endif
|
||||
#include <arpa/inet.h>
|
||||
#include <ldns/ldns.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unbound-event.h>
|
||||
#include <sys/time.h>
|
||||
#include <unbound.h>
|
||||
|
||||
#include "context.h"
|
||||
|
@ -64,11 +59,13 @@ static struct getdns_list *create_from_ldns_list(struct getdns_context *,
|
|||
ldns_rdf **, size_t);
|
||||
static getdns_return_t set_os_defaults(struct getdns_context *);
|
||||
static int transaction_id_cmp(const void *, const void *);
|
||||
static int timeout_cmp(const void *, const void *);
|
||||
static void set_ub_string_opt(struct getdns_context *, char *, char *);
|
||||
static void set_ub_number_opt(struct getdns_context *, char *, uint16_t);
|
||||
static inline void clear_resolution_type_set_flag(struct getdns_context *, uint16_t);
|
||||
static void dispatch_updated(struct getdns_context *, uint16_t);
|
||||
static void cancel_dns_req(getdns_dns_req *);
|
||||
static void cancel_outstanding_requests(struct getdns_context*, int);
|
||||
|
||||
/* Stuff to make it compile pedantically */
|
||||
#define UNUSED_PARAM(x) ((void)(x))
|
||||
|
@ -218,6 +215,9 @@ set_os_defaults(struct getdns_context *context)
|
|||
return GETDNS_RETURN_GOOD;
|
||||
} /* set_os_defaults */
|
||||
|
||||
/* compare of transaction ids in DESCENDING order
|
||||
so that 0 comes last
|
||||
*/
|
||||
static int
|
||||
transaction_id_cmp(const void *id1, const void *id2)
|
||||
{
|
||||
|
@ -234,7 +234,7 @@ transaction_id_cmp(const void *id1, const void *id2)
|
|||
*((const getdns_transaction_t *) id2);
|
||||
if (t1 == t2) {
|
||||
return 0;
|
||||
} else if (t1 < t2) {
|
||||
} else if (t1 > t2) {
|
||||
return -1;
|
||||
} else {
|
||||
return 1;
|
||||
|
@ -242,6 +242,33 @@ transaction_id_cmp(const void *id1, const void *id2)
|
|||
}
|
||||
}
|
||||
|
||||
static int timeout_cmp(const void *to1, const void *to2) {
|
||||
if (to1 == NULL && to2 == NULL) {
|
||||
return 0;
|
||||
} else if (to1 == NULL && to2 != NULL) {
|
||||
return 1;
|
||||
} else if (to1 != NULL && to2 == NULL) {
|
||||
return -1;
|
||||
} else {
|
||||
const getdns_timeout_data_t* t1 = (const getdns_timeout_data_t*) to1;
|
||||
const getdns_timeout_data_t* t2 = (const getdns_timeout_data_t*) to2;
|
||||
if (t1->timeout_time.tv_sec < t2->timeout_time.tv_sec) {
|
||||
return -1;
|
||||
} else if (t1->timeout_time.tv_sec > t2->timeout_time.tv_sec) {
|
||||
return 1;
|
||||
} else {
|
||||
/* compare usec.. */
|
||||
if (t1->timeout_time.tv_usec < t2->timeout_time.tv_usec) {
|
||||
return -1;
|
||||
} else if (t1->timeout_time.tv_usec > t2->timeout_time.tv_usec) {
|
||||
return 1;
|
||||
} else {
|
||||
return transaction_id_cmp(&t1->transaction_id, &t2->transaction_id);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* getdns_context_create
|
||||
*
|
||||
|
@ -283,11 +310,7 @@ getdns_context_create_with_extended_memory_functions(
|
|||
result->mf.mf.ext.realloc = realloc;
|
||||
result->mf.mf.ext.free = free;
|
||||
|
||||
result->event_base_sync = event_base_new();
|
||||
result->unbound_sync = ub_ctx_create_event(result->event_base_sync);
|
||||
/* create the async one also so options are kept up to date */
|
||||
result->unbound_async = ub_ctx_create_event(result->event_base_sync);
|
||||
result->event_base_async = NULL;
|
||||
result->unbound_ctx = ub_ctx_create();
|
||||
|
||||
result->resolution_type_set = 0;
|
||||
|
||||
|
@ -309,6 +332,11 @@ getdns_context_create_with_extended_memory_functions(
|
|||
result->edns_version = 0;
|
||||
result->edns_do_bit = 0;
|
||||
|
||||
result->extension = NULL;
|
||||
result->extension_data = NULL;
|
||||
result->timeouts_by_time = ldns_rbtree_create(timeout_cmp);
|
||||
result->timeouts_by_id = ldns_rbtree_create(transaction_id_cmp);
|
||||
|
||||
if (set_from_os) {
|
||||
if (GETDNS_RETURN_GOOD != set_os_defaults(result)) {
|
||||
getdns_context_destroy(result);
|
||||
|
@ -377,18 +405,19 @@ getdns_context_destroy(struct getdns_context *context)
|
|||
if (context->namespaces)
|
||||
GETDNS_FREE(context->my_mf, context->namespaces);
|
||||
|
||||
cancel_outstanding_requests(context, 0);
|
||||
|
||||
getdns_list_destroy(context->dns_root_servers);
|
||||
getdns_list_destroy(context->suffix);
|
||||
getdns_list_destroy(context->dnssec_trust_anchors);
|
||||
getdns_list_destroy(context->upstream_list);
|
||||
|
||||
/* destroy the ub context */
|
||||
ub_ctx_delete(context->unbound_async);
|
||||
ub_ctx_delete(context->unbound_sync);
|
||||
|
||||
event_base_free(context->event_base_sync);
|
||||
ub_ctx_delete(context->unbound_ctx);
|
||||
|
||||
ldns_rbtree_free(context->outbound_requests);
|
||||
ldns_rbtree_free(context->timeouts_by_id);
|
||||
ldns_rbtree_free(context->timeouts_by_time);
|
||||
|
||||
GETDNS_FREE(context->my_mf, context);
|
||||
return;
|
||||
|
@ -415,8 +444,7 @@ getdns_context_set_context_update_callback(struct getdns_context *context,
|
|||
static void
|
||||
set_ub_string_opt(struct getdns_context *ctx, char *opt, char *value)
|
||||
{
|
||||
ub_ctx_set_option(ctx->unbound_sync, opt, value);
|
||||
ub_ctx_set_option(ctx->unbound_async, opt, value);
|
||||
ub_ctx_set_option(ctx->unbound_ctx, opt, value);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -891,27 +919,6 @@ getdns_context_set_memory_functions(struct getdns_context *context,
|
|||
context, MF_PLAIN, mf.ext.malloc, mf.ext.realloc, mf.ext.free);
|
||||
} /* getdns_context_set_memory_functions*/
|
||||
|
||||
|
||||
/*
|
||||
* getdns_extension_set_libevent_base
|
||||
*
|
||||
*/
|
||||
getdns_return_t
|
||||
getdns_extension_set_libevent_base(struct getdns_context *context,
|
||||
struct event_base * this_event_base)
|
||||
{
|
||||
RETURN_IF_NULL(context, GETDNS_RETURN_BAD_CONTEXT);
|
||||
if (this_event_base) {
|
||||
ub_ctx_set_event(context->unbound_async, this_event_base);
|
||||
context->event_base_async = this_event_base;
|
||||
} else {
|
||||
ub_ctx_set_event(context->unbound_async,
|
||||
context->event_base_sync);
|
||||
context->event_base_async = NULL;
|
||||
}
|
||||
return GETDNS_RETURN_GOOD;
|
||||
} /* getdns_extension_set_libevent_base */
|
||||
|
||||
/* cancel the request */
|
||||
static void
|
||||
cancel_dns_req(getdns_dns_req * req)
|
||||
|
@ -921,7 +928,7 @@ cancel_dns_req(getdns_dns_req * req)
|
|||
if (netreq->state == NET_REQ_IN_FLIGHT) {
|
||||
/* for ev based ub, this should always prevent
|
||||
* the callback from firing */
|
||||
ub_cancel(req->unbound, netreq->unbound_id);
|
||||
ub_cancel(req->context->unbound_ctx, netreq->unbound_id);
|
||||
netreq->state = NET_REQ_CANCELED;
|
||||
} else if (netreq->state == NET_REQ_NOT_SENT) {
|
||||
netreq->state = NET_REQ_CANCELED;
|
||||
|
@ -1071,19 +1078,15 @@ getdns_context_prepare_for_resolution(struct getdns_context *context)
|
|||
return GETDNS_RETURN_BAD_CONTEXT;
|
||||
}
|
||||
/* set upstreams */
|
||||
ub_setup_stub(context->unbound_async, context->upstream_list,
|
||||
upstream_len);
|
||||
ub_setup_stub(context->unbound_sync, context->upstream_list,
|
||||
ub_setup_stub(context->unbound_ctx, context->upstream_list,
|
||||
upstream_len);
|
||||
/* use /etc/hosts */
|
||||
ub_ctx_hosts(context->unbound_sync, NULL);
|
||||
ub_ctx_hosts(context->unbound_async, NULL);
|
||||
ub_ctx_hosts(context->unbound_ctx, NULL);
|
||||
|
||||
} else if (context->resolution_type == GETDNS_CONTEXT_RECURSING) {
|
||||
/* set recursive */
|
||||
/* TODO: use the root servers via root hints file */
|
||||
ub_ctx_set_fwd(context->unbound_async, NULL);
|
||||
ub_ctx_set_fwd(context->unbound_sync, NULL);
|
||||
ub_ctx_set_fwd(context->unbound_ctx, NULL);
|
||||
|
||||
} else {
|
||||
/* bogus? */
|
||||
|
@ -1129,48 +1132,271 @@ getdns_context_clear_outbound_request(getdns_dns_req * req)
|
|||
return GETDNS_RETURN_GOOD;
|
||||
}
|
||||
|
||||
|
||||
|
||||
char *
|
||||
getdns_strdup(const struct mem_funcs *mfs, const char *s)
|
||||
{
|
||||
size_t sz = strlen(s) + 1;
|
||||
char *r = GETDNS_XMALLOC(*mfs, char, sz);
|
||||
if (r)
|
||||
return memcpy(r, s, sz);
|
||||
else
|
||||
return NULL;
|
||||
size_t sz = strlen(s) + 1;
|
||||
char *r = GETDNS_XMALLOC(*mfs, char, sz);
|
||||
if (r)
|
||||
return memcpy(r, s, sz);
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct getdns_bindata *
|
||||
getdns_bindata_copy(struct mem_funcs *mfs,
|
||||
const struct getdns_bindata *src)
|
||||
{
|
||||
struct getdns_bindata *dst;
|
||||
struct getdns_bindata *dst;
|
||||
|
||||
if (!src)
|
||||
return NULL;
|
||||
if (!src)
|
||||
return NULL;
|
||||
|
||||
dst = GETDNS_MALLOC(*mfs, struct getdns_bindata);
|
||||
if (!dst)
|
||||
return NULL;
|
||||
dst = GETDNS_MALLOC(*mfs, struct getdns_bindata);
|
||||
if (!dst)
|
||||
return NULL;
|
||||
|
||||
dst->size = src->size;
|
||||
dst->data = GETDNS_XMALLOC(*mfs, uint8_t, src->size);
|
||||
if (!dst->data) {
|
||||
GETDNS_FREE(*mfs, dst);
|
||||
return NULL;
|
||||
}
|
||||
(void) memcpy(dst->data, src->data, src->size);
|
||||
return dst;
|
||||
dst->size = src->size;
|
||||
dst->data = GETDNS_XMALLOC(*mfs, uint8_t, src->size);
|
||||
if (!dst->data) {
|
||||
GETDNS_FREE(*mfs, dst);
|
||||
return NULL;
|
||||
}
|
||||
(void) memcpy(dst->data, src->data, src->size);
|
||||
return dst;
|
||||
}
|
||||
|
||||
void
|
||||
getdns_bindata_destroy(struct mem_funcs *mfs,
|
||||
struct getdns_bindata *bindata)
|
||||
{
|
||||
if (!bindata)
|
||||
return;
|
||||
GETDNS_FREE(*mfs, bindata->data);
|
||||
GETDNS_FREE(*mfs, bindata);
|
||||
if (!bindata)
|
||||
return;
|
||||
GETDNS_FREE(*mfs, bindata->data);
|
||||
GETDNS_FREE(*mfs, bindata);
|
||||
}
|
||||
|
||||
/* get the fd */
|
||||
int getdns_context_fd(struct getdns_context* context) {
|
||||
RETURN_IF_NULL(context, -1);
|
||||
return ub_fd(context->unbound_ctx);
|
||||
}
|
||||
|
||||
int
|
||||
getdns_context_get_num_pending_requests(struct getdns_context* context,
|
||||
struct timeval* next_timeout) {
|
||||
RETURN_IF_NULL(context, GETDNS_RETURN_BAD_CONTEXT);
|
||||
int r = context->outbound_requests->count;
|
||||
if (r > 0) {
|
||||
if (!context->extension && next_timeout) {
|
||||
/* get the first timeout */
|
||||
ldns_rbnode_t* first = ldns_rbtree_first(context->timeouts_by_time);
|
||||
if (first) {
|
||||
getdns_timeout_data_t* timeout_data = (getdns_timeout_data_t*) first->data;
|
||||
*next_timeout = (timeout_data->timeout_time);
|
||||
}
|
||||
}
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
/* process async reqs */
|
||||
getdns_return_t getdns_context_process_async(struct getdns_context* context) {
|
||||
RETURN_IF_NULL(context, GETDNS_RETURN_BAD_CONTEXT);
|
||||
if (ub_poll(context->unbound_ctx)) {
|
||||
if (ub_process(context->unbound_ctx) != 0) {
|
||||
/* need an async return code? */
|
||||
return GETDNS_RETURN_GENERIC_ERROR;
|
||||
}
|
||||
}
|
||||
if (context->extension != NULL) {
|
||||
/* no need to process timeouts since it is delegated
|
||||
* to the extension */
|
||||
return GETDNS_RETURN_GOOD;
|
||||
}
|
||||
getdns_timeout_data_t key;
|
||||
/* set to 0 so it is the last timeout if we have
|
||||
* two with the same time */
|
||||
key.transaction_id = 0;
|
||||
if (gettimeofday(&key.timeout_time, NULL) != 0) {
|
||||
return GETDNS_RETURN_GENERIC_ERROR;
|
||||
}
|
||||
ldns_rbnode_t* next_timeout = ldns_rbtree_first(context->timeouts_by_time);
|
||||
while (next_timeout) {
|
||||
getdns_timeout_data_t* timeout_data = (getdns_timeout_data_t*) next_timeout->data;
|
||||
if (timeout_cmp(timeout_data, &key) > 0) {
|
||||
/* no more timeouts need to be fired. */
|
||||
break;
|
||||
}
|
||||
/* get the next_timeout */
|
||||
next_timeout = ldns_rbtree_next(next_timeout);
|
||||
/* delete the node */
|
||||
/* timeout data is freed in the clear_timeout */
|
||||
ldns_rbnode_t* to_del = ldns_rbtree_delete(context->timeouts_by_time, timeout_data);
|
||||
if (to_del) {
|
||||
/* should always exist .. */
|
||||
GETDNS_FREE(context->my_mf, to_del);
|
||||
}
|
||||
|
||||
/* fire the timeout */
|
||||
timeout_data->callback(timeout_data->userarg);
|
||||
}
|
||||
|
||||
return GETDNS_RETURN_GOOD;
|
||||
}
|
||||
|
||||
typedef struct timeout_accumulator {
|
||||
getdns_transaction_t* ids;
|
||||
int idx;
|
||||
} timeout_accumulator;
|
||||
|
||||
static void
|
||||
accumulate_outstanding_transactions(ldns_rbnode_t* node, void* arg) {
|
||||
timeout_accumulator* acc = (timeout_accumulator*) arg;
|
||||
acc->ids[acc->idx] = *((getdns_transaction_t*) node->key);
|
||||
acc->idx++;
|
||||
}
|
||||
|
||||
static void
|
||||
cancel_outstanding_requests(struct getdns_context* context, int fire_callback) {
|
||||
if (context->outbound_requests->count > 0) {
|
||||
timeout_accumulator acc;
|
||||
int i;
|
||||
acc.idx = 0;
|
||||
acc.ids = GETDNS_XMALLOC(context->my_mf, getdns_transaction_t, context->outbound_requests->count);
|
||||
ldns_traverse_postorder(context->outbound_requests, accumulate_outstanding_transactions, &acc);
|
||||
for (i = 0; i < acc.idx; ++i) {
|
||||
getdns_context_cancel_request(context, acc.ids[i], fire_callback);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
getdns_return_t
|
||||
getdns_extension_detach_eventloop(struct getdns_context* context)
|
||||
{
|
||||
RETURN_IF_NULL(context, GETDNS_RETURN_BAD_CONTEXT);
|
||||
getdns_return_t r = GETDNS_RETURN_GOOD;
|
||||
if (context->extension) {
|
||||
/* cancel all outstanding requests */
|
||||
cancel_outstanding_requests(context, 1);
|
||||
r = context->extension->cleanup_data(context, context->extension_data);
|
||||
if (r != GETDNS_RETURN_GOOD) {
|
||||
return r;
|
||||
}
|
||||
context->extension = NULL;
|
||||
context->extension_data = NULL;
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
getdns_return_t
|
||||
getdns_extension_set_eventloop(struct getdns_context* context,
|
||||
getdns_eventloop_extension* extension, void* extension_data)
|
||||
{
|
||||
RETURN_IF_NULL(context, GETDNS_RETURN_BAD_CONTEXT);
|
||||
RETURN_IF_NULL(extension, GETDNS_RETURN_INVALID_PARAMETER);
|
||||
getdns_return_t r = getdns_extension_detach_eventloop(context);
|
||||
if (r != GETDNS_RETURN_GOOD) {
|
||||
return r;
|
||||
}
|
||||
context->extension = extension;
|
||||
context->extension_data = extension_data;
|
||||
return GETDNS_RETURN_GOOD;
|
||||
}
|
||||
|
||||
getdns_return_t
|
||||
getdns_context_schedule_timeout(struct getdns_context* context,
|
||||
getdns_transaction_t id, uint16_t timeout, getdns_timeout_callback callback,
|
||||
void* userarg) {
|
||||
RETURN_IF_NULL(context, GETDNS_RETURN_BAD_CONTEXT);
|
||||
RETURN_IF_NULL(callback, GETDNS_RETURN_INVALID_PARAMETER);
|
||||
getdns_return_t result;
|
||||
/* create a timeout */
|
||||
getdns_timeout_data_t* timeout_data = GETDNS_MALLOC(context->my_mf, getdns_timeout_data_t);
|
||||
if (!timeout_data) {
|
||||
return GETDNS_RETURN_GENERIC_ERROR;
|
||||
}
|
||||
timeout_data->context = context;
|
||||
timeout_data->transaction_id = id;
|
||||
timeout_data->callback = callback;
|
||||
timeout_data->userarg = userarg;
|
||||
timeout_data->extension_timer = NULL;
|
||||
|
||||
/* insert into transaction tree */
|
||||
ldns_rbnode_t *node = GETDNS_MALLOC(context->my_mf, ldns_rbnode_t);
|
||||
if (!node) {
|
||||
GETDNS_FREE(context->my_mf, timeout_data);
|
||||
return GETDNS_RETURN_GENERIC_ERROR;
|
||||
}
|
||||
node->key = &(timeout_data->transaction_id);
|
||||
node->data = timeout_data;
|
||||
node->left = NULL;
|
||||
node->right = NULL;
|
||||
if (!ldns_rbtree_insert(context->timeouts_by_id, node)) {
|
||||
/* free the node */
|
||||
GETDNS_FREE(context->my_mf, timeout_data);
|
||||
GETDNS_FREE(context->my_mf, node);
|
||||
return GETDNS_RETURN_GENERIC_ERROR;
|
||||
}
|
||||
|
||||
if (context->extension) {
|
||||
result = context->extension->schedule_timeout(context, context->extension_data,
|
||||
timeout, timeout_data, &(timeout_data->extension_timer));
|
||||
} else {
|
||||
result = GETDNS_RETURN_GENERIC_ERROR;
|
||||
if (gettimeofday(&timeout_data->timeout_time, NULL) == 0) {
|
||||
/* increment */
|
||||
uint16_t num_secs = timeout / 1000;
|
||||
/* timeout is in millis */
|
||||
timeout_data->timeout_time.tv_sec += num_secs;
|
||||
|
||||
ldns_rbnode_t* id_node = GETDNS_MALLOC(context->my_mf, ldns_rbnode_t);
|
||||
if (id_node) {
|
||||
id_node->key = timeout_data;
|
||||
id_node->data = timeout_data;
|
||||
id_node->left = NULL;
|
||||
id_node->right = NULL;
|
||||
if (!ldns_rbtree_insert(context->timeouts_by_time, id_node)) {
|
||||
GETDNS_FREE(context->my_mf, id_node);
|
||||
} else {
|
||||
result = GETDNS_RETURN_GOOD;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (result != GETDNS_RETURN_GOOD) {
|
||||
GETDNS_FREE(context->my_mf, timeout_data);
|
||||
GETDNS_FREE(context->my_mf, node);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
getdns_return_t
|
||||
getdns_context_clear_timeout(struct getdns_context* context,
|
||||
getdns_transaction_t id) {
|
||||
RETURN_IF_NULL(context, GETDNS_RETURN_BAD_CONTEXT);
|
||||
/* find the timeout_data by id */
|
||||
ldns_rbnode_t* node = ldns_rbtree_delete(context->timeouts_by_id, &id);
|
||||
if (!node) {
|
||||
return GETDNS_RETURN_UNKNOWN_TRANSACTION;
|
||||
}
|
||||
getdns_timeout_data_t* timeout_data = (getdns_timeout_data_t*) node->data;
|
||||
GETDNS_FREE(context->my_mf, node);
|
||||
if (context->extension) {
|
||||
context->extension->clear_timeout(context, context->extension,
|
||||
timeout_data->extension_timer);
|
||||
} else {
|
||||
/* make sure it is removed from the timeout node */
|
||||
ldns_rbnode_t* to_del = ldns_rbtree_delete(context->timeouts_by_time, timeout_data);
|
||||
if (to_del) {
|
||||
GETDNS_FREE(context->my_mf, to_del);
|
||||
}
|
||||
}
|
||||
GETDNS_FREE(context->my_mf, timeout_data);
|
||||
return GETDNS_RETURN_GOOD;
|
||||
}
|
||||
|
||||
|
||||
/* context.c */
|
||||
|
|
|
@ -40,7 +40,6 @@
|
|||
#include <getdns/getdns.h>
|
||||
#include "types-internal.h"
|
||||
|
||||
struct event_base;
|
||||
struct getdns_dns_req;
|
||||
struct ldns_rbtree_t;
|
||||
struct ub_ctx;
|
||||
|
@ -70,15 +69,9 @@ struct getdns_context {
|
|||
struct mem_funcs mf;
|
||||
struct mem_funcs my_mf;
|
||||
|
||||
/* Event loop for sync requests */
|
||||
struct event_base *event_base_sync;
|
||||
/* Event loop for async requests */
|
||||
struct event_base *event_base_async;
|
||||
|
||||
/* The underlying unbound contexts that do
|
||||
* the real work */
|
||||
struct ub_ctx *unbound_sync;
|
||||
struct ub_ctx *unbound_async;
|
||||
struct ub_ctx *unbound_ctx;
|
||||
|
||||
/* which resolution type the contexts are configured for
|
||||
* 0 means nothing set
|
||||
|
@ -89,6 +82,26 @@ struct getdns_context {
|
|||
* outbound requests -> transaction to getdns_dns_req
|
||||
*/
|
||||
struct ldns_rbtree_t *outbound_requests;
|
||||
|
||||
/*
|
||||
* Event loop extension functions
|
||||
* These structs are static and should never be freed
|
||||
* since they are just a collection of function pointers
|
||||
*/
|
||||
getdns_eventloop_extension* extension;
|
||||
/*
|
||||
* Extension data that will be freed by the functions
|
||||
* in the extension struct
|
||||
*/
|
||||
void* extension_data;
|
||||
|
||||
/*
|
||||
* Timeout info one tree to manage timeout data
|
||||
* keyed by transaction id. Second to manage by
|
||||
* timeout time (ascending)
|
||||
*/
|
||||
struct ldns_rbtree_t *timeouts_by_id;
|
||||
struct ldns_rbtree_t *timeouts_by_time;
|
||||
};
|
||||
|
||||
/** internal functions **/
|
||||
|
@ -118,4 +131,20 @@ void getdns_bindata_destroy(
|
|||
struct mem_funcs *mfs,
|
||||
struct getdns_bindata *bindata);
|
||||
|
||||
/* extension stuff */
|
||||
getdns_return_t getdns_extension_set_eventloop(struct getdns_context* context,
|
||||
getdns_eventloop_extension* extension, void* extension_data);
|
||||
|
||||
getdns_return_t
|
||||
getdns_extension_detach_eventloop(struct getdns_context* context);
|
||||
|
||||
|
||||
/* timeout scheduling */
|
||||
getdns_return_t getdns_context_schedule_timeout(struct getdns_context* context,
|
||||
getdns_transaction_t id, uint16_t timeout, getdns_timeout_callback callback,
|
||||
void* userarg);
|
||||
|
||||
getdns_return_t getdns_context_clear_timeout(struct getdns_context* context,
|
||||
getdns_transaction_t id);
|
||||
|
||||
#endif /* _GETDNS_CONTEXT_H_ */
|
||||
|
|
|
@ -17,7 +17,7 @@ VPATH = @srcdir@
|
|||
|
||||
CC=gcc
|
||||
CFLAGS=@CFLAGS@ -Wall -I$(srcdir)/ -I$(srcdir)/../ -I/usr/local/include -std=c99
|
||||
LDFLAGS=@LDFLAGS@ -L. -L.. -L/usr/local/lib
|
||||
LDFLAGS=@LDFLAGS@ -L. -L.. -L$(srcdir)/../ -L/usr/local/lib
|
||||
LDLIBS=-lgetdns @LIBS@
|
||||
PROGRAMS=example-all-functions example-simple-answers example-tree example-synchronous example-reverse
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#include <getdns/getdns.h>
|
||||
#include "config.h"
|
||||
#include <getdns/getdns_ext_libevent.h>
|
||||
#ifdef HAVE_EVENT2_EVENT_H
|
||||
#include <event2/event.h>
|
||||
#else
|
||||
|
|
|
@ -0,0 +1,162 @@
|
|||
/**
|
||||
* \file
|
||||
* \brief Public interfaces to getdns, include in your application to use getdns API.
|
||||
*
|
||||
* This source was taken from the original pseudo-implementation by
|
||||
* Paul Hoffman.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 2013, NLNet Labs, Versign, 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 name of the <organization> nor the
|
||||
* names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL Verisign, Inc. BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <getdns/getdns_ext_libevent.h>
|
||||
#include "config.h"
|
||||
#include "context.h"
|
||||
#include <sys/time.h>
|
||||
|
||||
#ifdef HAVE_EVENT2_EVENT_H
|
||||
# include <event2/event.h>
|
||||
#else
|
||||
# include <event.h>
|
||||
# define evutil_socket_t int
|
||||
# define event_free free
|
||||
# define evtimer_new(b, cb, arg) event_new((b), -1, 0, (cb), (arg))
|
||||
#endif
|
||||
#define RETURN_IF_NULL(ptr, code) if(ptr == NULL) return code;
|
||||
|
||||
#ifndef HAVE_EVENT2_EVENT_H
|
||||
static struct event *
|
||||
event_new(struct event_base *b, evutil_socket_t fd, short ev, void* cb, void *arg)
|
||||
{
|
||||
struct event* e = (struct event*)calloc(1, sizeof(struct event));
|
||||
if(!e) return NULL;
|
||||
event_set(e, fd, ev, cb, arg);
|
||||
event_base_set(b, e);
|
||||
return e;
|
||||
}
|
||||
#endif /* no event2 */
|
||||
|
||||
/* extension info */
|
||||
struct event_data {
|
||||
struct event* event;
|
||||
struct event_base* event_base;
|
||||
};
|
||||
|
||||
/* lib event callbacks */
|
||||
static void
|
||||
getdns_libevent_cb(evutil_socket_t fd, short what, void *userarg) {
|
||||
struct getdns_context* context = (struct getdns_context*) userarg;
|
||||
getdns_context_process_async(context);
|
||||
}
|
||||
|
||||
static void
|
||||
getdns_libevent_timeout_cb(evutil_socket_t fd, short what, void* userarg) {
|
||||
getdns_timeout_data_t* timeout_data = (getdns_timeout_data_t*) userarg;
|
||||
timeout_data->callback(timeout_data->userarg);
|
||||
}
|
||||
|
||||
/* getdns extension functions */
|
||||
static getdns_return_t
|
||||
getdns_libevent_cleanup(struct getdns_context* context, void* data) {
|
||||
struct event_data *edata = (struct event_data*) data;
|
||||
event_del(edata->event);
|
||||
event_free(edata->event);
|
||||
free(edata);
|
||||
return GETDNS_RETURN_GOOD;
|
||||
}
|
||||
|
||||
static getdns_return_t
|
||||
getdns_libevent_schedule_timeout(struct getdns_context* context,
|
||||
void* eventloop_data, uint16_t timeout,
|
||||
getdns_timeout_data_t* timeout_data,
|
||||
void** eventloop_timer) {
|
||||
|
||||
struct timeval tv;
|
||||
struct event* ev = NULL;
|
||||
struct event_data* ev_data = (struct event_data*) eventloop_data;
|
||||
|
||||
tv.tv_sec = timeout / 1000;
|
||||
tv.tv_usec = (timeout % 1000) * 1000;
|
||||
|
||||
ev = evtimer_new(ev_data->event_base, getdns_libevent_timeout_cb, timeout_data);
|
||||
evtimer_add(ev, &tv);
|
||||
|
||||
*eventloop_timer = ev;
|
||||
return GETDNS_RETURN_GOOD;
|
||||
}
|
||||
|
||||
static getdns_return_t
|
||||
getdns_libevent_clear_timeout(struct getdns_context* context,
|
||||
void* eventloop_data, void** eventloop_timer) {
|
||||
struct event* ev = (struct event*) eventloop_timer;
|
||||
event_del(ev);
|
||||
event_free(ev);
|
||||
return GETDNS_RETURN_GOOD;
|
||||
}
|
||||
|
||||
|
||||
static getdns_eventloop_extension LIBEVENT_EXT = {
|
||||
getdns_libevent_cleanup,
|
||||
getdns_libevent_schedule_timeout,
|
||||
getdns_libevent_clear_timeout
|
||||
};
|
||||
|
||||
/*
|
||||
* getdns_extension_set_libevent_base
|
||||
*
|
||||
*/
|
||||
getdns_return_t
|
||||
getdns_extension_set_libevent_base(struct getdns_context *context,
|
||||
struct event_base * this_event_base)
|
||||
{
|
||||
RETURN_IF_NULL(context, GETDNS_RETURN_BAD_CONTEXT);
|
||||
RETURN_IF_NULL(this_event_base, GETDNS_RETURN_INVALID_PARAMETER);
|
||||
/* TODO: cleanup current extension base */
|
||||
getdns_return_t r = getdns_extension_detach_eventloop(context);
|
||||
if (r != GETDNS_RETURN_GOOD) {
|
||||
return r;
|
||||
}
|
||||
int fd = getdns_context_fd(context);
|
||||
struct event* getdns_event = event_new(this_event_base, fd, EV_READ | EV_PERSIST, getdns_libevent_cb, context);
|
||||
if (!getdns_event) {
|
||||
return GETDNS_RETURN_GENERIC_ERROR;
|
||||
}
|
||||
event_add(getdns_event, NULL);
|
||||
|
||||
/* TODO: use context functs? */
|
||||
struct event_data* ev_data = (struct event_data*) malloc(sizeof(struct event_data));
|
||||
if (!ev_data) {
|
||||
/* cleanup */
|
||||
event_del(getdns_event);
|
||||
event_free(getdns_event);
|
||||
return GETDNS_RETURN_GENERIC_ERROR;
|
||||
}
|
||||
ev_data->event = getdns_event;
|
||||
ev_data->event_base = this_event_base;
|
||||
|
||||
return getdns_extension_set_eventloop(context, &LIBEVENT_EXT, ev_data);
|
||||
} /* getdns_extension_set_libevent_base */
|
160
src/general.c
160
src/general.c
|
@ -35,17 +35,8 @@
|
|||
*/
|
||||
|
||||
#include "config.h"
|
||||
#ifdef HAVE_EVENT2_EVENT_H
|
||||
# include <event2/event.h>
|
||||
#else
|
||||
# include <event.h>
|
||||
# define evutil_socket_t int
|
||||
# define event_free free
|
||||
# define evtimer_new(b, cb, arg) event_new((b), -1, 0, (cb), (arg))
|
||||
#endif
|
||||
#include <string.h>
|
||||
#include <unbound.h>
|
||||
#include <unbound-event.h>
|
||||
#include <ldns/ldns.h>
|
||||
#include "context.h"
|
||||
#include "types-internal.h"
|
||||
|
@ -57,11 +48,9 @@
|
|||
#define UNUSED_PARAM(x) ((void)(x))
|
||||
|
||||
/* declarations */
|
||||
static void ub_resolve_callback(void *arg, int err, void* result,
|
||||
int packet_len, int sec, char *bogus);
|
||||
static void ub_resolve_timeout(evutil_socket_t fd, short what, void *arg);
|
||||
static void ub_local_resolve_timeout(evutil_socket_t fd, short what,
|
||||
void *arg);
|
||||
static void ub_resolve_callback(void* mydata, int err, struct ub_result* result);
|
||||
static void ub_resolve_timeout(void *arg);
|
||||
static void ub_local_resolve_timeout(void *arg);
|
||||
|
||||
static void handle_network_request_error(getdns_network_req * netreq, int err);
|
||||
static void handle_dns_request_complete(getdns_dns_req * dns_req);
|
||||
|
@ -71,27 +60,12 @@ typedef struct netreq_cb_data
|
|||
{
|
||||
getdns_network_req *netreq;
|
||||
int err;
|
||||
void *result;
|
||||
int packet_len;
|
||||
int sec;
|
||||
char *bogus;
|
||||
struct ub_result* ub_res;
|
||||
} netreq_cb_data;
|
||||
|
||||
#ifndef HAVE_EVENT2_EVENT_H
|
||||
static struct event *
|
||||
event_new(struct event_base *b, evutil_socket_t fd, short ev, void* cb, void *arg)
|
||||
{
|
||||
struct event* e = (struct event*)calloc(1, sizeof(struct event));
|
||||
if(!e) return NULL;
|
||||
event_set(e, fd, ev, cb, arg);
|
||||
event_base_set(b, e);
|
||||
return e;
|
||||
}
|
||||
#endif /* no event2 */
|
||||
|
||||
/* cancel, cleanup and send timeout to callback */
|
||||
static void
|
||||
ub_resolve_timeout(evutil_socket_t fd, short what, void *arg)
|
||||
ub_resolve_timeout(void *arg)
|
||||
{
|
||||
getdns_dns_req *dns_req = (getdns_dns_req *) arg;
|
||||
struct getdns_context *context = dns_req->context;
|
||||
|
@ -109,7 +83,7 @@ ub_resolve_timeout(evutil_socket_t fd, short what, void *arg)
|
|||
}
|
||||
|
||||
static void
|
||||
ub_local_resolve_timeout(evutil_socket_t fd, short what, void *arg)
|
||||
ub_local_resolve_timeout(void *arg)
|
||||
{
|
||||
netreq_cb_data *cb_data = (netreq_cb_data *) arg;
|
||||
|
||||
|
@ -117,18 +91,15 @@ ub_local_resolve_timeout(evutil_socket_t fd, short what, void *arg)
|
|||
* invalid after calling ub_resolve_callback
|
||||
*/
|
||||
getdns_dns_req *dnsreq = cb_data->netreq->owner;
|
||||
event_free(dnsreq->local_cb_timer);
|
||||
dnsreq->local_cb_timer = NULL;
|
||||
/* clear the timeout */
|
||||
|
||||
getdns_context_clear_timeout(dnsreq->context, dnsreq->local_timeout_id);
|
||||
dnsreq->local_timeout_id = 0;
|
||||
|
||||
/* just call ub_resolve_callback */
|
||||
ub_resolve_callback(cb_data->netreq, cb_data->err, cb_data->result,
|
||||
cb_data->packet_len, cb_data->sec, cb_data->bogus);
|
||||
ub_resolve_callback(cb_data->netreq, cb_data->err, cb_data->ub_res);
|
||||
|
||||
/* cleanup the state */
|
||||
free(cb_data->result);
|
||||
if (cb_data->bogus) {
|
||||
free(cb_data->bogus);
|
||||
}
|
||||
free(cb_data);
|
||||
}
|
||||
|
||||
|
@ -176,7 +147,7 @@ static int
|
|||
submit_network_request(getdns_network_req * netreq)
|
||||
{
|
||||
getdns_dns_req *dns_req = netreq->owner;
|
||||
int r = ub_resolve_event(dns_req->unbound,
|
||||
int r = ub_resolve_async(dns_req->context->unbound_ctx,
|
||||
dns_req->name,
|
||||
netreq->request_type,
|
||||
netreq->request_class,
|
||||
|
@ -188,10 +159,15 @@ submit_network_request(getdns_network_req * netreq)
|
|||
}
|
||||
|
||||
static void
|
||||
ub_resolve_callback(void *arg, int err, void *result, int packet_len,
|
||||
int sec, char *bogus)
|
||||
ub_resolve_callback(void* arg, int err, struct ub_result* ub_res)
|
||||
// ub_resolve_callback(void *arg, int err, ldns_buffer * result, int sec,
|
||||
// char *bogus)
|
||||
{
|
||||
getdns_network_req *netreq = (getdns_network_req *) arg;
|
||||
getdns_network_req *netreq = (getdns_network_req *) arg;
|
||||
if (err != 0) {
|
||||
handle_network_request_error(netreq, err);
|
||||
return;
|
||||
}
|
||||
/* if netreq->state == NET_REQ_NOT_SENT here, that implies
|
||||
* that ub called us back immediately - probably from a local file.
|
||||
* This most likely means that getdns_general has not returned
|
||||
|
@ -201,72 +177,49 @@ ub_resolve_callback(void *arg, int err, void *result, int packet_len,
|
|||
* we can make this less hacky, but it gets interesting when multiple
|
||||
* netreqs need to be issued and some resolve immediately vs. not.
|
||||
*/
|
||||
struct timeval tv;
|
||||
getdns_dns_req *dnsreq = netreq->owner;
|
||||
netreq_cb_data *cb_data =
|
||||
(netreq_cb_data *) malloc(sizeof(netreq_cb_data));
|
||||
getdns_dns_req *dnsreq = netreq->owner;
|
||||
netreq_cb_data *cb_data =
|
||||
(netreq_cb_data *) malloc(sizeof(netreq_cb_data));
|
||||
cb_data->netreq = netreq;
|
||||
cb_data->err = err;
|
||||
cb_data->ub_res = ub_res;
|
||||
|
||||
cb_data->netreq = netreq;
|
||||
cb_data->err = err;
|
||||
cb_data->sec = sec;
|
||||
cb_data->result = NULL;
|
||||
cb_data->bogus = NULL; /* unused but here in case we need it */
|
||||
if (result) {
|
||||
cb_data->result = (uint8_t *) malloc(packet_len);
|
||||
if (!cb_data->result) {
|
||||
cb_data->err = GETDNS_RETURN_GENERIC_ERROR;
|
||||
} else {
|
||||
/* copy */
|
||||
(void) memcpy(
|
||||
cb_data->result, result, packet_len);
|
||||
}
|
||||
}
|
||||
/* schedule the timeout */
|
||||
dnsreq->local_cb_timer =
|
||||
evtimer_new(dnsreq->ev_base, ub_local_resolve_timeout,
|
||||
cb_data);
|
||||
tv.tv_sec = 0;
|
||||
/* half ms */
|
||||
tv.tv_usec = 500;
|
||||
evtimer_add(dnsreq->local_cb_timer, &tv);
|
||||
dnsreq->local_timeout_id = ldns_get_random();
|
||||
|
||||
getdns_context_schedule_timeout(dnsreq->context,
|
||||
dnsreq->local_timeout_id, 1, ub_local_resolve_timeout, cb_data);
|
||||
return;
|
||||
}
|
||||
netreq->state = NET_REQ_FINISHED;
|
||||
if (err) {
|
||||
handle_network_request_error(netreq, err);
|
||||
} else {
|
||||
/* parse */
|
||||
ldns_status r =
|
||||
ldns_wire2pkt(&(netreq->result), result, packet_len);
|
||||
if (r != LDNS_STATUS_OK) {
|
||||
handle_network_request_error(netreq, r);
|
||||
/* parse */
|
||||
/* TODO: optimize */
|
||||
getdns_return_t r = getdns_apply_network_result(netreq, ub_res);
|
||||
ub_resolve_free(ub_res);
|
||||
if (r != GETDNS_RETURN_GOOD) {
|
||||
handle_network_request_error(netreq, err);
|
||||
} else {
|
||||
/* is this the last request */
|
||||
if (!netreq->next) {
|
||||
/* finished */
|
||||
handle_dns_request_complete(netreq->owner);
|
||||
} else {
|
||||
/* is this the last request */
|
||||
if (!netreq->next) {
|
||||
/* finished */
|
||||
handle_dns_request_complete(netreq->owner);
|
||||
} else {
|
||||
/* not finished - update to next request and ship it */
|
||||
getdns_dns_req *dns_req = netreq->owner;
|
||||
dns_req->current_req = netreq->next;
|
||||
submit_network_request(netreq->next);
|
||||
}
|
||||
/* not finished - update to next request and ship it */
|
||||
getdns_dns_req *dns_req = netreq->owner;
|
||||
dns_req->current_req = netreq->next;
|
||||
submit_network_request(netreq->next);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
getdns_return_t
|
||||
getdns_general_ub(struct ub_ctx *unbound,
|
||||
struct event_base *ev_base,
|
||||
struct getdns_context *context,
|
||||
getdns_general_ub(struct getdns_context *context,
|
||||
const char *name,
|
||||
uint16_t request_type,
|
||||
struct getdns_dict *extensions,
|
||||
void *userarg,
|
||||
getdns_transaction_t * transaction_id, getdns_callback_t callbackfn)
|
||||
getdns_transaction_t * transaction_id,
|
||||
getdns_callback_t callbackfn)
|
||||
{
|
||||
/* timeout */
|
||||
struct timeval tv;
|
||||
getdns_return_t gr;
|
||||
int r;
|
||||
|
||||
|
@ -281,7 +234,6 @@ getdns_general_ub(struct ub_ctx *unbound,
|
|||
|
||||
/* request state */
|
||||
getdns_dns_req *req = dns_req_new(context,
|
||||
unbound,
|
||||
name,
|
||||
request_type,
|
||||
extensions);
|
||||
|
@ -299,11 +251,11 @@ getdns_general_ub(struct ub_ctx *unbound,
|
|||
getdns_context_track_outbound_request(req);
|
||||
|
||||
/* assign a timeout */
|
||||
req->ev_base = ev_base;
|
||||
req->timeout = evtimer_new(ev_base, ub_resolve_timeout, req);
|
||||
tv.tv_sec = context->timeout / 1000;
|
||||
tv.tv_usec = (context->timeout % 1000) * 1000;
|
||||
evtimer_add(req->timeout, &tv);
|
||||
// req->ev_base = ev_base;
|
||||
// req->timeout = evtimer_new(ev_base, ub_resolve_timeout, req);
|
||||
/* schedule the timeout */
|
||||
getdns_context_schedule_timeout(context, req->trans_id,
|
||||
context->timeout, ub_resolve_timeout, req);
|
||||
|
||||
/* issue the first network req */
|
||||
|
||||
|
@ -331,7 +283,7 @@ getdns_general(struct getdns_context *context,
|
|||
{
|
||||
int extcheck = GETDNS_RETURN_GOOD;
|
||||
|
||||
if (!context || !context->event_base_async) {
|
||||
if (!context) {
|
||||
/* Can't do async without an event loop
|
||||
* or callback
|
||||
*/
|
||||
|
@ -352,9 +304,7 @@ getdns_general(struct getdns_context *context,
|
|||
if (extcheck != GETDNS_RETURN_GOOD)
|
||||
return extcheck;
|
||||
|
||||
return getdns_general_ub(context->unbound_async,
|
||||
context->event_base_async,
|
||||
context,
|
||||
return getdns_general_ub(context,
|
||||
name, request_type, extensions, userarg, transaction_id, callback);
|
||||
|
||||
} /* getdns_general */
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
/*
|
||||
* Copyright (c) 2013, Versign, 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
|
||||
|
@ -40,13 +40,8 @@
|
|||
|
||||
/* private inner helper used by sync and async */
|
||||
|
||||
struct ub_ctx;
|
||||
struct event_base;
|
||||
|
||||
getdns_return_t
|
||||
getdns_general_ub(struct ub_ctx *unbound,
|
||||
struct event_base *ev_base,
|
||||
struct getdns_context *context,
|
||||
getdns_general_ub(struct getdns_context *context,
|
||||
const char *name,
|
||||
uint16_t request_type,
|
||||
struct getdns_dict *extensions,
|
||||
|
|
|
@ -43,8 +43,6 @@
|
|||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct event_base;
|
||||
|
||||
#define GETDNS_COMPILATION_COMMENT The API implementation should fill in something here, such as a compilation version string and date, and change it each time the API is compiled.
|
||||
|
||||
/**
|
||||
|
@ -797,19 +795,12 @@ char *getdns_pretty_print_dict(const struct getdns_dict *some_dict);
|
|||
char *getdns_display_ip_address(const struct getdns_bindata
|
||||
*bindata_of_ipv4_or_ipv6_address);
|
||||
|
||||
/*
|
||||
getdns_return_t getdns_context_set_context_update_callback(
|
||||
struct getdns_context *context,
|
||||
void (*value) (struct getdns_context *context, uint16_t changed_item)
|
||||
);
|
||||
*/
|
||||
getdns_return_t
|
||||
getdns_context_set_context_update_callback(
|
||||
struct getdns_context * context,
|
||||
void (*value)(struct getdns_context *context, uint16_t changed_item)
|
||||
);
|
||||
|
||||
|
||||
getdns_return_t
|
||||
getdns_context_set_resolution_type(struct getdns_context *context, uint16_t value);
|
||||
|
||||
|
@ -881,11 +872,14 @@ getdns_context_set_extended_memory_functions(struct getdns_context *context,
|
|||
void (*free) (void *userarg, void *ptr)
|
||||
);
|
||||
|
||||
/* Extension - refactor to abstract async evt loop */
|
||||
/* For libevent, which we are using for these examples */
|
||||
getdns_return_t
|
||||
getdns_extension_set_libevent_base(struct getdns_context *context,
|
||||
struct event_base *this_event_base);
|
||||
/* Async support */
|
||||
struct timeval;
|
||||
int getdns_context_get_num_pending_requests(struct getdns_context* context, struct timeval* next_timeout);
|
||||
|
||||
/* get the fd */
|
||||
int getdns_context_fd(struct getdns_context* context);
|
||||
/* process async reqs */
|
||||
getdns_return_t getdns_context_process_async(struct getdns_context* context);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -0,0 +1,55 @@
|
|||
/**
|
||||
* \file
|
||||
* \brief Public interfaces to getdns, include in your application to use getdns API.
|
||||
*
|
||||
* This source was taken from the original pseudo-implementation by
|
||||
* Paul Hoffman.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 2013, NLNet Labs, Versign, 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 name of the <organization> 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 GETDNS_EXT_LIBEVENT_H
|
||||
#define GETDNS_EXT_LIBEVENT_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <getdns/getdns.h>
|
||||
|
||||
struct event_base;
|
||||
|
||||
/* For libevent, which we are using for these examples */
|
||||
getdns_return_t
|
||||
getdns_extension_set_libevent_base(struct getdns_context *context,
|
||||
struct event_base *this_event_base);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
|
@ -9,7 +9,7 @@
|
|||
/*
|
||||
* Copyright (c) 2013, Versign, 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
|
||||
|
@ -34,15 +34,8 @@
|
|||
*/
|
||||
|
||||
#include "config.h"
|
||||
#ifdef HAVE_EVENT2_EVENT_H
|
||||
# include <event2/event.h>
|
||||
#else
|
||||
# include <event.h>
|
||||
# define event_free free
|
||||
#endif
|
||||
#include "types-internal.h"
|
||||
#include "util-internal.h"
|
||||
#include <unbound.h>
|
||||
|
||||
void
|
||||
network_req_free(getdns_network_req * net_req)
|
||||
|
@ -103,16 +96,11 @@ dns_req_free(getdns_dns_req * req)
|
|||
net_req = next;
|
||||
}
|
||||
|
||||
/* cleanup timeout */
|
||||
if (req->timeout) {
|
||||
event_del(req->timeout);
|
||||
event_free(req->timeout);
|
||||
}
|
||||
if (req->local_timeout_id != 0) {
|
||||
getdns_context_clear_timeout(context, req->local_timeout_id);
|
||||
}
|
||||
|
||||
if (req->local_cb_timer) {
|
||||
event_del(req->local_cb_timer);
|
||||
event_free(req->local_cb_timer);
|
||||
}
|
||||
getdns_context_clear_timeout(context, req->trans_id);
|
||||
|
||||
/* free strduped name */
|
||||
free(req->name);
|
||||
|
@ -123,7 +111,6 @@ dns_req_free(getdns_dns_req * req)
|
|||
/* create a new dns req to be submitted */
|
||||
getdns_dns_req *
|
||||
dns_req_new(struct getdns_context *context,
|
||||
struct ub_ctx *unbound,
|
||||
const char *name, uint16_t request_type, struct getdns_dict *extensions)
|
||||
{
|
||||
|
||||
|
@ -139,20 +126,17 @@ dns_req_new(struct getdns_context *context,
|
|||
|
||||
result->name = strdup(name);
|
||||
result->context = context;
|
||||
result->unbound = unbound;
|
||||
result->canceled = 0;
|
||||
result->current_req = NULL;
|
||||
result->first_req = NULL;
|
||||
result->trans_id = ldns_get_random();
|
||||
result->timeout = NULL;
|
||||
result->local_cb_timer = NULL;
|
||||
result->ev_base = NULL;
|
||||
|
||||
getdns_dict_copy(extensions, &result->extensions);
|
||||
|
||||
/* will be set by caller */
|
||||
result->user_pointer = NULL;
|
||||
result->user_callback = NULL;
|
||||
result->local_timeout_id = 0;
|
||||
|
||||
/* create the requests */
|
||||
req = network_req_new(result,
|
||||
|
|
59
src/sync.c
59
src/sync.c
|
@ -34,13 +34,8 @@
|
|||
*/
|
||||
|
||||
#include "config.h"
|
||||
#ifdef HAVE_EVENT2_EVENT_H
|
||||
# include <event2/event.h>
|
||||
#else
|
||||
# include <event.h>
|
||||
#endif
|
||||
#include <getdns/getdns.h>
|
||||
#include <unbound-event.h>
|
||||
#include <unbound.h>
|
||||
#include "context.h"
|
||||
#include "general.h"
|
||||
#include "types-internal.h"
|
||||
|
@ -51,14 +46,28 @@
|
|||
#define UNUSED_PARAM(x) ((void)(x))
|
||||
#define RETURN_IF_NULL(ptr, code) if(ptr == NULL) return code;
|
||||
|
||||
static void
|
||||
sync_callback_func(struct getdns_context *context,
|
||||
uint16_t callback_type,
|
||||
struct getdns_dict *response,
|
||||
void *userarg, getdns_transaction_t transaction_id)
|
||||
{
|
||||
|
||||
*((struct getdns_dict **) userarg) = response;
|
||||
getdns_return_t submit_request_sync(getdns_dns_req* req) {
|
||||
struct ub_result* ub_res = NULL;
|
||||
getdns_return_t gr = GETDNS_RETURN_GOOD;
|
||||
getdns_network_req *netreq = req->first_req;
|
||||
while (netreq) {
|
||||
int r = ub_resolve(req->context->unbound_ctx,
|
||||
req->name,
|
||||
netreq->request_type,
|
||||
netreq->request_class,
|
||||
&ub_res);
|
||||
if (r != 0) {
|
||||
return GETDNS_RETURN_GENERIC_ERROR;
|
||||
}
|
||||
gr = getdns_apply_network_result(netreq, ub_res);
|
||||
ub_resolve_free(ub_res);
|
||||
ub_res = NULL;
|
||||
if (gr != GETDNS_RETURN_GOOD) {
|
||||
return gr;
|
||||
}
|
||||
netreq = netreq->next;
|
||||
}
|
||||
return gr;
|
||||
}
|
||||
|
||||
getdns_return_t
|
||||
|
@ -78,12 +87,22 @@ getdns_general_sync(struct getdns_context *context,
|
|||
}
|
||||
response_status = validate_extensions(extensions);
|
||||
if (response_status == GETDNS_RETURN_GOOD) {
|
||||
response_status = getdns_general_ub(context->unbound_sync,
|
||||
context->event_base_sync,
|
||||
context, name, request_type,
|
||||
extensions, (void *) response, NULL, sync_callback_func);
|
||||
|
||||
event_base_dispatch(context->event_base_sync);
|
||||
/* for each netreq we call ub_ctx_resolve */
|
||||
/* request state */
|
||||
getdns_dns_req *req = dns_req_new(context,
|
||||
name,
|
||||
request_type,
|
||||
extensions);
|
||||
if (!req) {
|
||||
return GETDNS_RETURN_GENERIC_ERROR;
|
||||
}
|
||||
response_status = submit_request_sync(req);
|
||||
if (response_status != GETDNS_RETURN_GOOD) {
|
||||
dns_req_free(req);
|
||||
return response_status;
|
||||
}
|
||||
*response = create_getdns_response(req);
|
||||
dns_req_free(req);
|
||||
}
|
||||
return response_status;
|
||||
}
|
||||
|
|
|
@ -17,7 +17,7 @@ VPATH = @srcdir@
|
|||
|
||||
CC=gcc
|
||||
CFLAGS=@CFLAGS@ -Wall -I$(srcdir)/ -I$(srcdir)/../ -I/usr/local/include -std=c99 $(cflags)
|
||||
LDFLAGS=@LDFLAGS@ -L. -L.. -L/usr/local/lib
|
||||
LDFLAGS=@LDFLAGS@ -L. -L.. -L$(srcdir)/../ -L/usr/local/lib
|
||||
LDLIBS=-lgetdns @LIBS@ -lcheck
|
||||
PROGRAMS=tests_dict tests_list tests_stub_async tests_stub_sync check_getdns tests_dnssec
|
||||
|
||||
|
@ -45,7 +45,7 @@ tests_stub_sync: tests_stub_sync.o
|
|||
check_getdns_common: check_getdns_common.o
|
||||
$(LIBTOOL) --tag=CC --mode=link $(CC) $(CFLAGS) $(LDFLAGS) $(LDLIBS) -o $@ check_getdns_common.o
|
||||
|
||||
check_getdns: check_getdns.o check_getdns_common.o
|
||||
check_getdns: check_getdns.o check_getdns_common.o
|
||||
$(LIBTOOL) --tag=CC --mode=link $(CC) $(CFLAGS) $(LDFLAGS) $(LDLIBS) -o $@ check_getdns.o check_getdns_common.o
|
||||
|
||||
tests_dnssec: tests_dnssec.o testmessages.o
|
||||
|
|
|
@ -42,9 +42,12 @@
|
|||
|
||||
|
||||
int
|
||||
main (void)
|
||||
main (int argc, char** argv)
|
||||
{
|
||||
int number_failed;
|
||||
if (argc > 1) {
|
||||
event_loop_type = atoi(argv[1]);
|
||||
}
|
||||
SRunner *sr ;
|
||||
|
||||
Suite *getdns_general_suite(void);
|
||||
|
|
|
@ -5,12 +5,16 @@
|
|||
#include <inttypes.h>
|
||||
#include <check.h>
|
||||
#include <getdns/getdns.h>
|
||||
#include <getdns/getdns_ext_libevent.h>
|
||||
#include "check_getdns_common.h"
|
||||
#include <unistd.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
int callback_called = 0;
|
||||
int callback_completed = 0;
|
||||
int callback_canceled = 0;
|
||||
uint16_t expected_changed_item = 0;
|
||||
int event_loop_type = 0;
|
||||
|
||||
/*
|
||||
* extract_response extracts all of the various information
|
||||
|
@ -20,25 +24,25 @@ void extract_response(struct getdns_dict *response, struct extracted_response *e
|
|||
{
|
||||
ck_assert_msg(response != NULL, "Response should not be NULL");
|
||||
|
||||
ASSERT_RC(getdns_dict_get_int(response, "answer_type", &ex_response->top_answer_type),
|
||||
ASSERT_RC(getdns_dict_get_int(response, "answer_type", &ex_response->top_answer_type),
|
||||
GETDNS_RETURN_GOOD, "Failed to extract \"top answer_type\"");
|
||||
|
||||
ASSERT_RC(getdns_dict_get_bindata(response, "canonical_name", &ex_response->top_canonical_name),
|
||||
ASSERT_RC(getdns_dict_get_bindata(response, "canonical_name", &ex_response->top_canonical_name),
|
||||
GETDNS_RETURN_GOOD, "Failed to extract \"top canonical_name\"");
|
||||
|
||||
ASSERT_RC(getdns_dict_get_list(response, "just_address_answers", &ex_response->just_address_answers),
|
||||
ASSERT_RC(getdns_dict_get_list(response, "just_address_answers", &ex_response->just_address_answers),
|
||||
GETDNS_RETURN_GOOD, "Failed to extract \"just_address_answers\"");
|
||||
ck_assert_msg(ex_response->just_address_answers != NULL, "just_address_answers should not be NULL");
|
||||
|
||||
ASSERT_RC(getdns_dict_get_list(response, "replies_full", &ex_response->replies_full),
|
||||
ASSERT_RC(getdns_dict_get_list(response, "replies_full", &ex_response->replies_full),
|
||||
GETDNS_RETURN_GOOD, "Failed to extract \"replies_full\"");
|
||||
ck_assert_msg(ex_response->replies_full != NULL, "replies_full should not be NULL");
|
||||
|
||||
ASSERT_RC(getdns_dict_get_list(response, "replies_tree", &ex_response->replies_tree),
|
||||
ASSERT_RC(getdns_dict_get_list(response, "replies_tree", &ex_response->replies_tree),
|
||||
GETDNS_RETURN_GOOD, "Failed to extract \"replies_tree\"");
|
||||
ck_assert_msg(ex_response->replies_tree != NULL, "replies_tree should not be NULL");
|
||||
|
||||
ASSERT_RC(getdns_list_get_dict(ex_response->replies_tree, 0, &ex_response->replies_tree_sub_dict),
|
||||
ASSERT_RC(getdns_list_get_dict(ex_response->replies_tree, 0, &ex_response->replies_tree_sub_dict),
|
||||
GETDNS_RETURN_GOOD, "Failed to extract \"replies_tree[0]\"");
|
||||
ck_assert_msg(ex_response->replies_tree_sub_dict != NULL, "replies_tree[0] dict should not be NULL");
|
||||
|
||||
|
@ -46,29 +50,29 @@ void extract_response(struct getdns_dict *response, struct extracted_response *e
|
|||
GETDNS_RETURN_GOOD, "Failed to extract \"additional\"");
|
||||
ck_assert_msg(ex_response->additional != NULL, "additional should not be NULL");
|
||||
|
||||
ASSERT_RC(getdns_dict_get_list(ex_response->replies_tree_sub_dict, "answer", &ex_response->answer),
|
||||
ASSERT_RC(getdns_dict_get_list(ex_response->replies_tree_sub_dict, "answer", &ex_response->answer),
|
||||
GETDNS_RETURN_GOOD, "Failed to extract \"answer\"");
|
||||
ck_assert_msg(ex_response->answer != NULL, "answer should not be NULL");
|
||||
|
||||
ASSERT_RC(getdns_dict_get_int(ex_response->replies_tree_sub_dict, "answer_type", &ex_response->answer_type),
|
||||
ASSERT_RC(getdns_dict_get_int(ex_response->replies_tree_sub_dict, "answer_type", &ex_response->answer_type),
|
||||
GETDNS_RETURN_GOOD, "Failed to extract \"answer_type\"");
|
||||
|
||||
ASSERT_RC(getdns_dict_get_list(ex_response->replies_tree_sub_dict, "authority", &ex_response->authority),
|
||||
ASSERT_RC(getdns_dict_get_list(ex_response->replies_tree_sub_dict, "authority", &ex_response->authority),
|
||||
GETDNS_RETURN_GOOD, "Failed to extract \"authority\"");
|
||||
ck_assert_msg(ex_response->authority != NULL, "authority should not be NULL");
|
||||
|
||||
ASSERT_RC(getdns_dict_get_bindata(ex_response->replies_tree_sub_dict, "canonical_name", &ex_response->canonical_name),
|
||||
ASSERT_RC(getdns_dict_get_bindata(ex_response->replies_tree_sub_dict, "canonical_name", &ex_response->canonical_name),
|
||||
GETDNS_RETURN_GOOD, "Failed to extract \"canonical_name\"");
|
||||
|
||||
ASSERT_RC(getdns_dict_get_dict(ex_response->replies_tree_sub_dict, "header", &ex_response->header),
|
||||
ASSERT_RC(getdns_dict_get_dict(ex_response->replies_tree_sub_dict, "header", &ex_response->header),
|
||||
GETDNS_RETURN_GOOD, "Failed to extract \"header\"");
|
||||
ck_assert_msg(ex_response->header != NULL, "header should not be NULL");
|
||||
|
||||
ASSERT_RC(getdns_dict_get_dict(ex_response->replies_tree_sub_dict, "question", &ex_response->question),
|
||||
ASSERT_RC(getdns_dict_get_dict(ex_response->replies_tree_sub_dict, "question", &ex_response->question),
|
||||
GETDNS_RETURN_GOOD, "Failed to extract \"question\"");
|
||||
ck_assert_msg(ex_response->question != NULL, "question should not be NULL");
|
||||
|
||||
ASSERT_RC(getdns_dict_get_int(response, "status", &ex_response->status),
|
||||
ASSERT_RC(getdns_dict_get_int(response, "status", &ex_response->status),
|
||||
GETDNS_RETURN_GOOD, "Failed to extract \"status\"");
|
||||
}
|
||||
|
||||
|
@ -87,17 +91,17 @@ void assert_noerror(struct extracted_response *ex_response)
|
|||
/*
|
||||
* assert_nodata asserts that ancount in the header and the
|
||||
* of the answer section (list) are both zero.
|
||||
*/
|
||||
*/
|
||||
void assert_nodata(struct extracted_response *ex_response)
|
||||
{
|
||||
uint32_t ancount;
|
||||
size_t length;
|
||||
|
||||
ASSERT_RC(getdns_dict_get_int(ex_response->header, "ancount", &ancount),
|
||||
ASSERT_RC(getdns_dict_get_int(ex_response->header, "ancount", &ancount),
|
||||
GETDNS_RETURN_GOOD, "Failed to extract \"ancount\"");
|
||||
ck_assert_msg(ancount == 0, "Expected ancount == 0, got %d", ancount);
|
||||
|
||||
ASSERT_RC(getdns_list_get_length(ex_response->answer, &length),
|
||||
ASSERT_RC(getdns_list_get_length(ex_response->answer, &length),
|
||||
GETDNS_RETURN_GOOD, "Failed to extract \"answer\" length");
|
||||
ck_assert_msg(length == 0, "Expected \"answer\" length == 0, got %d", length);
|
||||
}
|
||||
|
@ -110,7 +114,7 @@ void assert_nodata(struct extracted_response *ex_response)
|
|||
*/
|
||||
void assert_address_in_answer(struct extracted_response *ex_response, int a, int aaaa)
|
||||
{
|
||||
uint32_t ancount;
|
||||
uint32_t ancount;
|
||||
size_t length;
|
||||
struct getdns_dict *rr_dict;
|
||||
uint32_t type;
|
||||
|
@ -127,9 +131,9 @@ void assert_address_in_answer(struct extracted_response *ex_response, int a, int
|
|||
|
||||
for(i = 0; i < length; i++)
|
||||
{
|
||||
ASSERT_RC(getdns_list_get_dict(ex_response->answer, i, &rr_dict),
|
||||
ASSERT_RC(getdns_list_get_dict(ex_response->answer, i, &rr_dict),
|
||||
GETDNS_RETURN_GOOD, "Failed to extract \"answer\" record");
|
||||
ASSERT_RC(getdns_dict_get_int(rr_dict, "type", &type),
|
||||
ASSERT_RC(getdns_dict_get_int(rr_dict, "type", &type),
|
||||
GETDNS_RETURN_GOOD, "Failed to extract \"type\" from answer record");
|
||||
switch (type)
|
||||
{
|
||||
|
@ -244,8 +248,8 @@ void callbackfn(struct getdns_context *context,
|
|||
|
||||
/*
|
||||
* If userarg is NULL, either a negative test case
|
||||
* erroneously reached the query state, or the value
|
||||
* in userarg (verification function) was somehow
|
||||
* erroneously reached the query state, or the value
|
||||
* in userarg (verification function) was somehow
|
||||
* lost in transit.
|
||||
*/
|
||||
ck_assert_msg(userarg != NULL, "Callback called with NULL userarg");
|
||||
|
@ -282,8 +286,38 @@ void callbackfn(struct getdns_context *context,
|
|||
void update_callbackfn(struct getdns_context *context,
|
||||
uint16_t changed_item)
|
||||
{
|
||||
|
||||
ck_assert_msg(changed_item == expected_changed_item,
|
||||
|
||||
ck_assert_msg(changed_item == expected_changed_item,
|
||||
"Expected changed_item == %d, got %d",
|
||||
changed_item, expected_changed_item);
|
||||
}
|
||||
|
||||
void run_event_loop(struct getdns_context* context, struct event_base* base) {
|
||||
if (event_loop_type == 0) {
|
||||
while (getdns_context_get_num_pending_requests(context, NULL) > 0) {
|
||||
event_base_loop(base, EVLOOP_ONCE);
|
||||
}
|
||||
} else if (event_loop_type == 1) {
|
||||
struct timeval tv;
|
||||
while (getdns_context_get_num_pending_requests(context, &tv) > 0) {
|
||||
int fd = getdns_context_fd(context);
|
||||
fd_set read_fds;
|
||||
FD_ZERO(&read_fds);
|
||||
FD_SET(fd, &read_fds);
|
||||
select(fd + 1, &read_fds, NULL, NULL, &tv);
|
||||
getdns_context_process_async(context);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct event_base* create_event_base(struct getdns_context* context) {
|
||||
if (event_loop_type == 0) {
|
||||
struct event_base* result = event_base_new();
|
||||
ck_assert_msg(result != NULL, "Event base creation failed");
|
||||
ASSERT_RC(getdns_extension_set_libevent_base(context, result),
|
||||
GETDNS_RETURN_GOOD,
|
||||
"Return code from getdns_extension_set_libevent_base()");
|
||||
return result;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
#ifndef _check_getdns_common_h_
|
||||
#define _check_getdns_common_h_
|
||||
|
||||
#include "check_getdns_libevent.h"
|
||||
|
||||
#define TRUE 1
|
||||
#define FALSE 0
|
||||
#define MAXLEN 200
|
||||
|
@ -9,7 +11,8 @@
|
|||
extern int callback_completed;
|
||||
extern int callback_canceled;
|
||||
extern uint16_t expected_changed_item;
|
||||
|
||||
extern int event_loop_type;
|
||||
|
||||
struct extracted_response {
|
||||
uint32_t top_answer_type;
|
||||
struct getdns_bindata *top_canonical_name;
|
||||
|
@ -26,7 +29,7 @@
|
|||
struct getdns_dict *question;
|
||||
uint32_t status;
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* The ASSERT_RC macro is used to assert
|
||||
* whether the return code from the last
|
||||
|
@ -42,12 +45,12 @@
|
|||
"%s: expecting %s: %d, but received: %d: %s", \
|
||||
prefix, #expected_rc, expected_rc, evaluated_rc, error_string); \
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* The CONTEXT_CREATE macro is used to
|
||||
* The CONTEXT_CREATE macro is used to
|
||||
* create a context and assert the proper
|
||||
* return code is returned.
|
||||
*/
|
||||
* return code is returned.
|
||||
*/
|
||||
#define CONTEXT_CREATE(set_from_os) \
|
||||
ASSERT_RC(getdns_context_create(&context, set_from_os), \
|
||||
GETDNS_RETURN_GOOD, \
|
||||
|
@ -60,24 +63,19 @@
|
|||
#define CONTEXT_DESTROY getdns_context_destroy(context);
|
||||
|
||||
/*
|
||||
* The EVENT_BASE_CREATE macro is used to
|
||||
* create an event base and put it in the
|
||||
* context.
|
||||
*/
|
||||
#define EVENT_BASE_CREATE \
|
||||
event_base = event_base_new(); \
|
||||
ck_assert_msg(event_base != NULL, "Event base creation failed"); \
|
||||
ASSERT_RC(getdns_extension_set_libevent_base(context, event_base), \
|
||||
GETDNS_RETURN_GOOD, \
|
||||
"Return code from getdns_extension_set_libevent_base()");
|
||||
|
||||
* The EVENT_BASE_CREATE macro is used to
|
||||
* create an event base and put it in the
|
||||
* context.
|
||||
*/
|
||||
#define EVENT_BASE_CREATE event_base = create_event_base(context);
|
||||
|
||||
/*
|
||||
* The RUN_EVENT_LOOP macro calls the event loop.
|
||||
*/
|
||||
#define RUN_EVENT_LOOP event_base_dispatch(event_base);
|
||||
#define RUN_EVENT_LOOP run_event_loop(context, event_base);
|
||||
|
||||
/*
|
||||
* The LIST_CREATE macro simply creates a
|
||||
* The LIST_CREATE macro simply creates a
|
||||
* list and verifies the returned pointer
|
||||
* is not NULL.
|
||||
*/
|
||||
|
@ -92,7 +90,7 @@
|
|||
#define LIST_DESTROY(list) getdns_list_destroy(list);
|
||||
|
||||
/*
|
||||
* The DICT_CREATE macro simply creates a
|
||||
* The DICT_CREATE macro simply creates a
|
||||
* dict and verifies the returned pointer
|
||||
* is not NULL.
|
||||
*/
|
||||
|
@ -105,8 +103,8 @@
|
|||
* The DICT_DESTROY macro destroys a dict.
|
||||
*/
|
||||
#define DICT_DESTROY(dict) getdns_dict_destroy(dict);
|
||||
|
||||
/*
|
||||
|
||||
/*
|
||||
* The process_response macro declares the
|
||||
* variables needed to house the response and
|
||||
* calls the function that extracts it.
|
||||
|
@ -116,14 +114,14 @@
|
|||
extract_response(response, &ex_response);
|
||||
|
||||
//
|
||||
// FUNCTION DECLARATIONS
|
||||
//
|
||||
// FUNCTION DECLARATIONS
|
||||
//
|
||||
|
||||
/*
|
||||
* extract_response extracts all of the various information
|
||||
* a test may want to look at from the response.
|
||||
*/
|
||||
void extract_response(struct getdns_dict *response, struct extracted_response *ex_response);
|
||||
void extract_response(struct getdns_dict *response, struct extracted_response *ex_response);
|
||||
|
||||
/*
|
||||
* assert_noerror asserts that the rcode is 0.
|
||||
|
@ -137,10 +135,10 @@
|
|||
void assert_nodata(struct extracted_response *ex_response);
|
||||
|
||||
/*
|
||||
* assert_address_records_in_answer asserts that ancount in
|
||||
* the header * is >= 1, ancount is equal to the length
|
||||
* of "answer", and that all of * the records in the
|
||||
* answer section are A and/or AAAA resource records based
|
||||
* assert_address_records_in_answer asserts that ancount in
|
||||
* the header * is >= 1, ancount is equal to the length
|
||||
* of "answer", and that all of * the records in the
|
||||
* answer section are A and/or AAAA resource records based
|
||||
* on the value of the a/aaaa arguments.
|
||||
*/
|
||||
void assert_address_in_answer(struct extracted_response *ex_response, int a, int aaaa);
|
||||
|
@ -169,17 +167,22 @@
|
|||
* be called for positive tests and will verify the
|
||||
* response that is returned.
|
||||
*/
|
||||
void callbackfn(struct getdns_context *context,
|
||||
void callbackfn(struct getdns_context *context,
|
||||
uint16_t callback_type,
|
||||
struct getdns_dict *response,
|
||||
struct getdns_dict *response,
|
||||
void *userarg,
|
||||
getdns_transaction_t transaction_id);
|
||||
|
||||
/*
|
||||
* update_callbackfn is the callback function given to
|
||||
* getdns_context_set_context_update_callback tests.
|
||||
* update_callbackfn is the callback function given to
|
||||
* getdns_context_set_context_update_callback tests.
|
||||
*/
|
||||
void update_callbackfn(struct getdns_context *context,
|
||||
void update_callbackfn(struct getdns_context *context,
|
||||
uint16_t changed_item);
|
||||
|
||||
/* run the event loop */
|
||||
void run_event_loop(struct getdns_context *context, struct event_base* event_base);
|
||||
|
||||
struct event_base* create_event_base(struct getdns_context* context);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -44,6 +44,7 @@
|
|||
#include <string.h>
|
||||
#include "testmessages.h"
|
||||
#include <getdns/getdns.h>
|
||||
#include <getdns/getdns_ext_libevent.h>
|
||||
|
||||
/* Set up the callback function, which will also do the processing of the results */
|
||||
void
|
||||
|
|
|
@ -43,6 +43,8 @@
|
|||
#include <string.h>
|
||||
#include "testmessages.h"
|
||||
#include <getdns/getdns.h>
|
||||
#include <getdns/getdns_ext_libevent.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
/* Set up the callback function, which will also do the processing of the results */
|
||||
void
|
||||
|
@ -90,8 +92,12 @@ main(int argc, char** argv)
|
|||
getdns_context_destroy(this_context);
|
||||
return (GETDNS_RETURN_GENERIC_ERROR);
|
||||
}
|
||||
(void) getdns_extension_set_libevent_base(this_context,
|
||||
this_event_base);
|
||||
if (getdns_extension_set_libevent_base(this_context,
|
||||
this_event_base) != GETDNS_RETURN_GOOD) {
|
||||
fprintf(stderr, "Setting event base failed.");
|
||||
getdns_context_destroy(this_context);
|
||||
return (GETDNS_RETURN_GENERIC_ERROR);
|
||||
}
|
||||
/* Set up the getdns call */
|
||||
const char *this_name = argc > 1 ? argv[1] : "www.google.com";
|
||||
char *this_userarg = "somestring"; // Could add things here to help identify this call
|
||||
|
@ -117,7 +123,10 @@ main(int argc, char** argv)
|
|||
// }
|
||||
else {
|
||||
/* Call the event loop */
|
||||
event_base_dispatch(this_event_base);
|
||||
event_base_loop(this_event_base, EVLOOP_ONCE);
|
||||
while (getdns_context_get_num_pending_requests(this_context, NULL) > 0) {
|
||||
event_base_loop(this_event_base, EVLOOP_ONCE);
|
||||
}
|
||||
// TODO: check the return value above
|
||||
}
|
||||
/* Clean up */
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
/*
|
||||
* Copyright (c) 2013, Versign, 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
|
||||
|
@ -100,9 +100,6 @@ struct getdns_context;
|
|||
/* declarations */
|
||||
struct getdns_dns_req;
|
||||
struct getdns_network_req;
|
||||
struct ub_ctx;
|
||||
struct event;
|
||||
struct event_base;
|
||||
|
||||
typedef enum network_req_state_enum
|
||||
{
|
||||
|
@ -165,21 +162,9 @@ typedef struct getdns_dns_req
|
|||
/* first request in list */
|
||||
struct getdns_network_req *first_req;
|
||||
|
||||
/* request timeout event */
|
||||
struct event *timeout;
|
||||
|
||||
/* local callback timer */
|
||||
struct event *local_cb_timer;
|
||||
|
||||
/* event base this req is scheduled on */
|
||||
struct event_base *ev_base;
|
||||
|
||||
/* context that owns the request */
|
||||
struct getdns_context *context;
|
||||
|
||||
/* ub_ctx issuing the request */
|
||||
struct ub_ctx *unbound;
|
||||
|
||||
/* request extensions */
|
||||
struct getdns_dict *extensions;
|
||||
|
||||
|
@ -190,6 +175,9 @@ typedef struct getdns_dns_req
|
|||
/* the transaction id */
|
||||
getdns_transaction_t trans_id;
|
||||
|
||||
/* local timeout id */
|
||||
getdns_transaction_t local_timeout_id;
|
||||
|
||||
} getdns_dns_req;
|
||||
|
||||
#define MF_PLAIN ((void *)&plain_mem_funcs_user_arg)
|
||||
|
@ -247,11 +235,40 @@ getdns_network_req *network_req_new(getdns_dns_req * owner,
|
|||
|
||||
/* dns request utils */
|
||||
getdns_dns_req *dns_req_new(struct getdns_context *context,
|
||||
struct ub_ctx *unbound,
|
||||
const char *name, uint16_t request_type, struct getdns_dict *extensions);
|
||||
|
||||
void dns_req_free(getdns_dns_req * req);
|
||||
|
||||
|
||||
/* extensions */
|
||||
typedef void (*getdns_timeout_callback) (void* userarg);
|
||||
|
||||
/* context timeout data */
|
||||
typedef struct getdns_timeout_data {
|
||||
getdns_transaction_t transaction_id;
|
||||
struct timeval timeout_time;
|
||||
getdns_timeout_callback callback;
|
||||
void* userarg;
|
||||
void* extension_timer;
|
||||
struct getdns_context* context;
|
||||
} getdns_timeout_data_t;
|
||||
|
||||
typedef getdns_return_t (*getdns_eventloop_cleanup_t)(struct getdns_context* context, void* eventloop_data);
|
||||
typedef getdns_return_t (*getdns_eventloop_schedule_timeout_t)(struct getdns_context* context,
|
||||
void* eventloop_data, uint16_t timeout,
|
||||
getdns_timeout_data_t* timeout_data,
|
||||
void** eventloop_timer);
|
||||
typedef getdns_return_t (*getdns_eventloop_clear_timeout_t)(struct getdns_context* context,
|
||||
void* eventloop_data, void** eventloop_timer);
|
||||
|
||||
|
||||
typedef struct getdns_eventloop_extension {
|
||||
getdns_eventloop_cleanup_t cleanup_data;
|
||||
getdns_eventloop_schedule_timeout_t schedule_timeout;
|
||||
getdns_eventloop_clear_timeout_t clear_timeout;
|
||||
} getdns_eventloop_extension;
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
/* types-internal.h */
|
||||
|
|
|
@ -41,6 +41,7 @@
|
|||
#include "list.h"
|
||||
#include "util-internal.h"
|
||||
#include "types-internal.h"
|
||||
#include <unbound.h>
|
||||
#include "rr-dict.h"
|
||||
|
||||
/**
|
||||
|
@ -571,6 +572,22 @@ validate_extensions(struct getdns_dict * extensions)
|
|||
return GETDNS_RETURN_GOOD;
|
||||
} /* validate_extensions */
|
||||
|
||||
getdns_return_t
|
||||
getdns_apply_network_result(getdns_network_req* netreq,
|
||||
struct ub_result* ub_res) {
|
||||
ldns_buffer *result = ldns_buffer_new(ub_res->answer_len);
|
||||
if (!result) {
|
||||
return GETDNS_RETURN_GENERIC_ERROR;
|
||||
}
|
||||
ldns_status r =
|
||||
ldns_wire2pkt(&(netreq->result), ub_res->answer_packet, ub_res->answer_len);
|
||||
if (r != LDNS_STATUS_OK) {
|
||||
return GETDNS_RETURN_GENERIC_ERROR;
|
||||
}
|
||||
return GETDNS_RETURN_GOOD;
|
||||
}
|
||||
|
||||
|
||||
getdns_return_t
|
||||
validate_dname(const char* dname) {
|
||||
int len;
|
||||
|
|
|
@ -41,6 +41,10 @@
|
|||
#include <ldns/ldns.h>
|
||||
#include "context.h"
|
||||
|
||||
struct ub_result;
|
||||
struct getdns_network_req;
|
||||
getdns_return_t getdns_apply_network_result(getdns_network_req* netreq, struct ub_result* result);
|
||||
|
||||
#define GETDNS_MAX_DNAME_LEN 255
|
||||
#define GETDNS_MAX_LABEL_LEN 63
|
||||
|
||||
|
|
|
@ -110,24 +110,23 @@ static void callback_on_complete_chain(struct validation_chain *chain)
|
|||
|
||||
|
||||
static void
|
||||
ub_chain_response_callback(void *arg, int err, void *result, int packet_len,
|
||||
int sec, char *bogus)
|
||||
ub_chain_response_callback(void *arg, int err, struct ub_result* ub_res)
|
||||
{
|
||||
struct chain_response *response = (struct chain_response *) arg;
|
||||
ldns_status r;
|
||||
ldns_pkt *p;
|
||||
ldns_rr_list *answer;
|
||||
ldns_rr_list *keys;
|
||||
size_t i;
|
||||
ldns_status r;
|
||||
ldns_pkt *p;
|
||||
ldns_rr_list *answer;
|
||||
ldns_rr_list *keys;
|
||||
size_t i;
|
||||
|
||||
response->err = err;
|
||||
response->sec = sec;
|
||||
response->bogus = bogus;
|
||||
response->err = err;
|
||||
response->sec = ub_res ? ub_res->secure : 0;
|
||||
response->bogus = ub_res ? ub_res->why_bogus : NULL;
|
||||
|
||||
if (result == NULL)
|
||||
goto done;
|
||||
if (ub_res == NULL)
|
||||
goto done;
|
||||
|
||||
r = ldns_wire2pkt(&p, (uint8_t *)result, (size_t)packet_len);
|
||||
r = ldns_wire2pkt(&p, ub_res->answer_packet, ub_res->answer_len);
|
||||
if (r != LDNS_STATUS_OK) {
|
||||
if (err == 0)
|
||||
response->err = r;
|
||||
|
@ -165,6 +164,7 @@ ub_chain_response_callback(void *arg, int err, void *result, int packet_len,
|
|||
ldns_rr_list_free(keys);
|
||||
|
||||
ldns_pkt_free(p);
|
||||
ub_resolve_free(ub_res);
|
||||
|
||||
done: if (response->err == 0 && response->result == NULL)
|
||||
response->err = -1;
|
||||
|
@ -202,14 +202,14 @@ static void launch_chain_link_lookup(struct validation_chain *chain, char *name)
|
|||
ldns_rbtree_insert(&(chain->root), (ldns_rbnode_t *)link);
|
||||
|
||||
chain->lock++;
|
||||
r = ub_resolve_event(chain->dns_req->unbound,
|
||||
r = ub_resolve_async(chain->dns_req->context->unbound_ctx,
|
||||
name, LDNS_RR_TYPE_DNSKEY, LDNS_RR_CLASS_IN, &link->DNSKEY,
|
||||
ub_chain_response_callback, &link->DNSKEY.unbound_id);
|
||||
if (r != 0)
|
||||
link->DNSKEY.err = r;
|
||||
|
||||
if (name[0] != '.' || name[1] != '\0') {
|
||||
r = ub_resolve_event(chain->dns_req->unbound,
|
||||
r = ub_resolve_async(chain->dns_req->context->unbound_ctx,
|
||||
name, LDNS_RR_TYPE_DS, LDNS_RR_CLASS_IN, &link->DS,
|
||||
ub_chain_response_callback, &link->DS.unbound_id);
|
||||
if (r != 0)
|
||||
|
|
Loading…
Reference in New Issue