mirror of https://github.com/getdnsapi/getdns.git
Merge branch 'develop' into features/windows-support
This commit is contained in:
commit
caba5f19d5
|
@ -55,3 +55,4 @@ m4/ltversion.m4
|
|||
m4/lt~obsolete.m4
|
||||
src/config.h.in
|
||||
build/
|
||||
getdns.pc
|
||||
|
|
24
.travis.yml
24
.travis.yml
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
12
Makefile.in
12
Makefile.in
|
@ -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 $@
|
||||
|
||||
|
|
82
configure.ac
82
configure.ac
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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}
|
|
@ -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();
|
||||
|
|
|
@ -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>
|
||||
|
|
105
src/Makefile.in
105
src/Makefile.in
|
@ -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
|
||||
|
|
144
src/const-info.c
144
src/const-info.c
|
@ -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 },
|
||||
};
|
||||
|
|
506
src/context.c
506
src/context.c
|
@ -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, ©) != 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
|
||||
|
|
|
@ -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,
|
||||
|
|
366
src/convert.c
366
src/convert.c
|
@ -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 */
|
||||
|
|
|
@ -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 */
|
|
@ -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 */
|
23
src/dict.c
23
src/dict.c
|
@ -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 ||
|
||||
|
|
|
@ -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 */
|
||||
|
|
268
src/dnssec.c
268
src/dnssec.c
|
@ -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;
|
||||
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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()"
|
||||
/** @}
|
||||
*/
|
||||
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
33
src/list.c
33
src/list.c
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
};
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
605
src/rr-dict.c
605
src/rr-dict.c
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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
|
||||
|
|
409
src/stub.c
409
src/stub.c
|
@ -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);
|
||||
|
|
|
@ -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 \
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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")
|
||||
|
||||
|
|
|
@ -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:
|
|
@ -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
|
|
@ -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
|
|
@ -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:
|
|
@ -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
|
|
@ -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
|
|
@ -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:
|
|
@ -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"
|
|
@ -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
|
|
@ -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:
|
|
@ -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
|
|
@ -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:
|
|
@ -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
|
|
@ -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:
|
|
@ -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
|
|
@ -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:
|
|
@ -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
|
|
@ -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:
|
|
@ -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
|
|
@ -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:
|
|
@ -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
|
|
@ -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
|
|
@ -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:
|
|
@ -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
|
|
@ -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:
|
|
@ -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
|
|
@ -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:
|
|
@ -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
|
|
@ -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 $@ $<
|
||||
|
|
@ -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:
|
|
@ -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
|
|
@ -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"
|
|
@ -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 $@ $<
|
||||
|
|
@ -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);
|
||||
}
|
|
@ -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
|
@ -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.
|
|
@ -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"
|
|
@ -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
|
|
@ -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
|
|
@ -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:
|
|
@ -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
|
|
@ -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
|
|
@ -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:
|
|
@ -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}
|
|
@ -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:
|
|
@ -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
|
|
@ -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:
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
||||
|
|
@ -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
|
|
@ -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
Loading…
Reference in New Issue