Merge branch 'develop' into features/windows-support

This commit is contained in:
Willem Toorop 2015-12-24 11:01:26 +01:00
commit caba5f19d5
103 changed files with 6829 additions and 1041 deletions

1
.gitignore vendored
View File

@ -55,3 +55,4 @@ m4/ltversion.m4
m4/lt~obsolete.m4
src/config.h.in
build/
getdns.pc

View File

@ -1,15 +1,19 @@
sudo: false
language: c
compiler:
- gcc
- clang
before_script:
- sudo apt-get update
- sudo apt-get install libunbound-dev libldns-dev libidn11-dev check libevent-dev
addons:
apt:
packages:
- libunbound-dev
- libldns-dev
- libidn11-dev
- check
- libevent-dev
- libev-dev
- bc
script:
- libtoolize -fic
- autoreconf -fi
- ./configure --with-libevent
- make
- sudo PATH=$PATH make install
- make test
- sudo make uninstall
- mkdir tests
- cd tests
- ../src/test/tpkg/run-all.sh

View File

@ -1,3 +1,8 @@
*
* Remove STARTTLS implementation (no change to SPEC)
* Enable TCP Fast Open when possible. Add OSX support for TFO.
* Rename return_call_debugging to return_call_reporting
* 2015-11-18: Version 0.5.1
* Bugfix: growing upstreams arrow.
* Bugfix: Segfault on timeout in specific conditions

View File

@ -39,16 +39,17 @@ datarootdir=@datarootdir@
exec_prefix = @exec_prefix@
bindir = @bindir@
docdir = @docdir@
libdir = @libdir@
srcdir = @srcdir@
INSTALL = @INSTALL@
all : default @GETDNS_QUERY@
all : default @GETDNS_QUERY@
default:
cd src && $(MAKE) $@
install: all @INSTALL_GETDNS_QUERY@
install: all getdns.pc @INSTALL_GETDNS_QUERY@
$(INSTALL) -m 755 -d $(DESTDIR)$(docdir)
$(INSTALL) -m 644 $(srcdir)/AUTHORS $(DESTDIR)$(docdir)
$(INSTALL) -m 644 $(srcdir)/ChangeLog $(DESTDIR)$(docdir)
@ -57,6 +58,8 @@ install: all @INSTALL_GETDNS_QUERY@
$(INSTALL) -m 644 $(srcdir)/LICENSE $(DESTDIR)$(docdir)
$(INSTALL) -m 644 $(srcdir)/NEWS $(DESTDIR)$(docdir)
$(INSTALL) -m 644 $(srcdir)/README.md $(DESTDIR)$(docdir)
$(INSTALL) -m 755 -d $(DESTDIR)$(libdir)/pkgconfig
$(INSTALL) -m 644 getdns.pc $(DESTDIR)$(libdir)/pkgconfig
$(INSTALL) -m 755 -d $(DESTDIR)$(docdir)/spec
$(INSTALL) -m 644 $(srcdir)/spec/index.html $(DESTDIR)$(docdir)/spec
$(INSTALL) -m 644 $(srcdir)/spec/getdns*tgz $(DESTDIR)$(docdir)/spec || true
@ -113,7 +116,7 @@ clean:
cd src && $(MAKE) $@
cd doc && $(MAKE) $@
cd spec/example && $(MAKE) $@
rm -f *.o
rm -f *.o *.pc
depend:
cd src && $(MAKE) $@
@ -232,6 +235,9 @@ distcheck: $(distdir).tar.gz
rm -rf $(distdir)
@echo "*** Package $(distdir).tar.gz is ready for distribution"
getdns.pc: $(srcdir)/getdns.pc.in
./config.status $@
Makefile: $(srcdir)/Makefile.in config.status
./config.status $@

View File

@ -35,8 +35,8 @@ sinclude(./m4/acx_openssl.m4)
sinclude(./m4/ax_check_compile_flag.m4)
sinclude(./m4/pkg.m4)
AC_INIT([getdns], [0.5.1], [stub-resolver@verisignlabs.com], [], [https://getdnsapi.net])
AC_SUBST(RELEASE_CANDIDATE, [])
AC_INIT([getdns], [0.6.1], [stub-resolver@verisignlabs.com], [], [https://getdnsapi.net])
AC_SUBST(RELEASE_CANDIDATE, [rc1])
# Set current date from system if not set
AC_ARG_WITH([current-date],
@ -46,7 +46,7 @@ AC_ARG_WITH([current-date],
[CURRENT_DATE="`date -u +%Y-%m-%dT%H:%M:%SZ`"])
AC_SUBST(GETDNS_VERSION, ["AC_PACKAGE_VERSION$RELEASE_CANDIDATE"])
AC_SUBST(GETDNS_NUMERIC_VERSION, [0x00050100])
AC_SUBST(GETDNS_NUMERIC_VERSION, [0x00060001])
AC_SUBST(API_VERSION, ["October 2015"])
AC_SUBST(API_NUMERIC_VERSION, [0x07df0a00])
GETDNS_COMPILATION_COMMENT="AC_PACKAGE_NAME $GETDNS_VERSION configured on $CURRENT_DATE for the $API_VERSION version of the API"
@ -74,9 +74,10 @@ GETDNS_COMPILATION_COMMENT="AC_PACKAGE_NAME $GETDNS_VERSION configured on $CURRE
# getdns-0.3.2 had libversion 3:5:2
# getdns-0.3.3 had libversion 3:6:2
# getdns-0.5.0 had libversion 4:0:3
# getdns-0.5.1 has libversion 4:1:3
# getdns-0.5.1 had libversion 4:1:3 (but should have been getdns-0.6.0)
# getdns-0.6.1 will have libversion 4:2:3
#
GETDNS_LIBVERSION=4:1:3
GETDNS_LIBVERSION=4:2:3
AC_SUBST(GETDNS_COMPILATION_COMMENT)
AC_SUBST(GETDNS_LIBVERSION)
@ -137,7 +138,20 @@ fi
])
ACX_ARG_RPATH
AC_ARG_ENABLE(debug-sched, AC_HELP_STRING([--enable-debug-sched], [Enable scheduling debugging messages]))
AC_ARG_ENABLE(debug-stub, AC_HELP_STRING([--enable-debug-stub], [Enable stub debugging messages]))
AC_ARG_ENABLE(debug-sec, AC_HELP_STRING([--enable-debug-sec], [Enable dnssec debugging messages]))
AC_ARG_ENABLE(all-debugging, AC_HELP_STRING([--enable-all-debugging], [Enable scheduling, stub and dnssec debugging]))
case "$enable_all_debugging" in
yes)
enable_debug_sched=yes
enable_debug_stub=yes
enable_debug_sec=yes
;;
no|*)
;;
esac
case "$enable_debug_sched" in
yes)
AC_DEFINE_UNQUOTED([SCHED_DEBUG], [1], [Define this to enable printing of scheduling debugging messages.])
@ -145,7 +159,6 @@ case "$enable_debug_sched" in
no|*)
;;
esac
AC_ARG_ENABLE(debug-stub, AC_HELP_STRING([--enable-debug-stub], [Enable stub debugging messages]))
case "$enable_debug_stub" in
yes)
AC_DEFINE_UNQUOTED([STUB_DEBUG], [1], [Define this to enable printing of stub debugging messages.])
@ -153,7 +166,6 @@ case "$enable_debug_stub" in
no|*)
;;
esac
AC_ARG_ENABLE(debug-sec, AC_HELP_STRING([--enable-debug-sec], [Enable dnssec debugging messages]))
case "$enable_debug_sec" in
yes)
AC_DEFINE_UNQUOTED([SEC_DEBUG], [1], [Define this to enable printing of dnssec debugging messages.])
@ -162,29 +174,22 @@ case "$enable_debug_sec" in
;;
esac
AC_ARG_ENABLE(tcp-fastopen, AC_HELP_STRING([--enable-tcp-fastopen], [Enable TCP Fast Open]))
case "$enable_tcp_fastopen" in
yes)
AC_CHECK_DECL([MSG_FASTOPEN], [], [AC_MSG_ERROR([TCP Fast Open is not available: please rerun without --enable-tcp-fastopen])], [AC_INCLUDES_DEFAULT
#include <sys/socket.h>
])
AC_DEFINE_UNQUOTED([USE_TCP_FASTOPEN], [1], [Define this to enable TCP fast open.])
;;
no|*)
;;
esac
# Not yet enabled by default as crash found when TCP fails.
# AC_ARG_ENABLE(tcp-fastopen, AC_HELP_STRING([--disable-tcp-fastopen], Disable TCP Fast Open (default=enabled if available)),
# enable_tcp_fastopen="$enableval", enable_tcp_fastopen=yes)
# if test "x$enable_tcp_fastopen" = xno; then
# AC_MSG_WARN([TCP Fast Open is disabled])
# else
# AC_CHECK_DECL([MSG_FASTOPEN], [AC_DEFINE_UNQUOTED([USE_TCP_FASTOPEN], [1], [Define this to enable TCP fast open.])],
# [AC_MSG_WARN([TCP Fast Open is not available.])], [AC_INCLUDES_DEFAULT
# #include <sys/socket.h>
# ])
# fi
AC_ARG_ENABLE(tcp-fastopen, AC_HELP_STRING([--disable-tcp-fastopen], Disable TCP Fast Open (default=enabled if available)),
enable_tcp_fastopen="$enableval", enable_tcp_fastopen=yes)
if test "x$enable_tcp_fastopen" = xno; then
AC_MSG_WARN([TCP Fast Open is disabled])
else
case `uname` in
Linux) AC_CHECK_DECL([MSG_FASTOPEN], [AC_DEFINE_UNQUOTED([USE_TCP_FASTOPEN], [1], [Define this to enable TCP fast open.])],
[AC_MSG_WARN([TCP Fast Open is not available, continuing without])], [#include <sys/socket.h>])
;;
Darwin) AC_CHECK_DECL([CONNECT_RESUME_ON_READ_WRITE], [AC_DEFINE_UNQUOTED([USE_OSX_TCP_FASTOPEN], [1], [Define this to enable TCP fast open.])],
[AC_MSG_WARN([TCP Fast Open is not available, continuing without])], [#include <sys/socket.h>])
;;
*) AC_MSG_WARN([TCP Fast Open is not available, continuing without])
;;
esac
fi
AC_ARG_ENABLE(native-stub-dnssec, AC_HELP_STRING([--disable-native-stub-dnssec], [Disable native stub DNSSEC support]))
case "$enable_native_stub_dnssec" in
@ -212,7 +217,7 @@ else
fi
AC_CHECK_HEADERS([openssl/conf.h],,, [AC_INCLUDES_DEFAULT])
AC_CHECK_HEADERS([openssl/engine.h],,, [AC_INCLUDES_DEFAULT])
AC_CHECK_FUNCS([OPENSSL_config EVP_sha1 EVP_sha256 EVP_sha512 FIPS_mode])
AC_CHECK_FUNCS([OPENSSL_config EVP_md5 EVP_sha1 EVP_sha224 EVP_sha256 EVP_sha384 EVP_sha512 FIPS_mode])
AC_CHECK_DECLS([SSL_COMP_get_compression_methods,sk_SSL_COMP_pop_free,SSL_CTX_set_ecdh_auto], [], [], [
AC_INCLUDES_DEFAULT
#ifdef HAVE_OPENSSL_ERR_H
@ -393,7 +398,18 @@ case "$enable_ecdsa" in
;;
esac
AC_ARG_ENABLE(draft-dnssec-roadblock-avoidance, AC_HELP_STRING([--enable-draft-dnssec-roadblock-avoidance], [Enable experimental dnssec roadblock avoidance]))
AC_ARG_ENABLE(draft-edns-cookies, AC_HELP_STRING([--enable-draft-edns-cookies], [Enable experimental edns cookies]))
AC_ARG_ENABLE(all-drafts, AC_HELP_STRING([--enable-all-drafts], [Enable cookies and roadblock avoidance]))
case "$enable_all_drafts" in
yes)
enable_draft_dnssec_roadblock_avoidance=yes
enable_draft_edns_cookies=yes
;;
no|*)
;;
esac
case "$enable_draft_dnssec_roadblock_avoidance" in
yes)
AC_DEFINE_UNQUOTED([DNSSEC_ROADBLOCK_AVOIDANCE], [1], [Define this to enable the experimental draft dnssec roadblock avoidance.])
@ -401,8 +417,6 @@ case "$enable_draft_dnssec_roadblock_avoidance" in
no|*)
;;
esac
AC_ARG_ENABLE(draft-edns-cookies, AC_HELP_STRING([--enable-draft-edns-cookies], [Enable experimental edns cookies]))
case "$enable_draft_edns_cookies" in
yes)
if test "x_$HAVE_SSL" != "x_yes"; then
@ -896,7 +910,7 @@ AC_SUBST(GETDNS_QUERY)
AC_SUBST(INSTALL_GETDNS_QUERY)
AC_SUBST(UNINSTALL_GETDNS_QUERY)
AC_CONFIG_FILES([Makefile src/Makefile src/version.c src/getdns/getdns.h src/getdns/getdns_extra.h spec/example/Makefile src/test/Makefile doc/Makefile])
AC_CONFIG_FILES([Makefile src/Makefile src/version.c src/getdns/getdns.h src/getdns/getdns_extra.h spec/example/Makefile src/test/Makefile doc/Makefile getdns.pc])
if [ test -n "$DOXYGEN" ]
then AC_CONFIG_FILES([src/Doxyfile])
fi

View File

@ -275,10 +275,10 @@ GETDNS_BAD_DNS_CNAME_RETURNED_FOR_OTHER_TYPE: query type for other than CNAME re
Set to the DNS class number (other than Internet (IN) class desired in query.
.HP 3
"return_call_debugging" (int)
"return_call_reporting" (int)
Set to GETDNS_EXTENSION_TRUE to add the name
.I call_debugging
.I call_reporting
(list) to the top level of the response object that includes a dict for each call made to the API. TBD: more detail
.LP

11
getdns.pc.in Normal file
View File

@ -0,0 +1,11 @@
prefix=@prefix@
exec_prefix=${prefix}
libdir=${exec_prefix}/lib
includedir=${prefix}/include
Name: getdns
Version: @GETDNS_VERSION@
Description: A modern asynchronous DNS library
Libs: -L${libdir} -lgetdns
Cflags: -I${includedir}

View File

@ -48,8 +48,8 @@ AC_DEFUN([ACX_SSL_CHECKS], [
fi
AC_MSG_CHECKING([for HMAC_CTX_init in -lcrypto])
LIBS="$LIBS -lcrypto -lssl"
LIBSSL_LIBS="$LIBSSL_LIBS -lcrypto -lssl"
LIBS="$LIBS -lssl -lcrypto"
LIBSSL_LIBS="$LIBSSL_LIBS -lssl -lcrypto"
AC_TRY_LINK(, [
int HMAC_CTX_init(void);
(void)HMAC_CTX_init();

View File

@ -668,7 +668,7 @@ getdns_dict_destroy(extensions);
<li><code>specify_class</code></li>
<li><code>return_call_debugging</code></li>
<li><code>return_call_reporting</code></li>
</ul>
@ -865,9 +865,9 @@ contains the class number. Few applications will ever use this extension.</p>
<h2>3.6 Extensions Relating to the API</h2>
<p>An application might want to see debugging information for queries such as the length of time it
takes for each query to return to the API. Use the <code>return_call_debugging</code> extension. The
takes for each query to return to the API. Use the <code>return_call_reporting</code> extension. The
extension's value (an int) is set to <code>GETDNS_EXTENSION_TRUE</code> to add the name
<code>call_debugging</code> (a list) to the top level of the response object. Each member of the
<code>call_reporting</code> (a list) to the top level of the response object. Each member of the
list is a dict that represents one call made for the call to the API. Each member has the following
names:</p>
@ -875,10 +875,10 @@ names:</p>
<li><code>query_name</code> (a bindata) is the name that was sent</li>
<li><code>query_type</code> (an int) is the type that was queried for</li>
<li><code>query_to</code> (a bindata) is the address to which the query was sent</li>
<li><code>start_time</code> (a bindata) is the time the query started in milliseconds since the epoch,
represented as a uint64_t</li>
<li><code>end_time</code> (a bindata) is the time the query was received in milliseconds since the epoch,
represented as a uint64_t</li>
<li><code>run_time</code> (a bindata) is the difference between the time the successful
query started and ended in milliseconds, represented
as a uint32_t (this does not include time taken for connection set up
or transport fallback)</li>
<li><code>entire_reply</code> (a bindata) is the entire response received</li>
<li><code>dnssec_result</code> (an int) is the DNSSEC status, or <code>GETDNS_DNSSEC_NOT_PERFORMED</code>
if DNSSEC validation was not performed</li>

View File

@ -203,8 +203,9 @@ configure.status: configure
depend:
(cd $(srcdir) ; awk 'BEGIN{P=1}{if(P)print}/^# Dependencies/{P=0}' Makefile.in > Makefile.in.new )
(cd $(srcdir) ; gcc -MM -I. *.c gldns/*.c compat/*.c util/*.c extension/*.c| \
sed -e 's?gldns/?$$(srcdir)/gldns/?g' \
(blddir=`pwd`; cd $(srcdir) ; gcc -MM -I. -I"$$blddir" *.c gldns/*.c compat/*.c util/*.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?extension/?$$(srcdir)/extension/?g' \
@ -226,66 +227,67 @@ FORCE:
# Dependencies for gldns, utils, the extensions and compat functions
const-info.lo const-info.o: $(srcdir)/const-info.c getdns/getdns.h getdns/getdns_extra.h \
getdns/getdns.h $(srcdir)/const-info.h
context.lo context.o: $(srcdir)/context.c config.h $(srcdir)/gldns/str2wire.h $(srcdir)/gldns/rrdef.h \
context.lo context.o: $(srcdir)/context.c config.h $(srcdir)/debug.h $(srcdir)/gldns/str2wire.h $(srcdir)/gldns/rrdef.h \
$(srcdir)/gldns/wire2str.h $(srcdir)/context.h getdns/getdns.h getdns/getdns_extra.h \
getdns/getdns.h $(srcdir)/types-internal.h $(srcdir)/util/rbtree.h $(srcdir)/extension/libmini_event.h \
config.h $(srcdir)/util/mini_event.h $(srcdir)/util/winsock_event.h $(srcdir)/util/rbtree.h $(srcdir)/types-internal.h \
config.h $(srcdir)/util/mini_event.h $(srcdir)/util/rbtree.h $(srcdir)/types-internal.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)/stub.h $(srcdir)/list.h
$(srcdir)/dnssec.h $(srcdir)/stub.h $(srcdir)/list.h $(srcdir)/dict.h
convert.lo convert.o: $(srcdir)/convert.c config.h getdns/getdns.h getdns/getdns_extra.h \
getdns/getdns.h $(srcdir)/util-internal.h $(srcdir)/context.h $(srcdir)/types-internal.h $(srcdir)/util/rbtree.h \
$(srcdir)/extension/libmini_event.h config.h $(srcdir)/util/mini_event.h $(srcdir)/util/winsock_event.h $(srcdir)/util/rbtree.h \
$(srcdir)/extension/libmini_event.h config.h $(srcdir)/util/mini_event.h $(srcdir)/util/rbtree.h \
$(srcdir)/types-internal.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
dict.lo dict.o: $(srcdir)/dict.c $(srcdir)/types-internal.h getdns/getdns.h getdns/getdns_extra.h \
getdns/getdns.h $(srcdir)/util/rbtree.h $(srcdir)/util-internal.h config.h $(srcdir)/context.h \
$(srcdir)/extension/libmini_event.h config.h $(srcdir)/util/mini_event.h $(srcdir)/util/winsock_event.h $(srcdir)/util/rbtree.h \
$(srcdir)/types-internal.h $(srcdir)/rr-iter.h $(srcdir)/rr-dict.h $(srcdir)/gldns/gbuffer.h $(srcdir)/gldns/pkthdr.h \
$(srcdir)/dict.h $(srcdir)/list.h $(srcdir)/const-info.h $(srcdir)/gldns/wire2str.h
dnssec.lo dnssec.o: $(srcdir)/dnssec.c getdns/getdns.h config.h $(srcdir)/context.h \
$(srcdir)/gldns/wire2str.h $(srcdir)/gldns/str2wire.h $(srcdir)/gldns/rrdef.h $(srcdir)/dict.h $(srcdir)/list.h $(srcdir)/convert.h
dict.lo dict.o: $(srcdir)/dict.c config.h $(srcdir)/types-internal.h getdns/getdns.h \
getdns/getdns_extra.h getdns/getdns.h $(srcdir)/util/rbtree.h $(srcdir)/util-internal.h \
$(srcdir)/context.h $(srcdir)/extension/libmini_event.h config.h $(srcdir)/util/mini_event.h \
$(srcdir)/util/rbtree.h $(srcdir)/types-internal.h $(srcdir)/rr-iter.h $(srcdir)/rr-dict.h $(srcdir)/gldns/gbuffer.h \
$(srcdir)/gldns/pkthdr.h $(srcdir)/dict.h $(srcdir)/list.h $(srcdir)/const-info.h $(srcdir)/gldns/wire2str.h
dnssec.lo dnssec.o: $(srcdir)/dnssec.c config.h $(srcdir)/debug.h getdns/getdns.h $(srcdir)/context.h \
getdns/getdns_extra.h getdns/getdns.h $(srcdir)/types-internal.h $(srcdir)/util/rbtree.h \
$(srcdir)/extension/libmini_event.h config.h $(srcdir)/util/mini_event.h $(srcdir)/util/winsock_event.h $(srcdir)/util/rbtree.h \
$(srcdir)/extension/libmini_event.h config.h $(srcdir)/util/mini_event.h $(srcdir)/util/rbtree.h \
$(srcdir)/types-internal.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/str2wire.h $(srcdir)/gldns/rrdef.h $(srcdir)/gldns/wire2str.h \
$(srcdir)/gldns/keyraw.h $(srcdir)/gldns/parseutil.h $(srcdir)/general.h $(srcdir)/dict.h $(srcdir)/list.h \
$(srcdir)/util/val_secalgo.h
general.lo general.o: $(srcdir)/general.c config.h $(srcdir)/gldns/wire2str.h $(srcdir)/context.h getdns/getdns.h \
getdns/getdns_extra.h getdns/getdns.h $(srcdir)/types-internal.h $(srcdir)/util/rbtree.h \
$(srcdir)/extension/libmini_event.h config.h $(srcdir)/util/mini_event.h $(srcdir)/util/winsock_event.h $(srcdir)/util/rbtree.h \
$(srcdir)/extension/libmini_event.h config.h $(srcdir)/util/mini_event.h $(srcdir)/util/rbtree.h \
$(srcdir)/types-internal.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)/stub.h
list.lo list.o: $(srcdir)/list.c $(srcdir)/types-internal.h getdns/getdns.h getdns/getdns_extra.h \
getdns/getdns.h $(srcdir)/util/rbtree.h $(srcdir)/util-internal.h config.h $(srcdir)/context.h \
$(srcdir)/extension/libmini_event.h config.h $(srcdir)/util/mini_event.h $(srcdir)/util/winsock_event.h $(srcdir)/util/rbtree.h \
$(srcdir)/extension/libmini_event.h config.h $(srcdir)/util/mini_event.h $(srcdir)/util/rbtree.h \
$(srcdir)/types-internal.h $(srcdir)/rr-iter.h $(srcdir)/rr-dict.h $(srcdir)/gldns/gbuffer.h $(srcdir)/gldns/pkthdr.h \
$(srcdir)/list.h $(srcdir)/dict.h
request-internal.lo request-internal.o: $(srcdir)/request-internal.c config.h $(srcdir)/types-internal.h \
getdns/getdns.h getdns/getdns_extra.h getdns/getdns.h $(srcdir)/util/rbtree.h \
$(srcdir)/util-internal.h $(srcdir)/context.h $(srcdir)/extension/libmini_event.h config.h \
$(srcdir)/util/mini_event.h $(srcdir)/util/winsock_event.h $(srcdir)/util/rbtree.h $(srcdir)/types-internal.h $(srcdir)/rr-iter.h $(srcdir)/rr-dict.h \
$(srcdir)/util/mini_event.h $(srcdir)/util/rbtree.h $(srcdir)/types-internal.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)/gldns/rrdef.h $(srcdir)/dict.h $(srcdir)/debug.h
rr-dict.lo rr-dict.o: $(srcdir)/rr-dict.c $(srcdir)/rr-dict.h config.h getdns/getdns.h $(srcdir)/gldns/gbuffer.h \
$(srcdir)/util-internal.h $(srcdir)/context.h getdns/getdns_extra.h getdns/getdns.h \
$(srcdir)/types-internal.h $(srcdir)/util/rbtree.h $(srcdir)/extension/libmini_event.h config.h \
$(srcdir)/util/winsock_event.h $(srcdir)/util/mini_event.h $(srcdir)/util/rbtree.h $(srcdir)/types-internal.h $(srcdir)/rr-iter.h \
$(srcdir)/util/mini_event.h $(srcdir)/util/rbtree.h $(srcdir)/types-internal.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 getdns/getdns.h $(srcdir)/rr-dict.h config.h \
$(srcdir)/gldns/gbuffer.h $(srcdir)/gldns/pkthdr.h $(srcdir)/gldns/rrdef.h
stub.lo stub.o: $(srcdir)/stub.c config.h $(srcdir)/stub.h getdns/getdns.h $(srcdir)/types-internal.h \
stub.lo stub.o: $(srcdir)/stub.c config.h $(srcdir)/debug.h $(srcdir)/stub.h getdns/getdns.h $(srcdir)/types-internal.h \
getdns/getdns_extra.h getdns/getdns.h $(srcdir)/util/rbtree.h $(srcdir)/gldns/gbuffer.h \
$(srcdir)/gldns/pkthdr.h $(srcdir)/gldns/rrdef.h $(srcdir)/gldns/str2wire.h $(srcdir)/gldns/rrdef.h $(srcdir)/rr-iter.h \
$(srcdir)/rr-dict.h $(srcdir)/context.h $(srcdir)/extension/libmini_event.h config.h $(srcdir)/util/mini_event.h $(srcdir)/util/winsock_event.h \
$(srcdir)/util/rbtree.h $(srcdir)/types-internal.h $(srcdir)/util-internal.h $(srcdir)/general.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/libmini_event.h \
config.h $(srcdir)/util/mini_event.h $(srcdir)/util/rbtree.h $(srcdir)/types-internal.h \
$(srcdir)/util-internal.h $(srcdir)/general.h
sync.lo sync.o: $(srcdir)/sync.c getdns/getdns.h config.h $(srcdir)/context.h getdns/getdns_extra.h \
getdns/getdns.h $(srcdir)/types-internal.h $(srcdir)/util/rbtree.h $(srcdir)/extension/libmini_event.h \
config.h $(srcdir)/util/mini_event.h $(srcdir)/util/winsock_event.h $(srcdir)/util/rbtree.h $(srcdir)/types-internal.h $(srcdir)/general.h \
config.h $(srcdir)/util/mini_event.h $(srcdir)/util/rbtree.h $(srcdir)/types-internal.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)/stub.h $(srcdir)/gldns/wire2str.h
util-internal.lo util-internal.o: $(srcdir)/util-internal.c getdns/getdns.h $(srcdir)/dict.h $(srcdir)/util/rbtree.h \
$(srcdir)/types-internal.h getdns/getdns_extra.h getdns/getdns.h $(srcdir)/list.h \
$(srcdir)/util-internal.h config.h $(srcdir)/context.h $(srcdir)/extension/libmini_event.h config.h \
$(srcdir)/util/winsock_event.h $(srcdir)/util/mini_event.h $(srcdir)/util/rbtree.h $(srcdir)/types-internal.h $(srcdir)/rr-iter.h $(srcdir)/rr-dict.h \
util-internal.lo util-internal.o: $(srcdir)/util-internal.c config.h getdns/getdns.h $(srcdir)/dict.h \
$(srcdir)/util/rbtree.h $(srcdir)/types-internal.h getdns/getdns_extra.h getdns/getdns.h \
$(srcdir)/list.h $(srcdir)/util-internal.h $(srcdir)/context.h $(srcdir)/extension/libmini_event.h config.h \
$(srcdir)/util/mini_event.h $(srcdir)/util/rbtree.h $(srcdir)/types-internal.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
version.lo version.o: version.c
gbuffer.lo gbuffer.o: $(srcdir)/gldns/gbuffer.c config.h $(srcdir)/gldns/gbuffer.h
@ -307,37 +309,26 @@ getentropy_linux.lo getentropy_linux.o: $(srcdir)/compat/getentropy_linux.c conf
getentropy_osx.lo getentropy_osx.o: $(srcdir)/compat/getentropy_osx.c config.h
getentropy_solaris.lo getentropy_solaris.o: $(srcdir)/compat/getentropy_solaris.c config.h
getentropy_win.lo getentropy_win.o: $(srcdir)/compat/getentropy_win.c
inet_ntop.lo inet_ntop.o: $(srcdir)/compat/inet_ntop.c config.h
inet_pton.lo inet_pton.o: $(srcdir)/compat/inet_pton.c config.h
sha512.lo sha512.o: $(srcdir)/compat/sha512.c config.h
strlcpy.lo strlcpy.o: $(srcdir)/compat/strlcpy.c config.h
winsock_event.lo winsock_event.o: $(srcdir)/util/winsock_event.c config.h $(srcdir)/util/winsock_event.h $(srcdir)/util/rbtree.h \
mini_event.lo mini_event.o: $(srcdir)/util/mini_event.c config.h $(srcdir)/util/mini_event.h $(srcdir)/util/rbtree.h \
$(srcdir)/util/fptr_wlist.h
mini_event.lo mini_event.o: $(srcdir)/util/mini_event.c config.h $(srcdir)/util/mini_event.h $(srcdir)/util/rbtree.h \
$(srcdir)/util/fptr_wlist.h
rbtree.lo rbtree.o: $(srcdir)/util/rbtree.c config.h $(srcdir)/util/log.h $(srcdir)/util-internal.h config.h \
$(srcdir)/context.h getdns/getdns.h getdns/getdns_extra.h getdns/getdns.h \
$(srcdir)/types-internal.h $(srcdir)/util/rbtree.h $(srcdir)/extension/libmini_event.h \
$(srcdir)/util/winsock_event.h $(srcdir)/util/mini_event.h $(srcdir)/util/rbtree.h $(srcdir)/types-internal.h $(srcdir)/rr-iter.h $(srcdir)/rr-dict.h \
$(srcdir)/gldns/gbuffer.h $(srcdir)/gldns/pkthdr.h $(srcdir)/util/fptr_wlist.h
rbtree.lo rbtree.o: $(srcdir)/util/rbtree.c config.h $(srcdir)/util/log.h $(srcdir)/debug.h config.h \
$(srcdir)/util/fptr_wlist.h $(srcdir)/util/rbtree.h
val_secalgo.lo val_secalgo.o: $(srcdir)/util/val_secalgo.c config.h $(srcdir)/util/val_secalgo.h $(srcdir)/util/log.h \
$(srcdir)/util-internal.h config.h $(srcdir)/context.h getdns/getdns.h getdns/getdns_extra.h \
getdns/getdns.h $(srcdir)/types-internal.h $(srcdir)/util/rbtree.h $(srcdir)/extension/libmini_event.h \
$(srcdir)/util/winsock_event.h $(srcdir)/util/mini_event.h $(srcdir)/util/rbtree.h $(srcdir)/types-internal.h $(srcdir)/rr-iter.h $(srcdir)/rr-dict.h \
$(srcdir)/gldns/gbuffer.h $(srcdir)/gldns/pkthdr.h $(srcdir)/gldns/rrdef.h $(srcdir)/gldns/keyraw.h \
$(srcdir)/gldns/gbuffer.h
libev.lo libev.o: $(srcdir)/extension/libev.c $(srcdir)/getdns/getdns_ext_libev.h getdns/getdns.h \
getdns/getdns_extra.h $(srcdir)/types-internal.h getdns/getdns.h \
getdns/getdns_extra.h $(srcdir)/util/rbtree.h config.h
libevent.lo libevent.o: $(srcdir)/extension/libevent.c $(srcdir)/getdns/getdns_ext_libevent.h \
getdns/getdns.h getdns/getdns_extra.h $(srcdir)/types-internal.h getdns/getdns.h \
getdns/getdns_extra.h $(srcdir)/util/rbtree.h config.h
libmini_event.lo libmini_event.o: $(srcdir)/extension/libmini_event.c $(srcdir)/extension/libmini_event.h \
config.h $(srcdir)/util/winsock_event.h $(srcdir)/util/mini_event.h $(srcdir)/util/rbtree.h $(srcdir)/types-internal.h \
$(srcdir)/debug.h config.h $(srcdir)/gldns/rrdef.h $(srcdir)/gldns/keyraw.h $(srcdir)/gldns/gbuffer.h
winsock_event.lo winsock_event.o: $(srcdir)/util/winsock_event.c config.h
libev.lo libev.o: $(srcdir)/extension/libev.c config.h $(srcdir)/types-internal.h getdns/getdns.h \
getdns/getdns_extra.h getdns/getdns.h $(srcdir)/util/rbtree.h \
$(srcdir)/getdns/getdns_ext_libev.h getdns/getdns_extra.h
libevent.lo libevent.o: $(srcdir)/extension/libevent.c config.h $(srcdir)/types-internal.h \
getdns/getdns.h getdns/getdns_extra.h getdns/getdns.h $(srcdir)/util/rbtree.h \
$(srcdir)/context.h config.h $(srcdir)/types-internal.h $(srcdir)/extension/libmini_event.h \
$(srcdir)/util-internal.h $(srcdir)/context.h $(srcdir)/rr-iter.h $(srcdir)/rr-dict.h $(srcdir)/gldns/gbuffer.h \
$(srcdir)/gldns/pkthdr.h
libuv.lo libuv.o: $(srcdir)/extension/libuv.c config.h $(srcdir)/getdns/getdns_ext_libuv.h \
getdns/getdns.h getdns/getdns_extra.h $(srcdir)/util-internal.h config.h $(srcdir)/context.h \
getdns/getdns.h getdns/getdns_extra.h $(srcdir)/types-internal.h $(srcdir)/util/rbtree.h \
$(srcdir)/extension/libmini_event.h $(srcdir)/util/winsock_event.h $(srcdir)/util/mini_event.h $(srcdir)/util/rbtree.h \
$(srcdir)/types-internal.h $(srcdir)/rr-iter.h $(srcdir)/rr-dict.h $(srcdir)/gldns/gbuffer.h $(srcdir)/gldns/pkthdr.h
$(srcdir)/getdns/getdns_ext_libevent.h getdns/getdns_extra.h
libmini_event.lo libmini_event.o: $(srcdir)/extension/libmini_event.c config.h $(srcdir)/debug.h config.h \
$(srcdir)/types-internal.h getdns/getdns.h getdns/getdns_extra.h getdns/getdns.h \
$(srcdir)/util/rbtree.h $(srcdir)/extension/libmini_event.h $(srcdir)/util/mini_event.h $(srcdir)/util/rbtree.h
libuv.lo libuv.o: $(srcdir)/extension/libuv.c config.h $(srcdir)/debug.h config.h $(srcdir)/types-internal.h \
getdns/getdns.h getdns/getdns_extra.h getdns/getdns.h $(srcdir)/util/rbtree.h \
$(srcdir)/getdns/getdns_ext_libuv.h getdns/getdns_extra.h

View File

@ -7,76 +7,79 @@
#include "const-info.h"
static struct const_info consts_info[] = {
{ -1, NULL, "/* <unknown getdns value> */" },
{ 0, "GETDNS_RETURN_GOOD", GETDNS_RETURN_GOOD_TEXT },
{ 1, "GETDNS_RETURN_GENERIC_ERROR", GETDNS_RETURN_GENERIC_ERROR_TEXT },
{ 300, "GETDNS_RETURN_BAD_DOMAIN_NAME", GETDNS_RETURN_BAD_DOMAIN_NAME_TEXT },
{ 301, "GETDNS_RETURN_BAD_CONTEXT", GETDNS_RETURN_BAD_CONTEXT_TEXT },
{ 302, "GETDNS_RETURN_CONTEXT_UPDATE_FAIL", GETDNS_RETURN_CONTEXT_UPDATE_FAIL_TEXT },
{ 303, "GETDNS_RETURN_UNKNOWN_TRANSACTION", GETDNS_RETURN_UNKNOWN_TRANSACTION_TEXT },
{ 304, "GETDNS_RETURN_NO_SUCH_LIST_ITEM", GETDNS_RETURN_NO_SUCH_LIST_ITEM_TEXT },
{ 305, "GETDNS_RETURN_NO_SUCH_DICT_NAME", GETDNS_RETURN_NO_SUCH_DICT_NAME_TEXT },
{ 306, "GETDNS_RETURN_WRONG_TYPE_REQUESTED", GETDNS_RETURN_WRONG_TYPE_REQUESTED_TEXT },
{ 307, "GETDNS_RETURN_NO_SUCH_EXTENSION", GETDNS_RETURN_NO_SUCH_EXTENSION_TEXT },
{ 308, "GETDNS_RETURN_EXTENSION_MISFORMAT", GETDNS_RETURN_EXTENSION_MISFORMAT_TEXT },
{ 309, "GETDNS_RETURN_DNSSEC_WITH_STUB_DISALLOWED", GETDNS_RETURN_DNSSEC_WITH_STUB_DISALLOWED_TEXT },
{ 310, "GETDNS_RETURN_MEMORY_ERROR", GETDNS_RETURN_MEMORY_ERROR_TEXT },
{ 311, "GETDNS_RETURN_INVALID_PARAMETER", GETDNS_RETURN_INVALID_PARAMETER_TEXT },
{ 400, "GETDNS_DNSSEC_SECURE", GETDNS_DNSSEC_SECURE_TEXT },
{ 401, "GETDNS_DNSSEC_BOGUS", GETDNS_DNSSEC_BOGUS_TEXT },
{ 402, "GETDNS_DNSSEC_INDETERMINATE", GETDNS_DNSSEC_INDETERMINATE_TEXT },
{ 403, "GETDNS_DNSSEC_INSECURE", GETDNS_DNSSEC_INSECURE_TEXT },
{ 404, "GETDNS_DNSSEC_NOT_PERFORMED", GETDNS_DNSSEC_NOT_PERFORMED_TEXT },
{ 500, "GETDNS_NAMESPACE_DNS", GETDNS_NAMESPACE_DNS_TEXT },
{ 501, "GETDNS_NAMESPACE_LOCALNAMES", GETDNS_NAMESPACE_LOCALNAMES_TEXT },
{ 502, "GETDNS_NAMESPACE_NETBIOS", GETDNS_NAMESPACE_NETBIOS_TEXT },
{ 503, "GETDNS_NAMESPACE_MDNS", GETDNS_NAMESPACE_MDNS_TEXT },
{ 504, "GETDNS_NAMESPACE_NIS", GETDNS_NAMESPACE_NIS_TEXT },
{ 520, "GETDNS_RESOLUTION_STUB", GETDNS_RESOLUTION_STUB_TEXT },
{ 521, "GETDNS_RESOLUTION_RECURSING", GETDNS_RESOLUTION_RECURSING_TEXT },
{ 530, "GETDNS_REDIRECTS_FOLLOW", GETDNS_REDIRECTS_FOLLOW_TEXT },
{ 531, "GETDNS_REDIRECTS_DO_NOT_FOLLOW", GETDNS_REDIRECTS_DO_NOT_FOLLOW_TEXT },
{ 540, "GETDNS_TRANSPORT_UDP_FIRST_AND_FALL_BACK_TO_TCP", GETDNS_TRANSPORT_UDP_FIRST_AND_FALL_BACK_TO_TCP_TEXT },
{ 541, "GETDNS_TRANSPORT_UDP_ONLY", GETDNS_TRANSPORT_UDP_ONLY_TEXT },
{ 542, "GETDNS_TRANSPORT_TCP_ONLY", GETDNS_TRANSPORT_TCP_ONLY_TEXT },
{ 543, "GETDNS_TRANSPORT_TCP_ONLY_KEEP_CONNECTIONS_OPEN", GETDNS_TRANSPORT_TCP_ONLY_KEEP_CONNECTIONS_OPEN_TEXT },
{ 544, "GETDNS_TRANSPORT_TLS_ONLY_KEEP_CONNECTIONS_OPEN", GETDNS_TRANSPORT_TLS_ONLY_KEEP_CONNECTIONS_OPEN_TEXT },
{ 545, "GETDNS_TRANSPORT_TLS_FIRST_AND_FALL_BACK_TO_TCP_KEEP_CONNECTIONS_OPEN", GETDNS_TRANSPORT_TLS_FIRST_AND_FALL_BACK_TO_TCP_KEEP_CONNECTIONS_OPEN_TEXT },
{ 546, "GETDNS_TRANSPORT_STARTTLS_FIRST_AND_FALL_BACK_TO_TCP_KEEP_CONNECTIONS_OPEN", GETDNS_TRANSPORT_STARTTLS_FIRST_AND_FALL_BACK_TO_TCP_KEEP_CONNECTIONS_OPEN_TEXT },
{ 550, "GETDNS_APPEND_NAME_ALWAYS", GETDNS_APPEND_NAME_ALWAYS_TEXT },
{ 551, "GETDNS_APPEND_NAME_ONLY_TO_SINGLE_LABEL_AFTER_FAILURE", GETDNS_APPEND_NAME_ONLY_TO_SINGLE_LABEL_AFTER_FAILURE_TEXT },
{ 552, "GETDNS_APPEND_NAME_ONLY_TO_MULTIPLE_LABEL_NAME_AFTER_FAILURE", GETDNS_APPEND_NAME_ONLY_TO_MULTIPLE_LABEL_NAME_AFTER_FAILURE_TEXT },
{ 553, "GETDNS_APPEND_NAME_NEVER", GETDNS_APPEND_NAME_NEVER_TEXT },
{ 600, "GETDNS_CONTEXT_CODE_NAMESPACES", GETDNS_CONTEXT_CODE_NAMESPACES_TEXT },
{ 601, "GETDNS_CONTEXT_CODE_RESOLUTION_TYPE", GETDNS_CONTEXT_CODE_RESOLUTION_TYPE_TEXT },
{ 602, "GETDNS_CONTEXT_CODE_FOLLOW_REDIRECTS", GETDNS_CONTEXT_CODE_FOLLOW_REDIRECTS_TEXT },
{ 603, "GETDNS_CONTEXT_CODE_UPSTREAM_RECURSIVE_SERVERS", GETDNS_CONTEXT_CODE_UPSTREAM_RECURSIVE_SERVERS_TEXT },
{ 604, "GETDNS_CONTEXT_CODE_DNS_ROOT_SERVERS", GETDNS_CONTEXT_CODE_DNS_ROOT_SERVERS_TEXT },
{ 605, "GETDNS_CONTEXT_CODE_DNS_TRANSPORT", GETDNS_CONTEXT_CODE_DNS_TRANSPORT_TEXT },
{ 606, "GETDNS_CONTEXT_CODE_LIMIT_OUTSTANDING_QUERIES", GETDNS_CONTEXT_CODE_LIMIT_OUTSTANDING_QUERIES_TEXT },
{ 607, "GETDNS_CONTEXT_CODE_APPEND_NAME", GETDNS_CONTEXT_CODE_APPEND_NAME_TEXT },
{ 608, "GETDNS_CONTEXT_CODE_SUFFIX", GETDNS_CONTEXT_CODE_SUFFIX_TEXT },
{ 609, "GETDNS_CONTEXT_CODE_DNSSEC_TRUST_ANCHORS", GETDNS_CONTEXT_CODE_DNSSEC_TRUST_ANCHORS_TEXT },
{ 610, "GETDNS_CONTEXT_CODE_EDNS_MAXIMUM_UDP_PAYLOAD_SIZE", GETDNS_CONTEXT_CODE_EDNS_MAXIMUM_UDP_PAYLOAD_SIZE_TEXT },
{ 611, "GETDNS_CONTEXT_CODE_EDNS_EXTENDED_RCODE", GETDNS_CONTEXT_CODE_EDNS_EXTENDED_RCODE_TEXT },
{ 612, "GETDNS_CONTEXT_CODE_EDNS_VERSION", GETDNS_CONTEXT_CODE_EDNS_VERSION_TEXT },
{ 613, "GETDNS_CONTEXT_CODE_EDNS_DO_BIT", GETDNS_CONTEXT_CODE_EDNS_DO_BIT_TEXT },
{ 614, "GETDNS_CONTEXT_CODE_DNSSEC_ALLOWED_SKEW", GETDNS_CONTEXT_CODE_DNSSEC_ALLOWED_SKEW_TEXT },
{ 615, "GETDNS_CONTEXT_CODE_MEMORY_FUNCTIONS", GETDNS_CONTEXT_CODE_MEMORY_FUNCTIONS_TEXT },
{ 616, "GETDNS_CONTEXT_CODE_TIMEOUT", GETDNS_CONTEXT_CODE_TIMEOUT_TEXT },
{ 617, "GETDNS_CONTEXT_CODE_IDLE_TIMEOUT", GETDNS_CONTEXT_CODE_IDLE_TIMEOUT_TEXT },
{ 618, "GETDNS_CONTEXT_CODE_TLS_AUTHENTICATION", GETDNS_CONTEXT_CODE_TLS_AUTHENTICATION_TEXT },
{ 700, "GETDNS_CALLBACK_COMPLETE", GETDNS_CALLBACK_COMPLETE_TEXT },
{ 701, "GETDNS_CALLBACK_CANCEL", GETDNS_CALLBACK_CANCEL_TEXT },
{ 702, "GETDNS_CALLBACK_TIMEOUT", GETDNS_CALLBACK_TIMEOUT_TEXT },
{ 703, "GETDNS_CALLBACK_ERROR", GETDNS_CALLBACK_ERROR_TEXT },
{ 800, "GETDNS_NAMETYPE_DNS", GETDNS_NAMETYPE_DNS_TEXT },
{ 801, "GETDNS_NAMETYPE_WINS", GETDNS_NAMETYPE_WINS_TEXT },
{ 900, "GETDNS_RESPSTATUS_GOOD", GETDNS_RESPSTATUS_GOOD_TEXT },
{ 901, "GETDNS_RESPSTATUS_NO_NAME", GETDNS_RESPSTATUS_NO_NAME_TEXT },
{ 902, "GETDNS_RESPSTATUS_ALL_TIMEOUT", GETDNS_RESPSTATUS_ALL_TIMEOUT_TEXT },
{ 903, "GETDNS_RESPSTATUS_NO_SECURE_ANSWERS", GETDNS_RESPSTATUS_NO_SECURE_ANSWERS_TEXT },
{ 904, "GETDNS_RESPSTATUS_ALL_BOGUS_ANSWERS", GETDNS_RESPSTATUS_ALL_BOGUS_ANSWERS_TEXT },
{ -1, NULL, "/* <unknown getdns value> */" },
{ 0, "GETDNS_RETURN_GOOD", GETDNS_RETURN_GOOD_TEXT },
{ 1, "GETDNS_RETURN_GENERIC_ERROR", GETDNS_RETURN_GENERIC_ERROR_TEXT },
{ 300, "GETDNS_RETURN_BAD_DOMAIN_NAME", GETDNS_RETURN_BAD_DOMAIN_NAME_TEXT },
{ 301, "GETDNS_RETURN_BAD_CONTEXT", GETDNS_RETURN_BAD_CONTEXT_TEXT },
{ 302, "GETDNS_RETURN_CONTEXT_UPDATE_FAIL", GETDNS_RETURN_CONTEXT_UPDATE_FAIL_TEXT },
{ 303, "GETDNS_RETURN_UNKNOWN_TRANSACTION", GETDNS_RETURN_UNKNOWN_TRANSACTION_TEXT },
{ 304, "GETDNS_RETURN_NO_SUCH_LIST_ITEM", GETDNS_RETURN_NO_SUCH_LIST_ITEM_TEXT },
{ 305, "GETDNS_RETURN_NO_SUCH_DICT_NAME", GETDNS_RETURN_NO_SUCH_DICT_NAME_TEXT },
{ 306, "GETDNS_RETURN_WRONG_TYPE_REQUESTED", GETDNS_RETURN_WRONG_TYPE_REQUESTED_TEXT },
{ 307, "GETDNS_RETURN_NO_SUCH_EXTENSION", GETDNS_RETURN_NO_SUCH_EXTENSION_TEXT },
{ 308, "GETDNS_RETURN_EXTENSION_MISFORMAT", GETDNS_RETURN_EXTENSION_MISFORMAT_TEXT },
{ 309, "GETDNS_RETURN_DNSSEC_WITH_STUB_DISALLOWED", GETDNS_RETURN_DNSSEC_WITH_STUB_DISALLOWED_TEXT },
{ 310, "GETDNS_RETURN_MEMORY_ERROR", GETDNS_RETURN_MEMORY_ERROR_TEXT },
{ 311, "GETDNS_RETURN_INVALID_PARAMETER", GETDNS_RETURN_INVALID_PARAMETER_TEXT },
{ 312, "GETDNS_RETURN_NOT_IMPLEMENTED", GETDNS_RETURN_NOT_IMPLEMENTED_TEXT },
{ 399, "GETDNS_RETURN_NEED_MORE_SPACE", GETDNS_RETURN_NEED_MORE_SPACE_TEXT },
{ 400, "GETDNS_DNSSEC_SECURE", GETDNS_DNSSEC_SECURE_TEXT },
{ 401, "GETDNS_DNSSEC_BOGUS", GETDNS_DNSSEC_BOGUS_TEXT },
{ 402, "GETDNS_DNSSEC_INDETERMINATE", GETDNS_DNSSEC_INDETERMINATE_TEXT },
{ 403, "GETDNS_DNSSEC_INSECURE", GETDNS_DNSSEC_INSECURE_TEXT },
{ 404, "GETDNS_DNSSEC_NOT_PERFORMED", GETDNS_DNSSEC_NOT_PERFORMED_TEXT },
{ 500, "GETDNS_NAMESPACE_DNS", GETDNS_NAMESPACE_DNS_TEXT },
{ 501, "GETDNS_NAMESPACE_LOCALNAMES", GETDNS_NAMESPACE_LOCALNAMES_TEXT },
{ 502, "GETDNS_NAMESPACE_NETBIOS", GETDNS_NAMESPACE_NETBIOS_TEXT },
{ 503, "GETDNS_NAMESPACE_MDNS", GETDNS_NAMESPACE_MDNS_TEXT },
{ 504, "GETDNS_NAMESPACE_NIS", GETDNS_NAMESPACE_NIS_TEXT },
{ 520, "GETDNS_RESOLUTION_STUB", GETDNS_RESOLUTION_STUB_TEXT },
{ 521, "GETDNS_RESOLUTION_RECURSING", GETDNS_RESOLUTION_RECURSING_TEXT },
{ 530, "GETDNS_REDIRECTS_FOLLOW", GETDNS_REDIRECTS_FOLLOW_TEXT },
{ 531, "GETDNS_REDIRECTS_DO_NOT_FOLLOW", GETDNS_REDIRECTS_DO_NOT_FOLLOW_TEXT },
{ 540, "GETDNS_TRANSPORT_UDP_FIRST_AND_FALL_BACK_TO_TCP", GETDNS_TRANSPORT_UDP_FIRST_AND_FALL_BACK_TO_TCP_TEXT },
{ 541, "GETDNS_TRANSPORT_UDP_ONLY", GETDNS_TRANSPORT_UDP_ONLY_TEXT },
{ 542, "GETDNS_TRANSPORT_TCP_ONLY", GETDNS_TRANSPORT_TCP_ONLY_TEXT },
{ 543, "GETDNS_TRANSPORT_TCP_ONLY_KEEP_CONNECTIONS_OPEN", GETDNS_TRANSPORT_TCP_ONLY_KEEP_CONNECTIONS_OPEN_TEXT },
{ 544, "GETDNS_TRANSPORT_TLS_ONLY_KEEP_CONNECTIONS_OPEN", GETDNS_TRANSPORT_TLS_ONLY_KEEP_CONNECTIONS_OPEN_TEXT },
{ 545, "GETDNS_TRANSPORT_TLS_FIRST_AND_FALL_BACK_TO_TCP_KEEP_CONNECTIONS_OPEN", GETDNS_TRANSPORT_TLS_FIRST_AND_FALL_BACK_TO_TCP_KEEP_CONNECTIONS_OPEN_TEXT },
{ 550, "GETDNS_APPEND_NAME_ALWAYS", GETDNS_APPEND_NAME_ALWAYS_TEXT },
{ 551, "GETDNS_APPEND_NAME_ONLY_TO_SINGLE_LABEL_AFTER_FAILURE", GETDNS_APPEND_NAME_ONLY_TO_SINGLE_LABEL_AFTER_FAILURE_TEXT },
{ 552, "GETDNS_APPEND_NAME_ONLY_TO_MULTIPLE_LABEL_NAME_AFTER_FAILURE", GETDNS_APPEND_NAME_ONLY_TO_MULTIPLE_LABEL_NAME_AFTER_FAILURE_TEXT },
{ 553, "GETDNS_APPEND_NAME_NEVER", GETDNS_APPEND_NAME_NEVER_TEXT },
{ 600, "GETDNS_CONTEXT_CODE_NAMESPACES", GETDNS_CONTEXT_CODE_NAMESPACES_TEXT },
{ 601, "GETDNS_CONTEXT_CODE_RESOLUTION_TYPE", GETDNS_CONTEXT_CODE_RESOLUTION_TYPE_TEXT },
{ 602, "GETDNS_CONTEXT_CODE_FOLLOW_REDIRECTS", GETDNS_CONTEXT_CODE_FOLLOW_REDIRECTS_TEXT },
{ 603, "GETDNS_CONTEXT_CODE_UPSTREAM_RECURSIVE_SERVERS", GETDNS_CONTEXT_CODE_UPSTREAM_RECURSIVE_SERVERS_TEXT },
{ 604, "GETDNS_CONTEXT_CODE_DNS_ROOT_SERVERS", GETDNS_CONTEXT_CODE_DNS_ROOT_SERVERS_TEXT },
{ 605, "GETDNS_CONTEXT_CODE_DNS_TRANSPORT", GETDNS_CONTEXT_CODE_DNS_TRANSPORT_TEXT },
{ 606, "GETDNS_CONTEXT_CODE_LIMIT_OUTSTANDING_QUERIES", GETDNS_CONTEXT_CODE_LIMIT_OUTSTANDING_QUERIES_TEXT },
{ 607, "GETDNS_CONTEXT_CODE_APPEND_NAME", GETDNS_CONTEXT_CODE_APPEND_NAME_TEXT },
{ 608, "GETDNS_CONTEXT_CODE_SUFFIX", GETDNS_CONTEXT_CODE_SUFFIX_TEXT },
{ 609, "GETDNS_CONTEXT_CODE_DNSSEC_TRUST_ANCHORS", GETDNS_CONTEXT_CODE_DNSSEC_TRUST_ANCHORS_TEXT },
{ 610, "GETDNS_CONTEXT_CODE_EDNS_MAXIMUM_UDP_PAYLOAD_SIZE", GETDNS_CONTEXT_CODE_EDNS_MAXIMUM_UDP_PAYLOAD_SIZE_TEXT },
{ 611, "GETDNS_CONTEXT_CODE_EDNS_EXTENDED_RCODE", GETDNS_CONTEXT_CODE_EDNS_EXTENDED_RCODE_TEXT },
{ 612, "GETDNS_CONTEXT_CODE_EDNS_VERSION", GETDNS_CONTEXT_CODE_EDNS_VERSION_TEXT },
{ 613, "GETDNS_CONTEXT_CODE_EDNS_DO_BIT", GETDNS_CONTEXT_CODE_EDNS_DO_BIT_TEXT },
{ 614, "GETDNS_CONTEXT_CODE_DNSSEC_ALLOWED_SKEW", GETDNS_CONTEXT_CODE_DNSSEC_ALLOWED_SKEW_TEXT },
{ 615, "GETDNS_CONTEXT_CODE_MEMORY_FUNCTIONS", GETDNS_CONTEXT_CODE_MEMORY_FUNCTIONS_TEXT },
{ 616, "GETDNS_CONTEXT_CODE_TIMEOUT", GETDNS_CONTEXT_CODE_TIMEOUT_TEXT },
{ 617, "GETDNS_CONTEXT_CODE_IDLE_TIMEOUT", GETDNS_CONTEXT_CODE_IDLE_TIMEOUT_TEXT },
{ 618, "GETDNS_CONTEXT_CODE_TLS_AUTHENTICATION", GETDNS_CONTEXT_CODE_TLS_AUTHENTICATION_TEXT },
{ 619, "GETDNS_CONTEXT_CODE_EDNS_CLIENT_SUBNET_PRIVATE", GETDNS_CONTEXT_CODE_EDNS_CLIENT_SUBNET_PRIVATE_TEXT },
{ 620, "GETDNS_CONTEXT_CODE_TLS_QUERY_PADDING_BLOCKSIZE", GETDNS_CONTEXT_CODE_TLS_QUERY_PADDING_BLOCKSIZE_TEXT },
{ 700, "GETDNS_CALLBACK_COMPLETE", GETDNS_CALLBACK_COMPLETE_TEXT },
{ 701, "GETDNS_CALLBACK_CANCEL", GETDNS_CALLBACK_CANCEL_TEXT },
{ 702, "GETDNS_CALLBACK_TIMEOUT", GETDNS_CALLBACK_TIMEOUT_TEXT },
{ 703, "GETDNS_CALLBACK_ERROR", GETDNS_CALLBACK_ERROR_TEXT },
{ 800, "GETDNS_NAMETYPE_DNS", GETDNS_NAMETYPE_DNS_TEXT },
{ 801, "GETDNS_NAMETYPE_WINS", GETDNS_NAMETYPE_WINS_TEXT },
{ 900, "GETDNS_RESPSTATUS_GOOD", GETDNS_RESPSTATUS_GOOD_TEXT },
{ 901, "GETDNS_RESPSTATUS_NO_NAME", GETDNS_RESPSTATUS_NO_NAME_TEXT },
{ 902, "GETDNS_RESPSTATUS_ALL_TIMEOUT", GETDNS_RESPSTATUS_ALL_TIMEOUT_TEXT },
{ 903, "GETDNS_RESPSTATUS_NO_SECURE_ANSWERS", GETDNS_RESPSTATUS_NO_SECURE_ANSWERS_TEXT },
{ 904, "GETDNS_RESPSTATUS_ALL_BOGUS_ANSWERS", GETDNS_RESPSTATUS_ALL_BOGUS_ANSWERS_TEXT },
{ 1000, "GETDNS_EXTENSION_TRUE", GETDNS_EXTENSION_TRUE_TEXT },
{ 1001, "GETDNS_EXTENSION_FALSE", GETDNS_EXTENSION_FALSE_TEXT },
{ 1100, "GETDNS_BAD_DNS_CNAME_IN_TARGET", GETDNS_BAD_DNS_CNAME_IN_TARGET_TEXT },
@ -85,7 +88,6 @@ static struct const_info consts_info[] = {
{ 1200, "GETDNS_TRANSPORT_UDP", GETDNS_TRANSPORT_UDP_TEXT },
{ 1201, "GETDNS_TRANSPORT_TCP", GETDNS_TRANSPORT_TCP_TEXT },
{ 1202, "GETDNS_TRANSPORT_TLS", GETDNS_TRANSPORT_TLS_TEXT },
{ 1203, "GETDNS_TRANSPORT_STARTTLS", GETDNS_TRANSPORT_STARTTLS_TEXT },
{ 1300, "GETDNS_AUTHENTICATION_NONE", GETDNS_AUTHENTICATION_NONE_TEXT },
{ 1301, "GETDNS_AUTHENTICATION_HOSTNAME", GETDNS_AUTHENTICATION_HOSTNAME_TEXT },
};

View File

@ -54,7 +54,8 @@ typedef unsigned short in_port_t;
#include <assert.h>
#include <ctype.h>
#include "config.h"
#include "debug.h"
#include "gldns/str2wire.h"
#include "gldns/wire2str.h"
#include "context.h"
@ -63,6 +64,7 @@ typedef unsigned short in_port_t;
#include "dnssec.h"
#include "stub.h"
#include "list.h"
#include "dict.h"
#define GETDNS_PORT_ZERO 0
#define GETDNS_PORT_DNS 53
@ -80,23 +82,23 @@ typedef struct host_name_addrs {
uint8_t host_name[];
} host_name_addrs;
/* If changing these lists also remember to
change the value of GETDNS_UPSTREAM_TRANSPORTS */
static getdns_transport_list_t
getdns_upstream_transports[GETDNS_UPSTREAM_TRANSPORTS] = {
GETDNS_TRANSPORT_STARTTLS, // Define before TCP to ease fallback
GETDNS_TRANSPORT_TCP,
GETDNS_TRANSPORT_TLS,
};
static in_port_t
getdns_port_array[GETDNS_UPSTREAM_TRANSPORTS] = {
GETDNS_PORT_DNS,
GETDNS_PORT_DNS,
GETDNS_PORT_DNS_OVER_TLS
};
char*
getdns_port_str_array[] = {
GETDNS_STR_PORT_DNS,
GETDNS_STR_PORT_DNS,
GETDNS_STR_PORT_DNS_OVER_TLS
};
@ -104,7 +106,6 @@ getdns_port_str_array[] = {
/* Private functions */
static getdns_return_t create_default_namespaces(struct getdns_context *context);
static getdns_return_t create_default_dns_transports(struct getdns_context *context);
static struct getdns_list *create_default_root_servers(void);
static getdns_return_t set_os_defaults(struct getdns_context *);
static int transaction_id_cmp(const void *, const void *);
static void dispatch_updated(struct getdns_context *, uint16_t);
@ -176,7 +177,7 @@ static inline void canonicalize_dname(uint8_t *dname)
{
uint8_t *next_label;
while (*dname) {
while (*dname && !(*dname & 0xC0)) {
next_label = dname + *dname + 1;
dname += 1;
while (dname < next_label) {
@ -451,16 +452,6 @@ read_more: ;
}
}
/**
* Helper to get the default root servers.
* TODO: Implement
*/
static struct getdns_list *
create_default_root_servers()
{
return NULL;
}
/**
* check a file for changes since the last check
* and refresh the current data if changes are detected
@ -571,6 +562,7 @@ _getdns_upstream_shutdown(getdns_upstream *upstream)
upstream->tcp.write_error = 0;
upstream->writes_done = 0;
upstream->responses_received = 0;
upstream->keepalive_timeout = 0;
if (upstream->tls_hs_state != GETDNS_HS_FAILED) {
upstream->tls_hs_state = GETDNS_HS_NONE;
upstream->tls_auth_failed = 0;
@ -588,8 +580,7 @@ _getdns_upstream_shutdown(getdns_upstream *upstream)
static int
tls_is_in_transports_list(getdns_context *context) {
for (int i=0; i< context->dns_transport_count;i++) {
if (context->dns_transports[i] == GETDNS_TRANSPORT_TLS ||
context->dns_transports[i] == GETDNS_TRANSPORT_STARTTLS)
if (context->dns_transports[i] == GETDNS_TRANSPORT_TLS)
return 1;
}
return 0;
@ -599,8 +590,7 @@ static int
tls_only_is_in_transports_list(getdns_context *context) {
if (context->dns_transport_count != 1)
return 0;
if (context->dns_transports[0] == GETDNS_TRANSPORT_TLS ||
context->dns_transports[0] == GETDNS_TRANSPORT_STARTTLS)
if (context->dns_transports[0] == GETDNS_TRANSPORT_TLS)
return 1;
return 0;
}
@ -612,6 +602,64 @@ net_req_query_id_cmp(const void *id1, const void *id2)
return (intptr_t)id1 - (intptr_t)id2;
}
static getdns_tsig_info tsig_info[] = {
{ GETDNS_NO_TSIG, NULL, 0, NULL, 0, 0, 0 }
, { GETDNS_HMAC_MD5 , "hmac-md5.sig-alg.reg.int", 24
, (uint8_t *)"\x08hmac-md5\x07sig-alg\x03reg\x03int", 26, 10, 16 }
, { GETDNS_NO_TSIG, NULL, 0, NULL, 0, 0, 0 }
, { GETDNS_HMAC_SHA1 , "hmac-sha1" , 9
, (uint8_t *)"\x09hmac-sha1" , 11, 10, 20 }
, { GETDNS_HMAC_SHA224, "hmac-sha224", 11
, (uint8_t *)"\x0bhmac-sha224", 13, 14, 28 }
, { GETDNS_HMAC_SHA224, "hmac-sha256", 11
, (uint8_t *)"\x0bhmac-sha256", 13, 16, 32 }
, { GETDNS_HMAC_SHA224, "hmac-sha384", 11
, (uint8_t *)"\x0bhmac-sha383", 13, 24, 48 }
, { GETDNS_HMAC_SHA224, "hmac-sha512", 11
, (uint8_t *)"\x0bhmac-sha512", 13, 32, 64 }
, { GETDNS_HMAC_MD5 , "hmac-md5" , 8
, (uint8_t *)"\x08hmac-md5" , 10, 10, 16 }
};
const getdns_tsig_info *_getdns_get_tsig_info(getdns_tsig_algo tsig_alg)
{
return tsig_alg > sizeof(tsig_info) - 1
|| tsig_info[tsig_alg].alg == GETDNS_NO_TSIG ? NULL
: &tsig_info[tsig_alg];
}
static const getdns_tsig_algo _getdns_get_tsig_algo(getdns_bindata *algo)
{
getdns_tsig_info *i;
if (!algo || algo->size == 0)
return GETDNS_NO_TSIG;
if (algo->data[algo->size-1] != 0) {
/* Unterminated string */
for (i = tsig_info; i < tsig_info + sizeof(tsig_info); i++)
if (algo->size == i->strlen_name &&
strncasecmp((const char *)algo->data, i->name,
i->strlen_name) == 0)
return i->alg;
} else if (!_getdns_bindata_is_dname(algo)) {
/* Terminated string */
for (i = tsig_info; i < tsig_info + sizeof(tsig_info); i++)
if (algo->size - 1 == i->strlen_name &&
strncasecmp((const char *)algo->data, i->name,
i->strlen_name) == 0)
return i->alg;
} else {
/* fqdn, canonical_dname_compare is now safe to use! */
for (i = tsig_info; i < tsig_info + sizeof(tsig_info); i++)
if (canonical_dname_compare(algo->data, i->dname) == 0)
return i->alg;
}
return GETDNS_NO_TSIG;
}
static void
upstream_init(getdns_upstream *upstream,
getdns_upstreams *parent, struct addrinfo *ai)
@ -624,13 +672,13 @@ upstream_init(getdns_upstream *upstream,
/* How is this upstream doing? */
upstream->writes_done = 0;
upstream->responses_received = 0;
upstream->keepalive_timeout = 0;
upstream->to_retry = 2;
upstream->back_off = 1;
/* For sharing a socket to this upstream with TCP */
upstream->fd = -1;
upstream->tls_obj = NULL;
upstream->starttls_req = NULL;
upstream->transport = GETDNS_TRANSPORT_TCP;
upstream->tls_hs_state = GETDNS_HS_NONE;
upstream->tls_auth_failed = 0;
@ -648,6 +696,10 @@ upstream_init(getdns_upstream *upstream,
upstream->has_prev_client_cookie = 0;
upstream->has_server_cookie = 0;
upstream->tsig_alg = GETDNS_NO_TSIG;
upstream->tsig_dname_len = 0;
upstream->tsig_size = 0;
/* Tracking of network requests on this socket */
_getdns_rbtree_init(&upstream->netreq_by_query_id,
net_req_query_id_cmp);
@ -948,7 +1000,8 @@ getdns_context_create_with_extended_memory_functions(
result->timeout = 5000;
result->idle_timeout = 0;
result->follow_redirects = GETDNS_REDIRECTS_FOLLOW;
result->dns_root_servers = create_default_root_servers();
result->dns_root_servers = NULL;
result->root_servers_fn[0] = 0;
result->append_name = GETDNS_APPEND_NAME_ALWAYS;
result->suffix = NULL;
@ -1118,7 +1171,11 @@ getdns_context_destroy(struct getdns_context *context)
if (context->tls_ctx)
SSL_CTX_free(context->tls_ctx);
getdns_list_destroy(context->dns_root_servers);
if (context->dns_root_servers)
getdns_list_destroy(context->dns_root_servers);
if (context->root_servers_fn[0])
unlink(context->root_servers_fn);
getdns_list_destroy(context->suffix);
if (context->trust_anchors &&
@ -1356,18 +1413,17 @@ getdns_set_base_dns_transports(
return GETDNS_RETURN_INVALID_PARAMETER;
/* Check for valid transports and that they are used only once*/
int u=0,t=0,l=0,s=0;
int u=0,t=0,l=0;
for(i=0; i<transport_count; i++)
{
switch (transports[i]) {
case GETDNS_TRANSPORT_UDP: u++; break;
case GETDNS_TRANSPORT_TCP: t++; break;
case GETDNS_TRANSPORT_TLS: l++; break;
case GETDNS_TRANSPORT_STARTTLS: s++; break;
default: return GETDNS_RETURN_INVALID_PARAMETER;
}
}
if ( u>1 || t>1 || l>1 || s>1)
if ( u>1 || t>1 || l>1)
return GETDNS_RETURN_INVALID_PARAMETER;
if (!(new_transports = GETDNS_XMALLOC(context->my_mf,
@ -1404,7 +1460,6 @@ set_ub_dns_transport(struct getdns_context* context) {
set_ub_string_opt(context, "do-tcp:", "yes");
break;
case GETDNS_TRANSPORT_TLS:
case GETDNS_TRANSPORT_STARTTLS:
set_ub_string_opt(context, "do-udp:", "no");
set_ub_string_opt(context, "do-tcp:", "yes");
/* Find out if there is a fallback available. */
@ -1421,15 +1476,9 @@ set_ub_dns_transport(struct getdns_context* context) {
break;
}
}
if (context->dns_transports[0] == GETDNS_TRANSPORT_TLS) {
if (fallback == 0)
/* Use TLS if it is the only thing.*/
set_ub_string_opt(context, "ssl-upstream:", "yes");
break;
} else if (fallback == 0)
/* Can't support STARTTLS with no fallback. This leads to
* timeouts with un stub validation.... */
set_ub_string_opt(context, "do-tcp:", "no");
if (fallback == 0)
/* Use TLS if it is the only thing.*/
set_ub_string_opt(context, "ssl-upstream:", "yes");
break;
default:
return GETDNS_RETURN_CONTEXT_UPDATE_FAIL;
@ -1486,10 +1535,6 @@ getdns_context_set_dns_transport(
context->dns_transports[0] = GETDNS_TRANSPORT_TLS;
context->dns_transports[1] = GETDNS_TRANSPORT_TCP;
break;
case GETDNS_TRANSPORT_STARTTLS_FIRST_AND_FALL_BACK_TO_TCP_KEEP_CONNECTIONS_OPEN:
context->dns_transports[0] = GETDNS_TRANSPORT_STARTTLS;
context->dns_transports[1] = GETDNS_TRANSPORT_TCP;
break;
default:
return GETDNS_RETURN_CONTEXT_UPDATE_FAIL;
}
@ -1603,9 +1648,8 @@ getdns_context_set_idle_timeout(struct getdns_context *context, uint64_t timeout
{
RETURN_IF_NULL(context, GETDNS_RETURN_INVALID_PARAMETER);
if (timeout == 0) {
return GETDNS_RETURN_INVALID_PARAMETER;
}
/* Shuold we enforce maximum based on edns-tcp-keepalive spec? */
/* 0 should be allowed as that is the default.*/
context->idle_timeout = timeout;
@ -1642,49 +1686,98 @@ getdns_context_set_follow_redirects(struct getdns_context *context,
*
*/
getdns_return_t
getdns_context_set_dns_root_servers(struct getdns_context *context,
struct getdns_list * addresses)
getdns_context_set_dns_root_servers(
getdns_context *context, getdns_list *addresses)
{
struct getdns_list *copy = NULL;
size_t count = 0;
RETURN_IF_NULL(context, GETDNS_RETURN_INVALID_PARAMETER);
if (context->resolution_type_set != 0) {
/* already setup */
return GETDNS_RETURN_CONTEXT_UPDATE_FAIL;
}
if (addresses != NULL) {
if (_getdns_list_copy(addresses, &copy) != GETDNS_RETURN_GOOD) {
return GETDNS_RETURN_CONTEXT_UPDATE_FAIL;
}
addresses = copy;
getdns_list_get_length(addresses, &count);
if (count == 0) {
getdns_list_destroy(addresses);
addresses = NULL;
} else {
size_t i = 0;
getdns_return_t r = GETDNS_RETURN_GOOD;
/* validate and add ip str */
for (i = 0; i < count; ++i) {
struct getdns_dict *dict = NULL;
getdns_list_get_dict(addresses, i, &dict);
if (r != GETDNS_RETURN_GOOD) {
break;
}
}
if (r != GETDNS_RETURN_GOOD) {
getdns_list_destroy(addresses);
return GETDNS_RETURN_CONTEXT_UPDATE_FAIL;
}
}
}
char tmpfn[FILENAME_MAX] = P_tmpdir "/getdns-root-dns-servers-XXXXXX";
FILE *fh;
int fd;
size_t i;
getdns_dict *rr_dict;
getdns_return_t r;
getdns_bindata *addr_bd;
char dst[2048];
size_t dst_len;
getdns_list *newlist;
getdns_list_destroy(context->dns_root_servers);
context->dns_root_servers = addresses;
if (!context)
return GETDNS_RETURN_INVALID_PARAMETER;
dispatch_updated(context, GETDNS_CONTEXT_CODE_DNS_ROOT_SERVERS);
if (!addresses) {
#ifdef HAVE_LIBUNBOUND
if (ub_ctx_set_option(
context->unbound_ctx, "root-hints:", ""))
return GETDNS_RETURN_CONTEXT_UPDATE_FAIL;
#endif
if (context->dns_root_servers)
getdns_list_destroy(context->dns_root_servers);
context->dns_root_servers = NULL;
return GETDNS_RETURN_GOOD;
if (context->root_servers_fn[0])
unlink(context->root_servers_fn);
context->root_servers_fn[0] = 0;
dispatch_updated(
context, GETDNS_CONTEXT_CODE_DNS_ROOT_SERVERS);
return GETDNS_RETURN_GOOD;
}
if ((fd = mkstemp(tmpfn)) < 0)
return GETDNS_RETURN_CONTEXT_UPDATE_FAIL;
if (!(fh = fdopen(fd, "w")))
return GETDNS_RETURN_CONTEXT_UPDATE_FAIL;
for (i=0; (!(r = getdns_list_get_dict(addresses, i, &rr_dict))); i++) {
dst_len = sizeof(dst);
if (!getdns_rr_dict2str_buf(rr_dict, dst, &dst_len))
fprintf(fh, "%s", dst);
else if (getdns_dict_get_bindata(
rr_dict, "address_data", &addr_bd) &&
getdns_dict_get_bindata(
rr_dict, "/rdata/ipv4_address", &addr_bd) &&
getdns_dict_get_bindata(
rr_dict, "/rdata/ipv6_address", &addr_bd))
; /* pass */
else if (addr_bd->size == 16 &&
inet_ntop(AF_INET6, addr_bd->data, dst, sizeof(dst)))
fprintf(fh, ". NS %zu.root-servers.getdnsapi.net.\n"
"%zu.root-servers.getdnsapi.net. AAAA %s\n",
i, i, dst);
else if (addr_bd->size == 4 &&
inet_ntop(AF_INET, addr_bd->data, dst, sizeof(dst)))
fprintf(fh, ". NS %zu.root-servers.getdnsapi.net.\n"
"%zu.root-servers.getdnsapi.net. A %s\n",
i, i, dst);
}
fclose(fh);
#ifdef HAVE_LIBUNBOUND
if (ub_ctx_set_option(
context->unbound_ctx, "root-hints:", tmpfn)) {
unlink(tmpfn);
return GETDNS_RETURN_CONTEXT_UPDATE_FAIL;
}
#endif
if (_getdns_list_copy(addresses, &newlist)) {
unlink(tmpfn);
return GETDNS_RETURN_CONTEXT_UPDATE_FAIL;
}
if (context->dns_root_servers)
getdns_list_destroy(context->dns_root_servers);
context->dns_root_servers = newlist;
if (context->root_servers_fn[0])
unlink(context->root_servers_fn);
(void) memcpy(context->root_servers_fn, tmpfn, strlen(tmpfn));
dispatch_updated(context, GETDNS_CONTEXT_CODE_DNS_ROOT_SERVERS);
return GETDNS_RETURN_GOOD;
} /* getdns_context_set_dns_root_servers */
/*
@ -1821,15 +1914,21 @@ getdns_context_set_upstream_recursive_servers(struct getdns_context *context,
upstreams = upstreams_create(
context, count * GETDNS_UPSTREAM_TRANSPORTS);
for (i = 0; i < count; i++) {
getdns_dict *dict;
getdns_dict *dict;
getdns_bindata *address_type;
getdns_bindata *address_data;
getdns_bindata *tls_auth_name;
struct sockaddr_storage addr;
getdns_bindata *scope_id;
getdns_bindata *scope_id;
getdns_upstream *upstream;
getdns_bindata *tsig_alg_name, *tsig_name, *tsig_key;
getdns_tsig_algo tsig_alg;
char tsig_name_str[1024];
uint8_t tsig_dname_spc[256], *tsig_dname;
size_t tsig_dname_len;
if ((r = getdns_list_get_dict(upstream_list, i, &dict)))
goto error;
@ -1866,6 +1965,63 @@ getdns_context_set_upstream_recursive_servers(struct getdns_context *context,
eos[scope_id->size] = 0;
}
tsig_alg_name = tsig_name = tsig_key = NULL;
tsig_dname = NULL;
tsig_dname_len = 0;
if (getdns_dict_get_bindata(dict,
"tsig_algorithm", &tsig_alg_name) == GETDNS_RETURN_GOOD)
tsig_alg = _getdns_get_tsig_algo(tsig_alg_name);
else
tsig_alg = GETDNS_HMAC_MD5;
if (getdns_dict_get_bindata(dict, "tsig_name", &tsig_name))
tsig_alg = GETDNS_NO_TSIG; /* No name, no TSIG */
else if (tsig_name->size == 0)
tsig_alg = GETDNS_NO_TSIG;
else if (tsig_name->data[tsig_name->size - 1] != 0) {
/* Unterminated string */
if (tsig_name->size >= sizeof(tsig_name_str) - 1)
tsig_alg = GETDNS_NO_TSIG;
else {
(void) memcpy(tsig_name_str, tsig_name->data
, tsig_name->size);
tsig_name_str[tsig_name->size] = 0;
tsig_dname_len = sizeof(tsig_dname_spc);
if (gldns_str2wire_dname_buf(tsig_name_str,
tsig_dname_spc, &tsig_dname_len))
tsig_alg = GETDNS_NO_TSIG;
else
tsig_dname = tsig_dname_spc;
}
} else if (!_getdns_bindata_is_dname(tsig_name)) {
/* Terminated string */
tsig_dname_len = sizeof(tsig_dname_spc);
if (gldns_str2wire_dname_buf(tsig_name_str,
tsig_dname_spc, &tsig_dname_len))
tsig_alg = GETDNS_NO_TSIG;
else
tsig_dname = tsig_dname_spc;
} else if (tsig_name->size > sizeof(tsig_dname_spc))
tsig_alg = GETDNS_NO_TSIG;
else {
/* fqdn */
tsig_dname = memcpy(tsig_dname_spc, tsig_name->data
, tsig_name->size);
tsig_dname_len = tsig_name->size;
}
if (getdns_dict_get_bindata(dict, "tsig_secret", &tsig_key))
tsig_alg = GETDNS_NO_TSIG; /* No key, no TSIG */
/* Don't check TSIG length contraints here.
* Let the upstream decide what is secure enough.
*/
/* Loop to create upstreams as needed*/
for (size_t j = 0; j < GETDNS_UPSTREAM_TRANSPORTS; j++) {
uint32_t port;
@ -1893,8 +2049,7 @@ getdns_context_set_upstream_recursive_servers(struct getdns_context *context,
upstream->addr.ss_family = addr.ss_family;
upstream_init(upstream, upstreams, ai);
upstream->transport = getdns_upstream_transports[j];
if (getdns_upstream_transports[j] == GETDNS_TRANSPORT_TLS ||
getdns_upstream_transports[j] == GETDNS_TRANSPORT_STARTTLS) {
if (getdns_upstream_transports[j] == GETDNS_TRANSPORT_TLS) {
if ((r = getdns_dict_get_bindata(
dict, "tls_auth_name", &tls_auth_name)) == GETDNS_RETURN_GOOD) {
/*TODO: VALIDATE THIS STRING!*/
@ -1904,6 +2059,25 @@ getdns_context_set_upstream_recursive_servers(struct getdns_context *context,
upstream->tls_auth_name[tls_auth_name->size] = '\0';
}
}
if ((upstream->tsig_alg = tsig_alg)) {
if (tsig_name) {
(void) memcpy(upstream->tsig_dname,
tsig_dname, tsig_dname_len);
upstream->tsig_dname_len =
tsig_dname_len;
} else
upstream->tsig_dname_len = 0;
if (tsig_key) {
(void) memcpy(upstream->tsig_key,
tsig_key->data, tsig_key->size);
upstream->tsig_size = tsig_key->size;
} else
upstream->tsig_size = 0;
} else {
upstream->tsig_dname_len = 0;
upstream->tsig_size = 0;
}
upstreams->count++;
freeaddrinfo(ai);
}
@ -2290,7 +2464,6 @@ ub_setup_recursing(struct ub_ctx *ctx, getdns_context *context)
_getdns_rr_iter rr_spc, *rr;
char ta_str[8192];
/* TODO: use the root servers via root hints file */
(void) ub_ctx_set_fwd(ctx, NULL);
if (!context->unbound_ta_set && context->trust_anchors) {
for ( rr = _getdns_rr_iter_init( &rr_spc
@ -2298,7 +2471,7 @@ ub_setup_recursing(struct ub_ctx *ctx, getdns_context *context)
, context->trust_anchors_len)
; rr ; rr = _getdns_rr_iter_next(rr) ) {
(void) gldns_wire2str_rr_buf(rr->pos,
(void) gldns_wire2str_rr_buf((UNCONST_UINT8_p)rr->pos,
rr->nxt - rr->pos, ta_str, sizeof(ta_str));
(void) ub_ctx_add_ta(ctx, ta_str);
}
@ -2386,9 +2559,9 @@ _getdns_context_prepare_for_resolution(struct getdns_context *context,
}
}
/* Block use of STARTTLS/TLS ONLY in recursive mode as it won't work */
/* Block use of TLS ONLY in recursive mode as it won't work */
/* Note: If TLS is used in recursive mode this will try TLS on port
* 53 so it is blocked here. So is 'STARTTLS only' at the moment. */
* 53 so it is blocked here. */
if (context->resolution_type == GETDNS_RESOLUTION_RECURSING &&
tls_only_is_in_transports_list(context) == 1)
return GETDNS_RETURN_BAD_CONTEXT;
@ -2490,8 +2663,7 @@ _getdns_strdup(const struct mem_funcs *mfs, const char *s)
}
struct getdns_bindata *
_getdns_bindata_copy(struct mem_funcs *mfs,
const struct getdns_bindata *src)
_getdns_bindata_copy(struct mem_funcs *mfs, size_t size, const uint8_t *data)
{
/* Don't know why, but nodata allows
* empty bindatas with the python bindings
@ -2499,20 +2671,16 @@ _getdns_bindata_copy(struct mem_funcs *mfs,
static uint8_t nodata[] = { 0, 0, 0, 0, 0, 0, 0, 0 };
struct getdns_bindata *dst;
if (!src)
return NULL;
if (!(dst = GETDNS_MALLOC(*mfs, struct getdns_bindata)))
return NULL;
dst->size = src->size;
if ((dst->size = src->size)) {
dst->data = GETDNS_XMALLOC(*mfs, uint8_t, src->size);
if ((dst->size = size)) {
dst->data = GETDNS_XMALLOC(*mfs, uint8_t, size);
if (!dst->data) {
GETDNS_FREE(*mfs, dst);
return NULL;
}
(void) memcpy(dst->data, src->data, src->size);
(void) memcpy(dst->data, data, size);
} else {
dst->data = nodata;
}
@ -2652,9 +2820,12 @@ upstream_port(getdns_upstream *upstream)
}
static getdns_dict*
_get_context_settings(getdns_context* context) {
_get_context_settings(getdns_context* context)
{
getdns_return_t r = GETDNS_RETURN_GOOD;
getdns_dict* result = getdns_dict_create_with_context(context);
getdns_list *upstreams;
if (!result) {
return NULL;
}
@ -2672,34 +2843,8 @@ _get_context_settings(getdns_context* context) {
r |= getdns_dict_set_int(result, "append_name", context->append_name);
/* list fields */
if (context->suffix) r |= getdns_dict_set_list(result, "suffix", context->suffix);
if (context->upstreams && context->upstreams->count > 0) {
size_t i;
getdns_upstream *upstream;
getdns_list *upstreams =
getdns_list_create_with_context(context);
for (i = 0; i < context->upstreams->count;) {
size_t j;
getdns_dict *d;
upstream = &context->upstreams->upstreams[i];
d = sockaddr_dict(context,
(struct sockaddr *)&upstream->addr);
for ( j = 1, i++
; j < GETDNS_UPSTREAM_TRANSPORTS &&
i < context->upstreams->count
; j++, i++) {
upstream = &context->upstreams->upstreams[i];
if (upstream->transport != GETDNS_TRANSPORT_TLS)
continue;
if (upstream_port(upstream) != getdns_port_array[j])
continue;
(void) getdns_dict_set_int(d, "tls_port",
(uint32_t) upstream_port(upstream));
}
r |= _getdns_list_append_dict(upstreams, d);
getdns_dict_destroy(d);
}
if (!getdns_context_get_upstream_recursive_servers(context, &upstreams)) {
r |= getdns_dict_set_list(result, "upstream_recursive_servers",
upstreams);
getdns_list_destroy(upstreams);
@ -2933,12 +3078,6 @@ getdns_context_get_dns_transport(getdns_context *context,
else
return GETDNS_RETURN_WRONG_TYPE_REQUESTED;
}
if (transports[0] == GETDNS_TRANSPORT_STARTTLS) {
if (count == 2 && transports[1] == GETDNS_TRANSPORT_TCP)
*value = GETDNS_TRANSPORT_STARTTLS_FIRST_AND_FALL_BACK_TO_TCP_KEEP_CONNECTIONS_OPEN;
else
return GETDNS_RETURN_WRONG_TYPE_REQUESTED;
}
return GETDNS_RETURN_GOOD;
}
@ -3009,9 +3148,8 @@ getdns_context_get_dns_root_servers(getdns_context *context,
RETURN_IF_NULL(context, GETDNS_RETURN_INVALID_PARAMETER);
RETURN_IF_NULL(value, GETDNS_RETURN_INVALID_PARAMETER);
*value = NULL;
if (context->dns_root_servers) {
if (context->dns_root_servers)
return _getdns_list_copy(context->dns_root_servers, value);
}
return GETDNS_RETURN_GOOD;
}
@ -3066,43 +3204,87 @@ getdns_context_get_dnssec_allowed_skew(getdns_context *context,
getdns_return_t
getdns_context_get_upstream_recursive_servers(getdns_context *context,
getdns_list **upstream_list) {
RETURN_IF_NULL(context, GETDNS_RETURN_INVALID_PARAMETER);
RETURN_IF_NULL(upstream_list, GETDNS_RETURN_INVALID_PARAMETER);
*upstream_list = NULL;
if (context->upstreams && context->upstreams->count > 0) {
getdns_return_t r = GETDNS_RETURN_GOOD;
size_t i;
getdns_upstream *upstream;
getdns_list *upstreams = getdns_list_create();
for (i = 0; i < context->upstreams->count;) {
getdns_list **upstreams_r)
{
size_t i;
getdns_list *upstreams;
getdns_return_t r;
if (!context || !upstreams_r)
return GETDNS_RETURN_INVALID_PARAMETER;
if (!(upstreams = getdns_list_create_with_context(context)))
return GETDNS_RETURN_MEMORY_ERROR;
if (!context->upstreams || context->upstreams->count == 0) {
*upstreams_r = upstreams;
return GETDNS_RETURN_GOOD;
}
r = GETDNS_RETURN_GOOD;
i = 0;
while (!r && i < context->upstreams->count) {
size_t j;
getdns_dict *d;
upstream = &context->upstreams->upstreams[i];
d = sockaddr_dict(context, (struct sockaddr *)&upstream->addr);
getdns_upstream *upstream = &context->upstreams->upstreams[i];
getdns_bindata bindata;
const getdns_tsig_info *tsig_info;
if (!(d =
sockaddr_dict(context, (struct sockaddr*)&upstream->addr))) {
r = GETDNS_RETURN_MEMORY_ERROR;
break;
}
if (upstream->tsig_alg) {
tsig_info = _getdns_get_tsig_info(upstream->tsig_alg);
if ((r = _getdns_dict_set_const_bindata(
d, "tsig_algorithm",
tsig_info->dname_len, tsig_info->dname)))
break;
if (upstream->tsig_dname_len) {
bindata.data = upstream->tsig_dname;
bindata.size = upstream->tsig_dname_len;
if ((r = getdns_dict_set_bindata(
d, "tsig_name", &bindata)))
break;
}
if (upstream->tsig_size) {
bindata.data = upstream->tsig_key;
bindata.size = upstream->tsig_size;
if ((r = getdns_dict_set_bindata(
d, "tsig_secret", &bindata)))
break;
}
}
for ( j = 1, i++
; j < GETDNS_UPSTREAM_TRANSPORTS &&
i < context->upstreams->count
; j++, i++) {
upstream = &context->upstreams->upstreams[i];
if (upstream->transport != GETDNS_TRANSPORT_TLS)
continue;
if (upstream_port(upstream) != getdns_port_array[j])
continue;
(void) getdns_dict_set_int(d, "tls_port",
(uint32_t) upstream_port(upstream));
if (upstream->transport == GETDNS_TRANSPORT_UDP &&
upstream_port(upstream) != getdns_port_array[j] &&
(r = getdns_dict_set_int(d, "port",
(uint32_t)upstream_port(upstream))))
break;
if (upstream->transport == GETDNS_TRANSPORT_TLS &&
upstream_port(upstream) != getdns_port_array[j] &&
(r = getdns_dict_set_int(d, "tls_port",
(uint32_t)upstream_port(upstream))))
break;
}
r |= _getdns_list_append_dict(upstreams, d);
if (!r)
r = _getdns_list_append_dict(upstreams, d);
getdns_dict_destroy(d);
}
if (r != GETDNS_RETURN_GOOD) {
getdns_list_destroy(upstreams);
return GETDNS_RETURN_MEMORY_ERROR;
}
*upstream_list = upstreams;
}
return GETDNS_RETURN_GOOD;
if (r)
getdns_list_destroy(upstreams);
else
*upstreams_r = upstreams;
return r;
}
getdns_return_t

View File

@ -79,6 +79,29 @@ typedef enum getdns_tls_hs_state {
GETDNS_HS_FAILED
} getdns_tls_hs_state_t;
typedef enum getdns_tsig_algo {
GETDNS_NO_TSIG = 0, /* Do not use tsig */
GETDNS_HMAC_MD5 = 1, /* 128 bits */
GETDNS_GSS_TSIG = 2, /* Not supported */
GETDNS_HMAC_SHA1 = 3, /* 160 bits */
GETDNS_HMAC_SHA224 = 4,
GETDNS_HMAC_SHA256 = 5,
GETDNS_HMAC_SHA384 = 6,
GETDNS_HMAC_SHA512 = 7
} getdns_tsig_algo;
typedef struct getdns_tsig_info {
getdns_tsig_algo alg;
const char *name;
size_t strlen_name;
const uint8_t *dname;
size_t dname_len;
size_t min_size; /* in # octets */
size_t max_size; /* Actual size in # octets */
} getdns_tsig_info;
const getdns_tsig_info *_getdns_get_tsig_info(getdns_tsig_algo tsig_alg);
typedef struct getdns_upstream {
/* backpointer to containing upstreams structure */
struct getdns_upstreams *upstreams;
@ -89,6 +112,7 @@ typedef struct getdns_upstream {
/* How is this upstream doing? */
size_t writes_done;
size_t responses_received;
uint64_t keepalive_timeout;
int to_retry;
int back_off;
@ -97,7 +121,6 @@ typedef struct getdns_upstream {
getdns_transport_list_t transport;
SSL* tls_obj;
getdns_tls_hs_state_t tls_hs_state;
getdns_dns_req * starttls_req;
getdns_eventloop_event event;
getdns_eventloop *loop;
getdns_tcp_state tcp;
@ -120,6 +143,13 @@ typedef struct getdns_upstream {
unsigned has_server_cookie : 1;
unsigned server_cookie_len : 5;
/* TSIG */
uint8_t tsig_dname[256];
size_t tsig_dname_len;
size_t tsig_size;
uint8_t tsig_key[256];
getdns_tsig_algo tsig_alg;
} getdns_upstream;
typedef struct getdns_upstreams {
@ -138,7 +168,8 @@ struct getdns_context {
uint64_t timeout;
uint64_t idle_timeout;
getdns_redirects_t follow_redirects;
struct getdns_list *dns_root_servers;
getdns_list *dns_root_servers;
char root_servers_fn[FILENAME_MAX];
getdns_append_name_t append_name;
struct getdns_list *suffix;
uint8_t *trust_anchors;
@ -240,8 +271,7 @@ getdns_return_t _getdns_context_cancel_request(struct getdns_context *context,
char *_getdns_strdup(const struct mem_funcs *mfs, const char *str);
struct getdns_bindata *_getdns_bindata_copy(
struct mem_funcs *mfs,
const struct getdns_bindata *src);
struct mem_funcs *mfs, size_t size, const uint8_t *data);
void _getdns_bindata_destroy(
struct mem_funcs *mfs,

View File

@ -48,6 +48,9 @@
#include "util-internal.h"
#include "gldns/wire2str.h"
#include "gldns/str2wire.h"
#include "dict.h"
#include "list.h"
#include "convert.h"
/* stuff to make it compile pedantically */
#define UNUSED_PARAM(x) ((void)(x))
@ -221,4 +224,367 @@ getdns_strerror(getdns_return_t err, char *buf, size_t buflen)
return GETDNS_RETURN_GOOD;
} /* getdns_strerror */
/* --------------------- rr_dict, wire, str conversions --------------------- */
getdns_return_t
getdns_rr_dict2wire(
const getdns_dict *rr_dict, uint8_t **wire, size_t *wire_sz)
{
uint8_t buf_spc[4096], *buf;
size_t buf_len = sizeof(buf_spc);
getdns_return_t r = getdns_rr_dict2wire_buf(
rr_dict, buf_spc, &buf_len);
if (r != GETDNS_RETURN_GOOD && r != GETDNS_RETURN_NEED_MORE_SPACE)
return r;
if (!(buf = malloc(buf_len)))
return GETDNS_RETURN_MEMORY_ERROR;
if (!r)
memcpy(buf, buf_spc, buf_len);
else if ((r = getdns_rr_dict2wire_buf(rr_dict, buf, &buf_len))) {
free(buf);
return r;
}
*wire = buf;
*wire_sz = buf_len;
return GETDNS_RETURN_GOOD;
}
getdns_return_t
getdns_rr_dict2wire_buf(
const getdns_dict *rr_dict, uint8_t *wire, size_t *wire_sz)
{
ssize_t my_wire_sz;
getdns_return_t r;
if (!wire_sz)
return GETDNS_RETURN_INVALID_PARAMETER;
else
my_wire_sz = *wire_sz;
r = getdns_rr_dict2wire_scan(rr_dict, &wire, &my_wire_sz);
if (r == GETDNS_RETURN_GOOD || r == GETDNS_RETURN_NEED_MORE_SPACE)
*wire_sz -= my_wire_sz;
return r;
}
getdns_return_t
getdns_rr_dict2wire_scan(
const getdns_dict *rr_dict, uint8_t **wire, ssize_t *wire_sz)
{
getdns_return_t r;
gldns_buffer gbuf;
if (!rr_dict || !wire || !*wire || !wire_sz)
return GETDNS_RETURN_INVALID_PARAMETER;
gldns_buffer_init_frm_data(&gbuf, *wire, *wire_sz);
if ((r = _getdns_rr_dict2wire(rr_dict, &gbuf)))
return r;
if (gldns_buffer_position(&gbuf) == 0)
return GETDNS_RETURN_GENERIC_ERROR;
*wire += gldns_buffer_position(&gbuf);
*wire_sz -= gldns_buffer_position(&gbuf);
if (gldns_buffer_position(&gbuf) > gldns_buffer_limit(&gbuf))
return GETDNS_RETURN_NEED_MORE_SPACE;
else
return GETDNS_RETURN_GOOD;
}
static struct mem_funcs _getdns_plain_mem_funcs = {
MF_PLAIN, .mf.pln = { malloc, realloc, free }
};
getdns_return_t
_getdns_wire2rr_dict(struct mem_funcs *mf,
const uint8_t *wire, size_t wire_len, getdns_dict **rr_dict)
{
return _getdns_wire2rr_dict_scan(mf, &wire, &wire_len, rr_dict);
}
getdns_return_t
getdns_wire2rr_dict(
const uint8_t *wire, size_t wire_len, getdns_dict **rr_dict)
{
return _getdns_wire2rr_dict(
&_getdns_plain_mem_funcs, wire, wire_len, rr_dict);
}
getdns_return_t
_getdns_wire2rr_dict_buf(struct mem_funcs *mf,
const uint8_t *wire, size_t *wire_len, getdns_dict **rr_dict)
{
size_t my_wire_len;
getdns_return_t r;
if (!wire_len)
return GETDNS_RETURN_INVALID_PARAMETER;
else
my_wire_len = *wire_len;
if ((r = _getdns_wire2rr_dict_scan(mf, &wire, &my_wire_len, rr_dict)))
return r;
*wire_len -= my_wire_len;
return GETDNS_RETURN_GOOD;
}
getdns_return_t
getdns_wire2rr_dict_buf(
const uint8_t *wire, size_t *wire_len, getdns_dict **rr_dict)
{
return _getdns_wire2rr_dict_buf(
&_getdns_plain_mem_funcs, wire, wire_len, rr_dict);
}
getdns_return_t
_getdns_wire2rr_dict_scan(struct mem_funcs *mf,
const uint8_t **wire, size_t *wire_len, getdns_dict **rr_dict)
{
_getdns_rr_iter rr_iter_spc, *rr_iter;
if (!wire || !*wire || !wire_len || !rr_dict)
return GETDNS_RETURN_INVALID_PARAMETER;
if (!(rr_iter = _getdns_single_rr_iter_init(
&rr_iter_spc, *wire, *wire_len)))
return GETDNS_RETURN_GENERIC_ERROR;
if (!(*rr_dict = _getdns_rr_iter2rr_dict(mf, rr_iter)))
return GETDNS_RETURN_MEMORY_ERROR;
*wire_len -= (rr_iter->nxt - rr_iter->pos);
*wire = rr_iter->nxt;
return GETDNS_RETURN_GOOD;
}
getdns_return_t
getdns_wire2rr_dict_scan(
const uint8_t **wire, size_t *wire_len, getdns_dict **rr_dict)
{
return _getdns_wire2rr_dict_scan(
&_getdns_plain_mem_funcs, wire, wire_len, rr_dict);
}
getdns_return_t
getdns_rr_dict2str(
const getdns_dict *rr_dict, char **str)
{
char buf_spc[4096], *buf;
size_t buf_len = sizeof(buf_spc) - 1;
getdns_return_t r = getdns_rr_dict2str_buf(
rr_dict, buf_spc, &buf_len);
if (r != GETDNS_RETURN_GOOD && r != GETDNS_RETURN_NEED_MORE_SPACE)
return r;
buf_len += 1;
if (!(buf = malloc(buf_len)))
return GETDNS_RETURN_MEMORY_ERROR;
if (!r)
memcpy(buf, buf_spc, buf_len);
else if ((r = getdns_rr_dict2str_buf(rr_dict, buf, &buf_len))) {
free(buf);
return r;
}
*str = buf;
return GETDNS_RETURN_GOOD;
}
getdns_return_t
getdns_rr_dict2str_buf(
const getdns_dict *rr_dict, char *str, size_t *str_len)
{
ssize_t my_str_len;
getdns_return_t r;
if (!str_len)
return GETDNS_RETURN_INVALID_PARAMETER;
else
my_str_len = *str_len;
r = getdns_rr_dict2str_scan(rr_dict, &str, &my_str_len);
if (r == GETDNS_RETURN_GOOD || r == GETDNS_RETURN_NEED_MORE_SPACE)
*str_len -= my_str_len;
return r;
}
getdns_return_t
getdns_rr_dict2str_scan(
const getdns_dict *rr_dict, char **str, ssize_t *str_len)
{
getdns_return_t r;
gldns_buffer gbuf;
uint8_t buf_spc[4096], *buf = buf_spc, *scan_buf;
size_t sz, scan_sz;
ssize_t prev_str_len;
char *prev_str;
int sz_needed;
if (!rr_dict || !str || !*str || !str_len)
return GETDNS_RETURN_INVALID_PARAMETER;
gldns_buffer_init_frm_data(&gbuf, buf, sizeof(buf_spc));
r = _getdns_rr_dict2wire(rr_dict, &gbuf);
if (gldns_buffer_position(&gbuf) > sizeof(buf_spc)) {
if (!(buf = GETDNS_XMALLOC(
rr_dict->mf, uint8_t, (sz = gldns_buffer_position(&gbuf))))) {
return GETDNS_RETURN_MEMORY_ERROR;
}
gldns_buffer_init_frm_data(&gbuf, buf, sz);
r = _getdns_rr_dict2wire(rr_dict, &gbuf);
}
if (r) {
if (buf != buf_spc)
GETDNS_FREE(rr_dict->mf, buf);
return r;
}
scan_buf = gldns_buffer_begin(&gbuf);
scan_sz = gldns_buffer_position(&gbuf);
prev_str = *str;
prev_str_len = *str_len;
sz = (size_t)*str_len;
sz_needed = gldns_wire2str_rr_scan(
&scan_buf, &scan_sz, str, &sz, NULL, 0);
if (sz_needed > prev_str_len) {
*str = prev_str + sz_needed;
*str_len = prev_str_len - sz_needed;
r = GETDNS_RETURN_NEED_MORE_SPACE;
} else {
*str_len = sz;
**str = 0;
}
if (buf != buf_spc)
GETDNS_FREE(rr_dict->mf, buf);
return r;
}
getdns_return_t
_getdns_str2rr_dict(struct mem_funcs *mf,
const char *str, getdns_dict **rr_dict, const char *origin, uint32_t default_ttl)
{
uint8_t wire_spc[4096], *wire = wire_spc;
uint8_t origin_spc[256], *origin_wf;
size_t origin_len = sizeof(origin_spc), wire_len = sizeof(wire_spc);
int e;
getdns_return_t r;
if (!str || !rr_dict)
return GETDNS_RETURN_INVALID_PARAMETER;
if (!origin)
origin_wf = NULL;
else if (gldns_str2wire_dname_buf(origin, origin_spc, &origin_len))
return GETDNS_RETURN_GENERIC_ERROR;
else
origin_wf = origin_spc;
e = gldns_str2wire_rr_buf(str, wire, &wire_len,
NULL, default_ttl, origin_wf, origin_len, NULL, 0);
if (GLDNS_WIREPARSE_ERROR(e) == GLDNS_WIREPARSE_ERR_BUFFER_TOO_SMALL) {
if (!(wire = GETDNS_XMALLOC(
*mf, uint8_t, (wire_len = GLDNS_RR_BUF_SIZE))))
return GETDNS_RETURN_MEMORY_ERROR;
e = gldns_str2wire_rr_buf(str, wire, &wire_len,
NULL, default_ttl, origin_wf, origin_len, NULL, 0);
}
if (e) {
if (wire != wire_spc)
GETDNS_FREE(*mf, wire);
return GETDNS_RETURN_GENERIC_ERROR;
}
r = _getdns_wire2rr_dict(mf, wire, wire_len, rr_dict);
if (wire != wire_spc)
GETDNS_FREE(*mf, wire);
return r;
}
getdns_return_t
getdns_str2rr_dict(
const char *str, getdns_dict **rr_dict, const char *origin, uint32_t default_ttl)
{
return _getdns_str2rr_dict(
&_getdns_plain_mem_funcs, str, rr_dict, origin, default_ttl);
}
getdns_return_t
_getdns_fp2rr_list(struct mem_funcs *mf,
FILE *in, getdns_list **rr_list, const char *origin, uint32_t default_ttl)
{
struct gldns_file_parse_state pst;
getdns_list *rrs;
getdns_return_t r = GETDNS_RETURN_GOOD;
uint8_t *rr;
size_t len, dname_len;
getdns_dict *rr_dict;
if (!in || !rr_list)
return GETDNS_RETURN_INVALID_PARAMETER;
if (!origin) {
*pst.origin = 0;
pst.origin_len = 1;
} else if (gldns_str2wire_dname_buf(origin,pst.origin,&pst.origin_len))
return GETDNS_RETURN_GENERIC_ERROR;
*pst.prev_rr = 0;
pst.prev_rr_len = 1;
pst.default_ttl = default_ttl;
pst.lineno = 1;
if (!(rrs = _getdns_list_create_with_mf(mf)))
return GETDNS_RETURN_MEMORY_ERROR;
if (!(rr = GETDNS_XMALLOC(*mf, uint8_t, GLDNS_RR_BUF_SIZE)))
r = GETDNS_RETURN_MEMORY_ERROR;
else while (r == GETDNS_RETURN_GOOD && !feof(in)) {
len = GLDNS_RR_BUF_SIZE;
dname_len = 0;
if (gldns_fp2wire_rr_buf(in, rr, &len, &dname_len, &pst))
break;
if (dname_len && dname_len < sizeof(pst.prev_rr)) {
memcpy(pst.prev_rr, rr, dname_len);
pst.prev_rr_len = dname_len;
}
if (len == 0)
continue;
if ((r = _getdns_wire2rr_dict(mf, rr, len, &rr_dict)))
break;
r = _getdns_list_append_dict(rrs, rr_dict);
getdns_dict_destroy(rr_dict);
}
if (rr)
GETDNS_FREE(*mf, rr);
if (r)
getdns_list_destroy(rrs);
else
*rr_list = rrs;
return r;
}
getdns_return_t
getdns_fp2rr_list(
FILE *in, getdns_list **rr_list, const char *origin, uint32_t default_ttl)
{
return _getdns_fp2rr_list(
&_getdns_plain_mem_funcs, in, rr_list, origin, default_ttl);
}
/* convert.c */

57
src/convert.h Normal file
View File

@ -0,0 +1,57 @@
/**
*
* \file convert.h
* @brief getdns label conversion functions
*
*/
/*
* 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 _GETDNS_CONVERT_H_
#define _GETDNS_CONVERT_H_
#include "types-internal.h"
#include <stdio.h>
getdns_return_t _getdns_wire2rr_dict(struct mem_funcs *mf,
const uint8_t *wire, size_t wire_len, getdns_dict **rr_dict);
getdns_return_t _getdns_wire2rr_dict_buf(struct mem_funcs *mf,
const uint8_t *wire, size_t *wire_len, getdns_dict **rr_dict);
getdns_return_t _getdns_wire2rr_dict_scan(struct mem_funcs *mf,
const uint8_t **wire, size_t *wire_len, getdns_dict **rr_dict);
getdns_return_t _getdns_str2rr_dict(struct mem_funcs *mf, const char *str,
getdns_dict **rr_dict, const char *origin, uint32_t default_ttl);
getdns_return_t _getdns_fp2rr_list(struct mem_funcs *mf, FILE *in,
getdns_list **rr_list, const char *origin, uint32_t default_ttl);
#endif
/* convert.h */

90
src/debug.h Normal file
View File

@ -0,0 +1,90 @@
/**
*
* \file debug.h
* /brief Macro's for debugging
*
*/
/*
* Copyright (c) 2015, 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 DEBUG_H
#define DEBUG_H
#include "config.h"
#define DEBUG_ON(...) do { \
struct timeval tv; \
struct tm tm; \
char buf[10]; \
\
gettimeofday(&tv, NULL); \
gmtime_r(&tv.tv_sec, &tm); \
strftime(buf, 10, "%T", &tm); \
fprintf(stderr, "[%s.%.6d] ", buf, (int)tv.tv_usec); \
fprintf(stderr, __VA_ARGS__); \
} while (0)
#define DEBUG_NL(...) do { \
struct timeval tv; \
struct tm tm; \
char buf[10]; \
\
gettimeofday(&tv, NULL); \
gmtime_r(&tv.tv_sec, &tm); \
strftime(buf, 10, "%T", &tm); \
fprintf(stderr, "[%s.%.6d] ", buf, (int)tv.tv_usec); \
fprintf(stderr, __VA_ARGS__); \
fprintf(stderr, "\n"); \
} while (0)
#define DEBUG_OFF(...) do {} while (0)
#if defined(SCHED_DEBUG) && SCHED_DEBUG
#include <time.h>
#define DEBUG_SCHED(...) DEBUG_ON(__VA_ARGS__)
#else
#define DEBUG_SCHED(...) DEBUG_OFF(__VA_ARGS__)
#endif
#if defined(STUB_DEBUG) && STUB_DEBUG
#include <time.h>
#define DEBUG_STUB(...) DEBUG_ON(__VA_ARGS__)
#else
#define DEBUG_STUB(...) DEBUG_OFF(__VA_ARGS__)
#endif
#if defined(SEC_DEBUG) && SEC_DEBUG
#include <time.h>
#define DEBUG_SEC(...) DEBUG_ON(__VA_ARGS__)
#else
#define DEBUG_SEC(...) DEBUG_OFF(__VA_ARGS__)
#endif
#endif
/* debug.h */

View File

@ -577,17 +577,17 @@ getdns_dict_set_list(
/*---------------------------------------- getdns_dict_set_bindata */
getdns_return_t
getdns_dict_set_bindata(
getdns_dict *dict, const char *name, const getdns_bindata *child_bindata)
_getdns_dict_set_const_bindata(
getdns_dict *dict, const char *name, size_t size, const uint8_t *data)
{
getdns_item *item;
getdns_bindata *newbindata;
getdns_return_t r;
if (!dict || !name || !child_bindata)
if (!dict || !name)
return GETDNS_RETURN_INVALID_PARAMETER;
if (!(newbindata = _getdns_bindata_copy(&dict->mf, child_bindata)))
if (!(newbindata = _getdns_bindata_copy(&dict->mf, size, data)))
return GETDNS_RETURN_MEMORY_ERROR;
if ((r = _getdns_dict_find_and_add(dict, name, &item))) {
@ -599,6 +599,15 @@ getdns_dict_set_bindata(
return GETDNS_RETURN_GOOD;
} /* getdns_dict_set_bindata */
getdns_return_t
getdns_dict_set_bindata(
getdns_dict *dict, const char *name, const getdns_bindata *child_bindata)
{
return !child_bindata ? GETDNS_RETURN_INVALID_PARAMETER
: _getdns_dict_set_const_bindata(
dict, name, child_bindata->size, child_bindata->data);
}
/*---------------------------------------- getdns_dict_set_bindata */
getdns_return_t
getdns_dict_util_set_string(getdns_dict *dict, char *name, const char *value)
@ -659,12 +668,15 @@ getdns_indent(size_t indent)
return spaces + 80 - (indent < 80 ? indent : 0);
} /* getdns_indent */
static int
int
_getdns_bindata_is_dname(getdns_bindata *bindata)
{
size_t i = 0, n_labels = 0;
while (i < bindata->size && bindata->data[i]) {
if (bindata->data[i] & 0xC0) /* Compression pointer! */
return 0;
i += ((size_t)bindata->data[i]) + 1;
n_labels++;
}
@ -995,6 +1007,7 @@ getdns_pp_dict(gldns_buffer * buf, size_t indent,
if (!json &&
(strcmp(item->node.key, "answer_type") == 0 ||
strcmp(item->node.key, "dnssec_status") == 0 ||
strcmp(item->node.key, "tsig_status") == 0 ||
strcmp(item->node.key, "status") == 0 ||
strcmp(item->node.key, "append_name") == 0 ||
strcmp(item->node.key, "follow_redirects") == 0 ||

View File

@ -71,6 +71,11 @@ getdns_return_t _getdns_dict_find(
getdns_return_t _getdns_dict_find_and_add(
getdns_dict *dict, const char *key, getdns_item **item);
/* Return 1 (true) if bindata can be interpreted as an
* uncompressed dname.
*/
int _getdns_bindata_is_dname(getdns_bindata *bindata);
#endif
/* dict.h */

View File

@ -188,13 +188,14 @@
* "dnssec_return_validation_chain Extension".
*/
#include "config.h"
#include "debug.h"
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <ctype.h>
#include <openssl/sha.h>
#include "getdns/getdns.h"
#include "config.h"
#include "context.h"
#include "util-internal.h"
#include "types-internal.h"
@ -219,16 +220,16 @@
/******************* Frequently Used Utility Functions *********************
*****************************************************************************/
inline static size_t _dname_len(uint8_t *name)
inline static size_t _dname_len(const uint8_t *name)
{
uint8_t *p;
const uint8_t *p;
for (p = name; *p; p += *p + 1)
/* pass */
;
return p - name + 1;
}
inline static size_t _dname_label_count(uint8_t *name)
inline static size_t _dname_label_count(const uint8_t *name)
{
size_t c;
for (c = 0; *name; name += *name + 1, c++)
@ -267,20 +268,24 @@ static uint8_t *_dname_label_copy(uint8_t *dst, const uint8_t *src, size_t dst_l
return r;
}
inline static void _dname_canonicalize(uint8_t *dname)
inline static void _dname_canonicalize(const uint8_t *src, uint8_t *dst)
{
uint8_t *next_label;
const uint8_t *next_label;
while (*dname) {
next_label = dname + *dname + 1;
dname += 1;
while (dname < next_label) {
*dname = (uint8_t)tolower((unsigned char)*dname);
dname++;
}
while (*src) {
next_label = src + *src + 1;
*dst++ = *src++;
while (src < next_label)
*dst++ = (uint8_t)tolower((unsigned char)*src++);
}
}
inline static void _dname_canonicalize2(uint8_t *dname)
{
_dname_canonicalize(dname, dname);
}
/* Fills the array pointed to by labels (of at least 128 uint8_t * pointers)
* with pointers to labels in given dname in reversed order. So that
* labels[0] will point to the root.
@ -294,7 +299,8 @@ inline static void _dname_canonicalize(uint8_t *dname)
* labels[3] will be "www.getdnsapi.net."
* The returned value will be &labels[4]
*/
static uint8_t **reverse_labels(uint8_t *dname, uint8_t **labels)
static const uint8_t **reverse_labels(
const uint8_t *dname, const uint8_t **labels)
{
if (*dname)
labels = reverse_labels(dname + *dname + 1, labels);
@ -302,10 +308,12 @@ static uint8_t **reverse_labels(uint8_t *dname, uint8_t **labels)
return labels + 1;
}
static uint8_t *dname_shared_parent(uint8_t *left, uint8_t *right)
static const uint8_t *dname_shared_parent(
const uint8_t *left, const uint8_t *right)
{
uint8_t *llabels[128], *rlabels[128], **last_llabel, **last_rlabel,
**llabel, **rlabel, *l, *r, sz;
const uint8_t *llabels[128], *rlabels[128], **last_llabel, **last_rlabel,
**llabel, **rlabel, *l, *r;
uint8_t sz;
last_llabel = reverse_labels(left, llabels);
last_rlabel = reverse_labels(right, rlabels);
@ -333,10 +341,11 @@ static uint8_t *dname_shared_parent(uint8_t *left, uint8_t *right)
return llabel[-1];
}
static int dname_compare(uint8_t *left, uint8_t *right)
static int dname_compare(const uint8_t *left, const uint8_t *right)
{
uint8_t *llabels[128], *rlabels[128], **last_llabel, **last_rlabel,
**llabel, **rlabel, *l, *r, lsz, rsz;
const uint8_t *llabels[128], *rlabels[128], **last_llabel, **last_rlabel,
**llabel, **rlabel, *l, *r;
uint8_t lsz, rsz;
last_llabel = reverse_labels(left, llabels);
last_rlabel = reverse_labels(right, rlabels);
@ -373,7 +382,7 @@ static int dname_compare(uint8_t *left, uint8_t *right)
static int bitmap_has_type(_getdns_rdf_iter *bitmap, uint16_t rr_type)
{
uint8_t *dptr, *dend;
const uint8_t *dptr, *dend;
uint8_t window = rr_type >> 8;
uint8_t subtype = rr_type & 0xFF;
@ -397,7 +406,7 @@ inline static void debug_sec_print_rr(const char *msg, _getdns_rr_iter *rr)
{
char str_spc[8192], *str = str_spc;
size_t str_len = sizeof(str_spc);
uint8_t *data = rr->pos;
const uint8_t *data = rr->pos;
size_t data_len = rr->nxt - rr->pos;
if (!rr || !rr->pos) {
@ -405,14 +414,16 @@ inline static void debug_sec_print_rr(const char *msg, _getdns_rr_iter *rr)
return;
}
(void) gldns_wire2str_rr_scan(
&data, &data_len, &str, &str_len, rr->pkt, rr->pkt_end - rr->pkt);
(UNCONST_UINT8_p *) &data, &data_len, &str, &str_len,
(UNCONST_UINT8_p) rr->pkt, rr->pkt_end - rr->pkt);
DEBUG_SEC("%s%s", msg, str_spc);
}
inline static void debug_sec_print_dname(const char *msg, uint8_t *label)
inline static void debug_sec_print_dname(const char *msg, const uint8_t *label)
{
char str[1024];
if (label && gldns_wire2str_dname_buf(label, 256, str, sizeof(str)))
if (label && gldns_wire2str_dname_buf(
(UNCONST_UINT8_p)label, 256, str, sizeof(str)))
DEBUG_SEC("%s%s\n", msg, str);
else
DEBUG_SEC("%s<nil>\n", msg);
@ -442,9 +453,10 @@ static inline uint16_t rr_iter_class(_getdns_rr_iter *rr)
{ return rr->rr_type + 4 <= rr->nxt ? gldns_read_uint16(rr->rr_type + 2) : 0; }
/* Utility function to compare owner name of rr with name */
static int rr_owner_equal(_getdns_rr_iter *rr, uint8_t *name)
static int rr_owner_equal(_getdns_rr_iter *rr, const uint8_t *name)
{
uint8_t owner_spc[256], *owner;
uint8_t owner_spc[256];
const uint8_t *owner;
size_t owner_len = sizeof(owner_spc);
return (owner = _getdns_owner_if_or_as_decompressed(rr, owner_spc
@ -470,7 +482,7 @@ static _getdns_rr_iter *rr_iter_ansauth(_getdns_rr_iter *rr)
/* Filter that only iterates over RRs with a certain name/class/type */
static _getdns_rr_iter *rr_iter_name_class_type(_getdns_rr_iter *rr,
uint8_t *name, uint16_t rr_class, uint16_t rr_type)
const uint8_t *name, uint16_t rr_class, uint16_t rr_type)
{
while (rr_iter_ansauth(rr) && !(
rr_iter_type(rr) == rr_type &&
@ -484,7 +496,7 @@ static _getdns_rr_iter *rr_iter_name_class_type(_getdns_rr_iter *rr,
/* Filter that only iterates over RRs that do not have a name/class/type */
static _getdns_rr_iter *rr_iter_not_name_class_type(_getdns_rr_iter *rr,
uint8_t *name, uint16_t rr_class, uint16_t rr_type)
const uint8_t *name, uint16_t rr_class, uint16_t rr_type)
{
while (rr_iter_ansauth(rr) && (
rr_iter_type(rr) == GETDNS_RRTYPE_RRSIG || (
@ -501,7 +513,7 @@ static _getdns_rr_iter *rr_iter_not_name_class_type(_getdns_rr_iter *rr,
* a RRset with a certain name/class/type
*/
static _getdns_rr_iter *rr_iter_rrsig_covering(_getdns_rr_iter *rr,
uint8_t *name, uint16_t rr_class, uint16_t rr_type)
const uint8_t *name, uint16_t rr_class, uint16_t rr_type)
{
while (rr_iter_ansauth(rr) && !(
rr_iter_type(rr) == GETDNS_RRTYPE_RRSIG &&
@ -516,11 +528,11 @@ static _getdns_rr_iter *rr_iter_rrsig_covering(_getdns_rr_iter *rr,
}
typedef struct getdns_rrset {
uint8_t *name;
uint16_t rr_class;
uint16_t rr_type;
uint8_t *pkt;
size_t pkt_len;
const uint8_t *name;
uint16_t rr_class;
uint16_t rr_type;
uint8_t *pkt;
size_t pkt_len;
} getdns_rrset;
typedef struct rrtype_iter {
@ -590,7 +602,8 @@ static void debug_sec_print_rrset(const char *msg, getdns_rrset *rrset)
return;
}
gldns_buffer_init_frm_data(&buf, buf_space, sizeof(buf_space));
if (gldns_wire2str_dname_buf(rrset->name, 256, owner, sizeof(owner)))
if (gldns_wire2str_dname_buf(
(UNCONST_UINT8_p)rrset->name, 256, owner, sizeof(owner)))
gldns_buffer_printf(&buf, "%s ", owner);
else gldns_buffer_printf(&buf, "<nil> ");
@ -764,23 +777,24 @@ struct chain_node {
* to equip the chain nodes with their RR sets are done alongside construction.
* Hence they need to be enumerated before the construction functions.
*/
static void val_chain_sched(chain_head *head, uint8_t *dname);
static void val_chain_sched_ds(chain_head *head, uint8_t *dname);
static void val_chain_sched(chain_head *head, const uint8_t *dname);
static void val_chain_sched_ds(chain_head *head, const uint8_t *dname);
static void val_chain_sched_signer(chain_head *head, rrsig_iter *rrsig);
static void val_chain_sched_soa(chain_head *head, uint8_t *dname);
static void val_chain_sched_soa(chain_head *head, const uint8_t *dname);
static chain_head *add_rrset2val_chain(struct mem_funcs *mf,
chain_head **chain_p, getdns_rrset *rrset, getdns_network_req *netreq)
{
chain_head *head;
uint8_t *labels[128], **last_label, **label;
const uint8_t *labels[128], **last_label, **label;
size_t max_labels; /* max labels in common */
chain_head *max_head;
chain_node *max_node;
size_t dname_len, head_sz, node_count, n;
uint8_t *dname, *region;
const uint8_t *dname;
uint8_t *region;
chain_node *node;
last_label = reverse_labels(rrset->name, labels);
@ -906,10 +920,11 @@ static int is_synthesized_cname(getdns_rrset *cname)
_getdns_rdf_iter rdf_spc, *rdf;
rrtype_iter drr_spc, *drr;
_getdns_rdf_iter drdf_spc, *drdf;
uint8_t cname_rdata_spc[256], *cname_rdata,
dname_rdata_spc[256], *dname_rdata,
uint8_t cname_rdata_spc[256],
dname_rdata_spc[256],
synth_name[256],
*synth_name_end = synth_name + sizeof(synth_name) - 1, *s, *c;
*synth_name_end = synth_name + sizeof(synth_name) - 1, *s;
const uint8_t *cname_rdata, *dname_rdata, *c;
size_t cname_rdata_len = sizeof(cname_rdata_spc),
dname_rdata_len = sizeof(dname_rdata_len),
cname_labels, dname_labels;
@ -1049,7 +1064,7 @@ static void add_pkt2val_chain(struct mem_funcs *mf,
*/
static void add_question2val_chain(struct mem_funcs *mf,
chain_head **chain_p, uint8_t *pkt, size_t pkt_len,
uint8_t *qname, uint16_t qtype, uint16_t qclass,
const uint8_t *qname, uint16_t qtype, uint16_t qclass,
getdns_network_req *netreq)
{
getdns_rrset q_rrset;
@ -1133,7 +1148,8 @@ static void val_chain_sched_soa_node(chain_node *node)
context = node->chains->netreq->owner->context;
loop = node->chains->netreq->owner->loop;
if (!gldns_wire2str_dname_buf(node->ds.name, 256, name, sizeof(name)))
if (!gldns_wire2str_dname_buf(
(UNCONST_UINT8_p)node->ds.name, 256, name, sizeof(name)))
return;
DEBUG_SEC("schedule SOA lookup for %s\n", name);
@ -1151,7 +1167,7 @@ static void val_chain_sched_soa_node(chain_node *node)
* answer, then a DS/DNSKEY lookup will follow the acquire the link of the
* authentication chain.
*/
static void val_chain_sched_soa(chain_head *head, uint8_t *dname)
static void val_chain_sched_soa(chain_head *head, const uint8_t *dname)
{
chain_node *node;
@ -1180,7 +1196,8 @@ static void val_chain_sched_node(chain_node *node)
context = node->chains->netreq->owner->context;
loop = node->chains->netreq->owner->loop;
if (!gldns_wire2str_dname_buf(node->ds.name, 256, name, sizeof(name)))
if (!gldns_wire2str_dname_buf(
(UNCONST_UINT8_p)node->ds.name, 256, name, sizeof(name)))
return;
DEBUG_SEC("schedule DS & DNSKEY lookup for %s\n", name);
@ -1200,7 +1217,7 @@ static void val_chain_sched_node(chain_node *node)
node->ds_req = dnsreq->netreqs[0];
}
static void val_chain_sched(chain_head *head, uint8_t *dname)
static void val_chain_sched(chain_head *head, const uint8_t *dname)
{
chain_node *node;
@ -1224,7 +1241,9 @@ static void val_chain_sched_ds_node(chain_node *node)
context = node->chains->netreq->owner->context;
loop = node->chains->netreq->owner->loop;
if (!gldns_wire2str_dname_buf(node->ds.name, 256, name, sizeof(name)))
if (!gldns_wire2str_dname_buf(
(UNCONST_UINT8_p)node->ds.name, 256, name, sizeof(name)))
return;
DEBUG_SEC("schedule DS lookup for %s\n", name);
@ -1237,7 +1256,7 @@ static void val_chain_sched_ds_node(chain_node *node)
node->ds_req = ds_req->netreqs[0];
}
static void val_chain_sched_ds(chain_head *head, uint8_t *dname)
static void val_chain_sched_ds(chain_head *head, const uint8_t *dname)
{
chain_node *node;
@ -1254,8 +1273,9 @@ static void val_chain_sched_ds(chain_head *head, uint8_t *dname)
static void val_chain_sched_signer_node(chain_node *node, rrsig_iter *rrsig)
{
_getdns_rdf_iter rdf_spc, *rdf;
uint8_t signer_spc[256], *signer;
size_t signer_len;
uint8_t signer_spc[256];
const uint8_t *signer;
size_t signer_len;
if (!(rdf = _getdns_rdf_iter_init_at(&rdf_spc, &rrsig->rr_i, 7)))
return;
@ -1369,7 +1389,8 @@ static int key_matches_signer(getdns_rrset *dnskey, getdns_rrset *rrset)
rrsig_iter rrsig_spc, *rrsig;
uint16_t keytag;
_getdns_rdf_iter rdf_spc, *rdf;
uint8_t signer_spc[256], *signer;
uint8_t signer_spc[256];
const uint8_t *signer;
size_t signer_len = sizeof(signer_spc);
assert(dnskey->rr_type == GETDNS_RRTYPE_DNSKEY);
@ -1384,8 +1405,9 @@ static int key_matches_signer(getdns_rrset *dnskey, getdns_rrset *rrset)
continue;
/* Then we have at least 4 bytes to calculate keytag */
keytag = gldns_calc_keytag_raw(rr->rr_i.rr_type + 10,
rr->rr_i.nxt - rr->rr_i.rr_type - 10);
keytag = gldns_calc_keytag_raw(
(UNCONST_UINT8_p)rr->rr_i.rr_type + 10,
rr->rr_i.nxt - rr->rr_i.rr_type - 10);
for ( rrsig = rrsig_iter_init(&rrsig_spc, rrset)
; rrsig ; rrsig = rrsig_iter_next(rrsig) ) {
@ -1457,7 +1479,7 @@ typedef struct canon_rdata_iter {
_getdns_rdf_iter rdf_spc;
_getdns_rdf_iter *rdf;
uint8_t cdname[256]; /* Canonical dname */
uint8_t *pos;
const uint8_t *pos;
size_t len;
} canon_rdata_iter;
@ -1467,8 +1489,10 @@ inline static void canon_rdata_iter_field_init(canon_rdata_iter *i)
if ((i->rdf->rdd_pos->type & GETDNS_RDF_N) == GETDNS_RDF_N) {
i->len = sizeof(i->cdname);
if ((i->pos = _getdns_rdf_if_or_as_decompressed(
i->rdf, i->cdname, &i->len)))
_dname_canonicalize(i->pos);
i->rdf, i->cdname, &i->len))) {
_dname_canonicalize(i->pos, i->cdname);
i->pos = i->cdname;
}
} else {
i->pos = i->rdf->pos;
i->len = i->rdf->nxt - i->rdf->pos;
@ -1558,7 +1582,7 @@ static int _rr_iter_rdata_cmp(const void *a, const void *b)
*/
#define VAL_RRSET_SPC_SZ 1024
static int _getdns_verify_rrsig(struct mem_funcs *mf,
getdns_rrset *rrset, rrsig_iter *rrsig, rrtype_iter *key, uint8_t **nc_name)
getdns_rrset *rrset, rrsig_iter *rrsig, rrtype_iter *key, const uint8_t **nc_name)
{
int r;
int to_skip;
@ -1568,7 +1592,8 @@ static int _getdns_verify_rrsig(struct mem_funcs *mf,
size_t n_rrs, i, valbuf_sz, owner_len;
_getdns_rdf_iter *signer, signer_spc, *rdf, rdf_spc;
uint8_t valbuf_spc[4096], *valbuf_buf = valbuf_spc;
uint8_t cdname_spc[256], *cdname, owner[256];
uint8_t cdname_spc[256], owner[256];
const uint8_t *cdname;
size_t cdname_len, pos;
uint32_t orig_ttl;
gldns_buffer valbuf;
@ -1620,15 +1645,19 @@ static int _getdns_verify_rrsig(struct mem_funcs *mf,
gldns_buffer_init_frm_data(&valbuf, valbuf_buf, valbuf_sz);
gldns_buffer_write(&valbuf,
rrsig->rr_i.rr_type + 10, signer->nxt - rrsig->rr_i.rr_type - 10);
_dname_canonicalize(gldns_buffer_at(&valbuf, 18));
_dname_canonicalize2(gldns_buffer_at(&valbuf, 18));
orig_ttl = gldns_read_uint32(rrsig->rr_i.rr_type + 14);
(void) memcpy(owner, rrset->name, owner_len);
_dname_canonicalize(owner);
_dname_canonicalize2(owner);
if (!_dnssec_rdata_to_canonicalize(rrset->rr_type))
for (i = 0; i < n_rrs; i++) {
if (i && !_rr_iter_rdata_cmp(
&val_rrset[i], &val_rrset[i-1]))
continue;
gldns_buffer_write(&valbuf, owner, owner_len);
gldns_buffer_write_u16(&valbuf, rrset->rr_type);
gldns_buffer_write_u16(&valbuf, rrset->rr_class);
@ -1637,6 +1666,8 @@ static int _getdns_verify_rrsig(struct mem_funcs *mf,
val_rrset[i].nxt - val_rrset[i].rr_type - 8);
}
else for (i = 0; i < n_rrs; i++) {
if (i && !_rr_iter_rdata_cmp(&val_rrset[i], &val_rrset[i-1]))
continue;
gldns_buffer_write(&valbuf, owner, owner_len);
gldns_buffer_write_u16(&valbuf, rrset->rr_type);
gldns_buffer_write_u16(&valbuf, rrset->rr_class);
@ -1656,7 +1687,7 @@ static int _getdns_verify_rrsig(struct mem_funcs *mf,
rdf, cdname_spc, &cdname_len)))
continue;
gldns_buffer_write(&valbuf, cdname, cdname_len);
_dname_canonicalize(
_dname_canonicalize2(
gldns_buffer_current(&valbuf) - cdname_len);
}
gldns_buffer_write_u16_at(&valbuf, pos,
@ -1664,16 +1695,22 @@ static int _getdns_verify_rrsig(struct mem_funcs *mf,
}
DEBUG_SEC( "written to valbuf: %zu bytes\n"
, gldns_buffer_position(&valbuf));
assert(gldns_buffer_position(&valbuf) == valbuf_sz);
assert(gldns_buffer_position(&valbuf) <= valbuf_sz);
gldns_buffer_flip(&valbuf);
r = _getdns_verify_canonrrset(&valbuf, key->rr_i.rr_type[13],
signer->nxt, rrsig->rr_i.nxt - signer->nxt,
key->rr_i.rr_type+14, key->rr_i.nxt - key->rr_i.rr_type-14,
(UNCONST_UINT8_p)signer->nxt, rrsig->rr_i.nxt - signer->nxt,
(UNCONST_UINT8_p)key->rr_i.rr_type+14,
key->rr_i.nxt - key->rr_i.rr_type-14,
&reason);
#if defined(SEC_DEBUG) && SEC_DEBUG
if (r == 0)
if (r == 0) {
DEBUG_SEC("verification failed: %s\n", reason);
debug_sec_print_rrset("verification failed: ", rrset);
debug_sec_print_rr("verification failed: ", &rrsig->rr_i);
debug_sec_print_rr("verification failed: ", &key->rr_i);
}
#endif
if (val_rrset != val_rrset_spc)
GETDNS_FREE(*mf, val_rrset);
@ -1710,7 +1747,8 @@ static int _getdns_verify_rrsig(struct mem_funcs *mf,
/* Calculates NSEC3 hash for name, and stores that into label */
static uint8_t *_getdns_nsec3_hash_label(uint8_t *label, size_t label_len,
uint8_t *name, uint8_t algorithm, uint16_t iterations, uint8_t *salt)
const uint8_t *name, uint8_t algorithm,
uint16_t iterations, const uint8_t *salt)
{
uint8_t buf[512], *dst, *eob;
const uint8_t *src;
@ -1747,11 +1785,12 @@ static uint8_t *_getdns_nsec3_hash_label(uint8_t *label, size_t label_len,
}
static uint8_t *name2nsec3_label(
getdns_rrset *nsec3, uint8_t *name, uint8_t *label, size_t label_len)
getdns_rrset *nsec3, const uint8_t *name, uint8_t *label, size_t label_len)
{
rrsig_iter rrsig_spc, *rrsig;
_getdns_rdf_iter rdf_spc, *rdf;
uint8_t signer_spc[256], *signer;
uint8_t signer_spc[256];
const uint8_t *signer;
size_t signer_len = sizeof(signer_spc);
rrtype_iter rr_spc, *rr;
@ -1832,11 +1871,12 @@ static int check_dates(int32_t now, int32_t skew, int32_t exp, int32_t inc)
* expansion, nc_name will point to the next closer part of the name in rrset.
*/
static int dnskey_signed_rrset(struct mem_funcs *mf, time_t now, uint32_t skew,
rrtype_iter *dnskey, getdns_rrset *rrset, uint8_t **nc_name)
rrtype_iter *dnskey, getdns_rrset *rrset, const uint8_t **nc_name)
{
rrsig_iter rrsig_spc, *rrsig;
_getdns_rdf_iter rdf_spc, *rdf;
uint8_t signer_spc[256], *signer;
uint8_t signer_spc[256];
const uint8_t *signer;
size_t signer_len = sizeof(signer_spc);
uint16_t keytag;
@ -1850,7 +1890,7 @@ static int dnskey_signed_rrset(struct mem_funcs *mf, time_t now, uint32_t skew,
return 0;
/* Then we have at least 4 bytes to calculate keytag */
keytag = gldns_calc_keytag_raw(dnskey->rr_i.rr_type + 10,
keytag = gldns_calc_keytag_raw((UNCONST_UINT8_p)dnskey->rr_i.rr_type + 10,
dnskey->rr_i.nxt - dnskey->rr_i.rr_type - 10);
for ( rrsig = rrsig_iter_init(&rrsig_spc, rrset)
@ -1899,15 +1939,15 @@ static int dnskey_signed_rrset(struct mem_funcs *mf, time_t now, uint32_t skew,
}
static int find_nsec_covering_name(
struct mem_funcs *mf, time_t now, uint32_t skew,
getdns_rrset *dnskey, getdns_rrset *rrset, uint8_t *name, int *opt_out);
struct mem_funcs *mf, time_t now, uint32_t skew, getdns_rrset *dnskey,
getdns_rrset *rrset, const uint8_t *name, int *opt_out);
/* Returns whether a dnskey for keyset signed rrset. */
static int a_key_signed_rrset(struct mem_funcs *mf, time_t now, uint32_t skew,
getdns_rrset *keyset, getdns_rrset *rrset)
{
rrtype_iter dnskey_spc, *dnskey;
uint8_t *nc_name;
const uint8_t *nc_name;
int keytag;
assert(keyset->rr_type == GETDNS_RRTYPE_DNSKEY);
@ -1949,7 +1989,7 @@ static int ds_authenticates_keys(struct mem_funcs *mf,
rrtype_iter dnskey_spc, *dnskey;
rrtype_iter ds_spc, *ds;
uint16_t keytag;
uint8_t *nc_name;
const uint8_t *nc_name;
size_t valid_dsses = 0, supported_dsses = 0;
uint8_t max_supported_digest = 0;
int max_supported_result = 0;
@ -1972,7 +2012,7 @@ static int ds_authenticates_keys(struct mem_funcs *mf,
return 0;
(void) memcpy(digest_buf_spc, dnskey_set->name, dnskey_owner_len);
_dname_canonicalize(digest_buf_spc);
_dname_canonicalize2(digest_buf_spc);
for ( dnskey = rrtype_iter_init(&dnskey_spc, dnskey_set)
; dnskey ; dnskey = rrtype_iter_next(dnskey)) {
@ -1981,8 +2021,9 @@ static int ds_authenticates_keys(struct mem_funcs *mf,
if (dnskey->rr_i.nxt < dnskey->rr_i.rr_type + 14)
continue;
keytag = gldns_calc_keytag_raw(dnskey->rr_i.rr_type + 10,
dnskey->rr_i.nxt - dnskey->rr_i.rr_type - 10);
keytag = gldns_calc_keytag_raw(
(UNCONST_UINT8_p) dnskey->rr_i.rr_type + 10,
dnskey->rr_i.nxt - dnskey->rr_i.rr_type - 10);
for ( ds = rrtype_iter_init(&ds_spc, ds_set)
; ds ; ds = rrtype_iter_next(ds)) {
@ -2105,16 +2146,16 @@ static int ds_authenticates_keys(struct mem_funcs *mf,
}
static int nsec_covers_name(
getdns_rrset *nsec, uint8_t *name, uint8_t **ce_name)
getdns_rrset *nsec, const uint8_t *name, const uint8_t **ce_name)
{
uint8_t owner_spc[256], *owner;
size_t owner_len = sizeof(owner_spc);
uint8_t next_spc[256], *next;
size_t next_len = sizeof(next_spc);
uint8_t owner_spc[256], next_spc[256];
const uint8_t *owner, *next;
size_t owner_len = sizeof(owner_spc), next_len = sizeof(next_spc);
rrtype_iter rr_spc, *rr;
_getdns_rdf_iter rdf_spc, *rdf;
int nsec_cmp;
uint8_t *common1, *common2;
const uint8_t *common1, *common2;
if (/* Get owner and next, nicely decompressed */
!(rr = rrtype_iter_init(&rr_spc, nsec))
@ -2163,7 +2204,7 @@ static int nsec_covers_name(
}
}
static int nsec3_matches_name(getdns_rrset *nsec3, uint8_t *name)
static int nsec3_matches_name(getdns_rrset *nsec3, const uint8_t *name)
{
uint8_t label[64], owner[64];
@ -2176,7 +2217,8 @@ static int nsec3_matches_name(getdns_rrset *nsec3, uint8_t *name)
return 0;
}
static int nsec3_covers_name(getdns_rrset *nsec3, uint8_t *name, int *opt_out)
static int nsec3_covers_name(
getdns_rrset *nsec3, const uint8_t *name, int *opt_out)
{
uint8_t label[65], next[65], owner[65];
rrtype_iter rr_spc, *rr;
@ -2227,8 +2269,8 @@ static int nsec3_covers_name(getdns_rrset *nsec3, uint8_t *name, int *opt_out)
}
static int find_nsec_covering_name(
struct mem_funcs *mf, time_t now, uint32_t skew,
getdns_rrset *dnskey, getdns_rrset *rrset, uint8_t *name, int *opt_out)
struct mem_funcs *mf, time_t now, uint32_t skew, getdns_rrset *dnskey,
getdns_rrset *rrset, const uint8_t *name, int *opt_out)
{
rrset_iter i_spc, *i;
getdns_rrset *n;
@ -2325,7 +2367,8 @@ static int find_nsec_covering_name(
static int nsec3_find_next_closer(
struct mem_funcs *mf, time_t now, uint32_t skew,
getdns_rrset *dnskey, getdns_rrset *rrset, uint8_t *nc_name, int *opt_out)
getdns_rrset *dnskey, getdns_rrset *rrset,
const uint8_t *nc_name, int *opt_out)
{
uint8_t wc_name[256] = { 1, (uint8_t)'*' };
int my_opt_out, keytag;
@ -2382,7 +2425,7 @@ static int key_proves_nonexistance(
rrtype_iter nsec_spc, *nsec_rr;
_getdns_rdf_iter bitmap_spc, *bitmap;
rrset_iter i_spc, *i;
uint8_t *ce_name, *nc_name;
const uint8_t *ce_name, *nc_name;
uint8_t wc_name[256] = { 1, (uint8_t)'*' };
int keytag;
@ -2766,7 +2809,7 @@ static int chain_head_validate_with_ta(struct mem_funcs *mf,
if ((s = chain_node_get_trusted_keys(
mf, now, skew, head->parent, ta, &keys)) != GETDNS_DNSSEC_SECURE)
return s;
return s;
if (rrset_has_rrs(&head->rrset)) {
if ((keytag = a_key_signed_rrset(
@ -2980,6 +3023,26 @@ static size_t count_outstanding_requests(chain_head *head)
return count + count_outstanding_requests(head->next);
}
static int rrset_in_list(getdns_rrset *rrset, getdns_list *list)
{
size_t i;
getdns_dict *rr_dict;
uint32_t rr_type;
uint32_t rr_class;
getdns_bindata *name;
for (i = 0; !getdns_list_get_dict(list, i, &rr_dict); i++) {
if (!getdns_dict_get_int(rr_dict, "type", &rr_type) &&
rrset->rr_type == rr_type &&
!getdns_dict_get_int(rr_dict, "class", &rr_class) &&
rrset->rr_class == rr_class &&
!getdns_dict_get_bindata(rr_dict, "name", &name) &&
dname_compare(rrset->name, name->data) == 0)
return 1;
}
return 0;
}
static void append_rrs2val_chain_list(getdns_context *ctxt,
getdns_list *val_chain_list, getdns_network_req *netreq, int signer)
{
@ -2995,10 +3058,14 @@ static void append_rrs2val_chain_list(getdns_context *ctxt,
rrset = rrset_iter_value(i);
if (rrset->rr_type != GETDNS_RRTYPE_DNSKEY &&
rrset->rr_type != GETDNS_RRTYPE_DS &&
rrset->rr_type != GETDNS_RRTYPE_NSEC &&
rrset->rr_type != GETDNS_RRTYPE_NSEC3)
if (rrset->rr_type == GETDNS_RRTYPE_NSEC ||
rrset->rr_type == GETDNS_RRTYPE_NSEC3) {
if (rrset_in_list(rrset, val_chain_list))
continue;
} else if (rrset->rr_type != GETDNS_RRTYPE_DNSKEY &&
rrset->rr_type != GETDNS_RRTYPE_DS)
continue;
for ( rr = rrtype_iter_init(&rr_spc, rrset)
@ -3044,7 +3111,7 @@ static void append_empty_ds2val_chain_list(
return;
bindata.size = _dname_len(ds->name);
bindata.data = ds->name;
bindata.data = (UNCONST_UINT8_p)ds->name;
(void) getdns_dict_set_bindata(rr_dict, "name", &bindata);
(void) getdns_dict_set_int(rr_dict, "class", ds->rr_class);
(void) getdns_dict_set_int(rr_dict, "type", ds->rr_type);
@ -3225,7 +3292,8 @@ static int wire_validate_dnssec(struct mem_funcs *mf,
chain_head *chain, *head, *next_head;
chain_node *node;
uint8_t qname_spc[256], *qname = NULL;
uint8_t qname_spc[256];
const uint8_t *qname = NULL;
size_t qname_len = sizeof(qname_spc);
uint16_t qtype = 0, qclass = GETDNS_RRCLASS_IN;

View File

@ -31,9 +31,9 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "getdns/getdns_ext_libev.h"
#include "types-internal.h"
#include "config.h"
#include "types-internal.h"
#include "getdns/getdns_ext_libev.h"
#ifdef HAVE_LIBEV_EV_H
#include <libev/ev.h>

View File

@ -31,10 +31,10 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "config.h"
#include "types-internal.h"
#include <sys/time.h>
#include "getdns/getdns_ext_libevent.h"
#include "types-internal.h"
#include "config.h"
#ifdef HAVE_EVENT2_EVENT_H
# include <event2/event.h>

View File

@ -32,9 +32,10 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "config.h"
#include "debug.h"
#include "types-internal.h"
#include "extension/libmini_event.h"
#include "context.h"
#include "util-internal.h"
#if defined(SCHED_DEBUG) && SCHED_DEBUG
#include <inttypes.h>
#endif
@ -222,7 +223,7 @@ _getdns_mini_event_init(getdns_context *context, _getdns_mini_event *ext)
if (!ext->base)
return GETDNS_RETURN_MEMORY_ERROR;
ext->mf = context->mf;
ext->mf = *priv_getdns_context_mf(context);
return GETDNS_RETURN_GOOD;
}
@ -232,6 +233,6 @@ _getdns_mini_event_create(getdns_context *context, _getdns_mini_event **ext)
if (!context) return GETDNS_RETURN_BAD_CONTEXT;
if (!ext) return GETDNS_RETURN_INVALID_PARAMETER;
*ext = GETDNS_MALLOC(context->mf, _getdns_mini_event);
*ext = GETDNS_MALLOC(*priv_getdns_context_mf(context), _getdns_mini_event);
return _getdns_mini_event_init(context, *ext);
}

View File

@ -32,9 +32,10 @@
*/
#include "config.h"
#include "debug.h"
#include "types-internal.h"
#include <uv.h>
#include "getdns/getdns_ext_libuv.h"
#include "util-internal.h"
#define UV_DEBUG 0

View File

@ -185,7 +185,6 @@ typedef enum getdns_transport_list_t {
GETDNS_TRANSPORT_UDP = 1200,
GETDNS_TRANSPORT_TCP = 1201,
GETDNS_TRANSPORT_TLS = 1202,
GETDNS_TRANSPORT_STARTTLS = 1203
} getdns_transport_list_t;
/**
@ -195,7 +194,6 @@ typedef enum getdns_transport_list_t {
#define GETDNS_TRANSPORT_UDP_TEXT "See getdns_context_set_dns_transport_list()"
#define GETDNS_TRANSPORT_TCP_TEXT "See getdns_context_set_dns_transport_list()"
#define GETDNS_TRANSPORT_TLS_TEXT "See getdns_context_set_dns_transport_list()"
#define GETDNS_TRANSPORT_STARTTLS_TEXT "See getdns_context_set_dns_transport_list()"
/** @}
*/

View File

@ -30,6 +30,7 @@
#include <getdns/getdns.h>
#include <sys/time.h>
#include <stdio.h>
#ifdef __cplusplus
extern "C" {
@ -399,8 +400,180 @@ getdns_context_get_tls_authentication(getdns_context *context,
#define GETDNS_TRANSPORT_TLS_ONLY_KEEP_CONNECTIONS_OPEN_TEXT "See getdns_context_set_dns_transport()"
#define GETDNS_TRANSPORT_TLS_FIRST_AND_FALL_BACK_TO_TCP_KEEP_CONNECTIONS_OPEN 545
#define GETDNS_TRANSPORT_TLS_FIRST_AND_FALL_BACK_TO_TCP_KEEP_CONNECTIONS_OPEN_TEXT "See getdns_context_set_dns_transport()"
#define GETDNS_TRANSPORT_STARTTLS_FIRST_AND_FALL_BACK_TO_TCP_KEEP_CONNECTIONS_OPEN 546
#define GETDNS_TRANSPORT_STARTTLS_FIRST_AND_FALL_BACK_TO_TCP_KEEP_CONNECTIONS_OPEN_TEXT "See getdns_context_set_dns_transport()"
#define GETDNS_RETURN_NEED_MORE_SPACE ((getdns_return_t) 399 )
#define GETDNS_RETURN_NEED_MORE_SPACE_TEXT "The buffer was too small"
/**
* Convert rr_dict to wireformat representation of the resource record.
*
* @param rr_dict The getdns dict representation of the resource record
* @return wire A newly allocated buffer which will contain the wireformat.
* @return wire_sz The size of the allocated buffer and the wireformat.
* @return GETDNS_RETURN_GOOD on success or an error code on failure.
*/
getdns_return_t
getdns_rr_dict2wire(
const getdns_dict *rr_dict, uint8_t **wire, size_t *wire_sz);
/**
* Convert rr_dict to wireformat representation of the resource record.
*
* @param rr_dict The getdns dict representation of the resource record
* @param wire The buffer in which the wireformat will be written
* @param wire_sz On input the size of the wire buffer,
* On output the amount of wireformat needed for the
* wireformat representation of the resource record;
* even if it did not fit.
* @return GETDNS_RETURN_GOOD on success or an error code on failure.
* GETDNS_RETURN_NEED_MORE_SPACE will be returned when the buffer was too
* small. wire_sz will be set to the needed buffer space then.
*/
getdns_return_t
getdns_rr_dict2wire_buf(
const getdns_dict *rr_dict, uint8_t *wire, size_t *wire_sz);
/**
* Convert rr_dict to wireformat representation of the resource record.
*
* @param rr_dict The getdns dict representation of the resource record
* @param wire A pointer to the buffer pointer in which the wireformat
* will be written.
* On output the buffer pointer will have moved along
* the buffer and point right after the just written RR.
* @param wire_sz On input the size of the wire buffer,
* On output the amount of wireformat needed for the
* wireformat will have been substracted from wire_sz.
* @return GETDNS_RETURN_GOOD on success or an error code on failure.
* GETDNS_RETURN_NEED_MORE_SPACE will be returned when the buffer was too
* small. The function will pretend that it had written beyond the end
* of the buffer, and wire will point past the buffer and wire_sz will
* contain a negative value.
*/
getdns_return_t
getdns_rr_dict2wire_scan(
const getdns_dict *rr_dict, uint8_t **wire, ssize_t *wire_sz);
/**
* Convert wireformat resource record in a getdns rr_dict representation.
*
* @param wire Buffer containing the wireformat rr
* @param wire_sz Size of the wire buffer
* @return rr_dict The returned rr_dict
* @return GETDNS_RETURN_GOOD on success or an error code on failure.
*/
getdns_return_t
getdns_wire2rr_dict(
const uint8_t *wire, size_t wire_sz, getdns_dict **rr_dict);
/**
* Convert wireformat resource record in a getdns rr_dict representation.
*
* @param wire Buffer containing the wireformat rr
* @param wire_sz On input the size of the wire buffer
* On output the length of the wireformat rr.
* @return rr_dict The returned rr_dict
* @return GETDNS_RETURN_GOOD on success or an error code on failure.
*/
getdns_return_t
getdns_wire2rr_dict_buf(
const uint8_t *wire, size_t *wire_sz, getdns_dict **rr_dict);
/**
* Convert wireformat resource record in a getdns rr_dict representation.
*
* @param wire A pointer to the pointer of the wireformat buffer.
* On return this pointer is moved to after first read
* in resource record.
* @param wire_sz On input the size of the wire buffer
* On output the size is decreased with the length
* of the wireformat resource record.
* @return rr_dict The returned rr_dict
* @return GETDNS_RETURN_GOOD on success or an error code on failure.
*/
getdns_return_t
getdns_wire2rr_dict_scan(
const uint8_t **wire, size_t *wire_sz, getdns_dict **rr_dict);
/**
* Convert rr_dict to the string representation of the resource record.
*
* @param rr_dict The getdns dict representation of the resource record
* @return str A newly allocated string representation of the rr
* @return GETDNS_RETURN_GOOD on success or an error code on failure.
*/
getdns_return_t
getdns_rr_dict2str(
const getdns_dict *rr_dict, char **str);
/**
* Convert rr_dict to the string representation of the resource record.
*
* @param rr_dict The getdns dict representation of the resource record
* @param str The buffer in which the string will be written
* @param str_len On input the size of the text buffer,
* On output the amount of characters needed to write
* the string representation of the rr. Even if it does
* not fit.
* @return GETDNS_RETURN_GOOD on success or an error code on failure.
* GETDNS_RETURN_NEED_MORE_SPACE will be returned when the buffer was too
* small. str_len will be set to the needed buffer space then.
*/
getdns_return_t
getdns_rr_dict2str_buf(
const getdns_dict *rr_dict, char *str, size_t *str_len);
/**
* Convert rr_dict to the string representation of the resource record.
*
* @param rr_dict The getdns dict representation of the resource record
* @param str A pointer to the buffer pointer in which the string
* will be written.
* On output the buffer pointer will have moved along
* the buffer and point right after the just written RR.
* @param str_len On input the size of the str buffer,
* On output the number of characters needed for the
* string will have been substracted from strlen.
* @return GETDNS_RETURN_GOOD on success or an error code on failure.
* GETDNS_RETURN_NEED_MORE_SPACE will be returned when the buffer was too
* small. The function will pretend that it had written beyond the end
* of the buffer, and str will point past the buffer and str_len will
* contain a negative value.
*/
getdns_return_t
getdns_rr_dict2str_scan(
const getdns_dict *rr_dict, char **str, ssize_t *str_len);
/**
* Convert the string representation of the resource record to rr_dict format.
*
* @param str String representation of the resource record.
* @return rr_dict The result getdns dict representation of the resource record
* @param origin Default suffix for not fully qualified domain names
* @param default_ttl Default ttl
* @return GETDNS_RETURN_GOOD on success or an error code on failure.
*/
getdns_return_t
getdns_str2rr_dict(
const char *str, getdns_dict **rr_dict,
const char *origin, uint32_t default_ttl);
/**
* Read the zonefile and convert to a list of rr_dict's.
*
* @param fp String representation of the resource record.
* @return rr_list The result list of rr_dicts representing the zone file.
* @param origin Default suffix for not fully qualified domain names
* @param default_ttl Default ttl
* @return GETDNS_RETURN_GOOD on success or an error code on failure.
*/
getdns_return_t
getdns_fp2rr_list(
FILE *in, getdns_list **rr_list,
const char *origin, uint32_t default_ttl);
#ifdef __cplusplus
}

View File

@ -87,6 +87,19 @@ gldns_write_uint32(void *dst, uint32_t data)
}
INLINE void
gldns_write_uint48(void *dst, uint64_t data)
{
uint8_t *p = (uint8_t *) dst;
p[0] = (uint8_t) ((data >> 40) & 0xff);
p[1] = (uint8_t) ((data >> 32) & 0xff);
p[2] = (uint8_t) ((data >> 24) & 0xff);
p[3] = (uint8_t) ((data >> 16) & 0xff);
p[4] = (uint8_t) ((data >> 8) & 0xff);
p[5] = (uint8_t) (data & 0xff);
}
/**
* \file gbuffer.h
*
@ -534,6 +547,20 @@ gldns_buffer_write_u32_at(gldns_buffer *buffer, size_t at, uint32_t data)
gldns_write_uint32(buffer->_data + at, data);
}
/**
* writes the given 6 byte integer at the given position in the buffer
* \param[in] buffer the buffer
* \param[in] at the position in the buffer
* \param[in] data the (lower) 48 bits to write
*/
INLINE void
gldns_buffer_write_u48_at(gldns_buffer *buffer, size_t at, uint64_t data)
{
if (buffer->_fixed && at + 6 > buffer->_limit) return;
assert(gldns_buffer_available_at(buffer, at, 6));
gldns_write_uint48(buffer->_data + at, data);
}
/**
* writes the given 4 byte integer at the current position in the buffer
* \param[in] buffer the buffer
@ -546,6 +573,18 @@ gldns_buffer_write_u32(gldns_buffer *buffer, uint32_t data)
buffer->_position += sizeof(data);
}
/**
* writes the given 6 byte integer at the current position in the buffer
* \param[in] buffer the buffer
* \param[in] data the 48 bits to write
*/
INLINE void
gldns_buffer_write_u48(gldns_buffer *buffer, uint64_t data)
{
gldns_buffer_write_u48_at(buffer, buffer->_position, data);
buffer->_position += 6;
}
/**
* copies count bytes of data at the given position to the given data-array
* \param[in] buffer the buffer

View File

@ -417,7 +417,8 @@ enum gldns_enum_edns_option
GLDNS_EDNS_DAU = 5, /* RFC6975 */
GLDNS_EDNS_DHU = 6, /* RFC6975 */
GLDNS_EDNS_N3U = 7, /* RFC6975 */
GLDNS_EDNS_CLIENT_SUBNET = 8 /* draft-vandergaast-edns-client-subnet */
GLDNS_EDNS_CLIENT_SUBNET = 8, /* draft-vandergaast-edns-client-subnet */
GLDNS_EDNS_KEEPALIVE = 11 /* draft-ietf-dnsop-edns-tcp-keepalive*/
};
typedef enum gldns_enum_edns_option gldns_edns_option;

View File

@ -867,7 +867,7 @@ int gldns_fp2wire_rr_buf(FILE* in, uint8_t* rr, size_t* len, size_t* dname_len,
return s;
} else if(strncmp(line, "$TTL", 4) == 0 && isspace(line[4])) {
const char* end = NULL;
size_t off = 8;
size_t off = 5;
*len = 0;
*dname_len = 0;
if(!parse_state) return GLDNS_WIREPARSE_ERR_OK;

View File

@ -165,6 +165,7 @@ static gldns_lookup_table gldns_edns_options_data[] = {
{ 6, "DHU" },
{ 7, "N3U" },
{ 8, "edns-client-subnet" },
{ 11, "edns-tcp-keepalive"},
{ 0, NULL}
};
gldns_lookup_table* gldns_edns_options = gldns_edns_options_data;
@ -1833,6 +1834,25 @@ int gldns_wire2str_edns_subnet_print(char** s, size_t* sl, uint8_t* data,
return w;
}
int gldns_wire2str_edns_keepalive_print(char** s, size_t* sl, uint8_t* data,
size_t len)
{
int w = 0;
uint16_t timeout;
if(!(len == 0 || len == 2)) {
w += gldns_str_print(s, sl, "malformed keepalive ");
w += print_hex_buf(s, sl, data, len);
return w;
}
if(len == 0 ) {
w += gldns_str_print(s, sl, "no timeout value (only valid for client option) ");
} else {
timeout = gldns_read_uint16(data);
w += gldns_str_print(s, sl, "timeout value in units of 100ms %u", (int)timeout);
}
return w;
}
int gldns_wire2str_edns_option_print(char** s, size_t* sl,
uint16_t option_code, uint8_t* optdata, size_t optlen)
{
@ -1861,6 +1881,9 @@ int gldns_wire2str_edns_option_print(char** s, size_t* sl,
case GLDNS_EDNS_CLIENT_SUBNET:
w += gldns_wire2str_edns_subnet_print(s, sl, optdata, optlen);
break;
case GLDNS_EDNS_KEEPALIVE:
w += gldns_wire2str_edns_keepalive_print(s, sl, optdata, optlen);
break;
default:
/* unknown option code */
w += print_hex_buf(s, sl, optdata, optlen);

View File

@ -13,7 +13,6 @@ getdns_context_get_dnssec_allowed_skew
getdns_context_get_dnssec_trust_anchors
getdns_context_get_dns_transport
getdns_context_get_dns_transport_list
getdns_context_get_tls_authentication
getdns_context_get_edns_client_subnet_private
getdns_context_get_edns_do_bit
getdns_context_get_edns_extended_rcode
@ -27,6 +26,7 @@ getdns_context_get_num_pending_requests
getdns_context_get_resolution_type
getdns_context_get_suffix
getdns_context_get_timeout
getdns_context_get_tls_authentication
getdns_context_get_tls_query_padding_blocksize
getdns_context_get_update_callback
getdns_context_get_upstream_recursive_servers
@ -83,6 +83,7 @@ getdns_dict_set_list
getdns_dict_util_get_string
getdns_dict_util_set_string
getdns_display_ip_address
getdns_fp2rr_list
getdns_general
getdns_general_sync
getdns_get_api_version
@ -114,11 +115,21 @@ getdns_pretty_snprint_list
getdns_print_json_dict
getdns_print_json_list
getdns_root_trust_anchor
getdns_rr_dict2str
getdns_rr_dict2str_buf
getdns_rr_dict2str_scan
getdns_rr_dict2wire
getdns_rr_dict2wire_buf
getdns_rr_dict2wire_scan
getdns_service
getdns_service_sync
getdns_snprint_json_dict
getdns_snprint_json_list
getdns_str2rr_dict
getdns_strerror
getdns_validate_dnssec
getdns_wire2rr_dict
getdns_wire2rr_dict_buf
getdns_wire2rr_dict_scan
plain_mem_funcs_user_arg
priv_getdns_context_mf

View File

@ -107,6 +107,13 @@ _getdns_list_remove_name(getdns_list *list, const char *name)
i = &list->items[index];
if (!*next) {
switch (i->dtype) {
case t_dict : getdns_dict_destroy(i->data.dict); break;
case t_list : getdns_list_destroy(i->data.list); break;
case t_bindata: _getdns_bindata_destroy(
&list->mf, i->data.bindata);
default : break;
}
if (index < list->numinuse - 1)
(void) memmove( i, &i[1],
(list->numinuse - index) * sizeof(getdns_item));
@ -545,17 +552,17 @@ getdns_list_set_list(
} /* getdns_list_set_list */
/*---------------------------------------- getdns_list_set_bindata */
getdns_return_t
getdns_list_set_bindata(
getdns_list *list, size_t index, const getdns_bindata *child_bindata)
static getdns_return_t
_getdns_list_set_const_bindata(
getdns_list *list, size_t index, size_t size, const uint8_t *data)
{
getdns_bindata *newbindata;
getdns_return_t r;
if (!list || !child_bindata)
if (!list)
return GETDNS_RETURN_INVALID_PARAMETER;
if (!(newbindata = _getdns_bindata_copy(&list->mf, child_bindata)))
if (!(newbindata = _getdns_bindata_copy(&list->mf, size, data)))
return GETDNS_RETURN_MEMORY_ERROR;
if ((r = _getdns_list_request_index(list, index))) {
@ -567,6 +574,15 @@ getdns_list_set_bindata(
return GETDNS_RETURN_GOOD;
} /* getdns_list_set_bindata */
getdns_return_t
getdns_list_set_bindata(
getdns_list *list, size_t index, const getdns_bindata *child_bindata)
{
return !child_bindata ? GETDNS_RETURN_INVALID_PARAMETER
: _getdns_list_set_const_bindata(
list, index, child_bindata->size, child_bindata->data);
}
/*----------------------------------------- getdns_list_set_string */
static getdns_return_t
getdns_list_set_string(getdns_list *list, size_t index, const char *value)
@ -631,6 +647,13 @@ _getdns_list_append_bindata(getdns_list *list, const getdns_bindata *child_binda
return getdns_list_set_bindata(list, list->numinuse, child_bindata);
}
getdns_return_t
_getdns_list_append_const_bindata(
getdns_list *list, size_t size, const uint8_t *data)
{
if (!list) return GETDNS_RETURN_INVALID_PARAMETER;
return _getdns_list_set_const_bindata(list, list->numinuse, size, data);
}
getdns_return_t
_getdns_list_append_string(getdns_list *list, const char *value)
{
if (!list) return GETDNS_RETURN_INVALID_PARAMETER;

View File

@ -10,9 +10,9 @@ cat > const-info.c << END_OF_HEAD
#include "const-info.h"
static struct const_info consts_info[] = {
{ -1, NULL, "/* <unknown getdns value> */" },
{ -1, NULL, "/* <unknown getdns value> */" },
END_OF_HEAD
gawk '/^[ ]+GETDNS_[A-Z_]+[ ]+=[ ]+[0-9]+/{ consts[$3] = $1; }/^#define GETDNS_[A-Z_]+[ ]+[0-9]+/ && !/^#define GETDNS_RRTYPE/ && !/^#define GETDNS_RRCLASS/ && !/^#define GETDNS_OPCODE/ && !/^#define GETDNS_RCODE/ && !/_TEXT/{ consts[$3] = $2; }END{ n = asorti(consts, const_vals, "@ind_num_asc"); for ( i = 1; i <= n; i++) { val = const_vals[i]; name = consts[val]; print "\t{ "val", \""name"\", "name"_TEXT },"}}' getdns/getdns.h.in getdns/getdns_extra.h.in | sed 's/,,/,/g' >> const-info.c
gawk '/^[ ]+GETDNS_[A-Z_]+[ ]+=[ ]+[0-9]+/{ key = sprintf("%4d", $3); consts[key] = $1; }/^#define GETDNS_[A-Z_]+[ ]+[0-9]+/ && !/^#define GETDNS_RRTYPE/ && !/^#define GETDNS_RRCLASS/ && !/^#define GETDNS_OPCODE/ && !/^#define GETDNS_RCODE/ && !/_TEXT/{ key = sprintf("%4d", $3); consts[key] = $2; }/^#define GETDNS_[A-Z_]+[ ]+\(\(getdns_return_t) [0-9]+ \)/{ key = sprintf("%4d", $4); consts[key] = $2; }END{ n = asorti(consts, const_vals); for ( i = 1; i <= n; i++) { val = const_vals[i]; name = consts[val]; print "\t{ "val", \""name"\", "name"_TEXT },"}}' getdns/getdns.h.in getdns/getdns_extra.h.in | sed 's/,,/,/g' >> const-info.c
cat >> const-info.c << END_OF_TAIL
};

View File

@ -7,7 +7,7 @@ write_symbols() {
| sed -e 's/(.*$//g' -e 's/^.*getdns_/getdns_/g' | sort | uniq > $OUTPUT
}
write_symbols libgetdns.symbols getdns/getdns.h.in getdns/getdns_extra.h
write_symbols libgetdns.symbols getdns/getdns.h.in getdns/getdns_extra.h.in
echo plain_mem_funcs_user_arg >> libgetdns.symbols
echo priv_getdns_context_mf >> libgetdns.symbols
write_symbols extension/libevent.symbols getdns/getdns_ext_libevent.h

View File

@ -41,6 +41,26 @@
#include "gldns/gbuffer.h"
#include "gldns/pkthdr.h"
#include "dict.h"
#include "debug.h"
/* MAXIMUM_TSIG_SPACE = TSIG name (dname) : 256
* TSIG type (uint16_t) : 2
* TSIG class (uint16_t) : 2
* TSIG TTL (uint32_t) : 4
* RdLen (uint16_t) : 2
* Algorithm name (dname) : 256
* Time Signed (uint48_t) : 6
* Fudge (uint16_t) : 2
* Mac Size (uint16_t) : 2
* Mac (variable) : EVP_MAX_MD_SIZE
* Original Id (uint16_t) : 2
* Error (uint16_t) : 2
* Other Len (uint16_t) : 2
* Other Data (nothing) : 0
* ---- +
* 538 + EVP_MAX_MD_SIZE
*/
#define MAXIMUM_TSIG_SPACE (538 + EVP_MAX_MD_SIZE)
getdns_dict dnssec_ok_checking_disabled_spc = {
{ RBTREE_NULL, 0, (int (*)(const void *, const void *)) strcmp },
@ -114,6 +134,7 @@ network_req_init(getdns_network_req *net_req, getdns_dns_req *owner,
net_req->owner = owner;
net_req->dnssec_status = GETDNS_DNSSEC_INDETERMINATE;
net_req->tsig_status = GETDNS_DNSSEC_INDETERMINATE;
net_req->upstream = NULL;
net_req->fd = -1;
@ -128,11 +149,12 @@ network_req_init(getdns_network_req *net_req, getdns_dns_req *owner,
net_req->edns_maximum_udp_payload_size = edns_maximum_udp_payload_size;
net_req->max_udp_payload_size = edns_maximum_udp_payload_size != -1
? edns_maximum_udp_payload_size : 1432;
net_req->keepalive_sent = 0;
net_req->write_queue_tail = NULL;
net_req->response_len = 0;
net_req->base_query_option_sz = opt_options_size;
/* Some fields to record info for return_call_debugging */
/* Some fields to record info for return_call_reporting */
net_req->debug_start_time = 0;
net_req->debug_end_time = 0;
net_req->debug_tls_auth_status = 0;
@ -249,7 +271,7 @@ _getdns_network_req_add_upstream_option(getdns_network_req * req, uint16_t code,
/* no overflow allowed for OPT size either (maybe this is overkill
given the above check?) */
oldlen = gldns_read_uint16(req->opt + 9);
oldlen = gldns_read_uint16(req->opt + 9);
newlen = oldlen + 4 + sz;
if (newlen > UINT16_MAX)
return GETDNS_RETURN_GENERIC_ERROR;
@ -277,6 +299,267 @@ _getdns_network_req_add_upstream_option(getdns_network_req * req, uint16_t code,
return GETDNS_RETURN_GOOD;
}
size_t
_getdns_network_req_add_tsig(getdns_network_req *req)
{
getdns_upstream *upstream = req->upstream;
gldns_buffer gbuf;
uint16_t arcount;
const getdns_tsig_info *tsig_info;
uint8_t md_buf[EVP_MAX_MD_SIZE];
unsigned int md_len = EVP_MAX_MD_SIZE;
const EVP_MD *digester;
/* Should only be called when in stub mode */
assert(req->query);
if (upstream->tsig_alg == GETDNS_NO_TSIG || !upstream->tsig_dname_len)
return req->response - req->query;
arcount = gldns_read_uint16(req->query + 10);
#if defined(STUB_DEBUG) && STUB_DEBUG
/* TSIG should not have been written yet. */
if (req->opt) {
assert(arcount == 1);
assert(req->opt + 11 + gldns_read_uint16(req->opt + 9)
== req->response);
} else
assert(arcount == 0);
#endif
tsig_info = _getdns_get_tsig_info(upstream->tsig_alg);
gldns_buffer_init_frm_data(&gbuf, req->response, MAXIMUM_TSIG_SPACE);
gldns_buffer_write(&gbuf,
upstream->tsig_dname, upstream->tsig_dname_len); /* Name */
gldns_buffer_write_u16(&gbuf, GETDNS_RRCLASS_ANY); /* Class */
gldns_buffer_write_u32(&gbuf, 0); /* TTL */
gldns_buffer_write(&gbuf,
tsig_info->dname, tsig_info->dname_len); /* Algorithm Name */
gldns_buffer_write_u48(&gbuf, time(NULL)); /* Time Signed */
gldns_buffer_write_u16(&gbuf, 300); /* Fudge */
gldns_buffer_write_u16(&gbuf, 0); /* Error */
gldns_buffer_write_u16(&gbuf, 0); /* Other len */
switch (upstream->tsig_alg) {
#ifdef HAVE_EVP_MD5
case GETDNS_HMAC_MD5 : digester = EVP_md5() ; break;
#endif
#ifdef HAVE_EVP_SHA1
case GETDNS_HMAC_SHA1 : digester = EVP_sha1() ; break;
#endif
#ifdef HAVE_EVP_SHA224
case GETDNS_HMAC_SHA224: digester = EVP_sha224(); break;
#endif
#ifdef HAVE_EVP_SHA256
case GETDNS_HMAC_SHA256: digester = EVP_sha256(); break;
#endif
#ifdef HAVE_EVP_SHA384
case GETDNS_HMAC_SHA384: digester = EVP_sha384(); break;
#endif
#ifdef HAVE_EVP_SHA512
case GETDNS_HMAC_SHA512: digester = EVP_sha512(); break;
#endif
default : return req->response - req->query;
}
(void) HMAC(digester, upstream->tsig_key, upstream->tsig_size,
(void *)req->query, gldns_buffer_current(&gbuf) - req->query,
md_buf, &md_len);
gldns_buffer_rewind(&gbuf);
gldns_buffer_write(&gbuf,
upstream->tsig_dname, upstream->tsig_dname_len); /* Name */
gldns_buffer_write_u16(&gbuf, GETDNS_RRTYPE_TSIG); /* Type*/
gldns_buffer_write_u16(&gbuf, GETDNS_RRCLASS_ANY); /* Class */
gldns_buffer_write_u32(&gbuf, 0); /* TTL */
gldns_buffer_write_u16(&gbuf,
tsig_info->dname_len + 10 + md_len + 6); /* RdLen */
gldns_buffer_write(&gbuf,
tsig_info->dname, tsig_info->dname_len); /* Algorithm Name */
gldns_buffer_write_u48(&gbuf, time(NULL)); /* Time Signed */
gldns_buffer_write_u16(&gbuf, 300); /* Fudge */
gldns_buffer_write_u16(&gbuf, md_len); /* MAC Size */
gldns_buffer_write(&gbuf, md_buf, md_len); /* MAC*/
gldns_buffer_write(&gbuf, req->query, 2); /* Original ID */
gldns_buffer_write_u16(&gbuf, 0); /* Error */
gldns_buffer_write_u16(&gbuf, 0); /* Other len */
if (gldns_buffer_position(&gbuf) > gldns_buffer_limit(&gbuf))
return req->response - req->query;
DEBUG_STUB("Sending with TSIG, mac length: %d\n", (int)md_len);
req->tsig_status = GETDNS_DNSSEC_INSECURE;
gldns_write_uint16(req->query + 10, arcount + 1);
req->response = gldns_buffer_current(&gbuf);
return req->response - req->query;
}
void
_getdns_network_validate_tsig(getdns_network_req *req)
{
_getdns_rr_iter rr_spc, *rr;
_getdns_rdf_iter rdf_spc, *rdf;
const uint8_t *request_mac;
uint16_t request_mac_len;
uint8_t tsig_vars[MAXIMUM_TSIG_SPACE];
gldns_buffer gbuf;
const uint8_t *dname;
size_t dname_len;
const uint8_t *response_mac;
uint16_t response_mac_len;
uint8_t other_len;
uint8_t result_mac[EVP_MAX_MD_SIZE];
unsigned int result_mac_len = EVP_MAX_MD_SIZE;
uint16_t original_id;
const EVP_MD *digester;
HMAC_CTX ctx;
DEBUG_STUB("Validate TSIG\n");
for ( rr = _getdns_rr_iter_init(&rr_spc, req->query,
(req->response - req->query))
; rr
; rr = _getdns_rr_iter_next(rr)) {
if (_getdns_rr_iter_section(rr) == GLDNS_SECTION_ADDITIONAL &&
gldns_read_uint16(rr->rr_type) == GETDNS_RRTYPE_TSIG)
break;
}
if (!rr || !(rdf = _getdns_rdf_iter_init_at(&rdf_spc, rr, 3)))
return; /* No good TSIG sent, so nothing expected on reply */
request_mac_len = gldns_read_uint16(rdf->pos);
if (request_mac_len != rdf->nxt - rdf->pos - 2)
return;
DEBUG_STUB("Request MAC found length: %d\n", (int)(request_mac_len));
request_mac = rdf->pos + 2;
/* Now we expect a TSIG on the response! */
req->tsig_status = GETDNS_DNSSEC_BOGUS;
for ( rr = _getdns_rr_iter_init(
&rr_spc, req->response, req->response_len)
; rr
; rr = _getdns_rr_iter_next(rr)) {
if (_getdns_rr_iter_section(rr) == GLDNS_SECTION_ADDITIONAL &&
gldns_read_uint16(rr->rr_type) == GETDNS_RRTYPE_TSIG)
break;
}
if (!rr || !(rdf = _getdns_rdf_iter_init(&rdf_spc, rr)))
return;
gldns_buffer_init_frm_data(&gbuf, tsig_vars, MAXIMUM_TSIG_SPACE);
dname_len = gldns_buffer_remaining(&gbuf);
if (!(dname = _getdns_owner_if_or_as_decompressed(
rr, gldns_buffer_current(&gbuf), &dname_len)))
return;
if (dname == gldns_buffer_current(&gbuf))
gldns_buffer_skip(&gbuf, dname_len);
else
gldns_buffer_write(&gbuf, dname, dname_len);
gldns_buffer_write(&gbuf, rr->rr_type + 2, 2); /* Class */
gldns_buffer_write(&gbuf, rr->rr_type + 4, 4); /* TTL */
dname_len = gldns_buffer_remaining(&gbuf);
if (!(dname = _getdns_rdf_if_or_as_decompressed(
rdf, gldns_buffer_current(&gbuf), &dname_len)))
return;
if (dname == gldns_buffer_current(&gbuf))
gldns_buffer_skip(&gbuf, dname_len);
else
gldns_buffer_write(&gbuf, dname, dname_len);
if (!(rdf = _getdns_rdf_iter_next(rdf)) ||
rdf->nxt - rdf->pos != 6)
return;
gldns_buffer_write(&gbuf, rdf->pos, 6); /* Time Signed */
if (!(rdf = _getdns_rdf_iter_next(rdf)) ||
rdf->nxt - rdf->pos != 2)
return;
gldns_buffer_write(&gbuf, rdf->pos, 2); /* Fudge */
if (!(rdf = _getdns_rdf_iter_next(rdf))) /* mac */
return;
response_mac_len = gldns_read_uint16(rdf->pos);
if (response_mac_len != rdf->nxt - rdf->pos - 2)
return;
DEBUG_STUB("Response MAC found length: %d\n", (int)(response_mac_len));
response_mac = rdf->pos + 2;
if (!(rdf = _getdns_rdf_iter_next(rdf)) ||
rdf->nxt -rdf->pos != 2) /* Original ID */
return;
original_id = gldns_read_uint16(rdf->pos);
if (!(rdf = _getdns_rdf_iter_next(rdf)) ||
rdf->nxt - rdf->pos != 2)
return;
gldns_buffer_write(&gbuf, rdf->pos, 2); /* Error */
if (!(rdf = _getdns_rdf_iter_next(rdf))) /* Other */
return;
gldns_buffer_write_u16(&gbuf, 0); /* Other len */
other_len = gldns_read_uint16(rdf->pos);
if (other_len != rdf->nxt - rdf->pos - 2)
return;
if (other_len)
gldns_buffer_write(&gbuf, rdf->pos, other_len);
/* TSIG found */
DEBUG_STUB("TSIG found, original ID: %d\n", (int)original_id);
gldns_write_uint16(req->response + 10,
gldns_read_uint16(req->response + 10) - 1);
gldns_write_uint16(req->response, original_id);
switch (req->upstream->tsig_alg) {
#ifdef HAVE_EVP_MD5
case GETDNS_HMAC_MD5 : digester = EVP_md5() ; break;
#endif
#ifdef HAVE_EVP_SHA1
case GETDNS_HMAC_SHA1 : digester = EVP_sha1() ; break;
#endif
#ifdef HAVE_EVP_SHA224
case GETDNS_HMAC_SHA224: digester = EVP_sha224(); break;
#endif
#ifdef HAVE_EVP_SHA256
case GETDNS_HMAC_SHA256: digester = EVP_sha256(); break;
#endif
#ifdef HAVE_EVP_SHA384
case GETDNS_HMAC_SHA384: digester = EVP_sha384(); break;
#endif
#ifdef HAVE_EVP_SHA512
case GETDNS_HMAC_SHA512: digester = EVP_sha512(); break;
#endif
default : return;
}
HMAC_CTX_init(&ctx);
(void) HMAC_Init_ex(&ctx, req->upstream->tsig_key,
req->upstream->tsig_size, digester, NULL);
(void) HMAC_Update(&ctx, request_mac - 2, request_mac_len + 2);
(void) HMAC_Update(&ctx, req->response, rr->pos - req->response);
(void) HMAC_Update(&ctx, tsig_vars, gldns_buffer_position(&gbuf));
HMAC_Final(&ctx, result_mac, &result_mac_len);
DEBUG_STUB("Result MAC length: %d\n", (int)(result_mac_len));
if (result_mac_len == response_mac_len &&
memcmp(result_mac, response_mac, result_mac_len) == 0)
req->tsig_status = GETDNS_DNSSEC_SECURE;
HMAC_CTX_cleanup(&ctx);
gldns_write_uint16(req->response, gldns_read_uint16(req->query));
gldns_write_uint16(req->response + 10,
gldns_read_uint16(req->response + 10) + 1);
}
void
_getdns_dns_req_free(getdns_dns_req * req)
{
@ -439,7 +722,7 @@ _getdns_dns_req_new(getdns_context *context, getdns_eventloop *loop,
+ strlen(name) + 1 + 4 /* dname always smaller then strlen(name) + 1 */
+ 12 + opt_options_size /* space needed for OPT (if needed) */
+ MAXIMUM_UPSTREAM_OPTION_SPACE
/* TODO: TSIG */
+ MAXIMUM_TSIG_SPACE
+ 7) / 8 * 8;
}
max_response_sz = (( edns_maximum_udp_payload_size != -1
@ -488,8 +771,8 @@ _getdns_dns_req_new(getdns_context *context, getdns_eventloop *loop,
#endif
result->edns_client_subnet_private = context->edns_client_subnet_private;
result->tls_query_padding_blocksize = context->tls_query_padding_blocksize;
result->return_call_debugging
= is_extension_set(extensions, "return_call_debugging");
result->return_call_reporting
= is_extension_set(extensions, "return_call_reporting");
/* will be set by caller */
result->user_pointer = NULL;

View File

@ -44,52 +44,139 @@
#define ALEN(a) (sizeof(a)/sizeof(a[0]))
#define UNKNOWN_RDATA NULL
static uint8_t *
apl_n_rdf_end(uint8_t *pkt, uint8_t *pkt_end, uint8_t *rdf)
static const uint8_t *
apl_n_rdf_end(const uint8_t *pkt, const uint8_t *pkt_end, const uint8_t *rdf)
{
return rdf < pkt_end ? rdf + 1 : NULL;
}
static getdns_return_t
apl_n_dict_set_value(getdns_dict *dict, uint8_t *rdf)
apl_n_wire2dict(getdns_dict *dict, const uint8_t *rdf)
{
return getdns_dict_set_int(dict, "n", (*rdf >> 7));
}
static getdns_return_t
apl_n_list_append_value(getdns_list *list, uint8_t *rdf)
apl_n_wire2list(getdns_list *list, const uint8_t *rdf)
{
return _getdns_list_append_int(list, (*rdf >> 7));
}
static getdns_return_t
apl_n_2wire(uint32_t value, uint8_t *rdata, uint8_t *rdf, size_t *rdf_len)
{
(void)rdata; /* unused parameter */
if (*rdf_len < 1) {
*rdf_len = 1;
return GETDNS_RETURN_NEED_MORE_SPACE;
}
*rdf_len = 1;
*rdf = value ? 0x80 : 0x00;
return GETDNS_RETURN_GOOD;
}
static getdns_return_t
apl_n_dict2wire(const getdns_dict *dict,
uint8_t *rdata, uint8_t *rdf, size_t *rdf_len)
{
getdns_return_t r;
uint32_t value;
if ((r = getdns_dict_get_int(dict, "n", &value)))
return r;
else
return apl_n_2wire(value, rdata, rdf, rdf_len);
}
static getdns_return_t
apl_n_list2wire(const getdns_list *list, size_t i,
uint8_t *rdata, uint8_t *rdf, size_t *rdf_len)
{
getdns_return_t r;
uint32_t value;
if ((r = getdns_list_get_int(list, i, &value)))
return r;
else
return apl_n_2wire(value, rdata, rdf, rdf_len);
}
static _getdns_rdf_special apl_n = {
apl_n_rdf_end, apl_n_dict_set_value, apl_n_list_append_value
apl_n_rdf_end,
apl_n_wire2dict, apl_n_wire2list,
apl_n_dict2wire, apl_n_list2wire
};
static uint8_t *
apl_afdpart_rdf_end(uint8_t *pkt, uint8_t *pkt_end, uint8_t *rdf)
static const uint8_t *
apl_afdpart_rdf_end(
const uint8_t *pkt, const uint8_t *pkt_end, const uint8_t *rdf)
{
uint8_t *end = rdf + (rdf[-1] & 0x7F);
const uint8_t *end = rdf + (rdf[-1] & 0x7F);
return end <= pkt_end ? end : NULL;
}
static getdns_return_t
apl_afdpart_dict_set_value(getdns_dict *dict, uint8_t *rdf)
apl_afdpart_wire2dict(getdns_dict *dict, const uint8_t *rdf)
{
getdns_bindata bindata = { (rdf[-1] & 0x7F), rdf };
return getdns_dict_set_bindata(dict, "afdpart", &bindata);
return _getdns_dict_set_const_bindata(
dict, "afdpart", (rdf[-1] & 0x7F), rdf);
}
static getdns_return_t
apl_afdpart_list_append_value(getdns_list *list, uint8_t *rdf)
apl_afdpart_wire2list(getdns_list *list, const uint8_t *rdf)
{
getdns_bindata bindata = { (rdf[-1] & 0x7F), rdf };
return _getdns_list_append_bindata(list, &bindata);
return _getdns_list_append_const_bindata(list, (rdf[-1] & 0x7F), rdf);
}
static getdns_return_t
apl_afdpart_2wire(
const getdns_bindata *value, uint8_t *rdata, uint8_t *rdf, size_t *rdf_len)
{
if (value->size > 0x7F)
return GETDNS_RETURN_INVALID_PARAMETER;
if (rdf - 1 < rdata)
return GETDNS_RETURN_GENERIC_ERROR;
if (*rdf_len < value->size) {
*rdf_len = value->size;
return GETDNS_RETURN_NEED_MORE_SPACE;
}
*rdf_len = value->size;
/* Keeping first bit is safe because value->size <= 0x7F */
rdf[-1] |= value->size;
(void) memcpy(rdf, value->data, value->size);
return GETDNS_RETURN_GOOD;
}
static getdns_return_t
apl_afdpart_dict2wire(
const getdns_dict *dict, uint8_t *rdata, uint8_t *rdf, size_t *rdf_len)
{
getdns_return_t r;
getdns_bindata *value;
if ((r = getdns_dict_get_bindata(dict, "afdpart", &value)))
return r;
else
return apl_afdpart_2wire(value, rdata, rdf, rdf_len);
}
static getdns_return_t
apl_afdpart_list2wire(const getdns_list *list,
size_t i, uint8_t *rdata, uint8_t *rdf, size_t *rdf_len)
{
getdns_return_t r;
getdns_bindata *value;
if ((r = getdns_list_get_bindata(list, i, &value)))
return r;
else
return apl_afdpart_2wire(value, rdata, rdf, rdf_len);
}
static _getdns_rdf_special apl_afdpart = {
apl_afdpart_rdf_end,
apl_afdpart_dict_set_value, apl_afdpart_list_append_value
apl_afdpart_wire2dict, apl_afdpart_wire2list,
apl_afdpart_dict2wire, apl_afdpart_list2wire
};
static uint8_t *
ipseckey_gateway_rdf_end(uint8_t *pkt, uint8_t *pkt_end, uint8_t *rdf)
static const uint8_t *
ipseckey_gateway_rdf_end(
const uint8_t *pkt, const uint8_t *pkt_end, const uint8_t *rdf)
{
uint8_t *end;
const uint8_t *end;
if (rdf - 5 < pkt)
return NULL;
@ -116,15 +203,16 @@ ipseckey_gateway_rdf_end(uint8_t *pkt, uint8_t *pkt_end, uint8_t *rdf)
return end <= pkt_end ? end : NULL;
}
static getdns_return_t
ipseckey_gateway_equip_bindata(uint8_t *rdf, getdns_bindata *bindata)
ipseckey_gateway_equip_const_bindata(
const uint8_t *rdf, size_t *size, const uint8_t **data)
{
bindata->data = rdf;
*data = rdf;
switch (rdf[-2]) {
case 0: bindata->size = 0;
case 0: *size = 0;
break;
case 1: bindata->size = 4;
case 1: *size = 4;
break;
case 2: bindata->size = 16;
case 2: *size = 16;
break;
case 3: while (*rdf)
if ((*rdf & 0xC0) == 0xC0)
@ -133,112 +221,318 @@ ipseckey_gateway_equip_bindata(uint8_t *rdf, getdns_bindata *bindata)
return GETDNS_RETURN_GENERIC_ERROR;
else
rdf += *rdf + 1;
bindata->size = rdf + 1 - bindata->data;
*size = rdf + 1 - *data;
break;
default:
return GETDNS_RETURN_GENERIC_ERROR;
}
return GETDNS_RETURN_GOOD;
}
static getdns_return_t
ipseckey_gateway_dict_set_value(getdns_dict *dict, uint8_t *rdf)
{
getdns_bindata bindata;
if (ipseckey_gateway_equip_bindata(rdf, &bindata))
static getdns_return_t
ipseckey_gateway_wire2dict(getdns_dict *dict, const uint8_t *rdf)
{
size_t size;
const uint8_t *data;
if (ipseckey_gateway_equip_const_bindata(rdf, &size, &data))
return GETDNS_RETURN_GENERIC_ERROR;
else if (! bindata.size)
else if (! size)
return GETDNS_RETURN_GOOD;
else
return getdns_dict_set_bindata(dict, "gateway", &bindata);
return _getdns_dict_set_const_bindata(dict, "gateway", size, data);
}
static getdns_return_t
ipseckey_gateway_list_append_value(getdns_list *list, uint8_t *rdf)
ipseckey_gateway_wire2list(getdns_list *list, const uint8_t *rdf)
{
getdns_bindata bindata;
size_t size;
const uint8_t *data;
if (ipseckey_gateway_equip_bindata(rdf, &bindata))
if (ipseckey_gateway_equip_const_bindata(rdf, &size, &data))
return GETDNS_RETURN_GENERIC_ERROR;
else if (! bindata.size)
else if (!size)
return GETDNS_RETURN_GOOD;
else
return _getdns_list_append_bindata(list, &bindata);
return _getdns_list_append_const_bindata(list, size, data);
}
static getdns_return_t
ipseckey_gateway_2wire(
const getdns_bindata *value, uint8_t *rdata, uint8_t *rdf, size_t *rdf_len)
{
if (rdf - 2 < rdata)
return GETDNS_RETURN_GENERIC_ERROR;
switch (rdf[-2]) {
case 0: if (value && value->size > 0)
return GETDNS_RETURN_INVALID_PARAMETER;
break;
case 1: if (!value || value->size != 4)
return GETDNS_RETURN_INVALID_PARAMETER;
if (*rdf_len < 4) {
*rdf_len = 4;
return GETDNS_RETURN_NEED_MORE_SPACE;
}
*rdf_len = 4;
(void)memcpy(rdf, value->data, 4);
return GETDNS_RETURN_GOOD;
case 2: if (!value || value->size != 16)
return GETDNS_RETURN_INVALID_PARAMETER;
if (*rdf_len < 16) {
*rdf_len = 16;
return GETDNS_RETURN_NEED_MORE_SPACE;
}
*rdf_len = 16;
(void)memcpy(rdf, value->data, 16);
return GETDNS_RETURN_GOOD;
case 3: if (!value || value->size == 0)
return GETDNS_RETURN_INVALID_PARAMETER;
/* Assume bindata is a valid dname; garbage in, garbage out */
if (*rdf_len < value->size) {
*rdf_len = value->size;
return GETDNS_RETURN_NEED_MORE_SPACE;
}
*rdf_len = value->size;
(void)memcpy(rdf, value->data, value->size);
return GETDNS_RETURN_GOOD;
default:
return GETDNS_RETURN_GENERIC_ERROR;
}
return GETDNS_RETURN_GOOD;
}
static getdns_return_t
ipseckey_gateway_dict2wire(
const getdns_dict *dict, uint8_t *rdata, uint8_t *rdf, size_t *rdf_len)
{
getdns_return_t r;
getdns_bindata *value;
if ((r = getdns_dict_get_bindata(dict, "gateway", &value)))
return r;
else
return ipseckey_gateway_2wire(value, rdata, rdf, rdf_len);
}
static getdns_return_t
ipseckey_gateway_list2wire(const getdns_list *list,
size_t i, uint8_t *rdata, uint8_t *rdf, size_t *rdf_len)
{
getdns_return_t r;
getdns_bindata *value;
if ((r = getdns_list_get_bindata(list, i, &value)))
return r;
else
return ipseckey_gateway_2wire(value, rdata, rdf, rdf_len);
}
static _getdns_rdf_special ipseckey_gateway = {
ipseckey_gateway_rdf_end,
ipseckey_gateway_dict_set_value, ipseckey_gateway_list_append_value
ipseckey_gateway_wire2dict, ipseckey_gateway_wire2list,
ipseckey_gateway_dict2wire, ipseckey_gateway_list2wire
};
static uint8_t *
hip_pk_algorithm_rdf_end(uint8_t *pkt, uint8_t *pkt_end, uint8_t *rdf)
static const uint8_t *
hip_pk_algorithm_rdf_end(
const uint8_t *pkt, const uint8_t *pkt_end, const uint8_t *rdf)
{
return rdf + 4 > pkt_end ? NULL
: rdf + 4 + *rdf + gldns_read_uint16(rdf + 2) > pkt_end ? NULL
: rdf + 1;
}
static getdns_return_t
hip_pk_algorithm_dict_set_value(getdns_dict *dict, uint8_t *rdf)
hip_pk_algorithm_wire2dict(getdns_dict *dict, const uint8_t *rdf)
{
return getdns_dict_set_int(dict, "pk_algorithm", rdf[1]);
}
static getdns_return_t
hip_pk_algorithm_list_append_value(getdns_list *list, uint8_t *rdf)
hip_pk_algorithm_wire2list(getdns_list *list, const uint8_t *rdf)
{
return _getdns_list_append_int(list, rdf[1]);
}
static getdns_return_t
hip_pk_algorithm_2wire(uint32_t value, uint8_t *rdata, uint8_t *rdf, size_t *rdf_len)
{
if (rdata != rdf)
return GETDNS_RETURN_GENERIC_ERROR;
if (value > 0xFF)
return GETDNS_RETURN_INVALID_PARAMETER;
if (*rdf_len < 4) {
*rdf_len = 4;
return GETDNS_RETURN_NEED_MORE_SPACE;
}
*rdf_len = 4;
rdata[1] = value;
return GETDNS_RETURN_GOOD;
}
static getdns_return_t
hip_pk_algorithm_dict2wire(
const getdns_dict *dict,uint8_t *rdata, uint8_t *rdf, size_t *rdf_len)
{
getdns_return_t r;
uint32_t value;
if ((r = getdns_dict_get_int(dict, "pk_algorithm", &value)))
return r;
else
return hip_pk_algorithm_2wire(value, rdata, rdf, rdf_len);
}
static getdns_return_t
hip_pk_algorithm_list2wire(const getdns_list *list,
size_t i, uint8_t *rdata, uint8_t *rdf, size_t *rdf_len)
{
getdns_return_t r;
uint32_t value;
if ((r = getdns_list_get_int(list, i, &value)))
return r;
else
return hip_pk_algorithm_2wire(value, rdata, rdf, rdf_len);
}
static _getdns_rdf_special hip_pk_algorithm = {
hip_pk_algorithm_rdf_end,
hip_pk_algorithm_dict_set_value, hip_pk_algorithm_list_append_value
hip_pk_algorithm_wire2dict, hip_pk_algorithm_wire2list,
hip_pk_algorithm_dict2wire, hip_pk_algorithm_list2wire
};
static uint8_t *
hip_hit_rdf_end(uint8_t *pkt, uint8_t *pkt_end, uint8_t *rdf)
static const uint8_t *
hip_hit_rdf_end(const uint8_t *pkt, const uint8_t *pkt_end, const uint8_t *rdf)
{
return rdf + 3 > pkt_end ? NULL
: rdf + 3 + rdf[-1] + gldns_read_uint16(rdf + 1) > pkt_end ? NULL
: rdf + 1;
}
static getdns_return_t
hip_hit_dict_set_value(getdns_dict *dict, uint8_t *rdf)
hip_hit_wire2dict(getdns_dict *dict, const uint8_t *rdf)
{
getdns_bindata bindata = { rdf[-1], rdf + 3 };
return getdns_dict_set_bindata(dict, "hit", &bindata);
return _getdns_dict_set_const_bindata(dict, "hit", rdf[-1], rdf + 3);
}
static getdns_return_t
hip_hit_list_append_value(getdns_list *list, uint8_t *rdf)
hip_hit_wire2list(getdns_list *list, const uint8_t *rdf)
{
getdns_bindata bindata = { rdf[-1], rdf + 3 };
return _getdns_list_append_bindata(list, &bindata);
return _getdns_list_append_const_bindata(list, rdf[-1], rdf + 3);
}
static getdns_return_t
hip_hit_2wire(
const getdns_bindata *value, uint8_t *rdata, uint8_t *rdf, size_t *rdf_len)
{
if (rdata != rdf - 4)
return GETDNS_RETURN_GENERIC_ERROR;
if (value && value->size > 0xFF)
return GETDNS_RETURN_INVALID_PARAMETER;
if (!value || value->size == 0) {
rdata[0] = 0;
*rdf_len = 0;
return GETDNS_RETURN_GOOD;
}
if (value->size > *rdf_len) {
*rdf_len = value->size;
return GETDNS_RETURN_NEED_MORE_SPACE;
}
*rdf_len = value->size;
rdata[0] = value->size;
(void)memcpy(rdf, value->data, value->size);
return GETDNS_RETURN_GOOD;
}
static getdns_return_t
hip_hit_dict2wire(
const getdns_dict *dict, uint8_t *rdata, uint8_t *rdf, size_t *rdf_len)
{
getdns_return_t r;
getdns_bindata *value;
if ((r = getdns_dict_get_bindata(dict, "hit", &value)))
return r;
else
return hip_hit_2wire(value, rdata, rdf, rdf_len);
}
static getdns_return_t
hip_hit_list2wire(const getdns_list *list,
size_t i, uint8_t *rdata, uint8_t *rdf, size_t *rdf_len)
{
getdns_return_t r;
getdns_bindata *value;
if ((r = getdns_list_get_bindata(list, i, &value)))
return r;
else
return hip_hit_2wire(value, rdata, rdf, rdf_len);
}
static _getdns_rdf_special hip_hit = {
hip_hit_rdf_end, hip_hit_dict_set_value, hip_hit_list_append_value
hip_hit_rdf_end,
hip_hit_wire2dict, hip_hit_wire2list,
hip_hit_dict2wire, hip_hit_list2wire
};
static uint8_t *
hip_public_key_rdf_end(uint8_t *pkt, uint8_t *pkt_end, uint8_t *rdf)
static const uint8_t *
hip_public_key_rdf_end(
const uint8_t *pkt, const uint8_t *pkt_end, const uint8_t *rdf)
{
return rdf + 2 > pkt_end ? NULL
: rdf + 2 + rdf[-2] + gldns_read_uint16(rdf) > pkt_end ? NULL
: rdf + 2 + rdf[-2] + gldns_read_uint16(rdf);
}
static getdns_return_t
hip_public_key_dict_set_value(getdns_dict *dict, uint8_t *rdf)
hip_public_key_wire2dict(getdns_dict *dict, const uint8_t *rdf)
{
getdns_bindata bindata = { gldns_read_uint16(rdf), rdf + 2 + rdf[-2] };
return getdns_dict_set_bindata(dict, "public_key", &bindata);
return _getdns_dict_set_const_bindata(
dict, "public_key", gldns_read_uint16(rdf), rdf + 2 + rdf[-2]);
}
static getdns_return_t
hip_public_key_list_append_value(getdns_list *list, uint8_t *rdf)
hip_public_key_wire2list(getdns_list *list, const uint8_t *rdf)
{
getdns_bindata bindata = { gldns_read_uint16(rdf), rdf + 2 + rdf[-2] };
return _getdns_list_append_bindata(list, &bindata);
return _getdns_list_append_const_bindata(
list, gldns_read_uint16(rdf), rdf + 2 + rdf[-2]);
}
static getdns_return_t
hip_public_key_2wire(
const getdns_bindata *value, uint8_t *rdata, uint8_t *rdf, size_t *rdf_len)
{
if (rdata > rdf - 4 || rdata + 4 + rdata[0] != rdf)
return GETDNS_RETURN_GENERIC_ERROR;
if (value && value->size > 0xFFFF)
return GETDNS_RETURN_INVALID_PARAMETER;
if (!value || value->size == 0) {
rdata[2] = rdata[3] = 0;
*rdf_len = 0;
return GETDNS_RETURN_GOOD;
}
if (value->size > *rdf_len) {
*rdf_len = value->size;
return GETDNS_RETURN_NEED_MORE_SPACE;
}
*rdf_len = value->size;
gldns_write_uint16(rdata + 2, value->size);
(void)memcpy(rdf, value->data, value->size);
return GETDNS_RETURN_GOOD;
}
static getdns_return_t
hip_public_key_dict2wire(
const getdns_dict *dict, uint8_t *rdata, uint8_t *rdf, size_t *rdf_len)
{
getdns_return_t r;
getdns_bindata *value;
if ((r = getdns_dict_get_bindata(dict, "public_key", &value)))
return r;
else
return hip_public_key_2wire(value, rdata, rdf, rdf_len);
}
static getdns_return_t
hip_public_key_list2wire(
const getdns_list *list, size_t i, uint8_t *rdata, uint8_t *rdf, size_t *rdf_len)
{
getdns_return_t r;
getdns_bindata *value;
if ((r = getdns_list_get_bindata(list, i, &value)))
return r;
else
return hip_public_key_2wire(value, rdata, rdf, rdf_len);
}
static _getdns_rdf_special hip_public_key = {
hip_public_key_rdf_end,
hip_public_key_dict_set_value, hip_public_key_list_append_value
hip_public_key_wire2dict, hip_public_key_wire2list,
hip_public_key_dict2wire, hip_public_key_list2wire
};
@ -741,32 +1035,141 @@ _getdns_rr_type_name(int rr_type)
return _getdns_rr_def_lookup(rr_type)->name;
}
static void
write_int_rdata(gldns_buffer *buf, _getdns_rdf_type type, uint32_t value)
{
size_t j;
for (j = type & GETDNS_RDF_FIXEDSZ; j; j--)
gldns_buffer_write_u8(buf,
(uint8_t)(value >> (8 * (j - 1))) & 0xff);
}
static void
write_bindata_rdata(gldns_buffer *buf,
_getdns_rdf_type type, getdns_bindata *bindata)
{
if (type & GETDNS_RDF_LEN_VAL)
write_int_rdata(buf, type >> 8, bindata->size);
gldns_buffer_write(buf, bindata->data, bindata->size);
}
static getdns_return_t
write_rdata_field(gldns_buffer *buf, uint8_t *rdata_start,
const _getdns_rdata_def *rd_def, getdns_dict *rdata)
{
getdns_return_t r;
getdns_list *list;
uint32_t value;
getdns_bindata *bindata;
size_t i, rdf_len;
if (rd_def->type & GETDNS_RDF_INTEGER) {
if (!(rd_def->type & GETDNS_RDF_REPEAT)) {
if ((r = getdns_dict_get_int(
rdata, rd_def->name, &value)))
return r;
else
write_int_rdata(buf, rd_def->type, value);
} else if ((r = getdns_dict_get_list(
rdata, rd_def->name, &list)))
return r == GETDNS_RETURN_NO_SUCH_DICT_NAME
? GETDNS_RETURN_GOOD : r;
else for ( i = 0
; GETDNS_RETURN_GOOD ==
(r = getdns_list_get_int(list, i, &value))
; i++)
write_int_rdata(buf, rd_def->type, value);
} else if (rd_def->type & GETDNS_RDF_BINDATA) {
if (!(rd_def->type & GETDNS_RDF_REPEAT)) {
if ((r = getdns_dict_get_bindata(
rdata, rd_def->name, &bindata)))
return r;
else
write_bindata_rdata(buf, rd_def->type, bindata);
} else if ((r = getdns_dict_get_list(
rdata, rd_def->name, &list)))
return r == GETDNS_RETURN_NO_SUCH_DICT_NAME
? GETDNS_RETURN_GOOD : r;
else for ( i = 0
; GETDNS_RETURN_GOOD ==
(r = getdns_list_get_bindata(list, i, &bindata))
; i++)
write_bindata_rdata(buf, rd_def->type, bindata);
} else if (!(rd_def->type & GETDNS_RDF_SPECIAL)) {
/* Unknown rdata type */
return GETDNS_RETURN_GENERIC_ERROR;
} else if (!(rd_def->type & GETDNS_RDF_REPEAT)) {
rdf_len = gldns_buffer_remaining(buf);
r = rd_def->special->dict2wire(rdata, rdata_start,
gldns_buffer_current(buf), &rdf_len);
if (r == GETDNS_RETURN_GOOD ||
r == GETDNS_RETURN_NEED_MORE_SPACE)
gldns_buffer_skip(buf, rdf_len);
if (r)
return r;
} else if ((r = getdns_dict_get_list(rdata, rd_def->name, &list))) {
return r == GETDNS_RETURN_NO_SUCH_DICT_NAME
? GETDNS_RETURN_GOOD : r;
} else for ( i = 0; r == GETDNS_RETURN_GOOD; i++ ) {
rdf_len = gldns_buffer_remaining(buf);
r = rd_def->special->list2wire(list, i, rdata_start,
gldns_buffer_current(buf), &rdf_len);
if (r == GETDNS_RETURN_GOOD ||
r == GETDNS_RETURN_NEED_MORE_SPACE)
gldns_buffer_skip(buf, rdf_len);
}
return r != GETDNS_RETURN_NO_SUCH_LIST_ITEM ? r : GETDNS_RETURN_GOOD;
}
getdns_return_t
_getdns_rr_dict2wire(getdns_dict *rr_dict, gldns_buffer *buf)
_getdns_rr_dict2wire(const getdns_dict *rr_dict, gldns_buffer *buf)
{
getdns_return_t r = GETDNS_RETURN_GOOD;
struct getdns_bindata *name;
struct getdns_bindata *rdata_raw;
struct getdns_bindata *bindata;
struct getdns_dict *rdata;
getdns_bindata *name;
getdns_bindata *rdata_raw;
getdns_dict *rdata;
uint32_t rr_type;
uint32_t rr_class = GETDNS_RRCLASS_IN;
uint32_t rr_ttl = 0;
uint32_t value;
const _getdns_rr_def *rr_def;
const _getdns_rdata_def *rd_def;
int n_rdata_fields;
size_t j, rdata_size_mark;
const _getdns_rdata_def *rd_def, *rep_rd_def;
int n_rdata_fields, rep_n_rdata_fields;
size_t rdata_size_mark;
uint8_t *rdata_start;
getdns_list *list;
size_t i;
assert(rr_dict);
assert(buf);
if ((r = getdns_dict_get_bindata(rr_dict, "name", &name)))
goto error;
return r;
gldns_buffer_write(buf, name->data, name->size);
if ((r = getdns_dict_get_int(rr_dict, "type", &rr_type)))
goto error;
return r;
gldns_buffer_write_u16(buf, (uint16_t)rr_type);
(void) getdns_dict_get_int(rr_dict, "class", &rr_class);
@ -787,10 +1190,13 @@ _getdns_rr_dict2wire(getdns_dict *rr_dict, gldns_buffer *buf)
break;
}
if ((r = getdns_dict_get_dict(rr_dict, "rdata", &rdata)))
goto error;
if ((r = getdns_dict_get_dict(rr_dict, "rdata", &rdata))) {
if (r == GETDNS_RETURN_NO_SUCH_DICT_NAME) {
gldns_buffer_write_u16(buf, 0);
r = GETDNS_RETURN_GOOD;
}
if (n_rdata_fields == 0 && GETDNS_RETURN_GOOD ==
} else if (n_rdata_fields == 0 && GETDNS_RETURN_GOOD ==
(r = getdns_dict_get_bindata(rdata, "rdata_raw", &rdata_raw))) {
gldns_buffer_write_u16(buf, (uint16_t)rdata_raw->size);
@ -798,38 +1204,51 @@ _getdns_rr_dict2wire(getdns_dict *rr_dict, gldns_buffer *buf)
} else if (n_rdata_fields || r == GETDNS_RETURN_NO_SUCH_DICT_NAME) {
r = GETDNS_RETURN_GOOD;
rdata_size_mark = gldns_buffer_position(buf);
gldns_buffer_skip(buf, 2);
rdata_start = gldns_buffer_current(buf);
for ( rd_def = rr_def->rdata
, n_rdata_fields = rr_def->n_rdata_fields
; n_rdata_fields ; n_rdata_fields-- , rd_def++ ) {
if (rd_def->type & GETDNS_RDF_BINDATA) {
if ((r = getdns_dict_get_bindata(rdata,
rd_def->name, &bindata)))
break;
if (rd_def->type == GETDNS_RDF_REPEAT)
break;
gldns_buffer_write(buf, bindata->data
, bindata->size );
continue;
}
if (!(rd_def->type & GETDNS_RDF_INTEGER)) {
r = GETDNS_RETURN_GENERIC_ERROR;
if ((r = write_rdata_field(buf,
rdata_start, rd_def, rdata)))
break;
}
if (n_rdata_fields == 0 || r) {
/* pass */;
} else if ((r = getdns_dict_get_list(
rdata, rd_def->name, &list))) {
/* pass */;
} else for ( i = 0
; r == GETDNS_RETURN_GOOD
; i++) {
if ((r = getdns_list_get_dict(list, i, &rdata))) {
if (r == GETDNS_RETURN_NO_SUCH_LIST_ITEM)
r = GETDNS_RETURN_GOOD;
break;
}
if ((r = getdns_dict_get_int(
rdata, rd_def->name, &value)))
break;
for (j = rd_def->type & GETDNS_RDF_FIXEDSZ; j; j--)
gldns_buffer_write_u8(buf,
(uint8_t)(value >> (8 * (j - 1))) & 0xff);
for ( rep_rd_def = rd_def + 1
, rep_n_rdata_fields = n_rdata_fields - 1
; rep_n_rdata_fields
; rep_n_rdata_fields--, rep_rd_def++ ) {
if ((r = write_rdata_field(buf,
rdata_start, rep_rd_def, rdata)))
break;
}
}
gldns_buffer_write_u16_at(buf, rdata_size_mark,
(uint16_t)(gldns_buffer_position(buf)-rdata_size_mark-2));
}
error:
return r;
}

View File

@ -36,18 +36,28 @@
#include "getdns/getdns.h"
#include "gldns/gbuffer.h"
typedef uint8_t *(*_getdns_rdf_end_t)(
uint8_t *pkt, uint8_t *pkt_end, uint8_t *rdf);
/* rdf_end returns a pointer to the end of this rdf's data,
* i.e. where the next rdata field will start.
*/
typedef const uint8_t *(*_getdns_rdf_end_t)(
const uint8_t *pkt, const uint8_t *pkt_end, const uint8_t *rdf);
/* Limit checks are already done with _getdns_rdf_end_t */
typedef getdns_return_t (*_getdns_rdf_dict_set_value_t)(
getdns_dict *dict, uint8_t *rdf);
typedef getdns_return_t (*_getdns_rdf_list_append_value_t)(
getdns_list *list, uint8_t *rdf);
typedef getdns_return_t (*_getdns_rdf_wire2dict_t)(
getdns_dict *dict, const uint8_t *rdf);
typedef getdns_return_t (*_getdns_rdf_wire2list_t)(
getdns_list *list, const uint8_t *rdf);
typedef getdns_return_t (*_getdns_rdf_dict2wire_t)(
const getdns_dict *dict, uint8_t *rdata, uint8_t *rdf, size_t *rdf_len);
typedef getdns_return_t (*_getdns_rdf_list2wire_t)(
const getdns_list *list, size_t index,
uint8_t *rdata, uint8_t *rdf, size_t *rdf_len);
typedef struct _getdns_rdf_special {
_getdns_rdf_end_t rdf_end;
_getdns_rdf_dict_set_value_t dict_set_value;
_getdns_rdf_list_append_value_t list_append_value;
_getdns_rdf_end_t rdf_end;
_getdns_rdf_wire2dict_t wire2dict;
_getdns_rdf_wire2list_t wire2list;
_getdns_rdf_dict2wire_t dict2wire;
_getdns_rdf_list2wire_t list2wire;
} _getdns_rdf_special;
/* draft-levine-dnsextlang'ish type rr and rdata definitions */
@ -120,21 +130,21 @@ typedef enum _getdns_rdf_wf_type {
} _getdns_rdf_type;
typedef struct _getdns_rdata_def {
const char *name;
const char *name;
_getdns_rdf_type type;
_getdns_rdf_special *special;
} _getdns_rdata_def;
typedef struct _getdns_rr_def {
const char *name;
const char *name;
const _getdns_rdata_def *rdata;
int n_rdata_fields;
int n_rdata_fields;
} _getdns_rr_def;
const _getdns_rr_def *_getdns_rr_def_lookup(uint16_t rr_type);
getdns_return_t _getdns_rr_dict2wire(
getdns_dict *rr_dict, gldns_buffer *buf);
const getdns_dict *rr_dict, gldns_buffer *buf);
const char *_getdns_rr_type_name(int rr_type);

View File

@ -39,7 +39,7 @@ rr_iter_find_nxt(_getdns_rr_iter *i)
assert(i);
assert(i->rr_type);
i->nxt = i->n < GLDNS_QDCOUNT(i->pkt)
i->nxt = i->pkt && i->n < GLDNS_QDCOUNT(i->pkt)
? i->rr_type + 4
: i->rr_type + 10 > i->pkt_end
? i->pkt_end
@ -51,13 +51,14 @@ rr_iter_find_nxt(_getdns_rr_iter *i)
static _getdns_rr_iter *
find_rrtype(_getdns_rr_iter *i)
{
uint8_t *pos;
const uint8_t *pos;
assert(i);
assert(i->pos);
/* Past the last RR in the pkt */
if (GLDNS_QDCOUNT(i->pkt) + GLDNS_ANCOUNT(i->pkt) +
if (i->pkt &&
GLDNS_QDCOUNT(i->pkt) + GLDNS_ANCOUNT(i->pkt) +
GLDNS_NSCOUNT(i->pkt) + GLDNS_ARCOUNT(i->pkt) <= i->n)
goto done;
@ -83,7 +84,7 @@ done:
}
_getdns_rr_iter *
_getdns_rr_iter_init(_getdns_rr_iter *i, uint8_t *pkt, size_t pkt_len)
_getdns_rr_iter_init(_getdns_rr_iter *i, const uint8_t *pkt, size_t pkt_len)
{
assert(i);
@ -99,6 +100,25 @@ _getdns_rr_iter_init(_getdns_rr_iter *i, uint8_t *pkt, size_t pkt_len)
return find_rrtype(i);
}
_getdns_rr_iter *
_getdns_single_rr_iter_init(
_getdns_rr_iter *i, const uint8_t *wire, size_t wire_len)
{
assert(i);
if (!wire || wire_len < 5 /* name + type + class */) {
i->pos = NULL;
return NULL;
}
i->pkt = NULL;
i->pos = wire;
i->pkt_end = wire + wire_len;
i->n = 0;
return find_rrtype(i);
}
_getdns_rr_iter *
_getdns_rr_iter_rewind(_getdns_rr_iter *i)
{
@ -121,14 +141,14 @@ _getdns_rr_iter_next(_getdns_rr_iter *i)
return find_rrtype(i);
}
static uint8_t *
dname_if_or_as_decompressed(uint8_t *pkt, uint8_t *pkt_end, uint8_t *pos,
uint8_t *buf, size_t *len, size_t refs)
static const uint8_t *
dname_if_or_as_decompressed(const uint8_t *pkt, const uint8_t *pkt_end,
const uint8_t *pos, uint8_t *buf, size_t *len, size_t refs)
{
uint16_t offset;
uint8_t *start, *dst;
const uint8_t *start;
uint8_t *dst;
assert(pkt);
assert(pkt_end);
assert(pos);
assert(buf);
@ -138,7 +158,7 @@ dname_if_or_as_decompressed(uint8_t *pkt, uint8_t *pkt_end, uint8_t *pos,
goto error;
if ((*pos & 0xC0) == 0xC0) {
if (pos + 1 >= pkt_end)
if (!pkt || pos + 1 >= pkt_end)
goto error;
offset = gldns_read_uint16(pos) & 0x3FFF;
if (pkt + offset >= pkt_end)
@ -175,7 +195,7 @@ dname_if_or_as_decompressed(uint8_t *pkt, uint8_t *pkt_end, uint8_t *pos,
start = pos;
}
if ((*pos & 0xC0) == 0xC0) {
if (pos + 1 >= pkt_end)
if (!pkt || pos + 1 >= pkt_end)
goto error;
offset = gldns_read_uint16(pos) & 0x3FFF;
if (pkt + offset >= pkt_end)
@ -204,7 +224,7 @@ error:
return NULL;
}
uint8_t *
const uint8_t *
_getdns_owner_if_or_as_decompressed(_getdns_rr_iter *i,
uint8_t *ff_bytes, size_t *len)
{
@ -215,7 +235,7 @@ _getdns_owner_if_or_as_decompressed(_getdns_rr_iter *i,
static _getdns_rdf_iter *
rdf_iter_find_nxt(_getdns_rdf_iter *i)
{
uint8_t *pos;
const uint8_t *pos;
assert(i);
assert(i->pos);
@ -279,7 +299,7 @@ _getdns_rdf_iter_init(_getdns_rdf_iter *i, _getdns_rr_iter *rr)
i->end = NULL;
/* rr_iter already done or in question section */
if (!rr->pos || rr->n < GLDNS_QDCOUNT(rr->pkt))
if (!rr->pos || _getdns_rr_iter_section(rr) == GLDNS_SECTION_QUESTION)
goto done;
i->pkt = rr->pkt;
@ -334,7 +354,7 @@ _getdns_rdf_iter_init_at(
return i;
}
uint8_t *
const uint8_t *
_getdns_rdf_if_or_as_decompressed(
_getdns_rdf_iter *i, uint8_t *ff_bytes, size_t *len)
{

View File

@ -38,8 +38,8 @@
#include "gldns/gbuffer.h"
typedef struct _getdns_rr_iter {
uint8_t *pkt;
uint8_t *pkt_end;
const uint8_t *pkt;
const uint8_t *pkt_end;
/* Which RR are we currently at */
size_t n;
@ -47,32 +47,37 @@ typedef struct _getdns_rr_iter {
/* pos points to start of the owner name the RR.
* Or is NULL when there are no RR's left.
*/
uint8_t *pos;
const uint8_t *pos;
/* rr_type will point to the rr_type right after the RR's owner name.
* rr_type is guaranteed to have a value when pos has a value
*/
uint8_t *rr_type;
const uint8_t *rr_type;
/* nxt point to the owner name of the next RR or to pkt_end */
uint8_t *nxt;
const uint8_t *nxt;
} _getdns_rr_iter;
_getdns_rr_iter *_getdns_rr_iter_init(_getdns_rr_iter *i,
uint8_t *pkt, size_t pkt_len);
const uint8_t *pkt, const size_t pkt_len);
_getdns_rr_iter *_getdns_single_rr_iter_init(_getdns_rr_iter *i,
const uint8_t *wire, const size_t wire_len);
_getdns_rr_iter *_getdns_rr_iter_rewind(_getdns_rr_iter *i);
_getdns_rr_iter *_getdns_rr_iter_next(_getdns_rr_iter *i);
uint8_t *_getdns_owner_if_or_as_decompressed(
const uint8_t *_getdns_owner_if_or_as_decompressed(
_getdns_rr_iter *i, uint8_t *ff_bytes, size_t *len);
static inline gldns_pkt_section
_getdns_rr_iter_section(_getdns_rr_iter *i)
{
return i->n < GLDNS_QDCOUNT(i->pkt) ? GLDNS_SECTION_QUESTION
return !i->pkt ? (i->nxt - i->rr_type == 4 ? GLDNS_SECTION_QUESTION
: GLDNS_SECTION_ANSWER )
: i->n < GLDNS_QDCOUNT(i->pkt) ? GLDNS_SECTION_QUESTION
: i->n < GLDNS_QDCOUNT(i->pkt)
+ GLDNS_ANCOUNT(i->pkt) ? GLDNS_SECTION_ANSWER
: i->n < GLDNS_QDCOUNT(i->pkt)
@ -86,14 +91,14 @@ _getdns_rr_iter_section(_getdns_rr_iter *i)
}
typedef struct piv_getdns_rdf_iter {
uint8_t *pkt;
uint8_t *pkt_end;
const uint8_t *pkt;
const uint8_t *pkt_end;
const _getdns_rdata_def *rdd_pos;
const _getdns_rdata_def *rdd_end;
const _getdns_rdata_def *rdd_repeat;
uint8_t *pos;
uint8_t *end;
uint8_t *nxt;
const uint8_t *pos;
const uint8_t *end;
const uint8_t *nxt;
} _getdns_rdf_iter;
_getdns_rdf_iter *_getdns_rdf_iter_init(_getdns_rdf_iter *i,
@ -104,7 +109,7 @@ _getdns_rdf_iter *_getdns_rdf_iter_next(_getdns_rdf_iter *i);
_getdns_rdf_iter *_getdns_rdf_iter_init_at(_getdns_rdf_iter *i,
_getdns_rr_iter *rr, size_t pos);
uint8_t *_getdns_rdf_if_or_as_decompressed(
const uint8_t *_getdns_rdf_if_or_as_decompressed(
_getdns_rdf_iter *i, uint8_t *ff_bytes, size_t *len);
#endif

View File

@ -31,16 +31,18 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "config.h"
#include "debug.h"
#include <openssl/err.h>
#include <openssl/conf.h>
#include <openssl/x509v3.h>
#include "config.h"
#include <fcntl.h>
#include "stub.h"
#include "gldns/gbuffer.h"
#include "gldns/pkthdr.h"
#include "gldns/rrdef.h"
#include "gldns/str2wire.h"
#include "gldns/wire2str.h"
#include "rr-iter.h"
#include "context.h"
#include "util-internal.h"
@ -60,6 +62,8 @@ typedef u_short sa_family_t;
/* Don't currently have access to the context whilst doing handshake */
#define TIMEOUT_TLS 2500
/* Arbritray number of message for EDNS keepalive resend*/
#define EDNS_KEEPALIVE_RESEND 5
static time_t secret_rollover_time = 0;
static uint32_t secret = 0;
@ -81,7 +85,6 @@ static void netreq_upstream_read_cb(void *userarg);
static void netreq_upstream_write_cb(void *userarg);
static int fallback_on_write(getdns_network_req *netreq);
static void stub_tcp_write_cb(void *userarg);
static void stub_timeout_cb(void *userarg);
/*****************************/
/* General utility functions */
@ -151,6 +154,15 @@ attach_edns_client_subnet_private(getdns_network_req *req)
4, NULL);
}
static getdns_return_t
attach_edns_keepalive(getdns_network_req *req)
{
/* Client always sends length 0, omits the timeout */
return _getdns_network_req_add_upstream_option(req,
GLDNS_EDNS_KEEPALIVE,
0, NULL);
}
static getdns_return_t
attach_edns_cookie(getdns_network_req *req)
{
@ -189,12 +201,13 @@ attach_edns_cookie(getdns_network_req *req)
}
/* Will find a matching OPT RR, but leaves the caller to validate it*/
static int
match_and_process_server_cookie(
getdns_upstream *upstream, uint8_t *response, size_t response_len)
match_edns_opt_rr(uint16_t code, uint8_t *response, size_t response_len,
const uint8_t **position, uint16_t *option_len)
{
_getdns_rr_iter rr_iter_storage, *rr_iter;
uint8_t *pos;
const uint8_t *pos;
uint16_t rdata_len, opt_code = 0, opt_len = 0;
/* Search for the OPT RR (if any) */
@ -217,7 +230,17 @@ match_and_process_server_cookie(
pos = rr_iter->rr_type + 8;
/* OPT found, now search for the cookie option */
#if defined(STUB_DEBUG) && STUB_DEBUG
char str_spc[8192], *str = str_spc;
size_t str_len = sizeof(str_spc);
uint8_t *data = (uint8_t *)rr_iter->pos;
size_t data_len = rr_iter->nxt - rr_iter->pos;
(void) gldns_wire2str_rr_scan(
&data, &data_len, &str, &str_len, (uint8_t *)rr_iter->pkt, rr_iter->pkt_end - rr_iter->pkt);
DEBUG_STUB("OPT RR: %s", str_spc);
#endif
/* OPT found, now search for the specified option */
if (pos + 2 > rr_iter->nxt)
return 1; /* FORMERR */
@ -230,23 +253,39 @@ match_and_process_server_cookie(
opt_len = gldns_read_uint16(pos); pos += 2;
if (pos + opt_len > rr_iter->nxt)
return 1; /* FORMERR */
if (opt_code == EDNS_COOKIE_OPCODE)
if (opt_code == code)
break;
pos += opt_len; /* Skip unknown options */
}
if (pos >= rr_iter->nxt || opt_code != EDNS_COOKIE_OPCODE)
if (pos >= rr_iter->nxt || opt_code != code)
return 0; /* Everything OK, just no cookie found. */
*position = pos;
*option_len = opt_len;
return 2;
}
if (opt_len < 16 || opt_len > 40)
/* TODO: Test combinations of EDNS0 options*/
static int
match_and_process_server_cookie(
getdns_upstream *upstream, uint8_t *response, size_t response_len)
{
const uint8_t *position = NULL;
uint16_t option_len = 0;
int found = match_edns_opt_rr(EDNS_COOKIE_OPCODE, response,
response_len, &position, &option_len);
if (found != 2)
return found;
if (option_len < 16 || option_len > 40)
return 1; /* FORMERR */
if (!upstream->has_client_cookie)
return 1; /* Cookie reply, but we didn't sent one */
if (memcmp(upstream->client_cookie, pos, 8) != 0) {
if (memcmp(upstream->client_cookie, position, 8) != 0) {
if (!upstream->has_prev_client_cookie)
return 1; /* Cookie didn't match */
if (memcmp(upstream->prev_client_cookie, pos, 8) != 0)
if (memcmp(upstream->prev_client_cookie, position, 8) != 0)
return 1; /* Previous cookie didn't match either */
upstream->has_server_cookie = 0;
@ -254,85 +293,41 @@ match_and_process_server_cookie(
* is for our previous client cookie
*/
}
pos += 8;
opt_len -= 8;
position += 8;
option_len -= 8;
upstream->has_server_cookie = 1;
upstream->server_cookie_len = opt_len;
(void) memcpy(upstream->server_cookie, pos, opt_len);
upstream->server_cookie_len = option_len;
(void) memcpy(upstream->server_cookie, position, option_len);
return 0;
}
static int
create_starttls_request(getdns_dns_req *dnsreq, getdns_upstream *upstream,
getdns_eventloop *loop)
process_keepalive(
getdns_upstream *upstream, getdns_network_req *netreq,
uint8_t *response, size_t response_len)
{
getdns_return_t r = GETDNS_RETURN_GOOD;
getdns_dict* extensions = getdns_dict_create_with_context(dnsreq->context);
if (!extensions) {
return 0;
const uint8_t *position = NULL;
uint16_t option_len = 0;
int found = match_edns_opt_rr(GLDNS_EDNS_KEEPALIVE, response,
response_len, &position, &option_len);
if (found != 2) {
if (netreq->keepalive_sent == 1)
/* If no keepalive sent back, then we must use 0 idle timeout
as server does not support it.*/
upstream->keepalive_timeout = 0;
return found;
}
r = getdns_dict_set_int(extensions, "specify_class", GLDNS_RR_CLASS_CH);
if (r != GETDNS_RETURN_GOOD) {
getdns_dict_destroy(extensions);
return 0;
}
upstream->starttls_req = _getdns_dns_req_new(dnsreq->context, loop,
"STARTTLS", GETDNS_RRTYPE_TXT, extensions);
/*TODO[TLS]: TO BIT*/
if (upstream->starttls_req == NULL)
return 0;
getdns_dict_destroy(extensions);
upstream->starttls_req->netreqs[0]->upstream = upstream;
return 1;
}
static int
is_starttls_response(getdns_network_req *netreq)
{
_getdns_rr_iter rr_iter_storage, *rr_iter;
_getdns_rdf_iter rdf_iter_storage, *rdf_iter;
uint16_t rr_type;
gldns_pkt_section section;
uint8_t starttls_name_space[256], *starttls_name;
uint8_t owner_name_space[256], *owner_name;
size_t starttls_name_len = sizeof(starttls_name_space);
size_t owner_name_len = sizeof(owner_name_space);;
/* Servers that are not STARTTLS aware will refuse the CH query*/
if (GLDNS_RCODE_NOERROR != GLDNS_RCODE_WIRE(netreq->response))
return 0;
if (GLDNS_ANCOUNT(netreq->response) != 1)
return 0;
for ( rr_iter = _getdns_rr_iter_init(&rr_iter_storage
, netreq->response
, netreq->response_len)
; rr_iter
; rr_iter = _getdns_rr_iter_next(rr_iter)) {
section = _getdns_rr_iter_section(rr_iter);
rr_type = gldns_read_uint16(rr_iter->rr_type);
if (section != GLDNS_SECTION_ANSWER
|| rr_type != GETDNS_RRTYPE_TXT)
continue;
owner_name = _getdns_owner_if_or_as_decompressed(
rr_iter, owner_name_space, &owner_name_len);
if (!_getdns_dname_equal(netreq->owner->name, owner_name))
continue;
if (!(rdf_iter = _getdns_rdf_iter_init(
&rdf_iter_storage, rr_iter)))
continue;
if ((starttls_name = _getdns_rdf_if_or_as_decompressed(
rdf_iter, starttls_name_space, &starttls_name_len)) &&
_getdns_dname_equal(starttls_name, owner_name))
return 1;
return 0;
if (option_len != 2)
return 1; /* FORMERR */
/* Use server sent value unless the client specified a shorter one.
Convert to ms first (wire value has units of 100ms) */
uint64_t server_keepalive = ((uint64_t)gldns_read_uint16(position))*100;
if (netreq->owner->context->idle_timeout < server_keepalive)
upstream->keepalive_timeout = netreq->owner->context->idle_timeout;
else {
upstream->keepalive_timeout = server_keepalive;
DEBUG_STUB("*** %s: SERVER KEEPALIVE USED : %d ms\n",
__FUNCTION__, (int)server_keepalive);
}
return 0;
}
@ -367,9 +362,24 @@ tcp_connect(getdns_upstream *upstream, getdns_transport_list_t transport)
getdns_sock_nonblock(fd);
#ifdef USE_TCP_FASTOPEN
/* Leave the connect to the later call to sendto() if using TCP*/
if (transport == GETDNS_TRANSPORT_TCP ||
transport == GETDNS_TRANSPORT_STARTTLS)
if (transport == GETDNS_TRANSPORT_TCP)
return fd;
#elif USE_OSX_TCP_FASTOPEN
sa_endpoints_t endpoints;
endpoints.sae_srcif = 0;
endpoints.sae_srcaddr = NULL;
endpoints.sae_srcaddrlen = 0;
endpoints.sae_dstaddr = (struct sockaddr *)&upstream->addr;
endpoints.sae_dstaddrlen = upstream->addr_len;
if (connectx(fd, &endpoints, SAE_ASSOCID_ANY,
CONNECT_DATA_IDEMPOTENT | CONNECT_RESUME_ON_READ_WRITE,
NULL, 0, NULL, NULL) == -1) {
if (errno != EINPROGRESS) {
close(fd);
return -1;
}
}
return fd;
#endif
if (connect(fd, (struct sockaddr *)&upstream->addr,
upstream->addr_len) == -1) {
@ -456,7 +466,7 @@ stub_cleanup(getdns_network_req *netreq)
netreq->write_queue_tail = NULL;
break;
}
upstream_reschedule_events(upstream, netreq->owner->context->idle_timeout);
upstream_reschedule_events(upstream, upstream->keepalive_timeout);
}
static int
@ -512,33 +522,23 @@ _getdns_cancel_stub_request(getdns_network_req *netreq)
if (netreq->fd >= 0) close(netreq->fd);
}
static void
/* May be needed in future for better UDP error handling?*/
/*static void
stub_erred(getdns_network_req *netreq)
{
DEBUG_STUB("*** %s\n", __FUNCTION__);
stub_next_upstream(netreq);
stub_cleanup(netreq);
/* TODO[TLS]: When we get an error (which is probably a timeout) and are
* using to keep connections open should we leave the connection up here? */
if (netreq->fd >= 0) close(netreq->fd);
netreq->state = NET_REQ_FINISHED;
_getdns_check_dns_req_complete(netreq->owner);
}
}*/
static void
stub_timeout_cb(void *userarg)
{
DEBUG_STUB("*** %s(%p)\n", __FUNCTION__, userarg);
getdns_network_req *netreq = (getdns_network_req *)userarg;
/* For now, mark a STARTTLS timeout as a failured negotiation and allow
* fallback but don't close the connection. */
if (netreq->owner == netreq->upstream->starttls_req) {
netreq->upstream->tls_hs_state = GETDNS_HS_FAILED;
stub_next_upstream(netreq);
stub_cleanup(netreq);
return;
}
stub_next_upstream(netreq);
stub_cleanup(netreq);
@ -740,8 +740,16 @@ stub_tcp_write(int fd, getdns_tcp_state *tcp, getdns_network_req *netreq)
if (netreq->owner->edns_client_subnet_private)
if (attach_edns_client_subnet_private(netreq))
return STUB_OUT_OF_OPTIONS;
if (netreq->upstream->writes_done == 0 &&
netreq->owner->context->idle_timeout != 0) {
/* Add the keepalive option to the first query on this connection*/
DEBUG_STUB("# %s: Requesting keepalive\n", __FUNCTION__);
if (attach_edns_keepalive(netreq))
return STUB_OUT_OF_OPTIONS;
netreq->keepalive_sent = 1;
}
}
pkt_len = netreq->response - netreq->query;
pkt_len = _getdns_network_req_add_tsig(netreq);
/* We have an initialized packet buffer.
* Lets see how much of it we can write
*/
@ -825,27 +833,22 @@ static int
tls_requested(getdns_network_req *netreq)
{
return (netreq->transports[netreq->transport_current] ==
GETDNS_TRANSPORT_TLS ||
netreq->transports[netreq->transport_current] ==
GETDNS_TRANSPORT_STARTTLS) ?
GETDNS_TRANSPORT_TLS) ?
1 : 0;
}
static int
tls_should_write(getdns_upstream *upstream)
{
/* Should messages be written on TLS upstream. Remember that for STARTTLS
* the first message should got over TCP as the handshake isn't started yet.*/
return ((upstream->transport == GETDNS_TRANSPORT_TLS ||
upstream->transport == GETDNS_TRANSPORT_STARTTLS) &&
/* Should messages be written on TLS upstream. */
return ((upstream->transport == GETDNS_TRANSPORT_TLS) &&
upstream->tls_hs_state != GETDNS_HS_NONE) ? 1 : 0;
}
static int
tls_should_read(getdns_upstream *upstream)
{
return ((upstream->transport == GETDNS_TRANSPORT_TLS ||
upstream->transport == GETDNS_TRANSPORT_STARTTLS) &&
return ((upstream->transport == GETDNS_TRANSPORT_TLS) &&
!(upstream->tls_hs_state == GETDNS_HS_FAILED ||
upstream->tls_hs_state == GETDNS_HS_NONE)) ? 1 : 0;
}
@ -854,8 +857,7 @@ static int
tls_failed(getdns_upstream *upstream)
{
/* No messages should be scheduled onto an upstream in this state */
return ((upstream->transport == GETDNS_TRANSPORT_TLS ||
upstream->transport == GETDNS_TRANSPORT_STARTTLS) &&
return ((upstream->transport == GETDNS_TRANSPORT_TLS) &&
upstream->tls_hs_state == GETDNS_HS_FAILED) ? 1 : 0;
}
@ -1201,6 +1203,7 @@ stub_tls_write(getdns_upstream *upstream, getdns_tcp_state *tcp,
&netreq->upstream->netreq_by_query_id, &netreq->node));
GLDNS_ID_SET(netreq->query, query_id);
/* TODO: Review if more EDNS0 handling can be centralised.*/
if (netreq->opt) {
_getdns_network_req_clear_upstream_options(netreq);
/* no limits on the max udp payload size with tcp */
@ -1211,6 +1214,15 @@ stub_tls_write(getdns_upstream *upstream, getdns_tcp_state *tcp,
if (netreq->owner->edns_client_subnet_private)
if (attach_edns_client_subnet_private(netreq))
return STUB_OUT_OF_OPTIONS;
if (netreq->upstream->writes_done % EDNS_KEEPALIVE_RESEND == 0 &&
netreq->owner->context->idle_timeout != 0) {
/* Add the keepalive option to every nth query on this
connection */
DEBUG_STUB("# %s: Requesting keepalive\n", __FUNCTION__);
if (attach_edns_keepalive(netreq))
return STUB_OUT_OF_OPTIONS;
netreq->keepalive_sent = 1;
}
if (netreq->owner->tls_query_padding_blocksize > 1) {
pkt_len = netreq->response - netreq->query;
pkt_len += 4; /* this accounts for the OPTION-CODE and OPTION-LENGTH of the padding */
@ -1224,7 +1236,7 @@ stub_tls_write(getdns_upstream *upstream, getdns_tcp_state *tcp,
}
}
pkt_len = netreq->response - netreq->query;
pkt_len = _getdns_network_req_add_tsig(netreq);
/* We have an initialized packet buffer.
* Lets see how much of it we can write */
@ -1293,17 +1305,19 @@ stub_udp_read_cb(void *userarg)
return; /* Client cookie didn't match? */
close(netreq->fd);
if (GLDNS_TC_WIRE(netreq->response)) {
while (GLDNS_TC_WIRE(netreq->response)) {
DEBUG_STUB("TC bit set\n");
if (!(netreq->transport_current < netreq->transport_count))
goto done;
break;
getdns_transport_list_t next_transport =
netreq->transports[++netreq->transport_current];
if (next_transport != GETDNS_TRANSPORT_TCP)
goto done;
if (next_transport != GETDNS_TRANSPORT_TCP &&
next_transport != GETDNS_TRANSPORT_TLS)
break;
/* For now, special case where fallback should be on the same upstream*/
if ((netreq->fd = upstream_connect(upstream, next_transport,
dnsreq)) == -1)
goto done;
break;
upstream_schedule_netreq(netreq->upstream, netreq);
GETDNS_SCHEDULE_EVENT(
dnsreq->loop, netreq->upstream->fd, dnsreq->context->timeout,
@ -1315,7 +1329,6 @@ stub_udp_read_cb(void *userarg)
}
netreq->response_len = read;
dnsreq->upstreams->current = 0;
done:
netreq->debug_end_time = _getdns_get_time_as_uintt64();
netreq->state = NET_REQ_FINISHED;
_getdns_check_dns_req_complete(dnsreq);
@ -1349,7 +1362,7 @@ stub_udp_write_cb(void *userarg)
if (attach_edns_client_subnet_private(netreq))
return; /* too many upstream options */
}
pkt_len = netreq->response - netreq->query;
pkt_len = _getdns_network_req_add_tsig(netreq);
if ((ssize_t)pkt_len != sendto(netreq->fd, netreq->query, pkt_len, 0,
(struct sockaddr *)&netreq->upstream->addr,
netreq->upstream->addr_len)) {
@ -1362,76 +1375,6 @@ stub_udp_write_cb(void *userarg)
stub_udp_read_cb, NULL, stub_timeout_cb));
}
/**************************/
/* TCP callback functions*/
/**************************/
static void
stub_tcp_read_cb(void *userarg)
{
getdns_network_req *netreq = (getdns_network_req *)userarg;
getdns_dns_req *dnsreq = netreq->owner;
int q;
switch ((q = stub_tcp_read(netreq->fd, &netreq->tcp,
&dnsreq->context->mf, &netreq->event))) {
case STUB_TCP_AGAIN:
return;
case STUB_TCP_ERROR:
stub_erred(netreq);
return;
default:
GETDNS_CLEAR_EVENT(dnsreq->loop, &netreq->event);
if (q != netreq->query_id)
return;
if (netreq->owner->edns_cookies &&
match_and_process_server_cookie(
netreq->upstream, netreq->tcp.read_buf,
netreq->tcp.read_pos - netreq->tcp.read_buf))
return; /* Client cookie didn't match? */
netreq->state = NET_REQ_FINISHED;
netreq->response = netreq->tcp.read_buf;
netreq->response_len =
netreq->tcp.read_pos - netreq->tcp.read_buf;
netreq->tcp.read_buf = NULL;
dnsreq->upstreams->current = 0;
netreq->debug_end_time = _getdns_get_time_as_uintt64();
stub_cleanup(netreq);
close(netreq->fd);
_getdns_check_dns_req_complete(dnsreq);
}
}
static void
stub_tcp_write_cb(void *userarg)
{
getdns_network_req *netreq = (getdns_network_req *)userarg;
getdns_dns_req *dnsreq = netreq->owner;
int q;
netreq->debug_start_time = _getdns_get_time_as_uintt64();
switch ((q = stub_tcp_write(netreq->fd, &netreq->tcp, netreq))) {
case STUB_TCP_AGAIN:
return;
case STUB_TCP_ERROR:
stub_erred(netreq);
return;
default:
netreq->debug_udp = 0;
netreq->query_id = (uint16_t) q;
GETDNS_CLEAR_EVENT(dnsreq->loop, &netreq->event);
GETDNS_SCHEDULE_EVENT(
dnsreq->loop, netreq->fd, dnsreq->context->timeout,
getdns_eventloop_event_init(&netreq->event, netreq,
stub_tcp_read_cb, NULL, stub_timeout_cb));
return;
}
}
/**************************/
/* Upstream callback functions*/
/**************************/
@ -1442,7 +1385,6 @@ upstream_read_cb(void *userarg)
DEBUG_STUB("--- READ: %s\n", __FUNCTION__);
getdns_upstream *upstream = (getdns_upstream *)userarg;
getdns_network_req *netreq;
getdns_dns_req *dnsreq;
int q;
uint16_t query_id;
intptr_t query_id_intptr;
@ -1485,26 +1427,19 @@ upstream_read_cb(void *userarg)
/* TODO[TLS]: I don't think we should do this for TCP. We should stay
* on a working connection until we hit a problem.*/
upstream->upstreams->current = 0;
/* !THIS CODE NEEDS TESTING!*/
if (netreq->owner->edns_cookies &&
match_and_process_server_cookie(
netreq->upstream, netreq->tcp.read_buf,
netreq->tcp.read_pos - netreq->tcp.read_buf))
return; /* Client cookie didn't match? */
if (netreq->owner == upstream->starttls_req) {
dnsreq = netreq->owner;
if (is_starttls_response(netreq)) {
upstream->tls_obj = tls_create_object(dnsreq,
upstream->fd,
upstream);
if (upstream->tls_obj == NULL)
upstream->tls_hs_state = GETDNS_HS_FAILED;
upstream->tls_hs_state = GETDNS_HS_WRITE;
} else
upstream->tls_hs_state = GETDNS_HS_FAILED;
if ((netreq->owner->context->idle_timeout != 0) &&
process_keepalive(netreq->upstream, netreq, netreq->response,
netreq->response_len))
return;
/* Now reschedule the writes on this connection */
GETDNS_CLEAR_EVENT(upstream->loop, &upstream->event);
GETDNS_SCHEDULE_EVENT(upstream->loop, upstream->fd,
netreq->owner->context->timeout,
getdns_eventloop_event_init(&upstream->event, upstream,
NULL, upstream_write_cb, NULL));
}
netreq->debug_end_time = _getdns_get_time_as_uintt64();
/* This also reschedules events for the upstream*/
stub_cleanup(netreq);
@ -1513,8 +1448,7 @@ upstream_read_cb(void *userarg)
if (netreq->event.read_cb)
upstream_reschedule_netreq_events(upstream, netreq);
if (netreq->owner != upstream->starttls_req)
_getdns_check_dns_req_complete(netreq->owner);
_getdns_check_dns_req_complete(netreq->owner);
}
}
@ -1594,20 +1528,6 @@ upstream_write_cb(void *userarg)
GETDNS_SCHEDULE_EVENT(upstream->loop,
upstream->fd, TIMEOUT_FOREVER, &upstream->event);
}
if (upstream->starttls_req && netreq->owner == upstream->starttls_req) {
/* Now deschedule any further writes on this connection until we get
* the STARTTLS answer*/
GETDNS_CLEAR_EVENT(upstream->loop, &upstream->event);
upstream->event.write_cb = NULL;
GETDNS_SCHEDULE_EVENT(upstream->loop,
upstream->fd, TIMEOUT_FOREVER, &upstream->event);
} else if (upstream->starttls_req) {
/* Delay the cleanup of the STARTTLS req until the write of the next
* req in the queue since for sync req, the event on a request is
* used for the callback that writes the next req. */
_getdns_dns_req_free(upstream->starttls_req);
upstream->starttls_req = NULL;
}
/* With synchonous lookups, schedule the read locally too */
if (netreq->event.write_cb) {
GETDNS_CLEAR_EVENT(dnsreq->loop, &netreq->event);
@ -1615,7 +1535,7 @@ upstream_write_cb(void *userarg)
dnsreq->loop, upstream->fd, dnsreq->context->timeout,
getdns_eventloop_event_init(&netreq->event, netreq,
netreq_upstream_read_cb,
(upstream->write_queue && !upstream->starttls_req ?
(upstream->write_queue ?
netreq_upstream_write_cb : NULL),
stub_timeout_cb));
}
@ -1651,12 +1571,6 @@ upstream_transport_valid(getdns_upstream *upstream,
upstream->tcp.write_error != 0) {
return 0;
}
/* Allow TCP messages to be sent on a STARTTLS upstream that hasn't
* upgraded to avoid opening a new connection if one is aleady open. */
if (transport == GETDNS_TRANSPORT_TCP &&
upstream->transport == GETDNS_TRANSPORT_STARTTLS &&
upstream->tls_hs_state == GETDNS_HS_FAILED)
return 1;
/* Otherwise, transport must match, and not have failed */
if (upstream->transport != transport)
return 0;
@ -1752,28 +1666,6 @@ upstream_connect(getdns_upstream *upstream, getdns_transport_list_t transport,
upstream->loop = dnsreq->context->extension;
upstream->fd = fd;
break;
case GETDNS_TRANSPORT_STARTTLS:
/* Use existing if available. Let the fallback code handle it if
* STARTTLS isn't availble. */
if (upstream->fd != -1)
return upstream->fd;
fd = tcp_connect(upstream, transport);
if (fd == -1) return -1;
if (!create_starttls_request(dnsreq, upstream, dnsreq->loop))
return GETDNS_RETURN_GENERIC_ERROR;
getdns_network_req *starttls_netreq = upstream->starttls_req->netreqs[0];
upstream->loop = dnsreq->context->extension;
upstream->fd = fd;
upstream_schedule_netreq(upstream, starttls_netreq);
/* Schedule at least the timeout locally, but use less than half the
* context value so by default this timeouts before the TIMEOUT_TLS.
* And also the write if we perform a synchronous lookup */
GETDNS_SCHEDULE_EVENT(
dnsreq->loop, upstream->fd, dnsreq->context->timeout / 3,
getdns_eventloop_event_init(&starttls_netreq->event,
starttls_netreq, NULL, (dnsreq->loop != upstream->loop
? netreq_upstream_write_cb : NULL), stub_timeout_cb));
break;
default:
return -1;
/* Nothing to do*/
@ -1810,6 +1702,7 @@ find_upstream_for_netreq(getdns_network_req *netreq)
continue;
netreq->transport_current = i;
netreq->upstream = upstream;
netreq->keepalive_sent = 0;
return fd;
}
return -1;
@ -1921,9 +1814,7 @@ upstream_schedule_netreq(getdns_upstream *upstream, getdns_network_req *netreq)
GETDNS_CLEAR_EVENT(upstream->loop, &upstream->event);
upstream->event.timeout_cb = NULL;
upstream->event.write_cb = upstream_write_cb;
if (upstream->tls_hs_state == GETDNS_HS_WRITE ||
(upstream->starttls_req &&
upstream->starttls_req->netreqs[0] == netreq)) {
if (upstream->tls_hs_state == GETDNS_HS_WRITE) {
/* Set a timeout on the upstream so we can catch failed setup*/
/* TODO[TLS]: When generic fallback supported, we should decide how
* to split the timeout between transports. */
@ -1963,11 +1854,9 @@ _getdns_submit_stub_request(getdns_network_req *netreq)
GETDNS_SCHEDULE_EVENT(
dnsreq->loop, netreq->fd, dnsreq->context->timeout,
getdns_eventloop_event_init(&netreq->event, netreq,
NULL, (transport == GETDNS_TRANSPORT_UDP ?
stub_udp_write_cb: stub_tcp_write_cb), stub_timeout_cb));
NULL, stub_udp_write_cb, stub_timeout_cb));
return GETDNS_RETURN_GOOD;
case GETDNS_TRANSPORT_STARTTLS:
case GETDNS_TRANSPORT_TLS:
case GETDNS_TRANSPORT_TCP:
upstream_schedule_netreq(netreq->upstream, netreq);

View File

@ -58,7 +58,7 @@ CHECK_EVENT_PROG=@CHECK_EVENT_PROG@
CHECK_EV_PROG=@CHECK_EV_PROG@
CC=@CC@
CFLAGS=-I$(srcdir)/.. -I$(srcdir) -I.. $(cflags) @CFLAGS@
CFLAGS=-I$(srcdir)/.. -I$(srcdir) -I.. $(cflags) @CFLAGS@ @CPPFLAGS@
LDFLAGS=-L.. @LDFLAGS@
LDLIBS=../libgetdns.la @LIBS@
CHECK_LIBS=@CHECK_LIBS@
@ -73,11 +73,11 @@ CHECK_OBJS=check_getdns_common.lo check_getdns_context_set_timeout.lo \
ALL_OBJS=$(CHECK_OBJS) check_getdns_libevent.lo check_getdns_libev.lo \
check_getdns_selectloop.lo getdns_query.lo scratchpad.lo \
testmessages.lo tests_dict.lo tests_list.lo tests_namespaces.lo \
tests_stub_async.lo tests_stub_sync.lo tests_json-pointers.lo
tests_stub_async.lo tests_stub_sync.lo
NON_C99_OBJS=check_getdns_libuv.lo
PROGRAMS=tests_dict tests_list tests_namespaces tests_stub_async tests_stub_sync tests_json-pointers getdns_query $(CHECK_GETDNS) $(CHECK_EV_PROG) $(CHECK_EVENT_PROG) $(CHECK_UV_PROG)
PROGRAMS=tests_dict tests_list tests_namespaces tests_stub_async tests_stub_sync getdns_query $(CHECK_GETDNS) $(CHECK_EV_PROG) $(CHECK_EVENT_PROG) $(CHECK_UV_PROG)
.SUFFIXES: .c .o .a .lo .h
@ -113,9 +113,6 @@ tests_stub_async: tests_stub_async.lo testmessages.lo
tests_stub_sync: tests_stub_sync.lo
$(LIBTOOL) --tag=CC --mode=link $(CC) $(CFLAGS) $(LDFLAGS) $(LDLIBS) -o $@ tests_stub_sync.lo
tests_json-pointers: tests_json-pointers.lo
$(LIBTOOL) --tag=CC --mode=link $(CC) $(CFLAGS) $(LDFLAGS) $(LDLIBS) -o $@ tests_json-pointers.lo
check_getdns_common: check_getdns_common.lo
$(LIBTOOL) --tag=CC --mode=link $(CC) $(CFLAGS) $(LDFLAGS) $(LDLIBS) -o $@ check_getdns_common.lo
@ -216,13 +213,15 @@ configure.status: configure
depend:
(cd $(srcdir) ; awk 'BEGIN{P=1}{if(P)print}/^# Dependencies/{P=0}' Makefile.in > Makefile.in.new )
(cd $(srcdir) ; gcc -MM -I. -I.. *.c | \
sed -e 's? \([a-z_-]*\)\.\([ch]\)? $$(srcdir)/\1.\2?g' \
(blddir=`pwd`; cd $(srcdir) ; gcc -MM -I. -I.. -I"$$blddir"/.. *.c | \
sed -e "s? $$blddir/? ?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' \
-e 's? \.\./getdns/getdns_ext_libevent\.h? $$(srcdir)/../getdns/getdns_ext_libevent.h?g' \
-e 's? \.\./getdns/getdns_ext_libev\.h? $$(srcdir)/../getdns/getdns_ext_libev.h?g' \
-e 's? \.\./getdns/getdns_ext_libuv\.h? $$(srcdir)/../getdns/getdns_ext_libuv.h?g' \
-e 's? \.\./debug\.h? $$(srcdir)/../debug.h?g' \
-e 's!\(.*\)\.o[ :]*!\1.lo \1.o: !g' >> Makefile.in.new )
(cd $(srcdir) ; diff Makefile.in.new Makefile.in && rm Makefile.in.new \
|| mv Makefile.in.new Makefile.in )
@ -275,14 +274,12 @@ check_getdns_selectloop.lo check_getdns_selectloop.o: $(srcdir)/check_getdns_sel
check_getdns_transport.lo check_getdns_transport.o: $(srcdir)/check_getdns_transport.c \
$(srcdir)/check_getdns_transport.h $(srcdir)/check_getdns_common.h ../getdns/getdns.h \
../getdns/getdns_extra.h
getdns_query.lo getdns_query.o: $(srcdir)/getdns_query.c ../config.h ../getdns/getdns.h \
../getdns/getdns_extra.h
getdns_query.lo getdns_query.o: $(srcdir)/getdns_query.c ../config.h $(srcdir)/../debug.h ../config.h \
../getdns/getdns.h ../getdns/getdns_extra.h
scratchpad.template.lo scratchpad.template.o: scratchpad.template.c ../getdns/getdns.h \
../getdns/getdns_extra.h
testmessages.lo testmessages.o: $(srcdir)/testmessages.c $(srcdir)/testmessages.h
tests_dict.lo tests_dict.o: $(srcdir)/tests_dict.c $(srcdir)/testmessages.h ../getdns/getdns.h
tests_json-pointers.lo tests_json-pointers.o: $(srcdir)/tests_json-pointers.c ../getdns/getdns.h \
../getdns/getdns_extra.h
tests_list.lo tests_list.o: $(srcdir)/tests_list.c $(srcdir)/testmessages.h ../getdns/getdns.h
tests_namespaces.lo tests_namespaces.o: $(srcdir)/tests_namespaces.c $(srcdir)/testmessages.h ../getdns/getdns.h
tests_stub_async.lo tests_stub_async.o: $(srcdir)/tests_stub_async.c ../config.h $(srcdir)/testmessages.h \

View File

@ -96,14 +96,14 @@ START_TEST (getdns_context_set_idle_timeout_2)
{
/*
* timeout is 0
* expect: GETDNS_RETURN_INVALID_PARAMETER
* expect: GETDNS_RETURN_GOOD
*/
struct getdns_context *context = NULL;
CONTEXT_CREATE(TRUE);
ASSERT_RC(getdns_context_set_idle_timeout(context, 0),
GETDNS_RETURN_INVALID_PARAMETER, "Return code from getdns_context_set_timeout()");
GETDNS_RETURN_GOOD, "Return code from getdns_context_set_timeout()");
CONTEXT_DESTROY;

View File

@ -331,6 +331,10 @@
}
END_TEST
/* This test disabled because travis does not support IPv6 in their
* container based infrastructure!
*/
#if 0
START_TEST (getdns_context_set_upstream_recursive_servers_10)
{
/*
@ -345,7 +349,7 @@
struct getdns_dict *dict = NULL;
struct getdns_dict *response = NULL;
struct getdns_bindata address_type = { 5, (void *)"IPv6" };
struct getdns_bindata address_data = { 16, (void *)"\x20\x01\x48\x60\x48\x60\x00\x00\x00\x00\x00\x00\x00\x00\x88\x44" };
struct getdns_bindata address_data = { 16, (void *)"\x26\x20\x00\x74\x00\x1b\x00\x00\x00\x00\x00\x00\x00\x01\x00\x01" };
size_t index = 0;
CONTEXT_CREATE(TRUE);
@ -379,7 +383,7 @@
DICT_DESTROY(response);
}
END_TEST
#endif
START_TEST (getdns_context_set_upstream_recursive_servers_11)
{
/*
@ -460,7 +464,7 @@
/* Positive test cases */
TCase *tc_pos = tcase_create("Positive");
tcase_add_test(tc_pos, getdns_context_set_upstream_recursive_servers_9);
tcase_add_test(tc_pos, getdns_context_set_upstream_recursive_servers_10);
/***** tcase_add_test(tc_pos, getdns_context_set_upstream_recursive_servers_10); *****/
tcase_add_test(tc_pos, getdns_context_set_upstream_recursive_servers_11);
suite_add_tcase(s, tc_pos);

View File

@ -26,13 +26,13 @@
*/
#include "config.h"
#include "debug.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <inttypes.h>
#include <getdns/getdns.h>
#include <getdns/getdns_extra.h>
#include "util-internal.h"
#define MAX_TIMEOUTS FD_SETSIZE
@ -267,6 +267,66 @@ static enum { GENERAL, ADDRESS, HOSTNAME, SERVICE } calltype = GENERAL;
int get_rrtype(const char *t);
int gqldns_b64_pton(char const *src, uint8_t *target, size_t targsize)
{
const uint8_t pad64 = 64; /* is 64th in the b64 array */
const char* s = src;
uint8_t in[4];
size_t o = 0, incount = 0;
while(*s) {
/* skip any character that is not base64 */
/* conceptually we do:
const char* b64 = pad'=' is appended to array
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
const char* d = strchr(b64, *s++);
and use d-b64;
*/
char d = *s++;
if(d <= 'Z' && d >= 'A')
d -= 'A';
else if(d <= 'z' && d >= 'a')
d = d - 'a' + 26;
else if(d <= '9' && d >= '0')
d = d - '0' + 52;
else if(d == '+')
d = 62;
else if(d == '/')
d = 63;
else if(d == '=')
d = 64;
else continue;
in[incount++] = (uint8_t)d;
if(incount != 4)
continue;
/* process whole block of 4 characters into 3 output bytes */
if(in[3] == pad64 && in[2] == pad64) { /* A B = = */
if(o+1 > targsize)
return -1;
target[o] = (in[0]<<2) | ((in[1]&0x30)>>4);
o += 1;
break; /* we are done */
} else if(in[3] == pad64) { /* A B C = */
if(o+2 > targsize)
return -1;
target[o] = (in[0]<<2) | ((in[1]&0x30)>>4);
target[o+1]= ((in[1]&0x0f)<<4) | ((in[2]&0x3c)>>2);
o += 2;
break; /* we are done */
} else {
if(o+3 > targsize)
return -1;
/* write xxxxxxyy yyyyzzzz zzwwwwww */
target[o] = (in[0]<<2) | ((in[1]&0x30)>>4);
target[o+1]= ((in[1]&0x0f)<<4) | ((in[2]&0x3c)>>2);
target[o+2]= ((in[2]&0x03)<<6) | in[3];
o += 3;
}
incount = 0;
}
return (int)o;
}
getdns_dict *
ipaddr_dict(getdns_context *context, char *ipstr)
{
@ -275,6 +335,13 @@ ipaddr_dict(getdns_context *context, char *ipstr)
char *p = strchr(ipstr, '@'), *portstr = "";
char *t = strchr(ipstr, '#'), *tls_portstr = "";
char *n = strchr(ipstr, '~'), *tls_namestr = "";
/* ^[alg:]name:key */
char *T = strchr(ipstr, '^'), *tsig_name_str = ""
, *tsig_secret_str = ""
, *tsig_algorithm_str = "";
int tsig_secret_size;
uint8_t tsig_secret_buf[256]; /* 4 times SHA512 */
getdns_bindata tsig_secret;
uint8_t buf[sizeof(struct in6_addr)];
getdns_bindata addr;
@ -297,6 +364,22 @@ ipaddr_dict(getdns_context *context, char *ipstr)
*n = 0;
tls_namestr = n + 1;
}
if (T) {
*T = 0;
tsig_name_str = T + 1;
if ((T = strchr(tsig_name_str, ':'))) {
*T = 0;
tsig_secret_str = T + 1;
if ((T = strchr(tsig_secret_str, ':'))) {
*T = 0;
tsig_algorithm_str = tsig_name_str;
tsig_name_str = tsig_secret_str;
tsig_secret_str = T + 1;
}
} else {
tsig_name_str = "";
}
}
if (strchr(ipstr, ':')) {
getdns_dict_util_set_string(r, "address_type", "IPv6");
addr.size = 16;
@ -322,7 +405,19 @@ ipaddr_dict(getdns_context *context, char *ipstr)
}
if (*scope_id_str)
getdns_dict_util_set_string(r, "scope_id", scope_id_str);
if (*tsig_name_str)
getdns_dict_util_set_string(r, "tsig_name", tsig_name_str);
if (*tsig_algorithm_str)
getdns_dict_util_set_string(r, "tsig_algorithm", tsig_name_str);
if (*tsig_secret_str) {
tsig_secret_size = gqldns_b64_pton(
tsig_secret_str, tsig_secret_buf, sizeof(tsig_secret_buf));
if (tsig_secret_size > 0) {
tsig_secret.size = tsig_secret_size;
tsig_secret.data = tsig_secret_buf;
getdns_dict_set_bindata(r, "tsig_secret", &tsig_secret);
}
}
return r;
}
@ -345,9 +440,6 @@ fill_transport_list(getdns_context *context, char *transport_list_str,
case 'L':
transports[i] = GETDNS_TRANSPORT_TLS;
break;
case 'S':
transports[i] = GETDNS_TRANSPORT_STARTTLS;
break;
default:
fprintf(stderr, "Unrecognised transport '%c' in string %s\n",
*(transport_list_str + i), transport_list_str);
@ -360,7 +452,7 @@ fill_transport_list(getdns_context *context, char *transport_list_str,
void
print_usage(FILE *out, const char *progname)
{
fprintf(out, "usage: %s [@<server>] [+extension] [<name>] [<type>]\n",
fprintf(out, "usage: %s [@<server>][~<server_hostname>] [+extension] [<name>] [<type>]\n",
progname);
fprintf(out, "options:\n");
fprintf(out, "\t-a\tPerform asynchronous resolution "
@ -373,6 +465,7 @@ print_usage(FILE *out, const char *progname)
fprintf(out, "\t-d\tclear edns0 do bit\n");
fprintf(out, "\t-e <idle_timeout>\tSet idle timeout in miliseconds\n");
fprintf(out, "\t-F <filename>\tread the queries from the specified file\n");
fprintf(out, "\t-f <filename>\tRead DNSSEC trust anchors from <filename>\n");
fprintf(out, "\t-G\tgeneral lookup\n");
fprintf(out, "\t-H\thostname lookup. (<name> must be an IP address; <type> is ignored)\n");
fprintf(out, "\t-h\tPrint this help\n");
@ -386,6 +479,7 @@ print_usage(FILE *out, const char *progname)
fprintf(out, "\t-p\tPretty print response dict\n");
fprintf(out, "\t-P <blocksize>\tPad TLS queries to a multiple of blocksize\n");
fprintf(out, "\t-r\tSet recursing resolution type\n");
fprintf(out, "\t-R <filename>\tRead root hints from <filename>\n");
fprintf(out, "\t-q\tQuiet mode - don't print response\n");
fprintf(out, "\t-s\tSet stub resolution type (default = recursing)\n");
fprintf(out, "\t-S\tservice lookup (<type> is ignored)\n");
@ -394,11 +488,10 @@ print_usage(FILE *out, const char *progname)
fprintf(out, "\t-O\tSet transport to TCP only keep connections open\n");
fprintf(out, "\t-L\tSet transport to TLS only keep connections open\n");
fprintf(out, "\t-E\tSet transport to TLS with TCP fallback only keep connections open\n");
fprintf(out, "\t-R\tSet transport to STARTTLS with TCP fallback only keep connections open\n");
fprintf(out, "\t-u\tSet transport to UDP with TCP fallback\n");
fprintf(out, "\t-U\tSet transport to UDP only\n");
fprintf(out, "\t-l <transports>\tSet transport list. List can contain 1 of each of the characters\n");
fprintf(out, "\t\t\t U T L S for UDP, TCP, TLS or STARTTLS e.g 'UT' or 'LST' \n");
fprintf(out, "\t\t\t U T L S for UDP, TCP or TLS e.g 'UT' or 'LTU' \n");
}
@ -416,7 +509,8 @@ static getdns_return_t validate_chain(getdns_dict *response)
if (!(to_validate = getdns_list_create()))
return GETDNS_RETURN_MEMORY_ERROR;
trust_anchor = getdns_root_trust_anchor(NULL);
if (getdns_context_get_dnssec_trust_anchors(context, &trust_anchor))
trust_anchor = getdns_root_trust_anchor(NULL);
if ((r = getdns_dict_get_list(
response, "validation_chain", &validation_chain)))
@ -586,8 +680,9 @@ getdns_return_t parse_args(int argc, char **argv)
char *arg, *c, *endptr;
int t, print_api_info = 0, print_trust_anchors = 0;
getdns_list *upstream_list = NULL;
getdns_list *tas = NULL;
getdns_list *tas = NULL, *hints = NULL;
size_t upstream_count = 0;
FILE *fh;
for (i = 1; i < argc; i++) {
arg = argv[i];
@ -667,6 +762,33 @@ getdns_return_t parse_args(int argc, char **argv)
case 'd':
(void) getdns_context_set_edns_do_bit(context, 0);
break;
case 'f':
if (c[1] != 0 || ++i >= argc || !*argv[i]) {
fprintf(stderr, "file name expected "
"after -f\n");
return GETDNS_RETURN_GENERIC_ERROR;
}
if (!(fh = fopen(argv[i], "r"))) {
fprintf(stderr, "Could not open \"%s\""
": %s\n",argv[i], strerror(errno));
return GETDNS_RETURN_GENERIC_ERROR;
}
if (getdns_fp2rr_list(fh, &tas, NULL, 3600)) {
fprintf(stderr,"Could not parse "
"\"%s\"\n", argv[i]);
return GETDNS_RETURN_GENERIC_ERROR;
}
fclose(fh);
if (getdns_context_set_dnssec_trust_anchors(
context, tas)) {
fprintf(stderr,"Could not set "
"trust anchors from \"%s\"\n",
argv[i]);
return GETDNS_RETURN_GENERIC_ERROR;
}
getdns_list_destroy(tas);
tas = NULL;
break;
case 'F':
if (c[1] != 0 || ++i >= argc || !*argv[i]) {
fprintf(stderr, "file name expected "
@ -735,6 +857,33 @@ getdns_return_t parse_args(int argc, char **argv)
context,
GETDNS_RESOLUTION_RECURSING);
break;
case 'R':
if (c[1] != 0 || ++i >= argc || !*argv[i]) {
fprintf(stderr, "file name expected "
"after -f\n");
return GETDNS_RETURN_GENERIC_ERROR;
}
if (!(fh = fopen(argv[i], "r"))) {
fprintf(stderr, "Could not open \"%s\""
": %s\n",argv[i], strerror(errno));
return GETDNS_RETURN_GENERIC_ERROR;
}
if (getdns_fp2rr_list(fh, &hints, NULL, 3600)) {
fprintf(stderr,"Could not parse "
"\"%s\"\n", argv[i]);
return GETDNS_RETURN_GENERIC_ERROR;
}
fclose(fh);
if (getdns_context_set_dns_root_servers(
context, hints)) {
fprintf(stderr,"Could not set "
"root servers from \"%s\"\n",
argv[i]);
return GETDNS_RETURN_GENERIC_ERROR;
}
getdns_list_destroy(hints);
hints = NULL;
break;
case 's':
getdns_context_set_resolution_type(
context, GETDNS_RESOLUTION_STUB);
@ -790,10 +939,6 @@ getdns_return_t parse_args(int argc, char **argv)
getdns_context_set_dns_transport(context,
GETDNS_TRANSPORT_TLS_FIRST_AND_FALL_BACK_TO_TCP_KEEP_CONNECTIONS_OPEN);
break;
case 'R':
getdns_context_set_dns_transport(context,
GETDNS_TRANSPORT_STARTTLS_FIRST_AND_FALL_BACK_TO_TCP_KEEP_CONNECTIONS_OPEN);
break;
case 'u':
getdns_context_set_dns_transport(context,
GETDNS_TRANSPORT_UDP_FIRST_AND_FALL_BACK_TO_TCP);
@ -845,7 +990,8 @@ next: ;
return CONTINUE;
}
if (print_trust_anchors) {
if ((tas = getdns_root_trust_anchor(NULL))) {
if (!getdns_context_get_dnssec_trust_anchors(context, &tas)) {
/* if ((tas = getdns_root_trust_anchor(NULL))) { */
fprintf(stdout, "%s\n", getdns_pretty_print_list(tas));
return CONTINUE;
} else

View File

@ -47,7 +47,6 @@
#define TRANSPORT_PIPELINE "pipeline"
#define TRANSPORT_TLS_KEEPOPEN "tls"
#define TRANSPORT_TLS_TCP_KEEPOPEN "dns-over-tls"
#define TRANSPORT_STARTTLS_TCP_KEEPOPEN "starttls"
#define RESOLUTION_STUB "stub"
#define RESOLUTION_REC "rec"
@ -111,8 +110,6 @@ main(int argc, char** argv)
getdns_context_set_dns_transport(this_context, GETDNS_TRANSPORT_TLS_ONLY_KEEP_CONNECTIONS_OPEN);
else if (strncmp(transport, TRANSPORT_TLS_TCP_KEEPOPEN, 12) == 0)
getdns_context_set_dns_transport(this_context, GETDNS_TRANSPORT_TLS_FIRST_AND_FALL_BACK_TO_TCP_KEEP_CONNECTIONS_OPEN);
else if (strncmp(transport, TRANSPORT_STARTTLS_TCP_KEEPOPEN, 8) == 0)
getdns_context_set_dns_transport(this_context, GETDNS_TRANSPORT_STARTTLS_FIRST_AND_FALL_BACK_TO_TCP_KEEP_CONNECTIONS_OPEN);
else if (strncmp(transport, TRANSPORT_UDP_TCP, 3) != 0) {
fprintf(stderr, "Invalid transport %s, must be one of udp, udp_tcp, tcp or pipeline\n", transport);
exit(EXIT_FAILURE);

View File

@ -49,7 +49,7 @@ usage () {
echo "it can be used to check the basic functionality for now. It is recommended that"
echo "local or known test servers are used, but it should work with the default servers:"
echo " - Google Open DNS for TCP and UDP only "
echo "- the getdnsapi.net test server Open Resolver for TLS, STARTTLS, TCP and UDP"
echo "- the getdnsapi.net test server Open Resolver for TLS, TCP and UDP"
echo "NOTE: By default this script assumes it is located in the same directory"
echo "as the getdns_query binary. If it is not, then the location of the binary"
echo "can be specified via the command line option."
@ -57,7 +57,7 @@ usage () {
echo "usage: test_transport.sh"
echo " -p path to getdns_query binary"
echo " -s server configured for only TCP and UDP"
echo " -t server configured for TLS, STARTTLS, TCP and UDP"
echo " -t server configured for TLS, TCP and UDP"
echo " (This must include the hostname e.g. 185.49.141.38~getdnsapi.net)"
}
@ -79,7 +79,6 @@ GOOD_QUERIES=(
"-s -A -q getdnsapi.net -l T @${SERVER_IP} "
"-s -A -q getdnsapi.net -l L @${TLS_SERVER_IP_NO_NAME}"
"-s -A -q getdnsapi.net -l L -m @${TLS_SERVER_IP}")
#"-s -A -q getdnsapi.net -l S @${TLS_SERVER_IP_NO_NAME}")
GOOD_FALLBACK_QUERIES=(
"-s -A -q getdnsapi.net -l LT @${SERVER_IP}"
@ -91,7 +90,6 @@ GOOD_FALLBACK_QUERIES=(
NOT_AVAILABLE_QUERIES=(
"-s -A -q getdnsapi.net -l L @${SERVER_IP} "
#"-s -A -q getdnsapi.net -l S @${SERVER_IP} "
"-s -A -q getdnsapi.net -l L -m @${TLS_SERVER_IP_NO_NAME} "
"-s -G -q DNSKEY getdnsapi.net -l U @${SERVER_IP} -b 512 -D")

View File

@ -0,0 +1,16 @@
BaseName: 050-constants
Version: 1.0
Description: Check if all constants are in const-info.c
CreationDate: wo dec 16 14:26:01 CET 2015
Maintainer: Willem Toorop
Category:
Component:
CmdDepends:
Depends:
Help:
Pre: 050-constants.pre
Post:
Test: 050-constants.test
AuxFiles:
Passed:
Failure:

View File

@ -0,0 +1,14 @@
# #-- 050-constants.pre--#
# source the master var file when it's there
if [ -f ../.tpkg.var.master ]
then
source ../.tpkg.var.master
else
(
cd ..
[ -f "${TPKG_SRCDIR}/setup-env.sh" ] \
&& sh "${TPKG_SRCDIR}/setup-env.sh"
) && source ../.tpkg.var.master
fi
# use .tpkg.var.test for in test variable passing
[ -f .tpkg.var.test ] && source .tpkg.var.test

View File

@ -0,0 +1,14 @@
# #-- 050-constants.test --#
# source the master var file when it's there
[ -f ../.tpkg.var.master ] && source ../.tpkg.var.master
# use .tpkg.var.test for in test variable passing
[ -f .tpkg.var.test ] && source .tpkg.var.test
cp -p ${SRCROOT}/src/const-info.c const-info.c.orig
(
cd ${SRCROOT}/src
sh mk-const-info.c.sh
)
cp -p ${SRCROOT}/src/const-info.c const-info.c.new
cp -p const-info.c.orig ${SRCROOT}/src/const-info.c
diff const-info.c.orig const-info.c.new

View File

@ -0,0 +1,16 @@
BaseName: 060-symbols
Version: 1.0
Description: Check if all symbols are in libgetdns.symbols
CreationDate: wo dec 16 15:41:23 CET 2015
Maintainer: Willem Toorop
Category:
Component:
CmdDepends:
Depends:
Help:
Pre: 060-symbols.pre
Post:
Test: 060-symbols.test
AuxFiles:
Passed:
Failure:

View File

@ -0,0 +1,14 @@
# #-- 060-symbols.pre--#
# source the master var file when it's there
if [ -f ../.tpkg.var.master ]
then
source ../.tpkg.var.master
else
(
cd ..
[ -f "${TPKG_SRCDIR}/setup-env.sh" ] \
&& sh "${TPKG_SRCDIR}/setup-env.sh"
) && source ../.tpkg.var.master
fi
# use .tpkg.var.test for in test variable passing
[ -f .tpkg.var.test ] && source .tpkg.var.test

View File

@ -0,0 +1,14 @@
# #-- 060-symbols.test --#
# source the master var file when it's there
[ -f ../.tpkg.var.master ] && source ../.tpkg.var.master
# use .tpkg.var.test for in test variable passing
[ -f .tpkg.var.test ] && source .tpkg.var.test
cp -p ${SRCROOT}/src/libgetdns.symbols libgetdns.symbols.orig
(
cd ${SRCROOT}/src
sh mk-symfiles.sh
)
cp -p ${SRCROOT}/src/libgetdns.symbols libgetdns.symbols.new
cp -p libgetdns.symbols.orig ${SRCROOT}/src/libgetdns.symbols
diff libgetdns.symbols.orig libgetdns.symbols.new

View File

@ -0,0 +1,16 @@
BaseName: 100-compile
Version: 1.0
Description: Create a builddir and compile
CreationDate: do dec 10 11:09:43 CET 2015
Maintainer: Willem Toorop
Category:
Component:
CmdDepends:
Depends:
Help:
Pre: 100-compile.pre
Post:
Test: 100-compile.test
AuxFiles:
Passed:
Failure:

View File

@ -0,0 +1,19 @@
# #-- 100-compile.pre--#
# source the master var file when it's there
if [ -f ../.tpkg.var.master ]
then
source ../.tpkg.var.master
else
(
cd ..
[ -f "${TPKG_SRCDIR}/setup-env.sh" ] \
&& sh "${TPKG_SRCDIR}/setup-env.sh"
) && source ../.tpkg.var.master
fi
# use .tpkg.var.test for in test variable passing
[ -f .tpkg.var.test ] && source .tpkg.var.test
rm -fr "${BUILDDIR}/build"
mkdir "${BUILDDIR}/build"
cd "${BUILDDIR}/build"
"${SRCROOT}/configure" --prefix "${BUILDDIR}/install"

View File

@ -0,0 +1,8 @@
# #-- 100-compile.test --#
# source the master var file when it's there
[ -f ../.tpkg.var.master ] && source ../.tpkg.var.master
# use .tpkg.var.test for in test variable passing
[ -f .tpkg.var.test ] && source .tpkg.var.test
cd "${BUILDDIR}/build"
make

View File

@ -0,0 +1,16 @@
BaseName: 105-install
Version: 1.0
Description: Install the library
CreationDate: vr dec 18 10:52:02 CET 2015
Maintainer: Willem Toorop
Category:
Component:
CmdDepends:
Depends: 100-compile.tpkg
Help:
Pre:
Post:
Test: 105-install.test
AuxFiles:
Passed:
Failure:

View File

@ -0,0 +1,8 @@
# #-- 105-install.test --#
# source the master var file when it's there
[ -f ../.tpkg.var.master ] && source ../.tpkg.var.master
# use .tpkg.var.test for in test variable passing
[ -f .tpkg.var.test ] && source .tpkg.var.test
cd "${BUILDDIR}/build"
make install

View File

@ -0,0 +1,16 @@
BaseName: 110-link
Version: 1.0
Description: Link getdns_query program
CreationDate: do dec 10 11:10:11 CET 2015
Maintainer: Willem Toorop
Category:
Component:
CmdDepends:
Depends: 100-compile.tpkg
Help:
Pre:
Post:
Test: 110-link.test
AuxFiles:
Passed:
Failure:

View File

@ -0,0 +1,10 @@
# #-- 110-link.test --#
# source the master var file when it's there
[ -f ../.tpkg.var.master ] && source ../.tpkg.var.master
# use .tpkg.var.test for in test variable passing
[ -f .tpkg.var.test ] && source .tpkg.var.test
cd "${BUILDDIR}/build"
make getdns_query \
&& echo "export GETDNS_QUERY=\"${BUILDDIR}/build/src/test/getdns_query\"" \
>> ../.tpkg.var.master

View File

@ -0,0 +1,16 @@
BaseName: 115-install-linked
Version: 1.0
Description: Install the getdns_query program
CreationDate: vr dec 18 10:52:26 CET 2015
Maintainer: Willem Toorop
Category:
Component:
CmdDepends:
Depends: 110-link.tpkg
Help:
Pre:
Post:
Test: 115-install-linked.test
AuxFiles:
Passed:
Failure:

View File

@ -0,0 +1,8 @@
# #-- 115-install-linked.test --#
# source the master var file when it's there
[ -f ../.tpkg.var.master ] && source ../.tpkg.var.master
# use .tpkg.var.test for in test variable passing
[ -f .tpkg.var.test ] && source .tpkg.var.test
cd "${BUILDDIR}/build"
make install-getdns_query

View File

@ -0,0 +1,16 @@
BaseName: 120-run-getdns_query
Version: 1.0
Description: Run the getdns_query program
CreationDate: do dec 10 11:09:59 CET 2015
Maintainer: Willem Toorop
Category:
Component:
CmdDepends:
Depends: 110-link.tpkg
Help:
Pre:
Post:
Test: 120-run-getdns_query.test
AuxFiles:
Passed:
Failure:

View File

@ -0,0 +1,7 @@
# #-- 120-run-getdns_query.test --#
# source the master var file when it's there
[ -f ../.tpkg.var.master ] && source ../.tpkg.var.master
# use .tpkg.var.test for in test variable passing
[ -f .tpkg.var.test ] && source .tpkg.var.test
"${GETDNS_QUERY}" -i

View File

@ -0,0 +1,16 @@
BaseName: 130-run-unit-tests
Version: 1.0
Description: Run the unit tests
CreationDate: do dec 10 11:10:29 CET 2015
Maintainer: Willem Toorop
Category:
Component:
CmdDepends:
Depends: 110-link.tpkg
Help:
Pre:
Post:
Test: 130-run-unit-tests.test
AuxFiles:
Passed:
Failure:

View File

@ -0,0 +1,8 @@
# #-- 130-run-unit-tests.test --#
# source the master var file when it's there
[ -f ../.tpkg.var.master ] && source ../.tpkg.var.master
# use .tpkg.var.test for in test variable passing
[ -f .tpkg.var.test ] && source .tpkg.var.test
cd "${BUILDDIR}/build"
make test

View File

@ -0,0 +1,16 @@
BaseName: 200-stub-only-compile
Version: 1.0
Description: Create builddir and compile stub only
CreationDate: do dec 10 11:08:24 CET 2015
Maintainer: Willem Toorop
Category:
Component:
CmdDepends:
Depends:
Help:
Pre: 200-stub-only-compile.pre
Post:
Test: 200-stub-only-compile.test
AuxFiles:
Passed:
Failure:

View File

@ -0,0 +1,19 @@
# #-- 200-stub-only-compile.pre--#
# source the master var file when it's there
if [ -f ../.tpkg.var.master ]
then
source ../.tpkg.var.master
else
(
cd ..
[ -f "${TPKG_SRCDIR}/setup-env.sh" ] \
&& sh "${TPKG_SRCDIR}/setup-env.sh"
) && source ../.tpkg.var.master
fi
# use .tpkg.var.test for in test variable passing
[ -f .tpkg.var.test ] && source .tpkg.var.test
rm -fr "${BUILDDIR}/build-stub-only"
mkdir "${BUILDDIR}/build-stub-only"
cd "${BUILDDIR}/build-stub-only"
"${SRCROOT}/configure" --enable-stub-only

View File

@ -0,0 +1,8 @@
# #-- 200-stub-only-compile.test --#
# source the master var file when it's there
[ -f ../.tpkg.var.master ] && source ../.tpkg.var.master
# use .tpkg.var.test for in test variable passing
[ -f .tpkg.var.test ] && source .tpkg.var.test
cd "${BUILDDIR}/build-stub-only"
make

View File

@ -0,0 +1,16 @@
BaseName: 210-stub-only-link
Version: 1.0
Description: Link getdns_query program
CreationDate: do dec 10 11:08:37 CET 2015
Maintainer: Willem Toorop
Category:
Component:
CmdDepends:
Depends: 200-stub-only-compile.tpkg
Help:
Pre:
Post:
Test: 210-stub-only-link.test
AuxFiles:
Passed:
Failure:

View File

@ -0,0 +1,10 @@
# #-- 210-stub-only-link.test --#
# source the master var file when it's there
[ -f ../.tpkg.var.master ] && source ../.tpkg.var.master
# use .tpkg.var.test for in test variable passing
[ -f .tpkg.var.test ] && source .tpkg.var.test
cd "${BUILDDIR}/build-stub-only"
make getdns_query \
&& echo "export GETDNS_STUB_QUERY=\"${BUILDDIR}/build-stub-only/src/test/getdns_query\"" \
>> ../.tpkg.var.master

View File

@ -0,0 +1,16 @@
BaseName: 220-stub-only-run-getdns_query
Version: 1.0
Description: Run the getdns_query program
CreationDate: do dec 10 11:08:51 CET 2015
Maintainer: Willem Toorop
Category:
Component:
CmdDepends:
Depends: 210-stub-only-link.tpkg
Help:
Pre:
Post:
Test: 220-stub-only-run-getdns_query.test
AuxFiles:
Passed:
Failure:

View File

@ -0,0 +1,7 @@
# #-- 220-stub-only-run-getdns_query.test --#
# source the master var file when it's there
[ -f ../.tpkg.var.master ] && source ../.tpkg.var.master
# use .tpkg.var.test for in test variable passing
[ -f .tpkg.var.test ] && source .tpkg.var.test
"${GETDNS_STUB_QUERY}" -i

View File

@ -0,0 +1,16 @@
BaseName: 230-stub-only-run-unit-tests
Version: 1.0
Description: Run the unit tests
CreationDate: do dec 10 11:09:02 CET 2015
Maintainer: Willem Toorop
Category:
Component:
CmdDepends:
Depends: 210-stub-only-link.tpkg
Help:
Pre:
Post:
Test: 230-stub-only-run-unit-tests.test
AuxFiles:
Passed:
Failure:

View File

@ -0,0 +1,8 @@
# #-- 230-stub-only-run-unit-tests.test --#
# source the master var file when it's there
[ -f ../.tpkg.var.master ] && source ../.tpkg.var.master
# use .tpkg.var.test for in test variable passing
[ -f .tpkg.var.test ] && source .tpkg.var.test
cd "${BUILDDIR}/build-stub-only"
make test

View File

@ -0,0 +1,15 @@
builddir = @BUILDDIR@
testname = @TPKG_NAME@
LIBTOOL = $(builddir)/libtool
CFLAGS=-I$(builddir)/src
LDLIBS=$(builddir)/src/libgetdns.la
.SUFFIXES: .c .o .a .lo .h
.c.lo:
$(LIBTOOL) --quiet --tag=CC --mode=compile $(CC) $(CFLAGS) -c $< -o $@
$(testname): $(testname).lo
$(LIBTOOL) --tag=CC --mode=link $(CC) $(LDLIBS) $(LDFLAGS) -o $@ $<

View File

@ -0,0 +1,16 @@
BaseName: 250-json-pointers
Version: 1.0
Description: Test json pointers
CreationDate: vr dec 11 11:09:57 CET 2015
Maintainer: Willem Toorop
Category:
Component:
CmdDepends:
Depends: 200-stub-only-compile.tpkg
Help:
Pre: 250-json-pointers.pre
Post:
Test: 250-json-pointers.test
AuxFiles:
Passed:
Failure:

View File

@ -0,0 +1,14 @@
# #-- 250-json-pointers.test --#
# source the master var file when it's there
[ -f ../.tpkg.var.master ] && source ../.tpkg.var.master
# use .tpkg.var.test for in test variable passing
[ -f .tpkg.var.test ] && source .tpkg.var.test
(
grep '^CC=' "${BUILDDIR}/build-stub-only/src/Makefile"
grep '^LDFLAGS=' "${BUILDDIR}/build-stub-only/src/Makefile"
BUILDDIR4SED=`echo "${BUILDDIR}/build-stub-only" | sed 's/\//\\\\\//g'`
sed -e "s/@BUILDDIR@/${BUILDDIR4SED}/g" \
-e "s/@TPKG_NAME@/${TPKG_NAME}/g" "${TPKG_NAME}.Makefile"
) > Makefile

View File

@ -0,0 +1,7 @@
# #-- 250-json-pointers.test --#
# source the master var file when it's there
[ -f ../.tpkg.var.master ] && source ../.tpkg.var.master
# use .tpkg.var.test for in test variable passing
[ -f .tpkg.var.test ] && source .tpkg.var.test
make && "./${TPKG_NAME}" | tee out && diff out "${TPKG_NAME}.good"

View File

@ -0,0 +1,15 @@
builddir = @BUILDDIR@
testname = @TPKG_NAME@
LIBTOOL = $(builddir)/libtool
CFLAGS=-I$(builddir)/src
LDLIBS=$(builddir)/src/libgetdns.la
.SUFFIXES: .c .o .a .lo .h
.c.lo:
$(LIBTOOL) --quiet --tag=CC --mode=compile $(CC) $(CFLAGS) -c $< -o $@
$(testname): $(testname).lo
$(LIBTOOL) --tag=CC --mode=link $(CC) $(LDLIBS) $(LDFLAGS) -o $@ $<

View File

@ -0,0 +1,325 @@
#include <stdio.h>
#include <ctype.h>
#include <getdns/getdns.h>
#include <getdns/getdns_extra.h>
#define FAIL(...) do { \
fprintf(stderr, "ERROR in %s:%d, ", __FILE__, __LINE__); \
fprintf(stderr, __VA_ARGS__); \
fprintf(stderr, "\n"); \
exit(EXIT_FAILURE); \
} while (0)
#define FAIL_r(function_name) FAIL( "%s returned %d: %s", function_name \
, (int)r, getdns_get_errorstr_by_id(r));
void print_dict(getdns_dict *rr_dict)
{
char *str = getdns_pretty_print_dict(rr_dict);
printf("%s\n", str);
free(str);
}
void print_list(getdns_list *rr_list)
{
char *str = getdns_pretty_print_list(rr_list);
printf("%s\n", str);
free(str);
}
void print_wire(uint8_t *wire, size_t wire_len)
{
size_t pos, i;
for (pos = 0; pos < wire_len; pos += 16) {
printf("%.4zx", pos);
for (i = 0; i < 16; i++) {
if (i % 8 == 0)
printf(" ");
if (pos + i < wire_len)
printf(" %.2x", (int)wire[pos + i]);
else
printf(" ");
}
printf(" ");
for (i = 0; i < 16; i++) {
if (i % 8 == 0)
printf(" ");
if (pos + i < wire_len && isprint(wire[pos + i]))
printf("%c", wire[pos + i]);
else
printf(".");
}
printf("\n");
}
}
int main(int argc, char const * const argv[])
{
getdns_return_t r;
getdns_dict *rr_dict;
getdns_bindata *dns_name;
getdns_bindata address = { 4, "\xb9\x31\x8d\x25" };
getdns_bindata fourth = { 11, "last string" };
size_t length;
char *str;
uint8_t *wire, *prev_wire;
size_t wire_len;
getdns_list *rr_list;
FILE *in;
uint8_t wire_buf[8200];
size_t i;
ssize_t available;
char str_buf[10000];
ssize_t str_len = sizeof(str_buf);
/* Convert string to rr_dict
*/
if ((r = getdns_str2rr_dict(
"some.domain.tld. 60 IN TXT \"first string\" second \"and third\"",
&rr_dict, NULL, 3600)))
FAIL_r("getdns_str2rr_dict");
/* Add a fourth text element.
*/
if ((r = getdns_dict_set_bindata(rr_dict, "/rdata/txt_strings/-", &fourth)))
FAIL_r("getdns_list_set_bindata");
print_dict(rr_dict);
/* Convert to wireformat from rdata_raw.
* Added fourth list element should NOT show.
*/
wire = NULL;
if ((r = getdns_rr_dict2wire(rr_dict, &wire, &wire_len)))
FAIL_r("getdns_rr_dict2wire");
print_wire(wire, wire_len);
free(wire);
/* Convert to wireformat from parsing rdata fields.
* Added fourth list element should show.
*/
if ((r = getdns_dict_remove_name(rr_dict, "/rdata/rdata_raw")))
FAIL_r("getdns_dict_remove_name");
printf("\nremoved \"/rdata/rdata_raw\":\n\n");
if ((r = getdns_rr_dict2wire(rr_dict, &wire, &wire_len)))
FAIL_r("getdns_rr_dict2wire");
print_wire(wire, wire_len);
free(wire);
/* Remove second and third string elements and show text format.
*/
if ((r = getdns_dict_remove_name(rr_dict, "/rdata/txt_strings/1")))
FAIL_r("getdns_dict_remove_name");
if ((r = getdns_dict_remove_name(rr_dict, "/rdata/txt_strings/1")))
FAIL_r("getdns_dict_remove_name");
if ((r = getdns_rr_dict2str(rr_dict, &str)))
FAIL_r("getdns_rr_dict2str");
printf("\n%s", str);
free(str);
/* Remove all string elements and show text format.
*/
if ((r = getdns_dict_remove_name(rr_dict, "/rdata/txt_strings/0")))
FAIL_r("getdns_dict_remove_name");
if ((r = getdns_dict_remove_name(rr_dict, "/rdata/txt_strings/0")))
FAIL_r("getdns_dict_remove_name");
if ((r = getdns_rr_dict2str(rr_dict, &str)))
FAIL_r("getdns_rr_dict2str");
printf("%s", str);
free(str);
getdns_dict_destroy(rr_dict);
/* Construct rr_dict and convert to string
*/
if (!(rr_dict = getdns_dict_create()))
FAIL("getdns_dict_create returned NULL");
if ((r = getdns_convert_fqdn_to_dns_name("www.getdnsapi.net", &dns_name)))
FAIL_r("getdns_convert_fqdn_to_dns_name");
r = getdns_dict_set_bindata(rr_dict, "name", dns_name);
free(dns_name->data);
free(dns_name);
if (r)
FAIL_r("getdns_dict_set_bindata");
if ((r = getdns_dict_set_int(rr_dict, "type", GETDNS_RRTYPE_A)))
FAIL_r("getdns_dict_set_int");
if ((r = getdns_dict_set_bindata(rr_dict, "/rdata/ipv4_address", &address)))
FAIL_r("getdns_dict_set_int");
if ((r = getdns_rr_dict2str(rr_dict, &str)))
FAIL_r("getdns_rr_dict2str");
printf("\n%s\n", str);
free(str);
if ((r = getdns_rr_dict2wire(rr_dict, &wire, &wire_len)))
FAIL_r("getdns_rr_dict2wire");
getdns_dict_destroy(rr_dict);
print_wire(wire, wire_len);
free(wire);
/* Convert RR with special rdata fields and repeating last element
* from string to rr_dict
*/
if ((r = getdns_str2rr_dict(
"hip2 IN HIP 2 200100107B1A74DF365639CC39F1D578 AwEAAbdxyhNuSutc5EMzxTs9LBPCIkOFH8cIvM4p9+LrV4e19WzK00+CI6zBCQTdtWsuxKbWIy87UOoJTwkUs7lBu+Upr1gsNrut79ryra+bSRGQb1slImA8YVJyuIDsj7kwzG7jnERNqnWxZ48AWkskmdHaVDP4BcelrTI3rMXdXF5D rvs1.example.com. rvs2.example.com.",
&rr_dict, "nlnetlabs.nl", 3600)))
FAIL_r("getdns_str2rr_dict");
if ((r = getdns_dict_remove_name(rr_dict, "/rdata/rdata_raw")))
FAIL_r("getdns_dict_remove_name");
printf("\n");
print_dict(rr_dict);
/* Convert RR with special rdata fields and repeating last element
* back to string.
*/
if ((r = getdns_rr_dict2str(rr_dict, &str)))
FAIL_r("getdns_rr_dict2str");
printf("%s", str);
free(str);
/* Convert RR with special rdata fields without repeating last element
* to string.
*/
if ((r = getdns_dict_remove_name(rr_dict, "/rdata/rendezvous_servers")))
FAIL_r("getdns_dict_remove_name");
if ((r = getdns_dict_get_bindata(rr_dict, "name", &dns_name)))
FAIL_r("getdns_dict_get_bindata");
dns_name->data[4] = '0';
if ((r = getdns_rr_dict2str(rr_dict, &str)))
FAIL_r("getdns_rr_dict2str");
printf("%s\n", str);
free(str);
getdns_dict_destroy(rr_dict);
/* Convert RR with repeat block from string to rr_dict
*/
if ((r = getdns_str2rr_dict(
"apl APL 1:192.168.42.0/26 1:192.168.42.64/26 !1:192.168.42.128/25 1:224.0.0.0/4 2:FF00:0:0:0:0:0:0:0/8",
&rr_dict, "net-dns.org", 3600)))
FAIL_r("getdns_str2rr_dict");
if ((r = getdns_dict_remove_name(rr_dict, "/rdata/rdata_raw")))
FAIL_r("getdns_dict_remove_name");
print_dict(rr_dict);
/* Convert repeat block from rr_dict back to string.
*/
if ((r = getdns_rr_dict2str(rr_dict, &str)))
FAIL_r("getdns_rr_dict2str");
printf("%s", str);
free(str);
getdns_dict_destroy(rr_dict);
if (!(in = fopen(argv[1], "r")))
FAIL("Could not fopen %s\n", argv[1]);
if ((r = getdns_fp2rr_list(in, &rr_list, NULL, 0)))
FAIL_r("getdns_fp2rr_list");
fclose(in);
print_list(rr_list);
/* Fill the wire_buf with wireformat RR's in rr_list
* wire_buf is too small for last two rr's.
*/
wire = wire_buf;
available = sizeof(wire_buf);
for (i = 0; !(r = getdns_list_get_dict(rr_list, i, &rr_dict)); i++) {
prev_wire = wire;
if ((r = getdns_rr_dict2wire_scan(rr_dict,&wire,&available))) {
if (r == GETDNS_RETURN_NEED_MORE_SPACE) {
printf("record %.3zu, available buffer space: "
"%zi\n", i, available);
/* The buffer was too small to fit the wire-
* format representation. available now holds
* a negative number. the wire pointer is this
* much beyond the end of the buffer space.
*
* If we would add available to wire, wire
* would be positioned at the end of the buffer
* but would not be positioned at a clean RR
* border. Therefore we have to remember the
* previous position of wire, so we can reset
* it at the end of the wireformat representa-
* tion of the previously converted rr_dict.
*/
wire = prev_wire;
break;
}
else
FAIL_r("getdns_rr_dict2wire_scan");
}
printf("record %3zu, available buffer space: "
"%zi\n", i, available);
fflush(stdout);
}
if (r == GETDNS_RETURN_NO_SUCH_LIST_ITEM)
r = GETDNS_RETURN_GOOD;
getdns_list_destroy(rr_list);
/* Now scan over the wireformat buffer and convert to rr_dicts again.
* Then fill a string buffer with those rr_dicts.
*/
available = wire - wire_buf;
wire = wire_buf;
str = str_buf;
str_len = sizeof(str_buf);
while (available > 0 && str_len > 0) {
rr_dict = NULL;
if ((r = getdns_wire2rr_dict_scan(
(const uint8_t **)&wire, &available, &rr_dict)))
FAIL_r("getdns_wire2rr_dict_scan");
if ((r = getdns_rr_dict2str_scan(rr_dict, &str, &str_len)))
FAIL_r("getdns_rr_dict2str_scan");
getdns_dict_destroy(rr_dict);
}
*str = 0;
/* Print the entire buffer */
printf("%s", str_buf);
exit(EXIT_SUCCESS);
}

View File

@ -0,0 +1,16 @@
BaseName: 260-conversion-functions
Version: 1.0
Description: Test json pointers
CreationDate: vr dec 11 13:09:47 CET 2015
Maintainer: Willem Toorop
Category:
Component:
CmdDepends:
Depends: 200-stub-only-compile.tpkg
Help: 260-conversion-functions.help
Pre: 260-conversion-functions.pre
Post:
Test: 260-conversion-functions.test
AuxFiles:
Passed:
Failure:

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,2 @@
Compile a program that setups a dict with json pointers and pretty prints the dict.
Then compare the output to the known to be good output.

View File

@ -0,0 +1,133 @@
$ORIGIN .
$TTL 30 ; 30 seconds
net-dns.org IN SOA ns.nlnetlabs.nl. sysadmin.nlnetlabs.nl. (
2015081800 ; serial
450 ; refresh (7 minutes 30 seconds)
600 ; retry (10 minutes)
345600 ; expire (4 days)
300 ; minimum (5 minutes)
)
NS ns.nlnetlabs.nl
NS ns.hactrn.net.
NS mcvax.nlnet.nl.
NS sec2.authdns.ripe.net.
A 185.49.140.22
AAAA 2a04:b900::2:0:0:22
MX 10 dicht.nlnetlabs.nl.
MX 20 mcvax.nlnet.nl.
TXT "Net::DNS domain"
$ORIGIN net-dns.org.
_443._tcp TLSA 3 1 1 274c6f96c9885c8050e8a05ad1c3162c1d51752c35b6196474e3f05ad31cd923
_443._tcp.www TLSA 3 1 1 274c6f96c9885c8050e8a05ad1c3162c1d51752c35b6196474e3f05ad31cd923
dynup TXT "fooFoo2" "Bla \; Foo"
lists A 63.209.15.196
localhost A 127.0.0.1
overflow TXT "And line 1 of al sorts of crap that will just fill the packet "
TXT "And line 2 of al sorts of crap that will just fill the packet "
TXT "And line 3 of al sorts of crap that will just fill the packet "
TXT "And line 4 of al sorts of crap that will just fill the packet "
TXT "And line 5 of al sorts of crap that will just fill the packet "
TXT "And line 6 of al sorts of crap that will just fill the packet "
TXT "And line 7 of al sorts of crap that will just fill the packet "
TXT "And line 8 of al sorts of crap that will just fill the packet "
TXT "And line 9 of al sorts of crap that will just fill the packet "
TXT "And line 10 of al sorts of crap that will just fill the packet "
TXT "And line 11 of al sorts of crap that will just fill the packet "
TXT "And line 12 of al sorts of crap that will just fill the packet "
TXT "And line 13 of al sorts of crap that will just fill the packet "
TXT "And line 14 of al sorts of crap that will just fill the packet "
TXT "And line 15 of al sorts of crap that will just fill the packet "
TXT "And line 16 of al sorts of crap that will just fill the packet "
TXT "And line 17 of al sorts of crap that will just fill the packet "
TXT "And line 18 of al sorts of crap that will just fill the packet "
TXT "And line 19 of al sorts of crap that will just fill the packet "
TXT "And line 20 of al sorts of crap that will just fill the packet "
TXT "And line 21 of al sorts of crap that will just fill the packet "
TXT "And line 22 of al sorts of crap that will just fill the packet "
TXT "And line 23 of al sorts of crap that will just fill the packet "
TXT "And line 25 of al sorts of crap that will just fill the packet "
TXT "And line 26 of al sorts of crap that will just fill the packet "
TXT "And line 27 of al sorts of crap that will just fill the packet "
TXT "And line 28 of al sorts of crap that will just fill the packet "
TXT "And line 29 of al sorts of crap that will just fill the packet "
TXT "And line 30 of al sorts of crap that will just fill the packet "
TXT "And line 31 of al sorts of crap that will just fill the packet "
TXT "And line 32 of al sorts of crap that will just fill the packet "
TXT "And line 33 of al sorts of crap that will just fill the packet "
TXT "And line 34 of al sorts of crap that will just fill the packet "
TXT "And line 35 of al sorts of crap that will just fill the packet "
TXT "And line 36 of al sorts of crap that will just fill the packet "
TXT "And line 37 of al sorts of crap that will just fill the packet "
TXT "And line 38 of al sorts of crap that will just fill the packet "
TXT "And line 39 of al sorts of crap that will just fill the packet "
TXT "And line 40 of al sorts of crap that will just fill the packet "
TXT "And line 41 of al sorts of crap that will just fill the packet "
TXT "And line 42 of al sorts of crap that will just fill the packet "
TXT "And line 43 of al sorts of crap that will just fill the packet "
TXT "And line 44 of al sorts of crap that will just fill the packet "
TXT "And line 45 of al sorts of crap that will just fill the packet "
TXT "And line 46 of al sorts of crap that will just fill the packet "
TXT "And line 47 of al sorts of crap that will just fill the packet "
TXT "And line 48 of al sorts of crap that will just fill the packet "
TXT "And line 49 of al sorts of crap that will just fill the packet "
TXT "And line 50 of al sorts of crap that will just fill the packet "
TXT "And line 51 of al sorts of crap that will just fill the packet "
TXT "And line 52 of al sorts of crap that will just fill the packet "
TXT "And line 53 of al sorts of crap that will just fill the packet "
TXT "And line 54 of al sorts of crap that will just fill the packet "
TXT "And line 55 of al sorts of crap that will just fill the packet "
TXT "And line 56 of al sorts of crap that will just fill the packet "
TXT "And line 57 of al sorts of crap that will just fill the packet "
TXT "And line 58 of al sorts of crap that will just fill the packet "
TXT "And line 59 of al sorts of crap that will just fill the packet "
TXT "And line 60 of al sorts of crap that will just fill the packet "
TXT "And line 224 of al sorts of crap that will just fill the packet "
TXT "An increadibly large answer section that will lead to packet overflow"
t TXT "The names within this domain are used for testing"
$ORIGIN t.net-dns.org.
a A 10.0.1.128
a2 A 10.0.1.129
cname CNAME a
mx MX 10 a
mx2 MX 10 a
MX 15 a2
txt TXT "Net-DNS"
txt2 TXT "Net-DNS\; complicated $tuff" "sort of \" text\; and binary \000 data"
connection-test TXT "connection-test succes"
txt-utf8 TXT \# 33 09E58FA4E6B1A0E382840CE89B99E9A39BE8BEBCE3828009E6B0B4E381AEE99FB3
txt-utf8-bin TXT "古池や" "蛙飛込む" "水の音"
a.few.empty.non.terminals TXT a few empty non terminals
A 185.49.140.22
AAAA 2a04:b900::2:0:0:22
yx1.cname CNAME -
yx2.cname CNAME a-a
yx3.cname CNAME a\.
yx4.cname CNAME a\000
nx1.cname CNAME does.not.exist
nx2.cname CNAME empty.non.terminals
$ORIGIN net-dns.org.
www A 185.49.140.22
www AAAA 2a04:b900::2:0:0:22
apl APL 1:192.168.42.0/26 1:192.168.42.64/26 !1:192.168.42.128/25 1:224.0.0.0/4 2:FF00:0:0:0:0:0:0:0/8
ipseckey0 IPSECKEY 10 0 2 . AQNRU3mG7TVTO2BkR47usntb102uFJtugbo6BSGvgqt4AQ==
ipseckey1 IPSECKEY 10 1 2 192.0.2.38 AQNRU3mG7TVTO2BkR47usntb102uFJtugbo6BSGvgqt4AQ==
ipseckey2 IPSECKEY 10 2 2 2001:0DB8:0:8002::2000:1 AQNRU3mG7TVTO2BkR47usntb102uFJtugbo6BSGvgqt4AQ==
ipseckey3 IPSECKEY 10 3 2 mygateway.example.com. AQNRU3mG7TVTO2BkR47usntb102uFJtugbo6BSGvgqt4AQ==
ipseckey IPSECKEY 10 0 2 . AQNRU3mG7TVTO2BkR47usntb102uFJtugbo6BSGvgqt4AQ==
IPSECKEY 10 1 2 192.0.2.38 AQNRU3mG7TVTO2BkR47usntb102uFJtugbo6BSGvgqt4AQ==
IPSECKEY 10 2 2 2001:0DB8:0:8002::2000:1 AQNRU3mG7TVTO2BkR47usntb102uFJtugbo6BSGvgqt4AQ==
IPSECKEY 10 3 2 mygateway.example.com. AQNRU3mG7TVTO2BkR47usntb102uFJtugbo6BSGvgqt4AQ==
default._domainkey IN TXT "v=DKIM1; r=postmaster; g=*; k=rsa; p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDVG/lfF5GtPlMOcSGnfbp5u+EWM+OOg/f6QmbDXOW/zKQkRIRIZ+BtfSYchP8MeFPfMvUZtdRPzCWg1G7OdD7qaTUqc6kV84on6/8kPVMgdDLyLl2DeU/Lts9hfVHVDSpWuChwDAFXnbnW8jpp54zuof9OIbWSWIxZqLL8flgOsQIDAQAB" ; ----- DKIM default for example.com
2.3.3.updates.spamassassin TXT "1418219 "
mirrors.updates.spamassassin TXT "http://anonymous@spamassassin.apache.org/updates/MIRRORED.BY"

View File

@ -0,0 +1,14 @@
# #-- 260-conversion-functions.test --#
# source the master var file when it's there
[ -f ../.tpkg.var.master ] && source ../.tpkg.var.master
# use .tpkg.var.test for in test variable passing
[ -f .tpkg.var.test ] && source .tpkg.var.test
(
grep '^CC=' "${BUILDDIR}/build-stub-only/src/Makefile"
grep '^LDFLAGS=' "${BUILDDIR}/build-stub-only/src/Makefile"
BUILDDIR4SED=`echo "${BUILDDIR}/build-stub-only" | sed 's/\//\\\\\//g'`
sed -e "s/@BUILDDIR@/${BUILDDIR4SED}/g" \
-e "s/@TPKG_NAME@/${TPKG_NAME}/g" "${TPKG_NAME}.Makefile"
) > Makefile

View File

@ -0,0 +1,15 @@
# #-- 260-conversion-functions.test --#
# source the master var file when it's there
[ -f ../.tpkg.var.master ] && source ../.tpkg.var.master
# use .tpkg.var.test for in test variable passing
[ -f .tpkg.var.test ] && source .tpkg.var.test
if ! make
then
exit 1
elif ! ( "./${TPKG_NAME}" "${TPKG_NAME}.net-dns.org" | tee out )
then
exit 1
else
diff out "${TPKG_NAME}.good"
fi

View File

@ -0,0 +1,16 @@
BaseName: 300-event-loops-configure
Version: 1.0
Description: Configure for maximum coverage
CreationDate: vr dec 18 11:21:07 CET 2015
Maintainer: Willem Toorop
Category:
Component:
CmdDepends:
Depends:
Help:
Pre: 300-event-loops-configure.pre
Post:
Test: 300-event-loops-configure.test
AuxFiles:
Passed:
Failure:

View File

@ -0,0 +1,14 @@
# #-- 300-event-loops-configure.pre--#
# source the master var file when it's there
if [ -f ../.tpkg.var.master ]
then
source ../.tpkg.var.master
else
(
cd ..
[ -f "${TPKG_SRCDIR}/setup-env.sh" ] \
&& sh "${TPKG_SRCDIR}/setup-env.sh"
) && source ../.tpkg.var.master
fi
# use .tpkg.var.test for in test variable passing
[ -f .tpkg.var.test ] && source .tpkg.var.test

View File

@ -0,0 +1,16 @@
# #-- 300-event-loops-configure.test --#
# source the master var file when it's there
[ -f ../.tpkg.var.master ] && source ../.tpkg.var.master
# use .tpkg.var.test for in test variable passing
[ -f .tpkg.var.test ] && source .tpkg.var.test
rm -fr "${BUILDDIR}/build-event-loops"
mkdir "${BUILDDIR}/build-event-loops"
cd "${BUILDDIR}/build-event-loops"
"${SRCROOT}/configure" --enable-all-drafts --enable-all-debugging --with-getdns_query --with-libevent --with-libev --with-libuv \
|| "${SRCROOT}/configure" --enable-all-drafts --enable-all-debugging --with-getdns_query --with-libevent --with-libev \
|| "${SRCROOT}/configure" --enable-all-drafts --enable-all-debugging --with-getdns_query --with-libevent --with-libuv \
|| "${SRCROOT}/configure" --enable-all-drafts --enable-all-debugging --with-getdns_query --with-libev --with-libuv \
|| "${SRCROOT}/configure" --enable-all-drafts --enable-all-debugging --with-getdns_query --with-libevent \
|| "${SRCROOT}/configure" --enable-all-drafts --enable-all-debugging --with-getdns_query --with-libev \
|| "${SRCROOT}/configure" --enable-all-drafts --enable-all-debugging --with-getdns_query --with-libuv

View File

@ -0,0 +1,16 @@
BaseName: 310-dependencies
Version: 1.0
Description: Check Makefile dependencies
CreationDate: vr dec 18 11:25:59 CET 2015
Maintainer: Willem Toorop
Category:
Component:
CmdDepends:
Depends: 300-event-loops-configure.tpkg
Help:
Pre:
Post:
Test: 310-dependencies.test
AuxFiles:
Passed:
Failure:

View File

@ -0,0 +1,49 @@
# #-- 310-dependencies.test --#
# source the master var file when it's there
[ -f ../.tpkg.var.master ] && source ../.tpkg.var.master
# use .tpkg.var.test for in test variable passing
[ -f .tpkg.var.test ] && source .tpkg.var.test
export TPKG_HERE=`pwd`
# Temporarily copy Makefile.in files
find . -type f -name "Makefile.in" -print0 | xargs -0 rm -f && (
cd "${SRCROOT}"
find . -maxdepth 3 -type f -name "Makefile.in" -print0 | xargs -0 tar cf -
) | (
cd "${TPKG_HERE}"
tar xf -
)
(
cd "${BUILDDIR}/build-event-loops"
if ! ./config.status --config | grep -q 'enable-all-drafts.*--with-libevent.*--with-libev.*--with-libuv'
then
echo Skipping because not covering enough code
exit 0
fi
make depend >/dev/null 2>&1
)
CHANGED_DEPENDENCIES=0
N_MAKEFILES=0
for mf in `find . -type f -name "Makefile.in"`
do
N_MAKEFILES=`expr $N_MAKEFILES + 1`
if ! diff -q "${mf}" "${SRCROOT}"/"${mf#./}"
then
echo "${mf}" and "${SRCROOT}"/"${mf#./}" differ
CHANGED_DEPENDENCIES=1
fi
done
if [ $N_MAKEFILES = 0 ]
then
echo "No Makefiles compared"
exit 1
fi
# Restore Makefile.in files
(
cd "${TPKG_HERE}"
find . -type f -name "Makefile.in" -print0 | xargs -0 tar cf -
)| (
cd "${SRCROOT}"
tar xf -
)
exit ${CHANGED_DEPENDENCIES}

View File

@ -0,0 +1,16 @@
BaseName: 320-event-loops-compile
Version: 1.0
Description: Compile
CreationDate: vr dec 18 11:20:35 CET 2015
Maintainer: Willem Toorop
Category:
Component:
CmdDepends:
Depends: 300-event-loops-configure.tpkg
Help:
Pre:
Post:
Test: 320-event-loops-compile.test
AuxFiles:
Passed:
Failure:

View File

@ -0,0 +1,8 @@
# #-- 320-event-loops-compile.test --#
# source the master var file when it's there
[ -f ../.tpkg.var.master ] && source ../.tpkg.var.master
# use .tpkg.var.test for in test variable passing
[ -f .tpkg.var.test ] && source .tpkg.var.test
cd "${BUILDDIR}/build-event-loops"
make

View File

@ -0,0 +1,16 @@
BaseName: 330-event-loops-unit-tests
Version: 1.0
Description: Run the unit tests
CreationDate: do dec 10 11:40:16 CET 2015
Maintainer: Willem Toorop
Category:
Component:
CmdDepends:
Depends: 320-event-loops-compile.tpkg
Help:
Pre:
Post:
Test: 330-event-loops-unit-tests.test
AuxFiles:
Passed:
Failure:

View File

@ -0,0 +1,8 @@
# #-- 330-event-loops-unit-tests.test --#
# source the master var file when it's there
[ -f ../.tpkg.var.master ] && source ../.tpkg.var.master
# use .tpkg.var.test for in test variable passing
[ -f .tpkg.var.test ] && source .tpkg.var.test
cd "${BUILDDIR}/build-event-loops"
make test

10
src/test/tpkg/run-all.sh Executable file
View File

@ -0,0 +1,10 @@
#!/bin/sh
export SRCDIR=`dirname $0`
. `dirname $0`/setup-env.sh
for TEST_PKG in ${SRCDIR}/*.tpkg
do
"${TPKG}" $* exe "${TEST_PKG}"
done
"${TPKG}" r

34
src/test/tpkg/setup-env.sh Executable file
View File

@ -0,0 +1,34 @@
#!/bin/sh
export SRCDIR=`dirname $0`
export SRCROOT=`(cd "${SRCDIR}/../../.."; pwd)`
export TPKG="${SRCDIR}/tpkg"
export BUILDDIR=`pwd`
export BUILDROOT=`(cd "${BUILDDIR}/../../.."; pwd)`
export LIBTOOL="${BUILDROOT}/libtool"
if [ ! -f "${SRCROOT}/libtool" ]
then
(cd "${SRCROOT}"; libtoolize -fic)
fi
if [ ! -f "${SRCROOT}/configure" ]
then
(cd "${SRCROOT}"; autoreconf -fi)
fi
if [ -f .tpkg.var.master ]
then
cat .tpkg.var.master \
| egrep -v '^export SRCDIR=|^export SRCROOT=|^export TPKG=' \
| egrep -v 'export BUILDDIR|^export BUILDROOT=|^export LIBTOOL=' \
>.tpkg.var.master.cleanup
mv .tpkg.var.master.cleanup .tpkg.var.master
fi
cat >>.tpkg.var.master << END_OF_TPKG_VAR_MASTER
export SRCDIR="${SRCDIR}"
export SRCROOT="${SRCROOT}"
export BUILDDIR="${BUILDDIR}"
export BUILDROOT="${BUILDROOT}"
export TPKG="${TPKG}"
export LIBTOOL="${LIBTOOL}"
END_OF_TPKG_VAR_MASTER

922
src/test/tpkg/tpkg Executable file
View File

@ -0,0 +1,922 @@
#!/usr/bin/env bash
# a utlity to run a shar test archive (aka tpkg)
# Created by Miek Gieben, NLnetLabs, (c) 2005, 2006
# Licensed under GPL version 2
export TPKG_VAR_MASTER="../.tpkg.var.master"
export TPKG_VAR_TEST=".tpkg.var.test"
export TPKG_VERSION="1.12";
export SHELL="/bin/sh"
TPKG_LOGGER=/usr/bin/logger
TPKG_BASE="."
TPKG_ARGS=""
TPKG_CURRENT=`pwd`
TPKG_QUIET=0 # only output err() msgs
TPKG_KEEP=0 # tpkg create doesn't remove dir/
TPKG_PASS=0 # how much must succeed
TPKG_LOG=0 # don't log
TPKG_PRI="" # log facility
TPKG_FORMAT="targz" # format of underlying tpkg files
TPKG_FORCE=0 # execute tests even when .done file is found
_DESC_WIDTH=${COLUMNS:-55}
if [ $_DESC_WIDTH -ge 70 ]; then
_DESC_WIDTH=70
fi
### Helper functions
function cleanup() {
out "[log] Cleaning up"
[[ -f result.$dsc_basename ]] && cp result.$dsc_basename ../
cd ..
if [[ ! -z "$dir" ]]; then
rm -rf `basename $dir`
fi
cd $TPKG_CURRENT
}
function cleanup_and_exit() {
cleanup; exit 1
}
function err() {
if [[ -z $testname ]]; then
echo -e " $1"
else
echo -e "[$testname] $1"
fi
}
function tpkg_log() {
if [[ $TPKG_LOG -eq 0 ]]; then
return
fi
if [[ -e $TPKG_LOGGER ]]; then
if [[ -z $TPKG_PRI ]]; then
$TPKG_LOGGER "$1"
else
$TPKG_LOGGER -p "$TPKG_PRI" "$1"
fi
fi
}
function out() {
if [[ $TPKG_QUIET -eq 1 ]]; then
return
fi
if [[ -z $testname ]]; then
echo -e " $1"
else
echo -e "[$testname] $1"
fi
}
function epoch() {
# make this sorta portable allthough not needed now
epoch=0
case $OSTYPE in
linux*)
epoch=`date +%s`
;;
freebsd*)
epoch=`date +%s`
;;
esac
}
function post() {
if [ -f "${dsc_post}" ]; then
err "[log] Executing post script: ${dsc_post} ${TPKG_ARGS}"
echo "--------- Start Post Output ------------------ " >> result.$dsc_basename
${SHELL} ${dsc_post} ${TPKG_ARGS} >> result.$dsc_basename
echo "----------- End Post Output ------------------ " >> result.$dsc_basename
result=$?
if [ $result -ne 0 ]; then
err "[warning] Post-script executed with errors: $result."
fi
fi
}
function pre() {
if [ -f "${dsc_pre}" ]; then
err "[log] Executing pre script: ${dsc_pre} ${TPKG_ARGS}"
echo "--------- Start Pre Output ------------------- " >> result.$dsc_basename
${SHELL} ${dsc_pre} ${TPKG_ARGS} >> result.$dsc_basename
echo "----------- End Pre Output ------------------- " >> result.$dsc_basename
result=$?
if [ $result -ne 0 ]; then
err "[warning] Pre-script executed with errors: $result."
fi
fi
}
function write_done() {
# we are executing in a subdir
if [ -f "../.done-${testname}" -a $TPKG_FORCE -ne 1 ]; then
err "[warning] Overwriting .done-${testname}"
fi
> ../.done-${testname}
}
# write done file in current dir
function write_fake_done() {
if [ -f ".done-${testname}" -a $TPKG_FORCE -ne 1 ]; then
err "[warning] Overwriting .done-${testname}"
fi
> .done-${testname}
}
function mktempdir() {
# check if mktemp is there, if not use plain mkdir with $$
# as a side effect set $dir
dir=
case $OSTYPE in
solaris*)
# use mkdir
dir="$1.$$"
mkdir "$dir"
return
;;
*)
dir=`mktemp -d "$1"`
return
;;
esac
}
function usage() {
out "Usage:"
out "$0 [OPTIONS] [exe|create|extract|tmpl|fake] test.tpkg"
out "or:"
out "$0 [OPTIONS] [report|clean|list|desc|help] test.tpkg"
out "or:"
out "$0 [OPTIONS] clone test1.tpkg test2.tpkg"
out
out "Testing"
out " exe.........:\texecute a test, safe the result result.testname"
out " c | create..:\tcreate a .tpkg out of the test.{pre, post, test} files"
out " e | extract.:\textract a .tpkg to tmp. dir"
out " t | tmpl....:\tcreate empty template files for a new test"
out " f | fake....:\tfake the running of test, but do create a .done file"
out
out "When no action is given a test is executed"
out
out "Reporting/Cleanup"
out " clean........:\tremove all the result files"
out " cd | cleandir:\tremove all .dir directories"
out " r | report..:\tcreate a nice report from all the result files"
out " cl | clone...:\tclone test1.tpkg to test2.tkpg"
out " l | list....:\tprint the files of the test to stdout"
out " d | desc....:\tprint the test's description to stdout"
out " h | help....:\tprint the help message for this test, if available"
out
out " When multiple tests depend on a single other test, this"
out " other test is only executed once."
out
out "OPTIONS"
out " -h\t\tshow this help"
out " -v\t\tshow version"
out " -q\t\tonly print errors"
out " -l\t\tlog test name to syslog when starting the test (using logger)"
out " -p PRI\tlog using PRI as priority"
out " -k\t\tdon't remove test directory when creating/executing a tpkg package"
out " -n NUM\tif less than NUM of the tests are passed exit with 1"
out " \t\tOtherwise exit with 0. Only valid when running tpkg report"
out " -b DIR\tuse DIR is a base directory in stead of ."
out " -a ARGS\tpass the string ARGS through to the test scripts"
out " -d\t\tUse directories instead of tar.gz for tpkg archive format"
out
out " (C) NLnetLabs, Miek Gieben. Licensed under the GPL version 2."
}
function version() {
out "tpkg (test package), version $TPKG_VERSION"
out "Written by Miek Gieben, NLnet Labs"
out
out "Copyright (C) 2005, 2006 NLnet Labs"
out
out "This is free software; see the source for copying conditions. There is no"
out "warranty; even not for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE"
}
function cleanreport() {
# cleanup all the result. files
for result in `ls result.* 2>/dev/null`; do
err "[log] rm $result"
rm $result
done
# rm any .var files
out "[log] rm `basename $TPKG_VAR_MASTER`"
rm -f `basename $TPKG_VAR_MASTER`
rm -f $TPKG_VAR_TEST
out "[log] rm .done files"
rm -f .done*
cd $TPKG_CURRENT
}
function cleandirs() {
for result in `ls -d *.dir 2> /dev/null`; do
err "[log] rm -rf $result"
rm -rf $result
done
}
function report() {
# generate a report from the result. files.
passed=0
failed=0
unknown=0
first=0
tp="passed"
tf="failed"
tu="unknown"
for result in `ls result.* 2>/dev/null` ; do
passfailed=`head -1 $result | awk ' { print $2 }'`
basename=`head -3 $result | grep BaseName | awk -F': ?' ' { print $2 }'`
description=`head -4 $result | grep Description | awk -F': ?' ' { print $2 }'`
runend=`head -2 $result | grep DateRunEnd | awk -F': ?' ' { print $2 }'`
runstart=`head -5 $result | grep DateRunStart | awk -F': ?' ' { print $2 }'`
# truncate the description to 35 chars
if [ ${#description} -gt $_DESC_WIDTH ]; then
description=${description:0:$_DESC_WIDTH}
description=$description"..."
fi
if [ -z $runend ]; then
runend=0
fi
if [ -z $runstart ]; then
runstart=0
fi
((period=$runend - $runstart))
# prefix period if < 9
if [ $period -lt 10 ]; then
period="0$period"
fi
case $passfailed in
"FAILED")
if [ $first -eq 0 ]; then
echo " STATUS : ELAPSED : TESTNAME : TESTDESCRIPTION"
first=1
fi
echo -e "!! $passfailed !! : $period s : $basename : $description"
((failed=$failed + 1))
failed_tests="$failed_tests $basename"
tf="FAILED"
;;
"PASSED")
if [ $TPKG_QUIET -eq 0 ]; then
if [ $first -eq 0 ]; then
echo " STATUS : ELAPSED : TESTNAME : TESTDESCRIPTION"
first=1
fi
echo -e "** $passfailed ** : $period s : $basename : $description"
fi
((passed=$passed + 1))
tp="PASSED"
;;
*)
if [ $first -eq 0 ]; then
echo " STATUS : ELAPSED : TESTNAME : TESTDESCRIPTION"
first=1
fi
echo -e "-- $passfailed -- : $period s : $basename : $description"
((unknown=$unknown + 1))
failed_tests="$failed_tests $basename"
tu="UNKNOWN"
;;
esac
done
((total=$passed + $failed + $unknown))
if [[ $total -eq 0 ]]; then
fper=0
pper=0
uper=0
else
fper=`echo -e "scale=4\n$failed/$total*100" | bc | sed 's/00$//'`
pper=`echo -e "scale=4\n$passed/$total*100" | bc | sed 's/00$//'`
uper=`echo -e "scale=4\n$unknown/$total*100" | bc | sed 's/00$//'`
fi
echo
echo -e "$tp: $passed ($pper %)\t$tf: $failed ($fper %)\t$tu: $unknown ($uper %)"
# for each failed test include the complete result file
# $i is basename
echo
for i in $failed_tests; do
echo --------------- Start Output: $i ------------------
cat result.$i
echo --------------- End Output: $i ------------------
done
cd $NT
if [[ $TPKG_PASS -gt 0 ]]; then
if [[ $passed -lt $TPKG_PASS ]]; then
exit 1
fi
elif [[ $failed -gt 0 ]]; then
exit 1
else
exit 0
fi
}
# clone test1 to test2
function clone() {
$0 extract $test1.tpkg
if [ $? -ne 0 ]; then
err "[fatal] Extract of $test1.tpkg failed. Abort."
exit 1
fi
if [ ! -d "$test1.dir" ]; then
err "[fatal] No $test1.dir directory? Abort."
exit 1
fi
cd $test1.dir
for i in $test1.* ; do
ext=`echo $i | sed s/$test1//`
if [ ! -z "$ext" ]; then
# rename the content of the files too
sed "s/$test1/$test2/g" < $i > $i.$$
mv $i.$$ $i
# rename
mv $i $test2$ext
fi
done
# edit the dsc file too
# update the date
sed "s/^CreationDate:.*/CreationDate: `date`/" < $test2.dsc > $test2.dsc.$$
mv $test2.dsc.$$ $test2.dsc
cd ..
# rename the dir
mv $test1.dir $test2.dir
if [ $TPKG_KEEP -eq 0 ]; then
if [ $TPKG_FORMAT = "dir" ]; then
$0 -d create $test2.tpkg
else
$0 create $test2.tpkg
fi
else
if [ $TPKG_FORMAT = "dir" ]; then
$0 -d -k create $test2.tpkg
else
$0 -k create $test2.tpkg
fi
fi
if [ $? -ne 0 ]; then
err "[warning] Creating of $test2.tpkg failed."
fi
cd $TPKG_CURRENT
}
# try to find the specific cmd
function find_cmd {
which "${i}" >/dev/null
if [ $? -ne 0 ]; then
err "[fatal] CmdDepend \"$i\" could not be satisfied: not found. Abort."
cleanup; exit 1
fi
}
# extract a tpkg to the given dir. The dir must exist already.
function extract_tpkg_to { # <dir>
out "[log] Extracting..."
# tar xfz ${testname}.tpkg -C $1 2>/dev/null
if [ -d "${test_pkg}" ]
then
cp -pr "${test_pkg}" "$1/${testname}.dir"
else
gzip -cd "${test_pkg}" | (cd $1; tar xf -) 2>/dev/null
fi
if [ $? -ne 0 ]; then
err "[fatal] Could not untar archive. Abort."
cd $TPKG_CURRENT; exit 1
fi
# now stuff is in: $1/testname.dir/...
mv $1/${testname}.dir $1/${testname}.dir.tmp$$
mv $1/${testname}.dir.tmp$$/* $1/.
rm -rf $1/${testname}.dir.tmp$$
}
### MAIN
# check the arguments
while getopts ":vhkqb:a:n:lp:df" o
do case "$o" in
b) TPKG_BASE="$OPTARG";;
h) usage; exit 0;;
v) version; exit 0;;
l) TPKG_LOG=1;;
p) TPKG_PRI="$OPTARG";;
a) TPKG_ARGS="$OPTARG";;
q) TPKG_QUIET=1;;
k) TPKG_KEEP=1;;
n) TPKG_PASS=$OPTARG
if [ $TPKG_PASS -eq 0 ]; then
err "[fatal] A null or non numerical value is not valid. Abort."
exit 1
fi
;;
d) TPKG_FORMAT="dir";;
f) TPKG_FORCE=1;;
*) err "[fatal] Unknown option. Abort."; exit 1;;
esac
done
shift $(($OPTIND - 1))
# go to the base dir
if [ ! -d $TPKG_BASE ]; then
err "[fatal] Directory $TPKG_BASE does not exist. Abort"
exit 1
else
cd $TPKG_BASE
fi
# either create a tpkg (ie. call shar) or exe (do a test)
goal=$1
archive=$2
if [ -z "${goal}" ]; then
usage
cd $TPKG_CURRENT; exit 0
fi
# allow short goals
case $goal in
# none for exe - short enough
c) goal="create";;
e) goal="extract";;
t) goal="tmpl";;
f) goal="fake";;
cd) goal="cleandir";;
r) goal="report";;
# none for clean
cl) goal="clone";;
l) goal="list";;
d) goal="desc";;
h) goal="help";;
esac
### REPORT ###
# no extra args required
if [ "${goal}" = "report" ]; then
report;
fi
if [ "${goal}" = "clean" ]; then
cleanreport; exit 0
fi
if [ "${goal}" = "cleandir" ]; then
cleandirs; exit 0
fi
if [ "${goal}" = "clone" ]; then
test1=`basename $2 .tpkg`
test2=`basename $3 .tpkg`;
if [ -z "$test1" -o -z "$test2" ]; then
usage; cd $TPKG_CURRENT; exit 0
fi
clone; exit 0
fi
if [ -z "${archive}" ]; then
out "[log] Defaulting to \`execute'"
archive=$1
goal="exe"
fi
if [ -z "${archive}" ]; then
usage; cd $TPKG_CURRENT; exit 0
fi
testname=`basename "${archive}" .tpkg`
export TPKG_SRCDIR=`dirname "${archive}"`
export TPKG_NAME=${testname}
test_pkg="${TPKG_SRCDIR}/${testname}.tpkg"
dsc_file=$testname.dsc
if [ -z $testname ]; then
err "[fatal] The test package should have a .tpkg extension. Abort."
cd $TPKG_CURRENT; exit 1
fi
if [ "${goal}" = "fake" ]; then
out "[log] Writing .done-$testname file."
write_fake_done; exit 0
fi
if [ $goal = "create" ]; then
### CREATE ###
# get all files with the same basename except those that ends in .tpkg
# check for shar
which tar >/dev/null
if [ $? -ne 0 ]; then
err "[fatal] Tar command not found. Abort."
cd $TPKG_CURRENT; exit 1
fi
# assume there is a dir named $testname.dir
if [ ! -d "${testname}.dir" ]; then
err "[fatal] No $testname.dir directory found. Abort."
cd $TPKG_CURRENT; exit 1
fi
cd $testname.dir
# rm unwanted files
cleanreport # this cd's to $TPKG_CURRENT
cd - >/dev/null # jump back
# tar is smart enough to handle this
cd ../
i=$( ls ${testname}.dir/$testname.* 2>/dev/null )
if [ -z "${i}" ]; then
err "[fatal] No $testname.* files found. Abort."
cd $TPKG_CURRENT; exit 1
fi
# tar --create --file $testname.tpkg --gzip ${testname}.dir
(
if [ -d "${test_pkg}" ]
then
TPKG_FORMAT="dir"
fi
if [ $TPKG_FORMAT = "dir" ]
then
if [ -e "${test_pkg}" ]
then
rm -fr "${test_pkg}"
fi
cp -pr "${testname}.dir" "${test_pkg}" \
|| cp -pr "${testname}.dir" "${test_pkg}" \
|| ( mkdir "${test_pkg}" \
&& ( ( cd "${testname}.dir" ; tar cf - . ) \
| ( cd "${test_pkg}"; tar xf -)
)
)
else
tar -cf - ${testname}.dir | gzip - > "${test_pkg}"
fi
)
if [ $? -ne 0 ]; then
err "[fatal] Archive create error. Abort."
cd $TPKG_CURRENT; exit 1
fi
if [ $TPKG_KEEP -eq 0 ]; then
out "[log] Removing member files"
rm $i
fi
if [ $TPKG_KEEP -eq 0 ]; then
out "[log] Removing directory"
rmdir $testname.dir
fi
cd $TPKG_CURRENT; exit 0
fi
### TMPL ####
# write out a .dsc and touch a .pre/.post/.test
if [ $goal = "tmpl" ]; then
if [ -f $testname.dsc ]; then
err "[fatal] $testname.dsc already exists. Abort."
cd $TPKG_CURRENT; exit 1
fi
# make tmp dir
dir="$testname.dir"
mkdir $dir
if [ ! -d $dir ]; then
err "[fatal] Failure to create a temporary working directory. Abort."
cd $TPKG_CURRENT; exit 1
fi
cd $dir
cat <<TMPL_EOF > $testname.dsc
BaseName: $testname
Version: 1.0
Description: [Put something nice here]
CreationDate: `date`
Maintainer: `grep $LOGNAME /etc/passwd | awk -F: ' { print $5 }' | sed s/,//g`
Category:
Component:
CmdDepends:
Depends:
Help: $testname.help
Pre: $testname.pre
Post: $testname.post
Test: $testname.test
AuxFiles:
Passed:
Failure:
TMPL_EOF
# .help file
echo "Please describe how to use this test." > $testname.help
echo "i.e. tpkg -a ARG exe testname:" >> $testname.help
echo " ARG is used to ..." >> $testname.help
# .test file
echo "# #-- $testname.test --#" > $testname.test
echo "# source the master var file when it's there" >> $testname.test
echo "[ -f $TPKG_VAR_MASTER ] && source $TPKG_VAR_MASTER" >> $testname.test
echo "# use $TPKG_VAR_TEST for in test variable passing" >> $testname.test
echo "[ -f $TPKG_VAR_TEST ] && source $TPKG_VAR_TEST" >> $testname.test
# .post file
echo "# #-- $testname.post --#" > $testname.post
echo "# source the master var file when it's there" >> $testname.post
echo "[ -f $TPKG_VAR_MASTER ] && source $TPKG_VAR_MASTER" >> $testname.post
echo "# source the test var file when it's there" >> $testname.post
echo "[ -f $TPKG_VAR_TEST ] && source $TPKG_VAR_TEST" >> $testname.post
echo "#" >> $testname.post
echo "# do your teardown here" >> $testname.post
# .pre file
echo "# #-- $testname.pre--#" > $testname.pre
echo "# source the master var file when it's there" >> $testname.pre
echo "[ -f $TPKG_VAR_MASTER ] && source $TPKG_VAR_MASTER" >> $testname.pre
echo "# use $TPKG_VAR_TEST for in test variable passing" >> $testname.pre
echo "[ -f $TPKG_VAR_TEST ] && source $TPKG_VAR_TEST" >> $testname.pre
out "[log] created $testname.{dsc, test, help, pre, post}"
out "[log] please create the script(s) and then run: tpkg create $testname.tpkg"
out "[log] created $testname in $dir."
cd $TPKG_CURRENT; exit 0
fi
if [ ! -e $archive ]; then
err "[fatal] Cannot find the test package: $archive. Abort."
cd $TPKG_CURRENT; exit 1
fi
## EXTRACT
if [ $goal = "extract" ]; then
dir="${testname}.dir"
if [ -d $dir ]; then
err "[fatal] Directory $dir already exists. Abort."
cd $TPKG_CURRENT; exit 1
fi
mkdir $dir
if [ ! -d $dir ]; then
err "[fatal] Failure to create $dir directory. Abort."
cd $TPKG_CURRENT; exit 1
fi
extract_tpkg_to $dir
cd $dir
trap cleanup_and_exit INT
# stop here
out "[log] extracted ${test_pkg} $dir."
cd $TPKG_CURRENT; exit 0
fi
## LIST OR DESC OR HELP
if [ $goal = "list" -o $goal = "desc" -o $goal = "help" ]; then
$0 extract "${archive}"
if [ $? -ne 0 ]; then
cd $TPKG_CURRENT; exit 1
fi
cd ${testname}.dir/
case $goal in
list*)
cat *
;;
desc*)
echo -n "$testname: "
cat $testname.dsc | awk -F': ?' '/^Description/ { print $2 }'
;;
help*)
if [ -f $testname.help ]; then
cat $testname.help
else
err "[warning] No help file found."
fi
;;
esac
cd $TPKG_CURRENT
# dir can go
rm -rf ${testname}.dir; exit 0
fi
trap cleanup_and_exit INT
# make a tmp dir during execution
if [ "$goal" != "exe" ]; then
err "[fatal] What do you mean with $goal?. Abort."
cd $TPKG_CURRENT; exit 1
fi
mktempdir "${testname}.XXXXXX"
if [ ! -d $dir ]; then
err "[fatal] Failure to create a temporary working directory. Abort."
cd $TPKG_CURRENT; exit 1
fi
## EXTRACT
extract_tpkg_to $dir
cd $dir
### EXE ###
# extract the information out of the *.dsc files
if [ ! -f $dsc_file ]; then
err "[fatal] Can't locate the description file: $dsc_file. Abort."
cleanup; exit 1
fi
SHELL=`which bash`
if [ -z ${SHELL} ]; then
SHELL=/usr/local/bin/bash
if [ ! -x $SHELL ]; then
err "[fatal] Can't find the bash shell. Abort."
cleanup; exit 1
fi
fi
# check for a .done file
if [ -f "../.done-${testname}" -a $TPKG_FORCE -ne 1 ]; then
out "[log] Found .done-${testname}. Not executing this test."
cleanup; exit 0
fi
# this is the template for .dsc files
# we need to check if all these files also exist TODO
dsc_basename=$testname
function get_field_from_dsc() # fieldname
{
grep "^$1: " $dsc_file | sed -e "s/^$1:[ ]*//" -e "s/[ ]*$//"
}
dsc_version=`get_field_from_dsc Version`
dsc_description=`get_field_from_dsc Description`
dsc_creationdate=`get_field_from_dsc CreationDate`
dsc_category=`get_field_from_dsc Category`
dsc_component=`get_field_from_dsc Component`
dsc_cmddepends=`get_field_from_dsc CmdDepends`
dsc_depends=`get_field_from_dsc Depends`
dsc_maintainer=`get_field_from_dsc Maintainer`
dsc_help=`get_field_from_dsc Help`
dsc_pre=`get_field_from_dsc Pre`
dsc_post=`get_field_from_dsc Post`
dsc_test=`get_field_from_dsc Test`
dsc_aux=`get_field_from_dsc AuxFiles`
dsc_passed=`get_field_from_dsc Passed`
dsc_failure=`get_field_from_dsc Failure`
# consistency check the lot
for i in $dsc_pre $dsc_post $dsc_test $dsc_help; do
if [ ! -z ${i} ]; then
if [ ! -f "${i}" ]; then
err "[fatal] File defined, but ${i} cannot be found. Abort."
cleanup; exit 1
fi
fi
done
for i in $dsc_pre $dsc_post $dsc_test $dsc_help; do
if [ -z ${i} ]; then
if [ -f "${i}" ]; then
err "[fatal] File not defined, but ${i} is included in the package. Abort."
cleanup; exit 1
fi
fi
done
# if we depend on another test to that one first and then return
for deptest in ${dsc_depends}; do
cd .. # go up one dir
out "[log] executing dependency test: ${TPKG_SRCDIR}/${deptest}"
${SHELL} $0 "-b ${TPKG_BASE}" exe "${TPKG_SRCDIR}/${deptest}"
test_result=$?
cd - > /dev/null # back where we belong
if [ $test_result -ne 0 ]; then
err "[fatal] Test depends on $deptest which failed. Abort."
cleanup; exit 1
fi
done
# this enhances the template from above
## Post Processing of some of these variables
# dsc_aux is a comma seperated list of files, max 8 files
i=$( echo $dsc_aux | awk -F', ?' '{ print $1 "\n" $2 "\n" $3 "\n" $4 "\n" \
$5 "\n" $6 "\n" $7 "\n" $8 }' )
dsc_aux_files=($i)
dsc_aux_files_total=${#dsc_aux_files[*]}
# cmd depends
i=$( echo $dsc_cmddepends | awk -F', ?' '{ print $1 "\n" $2 "\n" $3 "\n" $4 "\n" \
$5 "\n" $6 "\n" $7 "\n" $8 }' )
dsc_cmddepends_files=($i)
dsc_cmddepends_files_total=${#dsc_cmddepends_files[*]}
for i in ${dsc_cmddepends_files[*]}; do
find_cmd $i
done
# depends can also be a comma seperated list of package
# TODO
# check is the aux files are also really in the shar
for i in ${dsc_aux_files[*]}; do
if [ ! -f $i ]; then
err "[fatal] Aux. file $i must be in the archive. Abort."
cleanup; exit 1
fi
done
if [ ! -f $dsc_test ]; then
err "[fatal] Can't locate the test script: $dsc_test. Abort."
cleanup; exit 1
fi
### Actual executing of the scripts
tpkg_log "Starting test: '$dsc_basename'"
epoch # run before pre()
echo "BaseName: $dsc_basename" > result.$dsc_basename
echo "Description: $dsc_description" >> result.$dsc_basename
echo "DateRunStart: $epoch " >> result.$dsc_basename
echo "--------------- Test Output ------------------" >> result.$dsc_basename
pre
out "[log] Executing test"
( ${SHELL} $dsc_test ${TPKG_ARGS} 2>&1 ) >> result.$dsc_basename
test_result=$?
epoch # would like to run after post, but that is not possible :-(
if [ $test_result -ne 0 ]; then
err "[warning] Test executed with errors: $test_result."
echo "!! FAILED !! !! FAILED !!" > result.$dsc_basename.tmp
echo "DateRunEnd: $epoch" >> result.$dsc_basename.tmp
err "[log] !! FAILED !!"
cat result.$dsc_basename >> result.$dsc_basename.tmp
echo "exit code: $test_result" >> result.$dsc_basename.tmp
mv result.$dsc_basename.tmp result.$dsc_basename
post;
if [ $TPKG_KEEP -eq 0 ]; then
out "[log] Removing temp directory $dir"
cleanup
else
out "[log] Keeping temp directory $dir"
fi
exit 1
fi
cp -f result.$dsc_basename result.$dsc_basename.$$
failed=-1 # -1 undef, 0 passed, 1 failed
## PASSED
[ ! -z "${dsc_passed}" ] && egrep "${dsc_passed}" result.$dsc_basename.$$ > /dev/null
if [ $? -eq 0 ]; then
err "[log] ** PASSED **"
echo "** PASSED ** ** PASSED **" > result.$dsc_basename.tmp
echo "DateRunEnd: $epoch" >> result.$dsc_basename.tmp
cat result.$dsc_basename >> result.$dsc_basename.tmp
echo "exit code: $test_result" >> result.$dsc_basename.tmp
mv result.$dsc_basename.tmp result.$dsc_basename
write_done
failed=0
fi
## FAILED
[ ! -z "${dsc_failure}" ] && egrep "${dsc_failure}" result.$dsc_basename.$$ > /dev/null
# if not found this actually means PASSED
if [ $? -eq 0 ]; then
err "[log] !! FAILED !!"
echo "!! FAILED !! !! FAILED !!" > result.$dsc_basename.tmp
echo "DateRunEnd: $epoch" >> result.$dsc_basename.tmp
cat result.$dsc_basename >> result.$dsc_basename.tmp
echo "exit code: $test_result" >> result.$dsc_basename.tmp
mv result.$dsc_basename.tmp result.$dsc_basename
failed=1
else
err "[log] ** PASSED **"
echo "** PASSED ** ** PASSED **" > result.$dsc_basename.tmp
echo "DateRunEnd: $epoch" >> result.$dsc_basename.tmp
cat result.$dsc_basename >> result.$dsc_basename.tmp
echo "exit code: $test_result" >> result.$dsc_basename.tmp
mv result.$dsc_basename.tmp result.$dsc_basename
write_done
failed=0
fi
## UNKNOWN
if [ $failed -eq -1 ]; then
# neither failed, not success, unknown
err "[log] -- UNKNOWN --"
echo "-- UNKNOWN -- -- UNKNOWN --" > result.$dsc_basename.tmp
echo "DateRunEnd: $epoch" >> result.$dsc_basename.tmp
cat result.$dsc_basename >> result.$dsc_basename.tmp
echo "exit code: $test_result" >> result.$dsc_basename.tmp
mv result.$dsc_basename.tmp result.$dsc_basename
write_done
failed=1 # not passed
fi
post
if [ $TPKG_KEEP -eq 0 ]; then
out "[log] Removing temp directory $dir"
cleanup
else
out "[log] Keeping temp directory $dir"
fi
exit $failed

View File

@ -116,8 +116,8 @@ struct getdns_upstream;
#define TIMEOUT_FOREVER ((int64_t)-1)
#define ASSERT_UNREACHABLE 0
#define GETDNS_TRANSPORTS_MAX 4
#define GETDNS_UPSTREAM_TRANSPORTS 3
#define GETDNS_TRANSPORTS_MAX 3
#define GETDNS_UPSTREAM_TRANSPORTS 2
/** @}
*/
@ -209,6 +209,14 @@ typedef struct getdns_network_req
/* dnssec status */
int dnssec_status;
/* tsig status:
* GETDNS_DNSSEC_INDETERMINATE means "No TSIG processing"
* GETDNS_DNSSEC_INSECURE means "TSIG sent, validate reply"
* GETDNS_DNSSEC_SECURE means "Validated"
* GETDNS_DNSSEC_BOGUS means "Validation failed"
*/
int tsig_status;
/* For stub resolving */
struct getdns_upstream *upstream;
int fd;
@ -223,10 +231,12 @@ typedef struct getdns_network_req
int edns_maximum_udp_payload_size;
uint16_t max_udp_payload_size;
size_t keepalive_sent;
/* Network requests scheduled to write after me */
struct getdns_network_req *write_queue_tail;
/* Some fields to record info for return_call_debugging */
/* Some fields to record info for return_call_reporting */
uint64_t debug_start_time;
uint64_t debug_end_time;
size_t debug_tls_auth_status;
@ -289,7 +299,7 @@ typedef struct getdns_dns_req {
int edns_cookies;
int edns_client_subnet_private;
uint16_t tls_query_padding_blocksize;
int return_call_debugging;
int return_call_reporting;
/* Internally used by return_validation_chain */
int dnssec_ok_checking_disabled;
@ -379,5 +389,10 @@ getdns_return_t _getdns_network_req_add_upstream_option(getdns_network_req * req
uint16_t code, uint16_t sz, const void* data);
void _getdns_network_req_clear_upstream_options(getdns_network_req * req);
/* Adds TSIG signature (if needed) and returns query length */
size_t _getdns_network_req_add_tsig(getdns_network_req *req);
void _getdns_network_validate_tsig(getdns_network_req *req);
#endif
/* types-internal.h */

Some files were not shown because too many files have changed in this diff Show More