Merge branch 'develop'

This commit is contained in:
Willem Toorop 2017-12-22 12:43:06 +01:00
commit fe7d6678cf
29 changed files with 919 additions and 304 deletions

View File

@ -21,4 +21,4 @@ script:
- mkdir tests - mkdir tests
- cd tests - cd tests
- ../src/test/tpkg/run-all.sh - ../src/test/tpkg/run-all.sh
# - ../src/test/tpkg/run-one.sh 400-static-analysis -V # - ../src/test/tpkg/run-one.sh 225-stub-only-valgrind-checks

View File

@ -1,3 +1,36 @@
* 2017-12-21: Version 1.3.0
* Bugfix #300: Detect dnsmasq and skip unit test that fails with it.
Thanks Tim Rühsen and Konomi Kitten
* Specify default available cipher suites for authenticated TLS
upstreams with getdns_context_set_tls_ciphers_list()
An upstream specific available cipher suite may also be given
with the tls_cipher_list setting in the upstream dict with
getdns_context_set_upstream_recursive_servers()
* PR #366: Add support for TLS 1.3 and Chacha20-Poly1305
Thanks Pascal Ernster
* Bugfix #356: Do Zero configuration DNSSEC meta queries over on the
context configured upstreams. Thanks Andreas Schulze
* Report default extension settings with
getdns_context_get_api_information()
* Specify locations at which CA certificates for verification purposes
are located: getdns_context_set_tls_ca_path()
getdns_context_set_tls_ca_file()
* getdns_context_set_resolvconf() function to initialize a context
upstreams and suffices with a resolv.conf file.
getdns_context_get_resolvconf() to get the file used to initialize
the context's upstreams and suffixes.
getdns_context_set_hosts() function to initialize a context's
LOCALNAMES namespace.
getdns_context_get_hosts() function to get the file used to initialize
the context's LOCALNAMES namespace.
* get which version of OpenSSL was used at build time and at run time
when available with getdns_context_get_api_information()
* GETDNS_RETURN_IO_ERROR return error code
* Bugfix #359: edns_client_subnet_private should set family
Thanks Daniel Areiza & Andreas Schulze
* Bugfix getdnsapi/stubby#34: Segfault issue with native DNSSEC
validation. Thanks Bruno Pagani
* 2017-11-11: Version 1.2.1 * 2017-11-11: Version 1.2.1
* Handle more I/O error cases. Also, when an I/O error does occur, * Handle more I/O error cases. Also, when an I/O error does occur,
never stop listening (with servers), and never stop listening (with servers), and

View File

@ -253,7 +253,7 @@ $(distdir):
cp $(srcdir)/src/tools/Makefile.in $(distdir)/src/tools cp $(srcdir)/src/tools/Makefile.in $(distdir)/src/tools
cp $(srcdir)/src/tools/*.[ch] $(distdir)/src/tools cp $(srcdir)/src/tools/*.[ch] $(distdir)/src/tools
cp $(srcdir)/stubby/stubby.yml.example $(distdir)/stubby cp $(srcdir)/stubby/stubby.yml.example $(distdir)/stubby
cp $(srcdir)/stubby/stubby-setdns-macos.sh $(distdir)/stubby cp $(srcdir)/stubby/macos/stubby-setdns-macos.sh $(distdir)/stubby
cp $(srcdir)/stubby/src/*.[ch] $(distdir)/stubby/src cp $(srcdir)/stubby/src/*.[ch] $(distdir)/stubby/src
cp $(srcdir)/stubby/src/yaml/*.[ch] $(distdir)/stubby/src/yaml cp $(srcdir)/stubby/src/yaml/*.[ch] $(distdir)/stubby/src/yaml
cp $(srcdir)/stubby/COPYING $(distdir)/stubby cp $(srcdir)/stubby/COPYING $(distdir)/stubby

View File

@ -36,7 +36,7 @@ sinclude(./m4/acx_getaddrinfo.m4)
sinclude(./m4/ax_check_compile_flag.m4) sinclude(./m4/ax_check_compile_flag.m4)
sinclude(./m4/pkg.m4) sinclude(./m4/pkg.m4)
AC_INIT([getdns], [1.2.1], [team@getdnsapi.net], [getdns], [https://getdnsapi.net]) AC_INIT([getdns], [1.3.0], [team@getdnsapi.net], [getdns], [https://getdnsapi.net])
# Autoconf 2.70 will have set up runstatedir. 2.69 is frequently (Debian) # Autoconf 2.70 will have set up runstatedir. 2.69 is frequently (Debian)
# patched to do the same, but frequently (MacOS) not. So add a with option # patched to do the same, but frequently (MacOS) not. So add a with option
@ -62,7 +62,7 @@ AC_ARG_WITH([current-date],
[CURRENT_DATE="`date -u +%Y-%m-%dT%H:%M:%SZ`"]) [CURRENT_DATE="`date -u +%Y-%m-%dT%H:%M:%SZ`"])
AC_SUBST(GETDNS_VERSION, ["AC_PACKAGE_VERSION$RELEASE_CANDIDATE"]) AC_SUBST(GETDNS_VERSION, ["AC_PACKAGE_VERSION$RELEASE_CANDIDATE"])
AC_SUBST(GETDNS_NUMERIC_VERSION, [0x01020100]) AC_SUBST(GETDNS_NUMERIC_VERSION, [0x01030000])
AC_SUBST(API_VERSION, ["December 2015"]) AC_SUBST(API_VERSION, ["December 2015"])
AC_SUBST(API_NUMERIC_VERSION, [0x07df0c00]) AC_SUBST(API_NUMERIC_VERSION, [0x07df0c00])
GETDNS_COMPILATION_COMMENT="AC_PACKAGE_NAME $GETDNS_VERSION configured on $CURRENT_DATE for the $API_VERSION version of the API" GETDNS_COMPILATION_COMMENT="AC_PACKAGE_NAME $GETDNS_VERSION configured on $CURRENT_DATE for the $API_VERSION version of the API"
@ -98,9 +98,10 @@ GETDNS_COMPILATION_COMMENT="AC_PACKAGE_NAME $GETDNS_VERSION configured on $CURRE
# getdns-1.1.2 had libversion 7:0:1 # getdns-1.1.2 had libversion 7:0:1
# getdns-1.1.3 had libversion 7:1:1 # getdns-1.1.3 had libversion 7:1:1
# getdns-1.2.0 had libversion 8:0:2 # getdns-1.2.0 had libversion 8:0:2
# getdns-1.2.1 has libversion 8:1:2 # getdns-1.2.1 had libversion 8:1:2
# getdns-1.3.0 has libversion 9:0:3
# #
GETDNS_LIBVERSION=8:1:2 GETDNS_LIBVERSION=9:0:3
AC_SUBST(GETDNS_COMPILATION_COMMENT) AC_SUBST(GETDNS_COMPILATION_COMMENT)
AC_SUBST(GETDNS_LIBVERSION) AC_SUBST(GETDNS_LIBVERSION)
@ -265,7 +266,7 @@ esac
DEFAULT_EVENTLOOP=select_eventloop DEFAULT_EVENTLOOP=select_eventloop
AC_CHECK_HEADERS([signal.h sys/poll.h poll.h sys/resource.h sys/types.h],,, [AC_INCLUDES_DEFAULT]) AC_CHECK_HEADERS([signal.h sys/poll.h poll.h sys/resource.h sys/types.h sys/stat.h],,, [AC_INCLUDES_DEFAULT])
AC_ARG_ENABLE(poll-eventloop, AC_HELP_STRING([--disable-poll-eventloop], [Disable default eventloop based on poll (default=enabled if available)])) AC_ARG_ENABLE(poll-eventloop, AC_HELP_STRING([--disable-poll-eventloop], [Disable default eventloop based on poll (default=enabled if available)]))
case "$enable_poll_eventloop" in case "$enable_poll_eventloop" in
no) no)
@ -345,6 +346,22 @@ AC_CHECK_FUNCS([strptime],[AC_CHECK_STRPTIME_WORKS],[AC_LIBOBJ([strptime])])
AC_CHECK_HEADERS([windows.h winsock.h stdio.h winsock2.h ws2tcpip.h],,, [AC_INCLUDES_DEFAULT]) AC_CHECK_HEADERS([windows.h winsock.h stdio.h winsock2.h ws2tcpip.h],,, [AC_INCLUDES_DEFAULT])
ACX_CHECK_GETADDRINFO_WITH_INCLUDES ACX_CHECK_GETADDRINFO_WITH_INCLUDES
AC_ARG_WITH(resolvconf, AS_HELP_STRING([--with-resolvconf=PATH],
[Set the resolver configuration file path. Defaults to /etc/resolv.conf or values retrieved via GetNetworkParams() on Windows]),
[], [withval="/etc/resolv.conf"])
AC_DEFINE_UNQUOTED([GETDNS_FN_RESOLVCONF], ["$withval"], [Path to resolver configuration file])
AC_ARG_WITH(hosts, AS_HELP_STRING([--with-hosts=PATH],
[Set the static table lookup for hostnames path. Defaults to /etc/hosts or C:\Windows\System32\Drivers\etc\hosts on Windows]),
[], [
if test "$USE_WINSOCK" = 1; then
withval="C:\\\\Windows\\\\System32\\\\Drivers\\\\etc\\\\hosts"
else
withval="/etc/hosts"
fi
])
AC_DEFINE_UNQUOTED([GETDNS_FN_HOSTS], ["$withval"], [Path to static table lookup for hostnames])
AC_ARG_WITH(fd-setsize, AS_HELP_STRING([--with-fd-setsize=size], AC_ARG_WITH(fd-setsize, AS_HELP_STRING([--with-fd-setsize=size],
[Set maximum file descriptor number that can be used by select]), [Set maximum file descriptor number that can be used by select]),
[], [withval="no"]) [], [withval="no"])
@ -391,7 +408,7 @@ fi
AC_CHECK_HEADERS([openssl/conf.h],,, [AC_INCLUDES_DEFAULT]) AC_CHECK_HEADERS([openssl/conf.h],,, [AC_INCLUDES_DEFAULT])
AC_CHECK_HEADERS([openssl/engine.h],,, [AC_INCLUDES_DEFAULT]) AC_CHECK_HEADERS([openssl/engine.h],,, [AC_INCLUDES_DEFAULT])
AC_CHECK_HEADERS([openssl/bn.h openssl/rsa.h openssl/dsa.h],,, [AC_INCLUDES_DEFAULT]) AC_CHECK_HEADERS([openssl/bn.h openssl/rsa.h openssl/dsa.h],,, [AC_INCLUDES_DEFAULT])
AC_CHECK_FUNCS([OPENSSL_config EVP_md5 EVP_sha1 EVP_sha224 EVP_sha256 EVP_sha384 EVP_sha512 FIPS_mode ENGINE_load_cryptodev EVP_PKEY_keygen ECDSA_SIG_get0 EVP_MD_CTX_new EVP_PKEY_base_id HMAC_CTX_new HMAC_CTX_free TLS_client_method DSA_SIG_set0 EVP_dss1 EVP_DigestVerify SSL_CTX_set_min_proto_version]) AC_CHECK_FUNCS([OPENSSL_config EVP_md5 EVP_sha1 EVP_sha224 EVP_sha256 EVP_sha384 EVP_sha512 FIPS_mode ENGINE_load_cryptodev EVP_PKEY_keygen ECDSA_SIG_get0 EVP_MD_CTX_new EVP_PKEY_base_id HMAC_CTX_new HMAC_CTX_free TLS_client_method DSA_SIG_set0 EVP_dss1 EVP_DigestVerify SSL_CTX_set_min_proto_version OpenSSL_version_num OpenSSL_version])
AC_CHECK_DECLS([SSL_COMP_get_compression_methods,sk_SSL_COMP_pop_free,SSL_CTX_set_ecdh_auto], [], [], [ AC_CHECK_DECLS([SSL_COMP_get_compression_methods,sk_SSL_COMP_pop_free,SSL_CTX_set_ecdh_auto], [], [], [
AC_INCLUDES_DEFAULT AC_INCLUDES_DEFAULT
#ifdef HAVE_OPENSSL_ERR_H #ifdef HAVE_OPENSSL_ERR_H
@ -1500,6 +1517,10 @@ static inline int _gldns_custom_vsnprintf(char *str, size_t size, const char *fo
#include <sys/types.h> #include <sys/types.h>
#endif #endif
#ifdef HAVE_SYS_STAT_H
#include <sys/stat.h>
#endif
#ifdef HAVE_NETINET_IN_H #ifdef HAVE_NETINET_IN_H
#include <netinet/in.h> #include <netinet/in.h>
#endif #endif

View File

@ -208,9 +208,9 @@ install-stubby-files-unix: $(stubbysrcdir)/stubby.yml.example
test -f $(DESTDIR)$(stubbyconfdir)/stubby.yml || \ test -f $(DESTDIR)$(stubbyconfdir)/stubby.yml || \
$(INSTALL_DATA) $(stubbysrcdir)/stubby.yml.example $(DESTDIR)$(stubbyconfdir)/stubby.yml $(INSTALL_DATA) $(stubbysrcdir)/stubby.yml.example $(DESTDIR)$(stubbyconfdir)/stubby.yml
install-stubby-files-macos: $(stubbysrcdir)/stubby-setdns-macos.sh install-stubby-files-unix install-stubby-files-macos: $(stubbysrcdir)/macos/stubby-setdns-macos.sh install-stubby-files-unix
$(INSTALL) -m 755 -d $(DESTDIR)$(sbindir) $(INSTALL) -m 755 -d $(DESTDIR)$(sbindir)
$(INSTALL) -m 755 $(stubbysrcdir)/stubby-setdns-macos.sh $(DESTDIR)$(sbindir) $(INSTALL) -m 755 $(stubbysrcdir)/macos/stubby-setdns-macos.sh $(DESTDIR)$(sbindir)
stubby.yml.windows: $(stubbysrcdir)/stubby.yml.example stubby.yml.windows: $(stubbysrcdir)/stubby.yml.example
awk "{sub(/$$/,\"\r\")}1" $(stubbysrcdir)/stubby.yml.example > stubby.yml.windows awk "{sub(/$$/,\"\r\")}1" $(stubbysrcdir)/stubby.yml.example > stubby.yml.windows

View File

@ -1557,44 +1557,13 @@ void _getdns_start_fetching_ta(getdns_context *context, getdns_eventloop *loop)
DEBUG_ANCHOR("%s on the %ssynchronous loop\n", __FUNC__, DEBUG_ANCHOR("%s on the %ssynchronous loop\n", __FUNC__,
loop == &context->sync_eventloop.loop ? "" : "a"); loop == &context->sync_eventloop.loop ? "" : "a");
while (!context->sys_ctxt) { /* Used as breakable if. Never repeats. */
if ((r = getdns_context_create_with_extended_memory_functions(
&context->sys_ctxt, 1, context->mf.mf_arg,
context->mf.mf.ext.malloc, context->mf.mf.ext.realloc,
context->mf.mf.ext.free)))
DEBUG_ANCHOR("Could not create system context: %s\n"
, getdns_get_errorstr_by_id(r));
else if ((r = getdns_context_set_eventloop(
context->sys_ctxt, loop)))
DEBUG_ANCHOR("Could not configure %ssynchronous loop "
"with system context: %s\n"
, ( loop == &context->sync_eventloop.loop
? "" : "a" )
, getdns_get_errorstr_by_id(r));
else if ((r = getdns_context_set_resolution_type(
context->sys_ctxt, GETDNS_RESOLUTION_STUB)))
DEBUG_ANCHOR("Could not configure system context for "
"stub resolver: %s\n"
, getdns_get_errorstr_by_id(r));
else
break;
getdns_context_destroy(context->sys_ctxt);
context->sys_ctxt = NULL;
DEBUG_ANCHOR("Fatal error fetching trust anchor: "
"missing system context\n");
context->trust_anchors_source = GETDNS_TASRC_FAILED;
_getdns_ta_notify_dnsreqs(context);
return;
}
scheduled = 0; scheduled = 0;
#if 1 #if 1
context->a.state = TAS_LOOKUP_ADDRESSES; context->a.state = TAS_LOOKUP_ADDRESSES;
if ((r = _getdns_general_loop(context->sys_ctxt, loop, if ((r = _getdns_general_loop(context, loop,
tas_hostname, GETDNS_RRTYPE_A, NULL, context, tas_hostname, GETDNS_RRTYPE_A,
&context->a.req, NULL, _tas_hostname_lookup_cb))) { no_dnssec_checking_disabled_opportunistic,
context, &context->a.req, NULL, _tas_hostname_lookup_cb))) {
DEBUG_ANCHOR("Error scheduling A lookup for %s: %s\n" DEBUG_ANCHOR("Error scheduling A lookup for %s: %s\n"
, tas_hostname, getdns_get_errorstr_by_id(r)); , tas_hostname, getdns_get_errorstr_by_id(r));
} else } else
@ -1603,9 +1572,10 @@ void _getdns_start_fetching_ta(getdns_context *context, getdns_eventloop *loop)
#if 1 #if 1
context->aaaa.state = TAS_LOOKUP_ADDRESSES; context->aaaa.state = TAS_LOOKUP_ADDRESSES;
if ((r = _getdns_general_loop(context->sys_ctxt, loop, if ((r = _getdns_general_loop(context, loop,
tas_hostname, GETDNS_RRTYPE_AAAA, NULL, context, tas_hostname, GETDNS_RRTYPE_AAAA,
&context->aaaa.req, NULL, _tas_hostname_lookup_cb))) { no_dnssec_checking_disabled_opportunistic,
context, &context->aaaa.req, NULL, _tas_hostname_lookup_cb))) {
DEBUG_ANCHOR("Error scheduling AAAA lookup for %s: %s\n" DEBUG_ANCHOR("Error scheduling AAAA lookup for %s: %s\n"
, tas_hostname, getdns_get_errorstr_by_id(r)); , tas_hostname, getdns_get_errorstr_by_id(r));
} else } else

View File

@ -30,6 +30,7 @@ static struct const_info consts_info[] = {
{ 310, "GETDNS_RETURN_MEMORY_ERROR", GETDNS_RETURN_MEMORY_ERROR_TEXT }, { 310, "GETDNS_RETURN_MEMORY_ERROR", GETDNS_RETURN_MEMORY_ERROR_TEXT },
{ 311, "GETDNS_RETURN_INVALID_PARAMETER", GETDNS_RETURN_INVALID_PARAMETER_TEXT }, { 311, "GETDNS_RETURN_INVALID_PARAMETER", GETDNS_RETURN_INVALID_PARAMETER_TEXT },
{ 312, "GETDNS_RETURN_NOT_IMPLEMENTED", GETDNS_RETURN_NOT_IMPLEMENTED_TEXT }, { 312, "GETDNS_RETURN_NOT_IMPLEMENTED", GETDNS_RETURN_NOT_IMPLEMENTED_TEXT },
{ 397, "GETDNS_RETURN_IO_ERROR", GETDNS_RETURN_IO_ERROR_TEXT },
{ 398, "GETDNS_RETURN_NO_UPSTREAM_AVAILABLE", GETDNS_RETURN_NO_UPSTREAM_AVAILABLE_TEXT }, { 398, "GETDNS_RETURN_NO_UPSTREAM_AVAILABLE", GETDNS_RETURN_NO_UPSTREAM_AVAILABLE_TEXT },
{ 399, "GETDNS_RETURN_NEED_MORE_SPACE", GETDNS_RETURN_NEED_MORE_SPACE_TEXT }, { 399, "GETDNS_RETURN_NEED_MORE_SPACE", GETDNS_RETURN_NEED_MORE_SPACE_TEXT },
{ 400, "GETDNS_DNSSEC_SECURE", GETDNS_DNSSEC_SECURE_TEXT }, { 400, "GETDNS_DNSSEC_SECURE", GETDNS_DNSSEC_SECURE_TEXT },
@ -86,6 +87,11 @@ static struct const_info consts_info[] = {
{ 626, "GETDNS_CONTEXT_CODE_TRUST_ANCHORS_VERIFY_CA", GETDNS_CONTEXT_CODE_TRUST_ANCHORS_VERIFY_CA_TEXT }, { 626, "GETDNS_CONTEXT_CODE_TRUST_ANCHORS_VERIFY_CA", GETDNS_CONTEXT_CODE_TRUST_ANCHORS_VERIFY_CA_TEXT },
{ 627, "GETDNS_CONTEXT_CODE_TRUST_ANCHORS_VERIFY_EMAIL", GETDNS_CONTEXT_CODE_TRUST_ANCHORS_VERIFY_EMAIL_TEXT }, { 627, "GETDNS_CONTEXT_CODE_TRUST_ANCHORS_VERIFY_EMAIL", GETDNS_CONTEXT_CODE_TRUST_ANCHORS_VERIFY_EMAIL_TEXT },
{ 628, "GETDNS_CONTEXT_CODE_APPDATA_DIR", GETDNS_CONTEXT_CODE_APPDATA_DIR_TEXT }, { 628, "GETDNS_CONTEXT_CODE_APPDATA_DIR", GETDNS_CONTEXT_CODE_APPDATA_DIR_TEXT },
{ 629, "GETDNS_CONTEXT_CODE_RESOLVCONF", GETDNS_CONTEXT_CODE_RESOLVCONF_TEXT },
{ 630, "GETDNS_CONTEXT_CODE_HOSTS", GETDNS_CONTEXT_CODE_HOSTS_TEXT },
{ 631, "GETDNS_CONTEXT_CODE_TLS_CA_PATH", GETDNS_CONTEXT_CODE_TLS_CA_PATH_TEXT },
{ 632, "GETDNS_CONTEXT_CODE_TLS_CA_FILE", GETDNS_CONTEXT_CODE_TLS_CA_FILE_TEXT },
{ 633, "GETDNS_CONTEXT_CODE_TLS_CIPHER_LIST", GETDNS_CONTEXT_CODE_TLS_CIPHER_LIST_TEXT },
{ 700, "GETDNS_CALLBACK_COMPLETE", GETDNS_CALLBACK_COMPLETE_TEXT }, { 700, "GETDNS_CALLBACK_COMPLETE", GETDNS_CALLBACK_COMPLETE_TEXT },
{ 701, "GETDNS_CALLBACK_CANCEL", GETDNS_CALLBACK_CANCEL_TEXT }, { 701, "GETDNS_CALLBACK_CANCEL", GETDNS_CALLBACK_CANCEL_TEXT },
{ 702, "GETDNS_CALLBACK_TIMEOUT", GETDNS_CALLBACK_TIMEOUT_TEXT }, { 702, "GETDNS_CALLBACK_TIMEOUT", GETDNS_CALLBACK_TIMEOUT_TEXT },
@ -166,17 +172,22 @@ static struct const_name_info consts_name_info[] = {
{ "GETDNS_CONTEXT_CODE_EDNS_MAXIMUM_UDP_PAYLOAD_SIZE", 610 }, { "GETDNS_CONTEXT_CODE_EDNS_MAXIMUM_UDP_PAYLOAD_SIZE", 610 },
{ "GETDNS_CONTEXT_CODE_EDNS_VERSION", 612 }, { "GETDNS_CONTEXT_CODE_EDNS_VERSION", 612 },
{ "GETDNS_CONTEXT_CODE_FOLLOW_REDIRECTS", 602 }, { "GETDNS_CONTEXT_CODE_FOLLOW_REDIRECTS", 602 },
{ "GETDNS_CONTEXT_CODE_HOSTS", 630 },
{ "GETDNS_CONTEXT_CODE_IDLE_TIMEOUT", 617 }, { "GETDNS_CONTEXT_CODE_IDLE_TIMEOUT", 617 },
{ "GETDNS_CONTEXT_CODE_LIMIT_OUTSTANDING_QUERIES", 606 }, { "GETDNS_CONTEXT_CODE_LIMIT_OUTSTANDING_QUERIES", 606 },
{ "GETDNS_CONTEXT_CODE_MEMORY_FUNCTIONS", 615 }, { "GETDNS_CONTEXT_CODE_MEMORY_FUNCTIONS", 615 },
{ "GETDNS_CONTEXT_CODE_NAMESPACES", 600 }, { "GETDNS_CONTEXT_CODE_NAMESPACES", 600 },
{ "GETDNS_CONTEXT_CODE_PUBKEY_PINSET", 621 }, { "GETDNS_CONTEXT_CODE_PUBKEY_PINSET", 621 },
{ "GETDNS_CONTEXT_CODE_RESOLUTION_TYPE", 601 }, { "GETDNS_CONTEXT_CODE_RESOLUTION_TYPE", 601 },
{ "GETDNS_CONTEXT_CODE_RESOLVCONF", 629 },
{ "GETDNS_CONTEXT_CODE_ROUND_ROBIN_UPSTREAMS", 622 }, { "GETDNS_CONTEXT_CODE_ROUND_ROBIN_UPSTREAMS", 622 },
{ "GETDNS_CONTEXT_CODE_SUFFIX", 608 }, { "GETDNS_CONTEXT_CODE_SUFFIX", 608 },
{ "GETDNS_CONTEXT_CODE_TIMEOUT", 616 }, { "GETDNS_CONTEXT_CODE_TIMEOUT", 616 },
{ "GETDNS_CONTEXT_CODE_TLS_AUTHENTICATION", 618 }, { "GETDNS_CONTEXT_CODE_TLS_AUTHENTICATION", 618 },
{ "GETDNS_CONTEXT_CODE_TLS_BACKOFF_TIME", 623 }, { "GETDNS_CONTEXT_CODE_TLS_BACKOFF_TIME", 623 },
{ "GETDNS_CONTEXT_CODE_TLS_CA_FILE", 632 },
{ "GETDNS_CONTEXT_CODE_TLS_CA_PATH", 631 },
{ "GETDNS_CONTEXT_CODE_TLS_CIPHER_LIST", 633 },
{ "GETDNS_CONTEXT_CODE_TLS_CONNECTION_RETRIES", 624 }, { "GETDNS_CONTEXT_CODE_TLS_CONNECTION_RETRIES", 624 },
{ "GETDNS_CONTEXT_CODE_TLS_QUERY_PADDING_BLOCKSIZE", 620 }, { "GETDNS_CONTEXT_CODE_TLS_QUERY_PADDING_BLOCKSIZE", 620 },
{ "GETDNS_CONTEXT_CODE_TRUST_ANCHORS_URL", 625 }, { "GETDNS_CONTEXT_CODE_TRUST_ANCHORS_URL", 625 },
@ -248,6 +259,7 @@ static struct const_name_info consts_name_info[] = {
{ "GETDNS_RETURN_GENERIC_ERROR", 1 }, { "GETDNS_RETURN_GENERIC_ERROR", 1 },
{ "GETDNS_RETURN_GOOD", 0 }, { "GETDNS_RETURN_GOOD", 0 },
{ "GETDNS_RETURN_INVALID_PARAMETER", 311 }, { "GETDNS_RETURN_INVALID_PARAMETER", 311 },
{ "GETDNS_RETURN_IO_ERROR", 397 },
{ "GETDNS_RETURN_MEMORY_ERROR", 310 }, { "GETDNS_RETURN_MEMORY_ERROR", 310 },
{ "GETDNS_RETURN_NEED_MORE_SPACE", 399 }, { "GETDNS_RETURN_NEED_MORE_SPACE", 399 },
{ "GETDNS_RETURN_NOT_IMPLEMENTED", 312 }, { "GETDNS_RETURN_NOT_IMPLEMENTED", 312 },

View File

@ -57,6 +57,9 @@ typedef unsigned short in_port_t;
#include <shlobj.h> #include <shlobj.h>
#endif #endif
#include <openssl/opensslv.h>
#include <openssl/crypto.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <string.h> #include <string.h>
#include <stdio.h> #include <stdio.h>
@ -162,6 +165,17 @@ static void set_ub_dnssec_allowed_skew(struct getdns_context*, uint32_t);
/* Stuff to make it compile pedantically */ /* Stuff to make it compile pedantically */
#define RETURN_IF_NULL(ptr, code) if(ptr == NULL) return code; #define RETURN_IF_NULL(ptr, code) if(ptr == NULL) return code;
static char *
_getdns_strdup2(const struct mem_funcs *mfs, const getdns_bindata *s)
{
char *r;
if (!s || !(r = GETDNS_XMALLOC(*mfs, char, s->size + 1)))
return NULL;
else {
r[s->size] = '\0';
return memcpy(r, s, s->size);
}
}
#ifdef USE_WINSOCK #ifdef USE_WINSOCK
/* For windows, the CA trust store is not read by openssl. /* For windows, the CA trust store is not read by openssl.
@ -495,8 +509,45 @@ str_addr_dict(getdns_context *context, const char *str)
return address; return address;
} }
static void /**
create_local_hosts(getdns_context *context) * check a file for changes since the last check
* and refresh the current data if changes are detected
* @param context pointer to a previously created context to be used for this call
* @param fchg file to check
* @returns changes as OR'd list of GETDNS_FCHG_* values
* @returns GETDNS_FCHG_NONE if no changes
* @returns GETDNS_FCHG_ERRORS if problems (see fchg->errors for details)
*/
static int
_getdns_filechg_check(struct filechg *fchg)
{
struct stat finfo;
if(fchg == NULL)
return 0;
fchg->errors = GETDNS_FCHG_NOERROR;
fchg->changes = GETDNS_FCHG_NOCHANGES;
if(stat(fchg->fn, &finfo) != 0) {
fchg->errors = errno;
return GETDNS_FCHG_ERRORS;
}
/* we want to consider a file that previously returned error for stat() as a
change */
if(fchg->prevstat.st_mtime != finfo.st_mtime)
fchg->changes |= GETDNS_FCHG_MTIME;
if(fchg->prevstat.st_ctime != finfo.st_ctime)
fchg->changes |= GETDNS_FCHG_CTIME;
fchg->prevstat = finfo;
return fchg->changes;
} /* filechg */
getdns_return_t
getdns_context_set_hosts(getdns_context *context, const char *hosts)
{ {
/* enough space in buf for longest allowed domain name */ /* enough space in buf for longest allowed domain name */
char buf[1024]; char buf[1024];
@ -505,11 +556,21 @@ create_local_hosts(getdns_context *context)
int start_of_line = 1; int start_of_line = 1;
getdns_dict *address = NULL; getdns_dict *address = NULL;
#ifdef USE_WINSOCK if (!context || !hosts)
in = fopen("c:\\WINDOWS\\system32\\drivers\\etc\\hosts", "r"); return GETDNS_RETURN_INVALID_PARAMETER;
#else
in = fopen("/etc/hosts", "r"); if (!(in = fopen(hosts, "r")))
#endif return GETDNS_RETURN_IO_ERROR;
(void)strlcpy(context->fchg_hosts.fn, hosts, _GETDNS_PATH_MAX);
(void) memset(&context->fchg_hosts.prevstat, 0, sizeof(struct stat));
context->fchg_hosts.changes = GETDNS_FCHG_NOCHANGES;
context->fchg_hosts.errors = GETDNS_FCHG_NOERROR;
(void) _getdns_filechg_check(&context->fchg_hosts);
_getdns_traverse_postorder(&context->local_hosts,
destroy_local_host, context);
_getdns_rbtree_init(&context->local_hosts, local_host_cmp);
while (fgets(pos, (int)(sizeof(buf) - (pos - buf)), in)) { while (fgets(pos, (int)(sizeof(buf) - (pos - buf)), in)) {
pos = buf; pos = buf;
/* Break out of for to read more */ /* Break out of for to read more */
@ -589,59 +650,19 @@ read_more: ;
address = NULL; address = NULL;
getdns_dict_destroy(address); getdns_dict_destroy(address);
} }
return GETDNS_RETURN_GOOD;
} }
/** getdns_return_t
* check a file for changes since the last check getdns_context_get_hosts(getdns_context *context, const char **hosts)
* and refresh the current data if changes are detected
* @param context pointer to a previously created context to be used for this call
* @param fchg file to check
* @returns changes as OR'd list of GETDNS_FCHG_* values
* @returns GETDNS_FCHG_NONE if no changes
* @returns GETDNS_FCHG_ERRORS if problems (see fchg->errors for details)
*/
int
_getdns_filechg_check(struct getdns_context *context, struct filechg *fchg)
{ {
struct stat *finfo; if (!context || !hosts)
return GETDNS_RETURN_INVALID_PARAMETER;
if(fchg == NULL) *hosts = *context->fchg_hosts.fn ? context->fchg_hosts.fn : NULL;
return 0; return GETDNS_RETURN_GOOD;
}
fchg->errors = GETDNS_FCHG_NOERROR;
fchg->changes = GETDNS_FCHG_NOCHANGES;
finfo = GETDNS_MALLOC(context->my_mf, struct stat);
if(finfo == NULL)
{
fchg->errors = errno;
return GETDNS_FCHG_ERRORS;
}
if(stat(fchg->fn, finfo) != 0)
{
GETDNS_FREE(context->my_mf, finfo);
fchg->errors = errno;
return GETDNS_FCHG_ERRORS;
}
/* we want to consider a file that previously returned error for stat() as a
change */
if(fchg->prevstat == NULL)
fchg->changes = GETDNS_FCHG_MTIME | GETDNS_FCHG_CTIME;
else
{
if(fchg->prevstat->st_mtime != finfo->st_mtime)
fchg->changes |= GETDNS_FCHG_MTIME;
if(fchg->prevstat->st_ctime != finfo->st_ctime)
fchg->changes |= GETDNS_FCHG_CTIME;
GETDNS_FREE(context->my_mf, fchg->prevstat);
}
fchg->prevstat = finfo;
return fchg->changes;
} /* filechg */
static getdns_upstreams * static getdns_upstreams *
upstreams_create(getdns_context *context, size_t size) upstreams_create(getdns_context *context, size_t size)
@ -707,12 +728,16 @@ _getdns_upstreams_dereference(getdns_upstreams *upstreams)
{ {
_getdns_closesocket(upstream->fd); _getdns_closesocket(upstream->fd);
} }
if (upstream->tcp.read_buf)
GETDNS_FREE(upstreams->mf, upstream->tcp.read_buf);
while (pin) { while (pin) {
sha256_pin_t *nextpin = pin->next; sha256_pin_t *nextpin = pin->next;
GETDNS_FREE(upstreams->mf, pin); GETDNS_FREE(upstreams->mf, pin);
pin = nextpin; pin = nextpin;
} }
upstream->tls_pubkey_pinset = NULL; upstream->tls_pubkey_pinset = NULL;
if (upstream->tls_cipher_list)
GETDNS_FREE(upstreams->mf, upstream->tls_cipher_list);
} }
GETDNS_FREE(upstreams->mf, upstreams); GETDNS_FREE(upstreams->mf, upstreams);
} }
@ -996,6 +1021,7 @@ upstream_init(getdns_upstream *upstream,
upstream->fd = -1; upstream->fd = -1;
upstream->tls_obj = NULL; upstream->tls_obj = NULL;
upstream->tls_session = NULL; upstream->tls_session = NULL;
upstream->tls_cipher_list = NULL;
upstream->transport = GETDNS_TRANSPORT_TCP; upstream->transport = GETDNS_TRANSPORT_TCP;
upstream->tls_hs_state = GETDNS_HS_NONE; upstream->tls_hs_state = GETDNS_HS_NONE;
upstream->tls_auth_name[0] = '\0'; upstream->tls_auth_name[0] = '\0';
@ -1094,7 +1120,7 @@ static int get_dns_suffix_windows(getdns_list *suffix, char* domain)
static getdns_return_t static getdns_return_t
set_os_defaults_windows(struct getdns_context *context) set_os_defaults_windows(getdns_context *context)
{ {
char domain[1024] = ""; char domain[1024] = "";
size_t upstreams_limit = 10; size_t upstreams_limit = 10;
@ -1106,19 +1132,8 @@ set_os_defaults_windows(struct getdns_context *context)
int s; int s;
uint32_t info_err = 0; uint32_t info_err = 0;
if (context->fchg_resolvconf == NULL) { if (!(context->upstreams = upstreams_create(context, upstreams_limit)))
context->fchg_resolvconf = return GETDNS_RETURN_MEMORY_ERROR;
GETDNS_MALLOC(context->my_mf, struct filechg);
if (context->fchg_resolvconf == NULL)
return GETDNS_RETURN_MEMORY_ERROR;
context->fchg_resolvconf->fn = "InvalidOnWindows";
context->fchg_resolvconf->prevstat = NULL;
context->fchg_resolvconf->changes = GETDNS_FCHG_NOCHANGES;
context->fchg_resolvconf->errors = GETDNS_FCHG_NOERROR;
}
_getdns_filechg_check(context, context->fchg_resolvconf);
context->upstreams = upstreams_create(context, upstreams_limit);
memset(&hints, 0, sizeof(struct addrinfo)); memset(&hints, 0, sizeof(struct addrinfo));
hints.ai_family = AF_UNSPEC; /* Allow IPv4 or IPv6 */ hints.ai_family = AF_UNSPEC; /* Allow IPv4 or IPv6 */
@ -1189,8 +1204,8 @@ set_os_defaults_windows(struct getdns_context *context)
#else #else
static getdns_return_t getdns_return_t
set_os_defaults(struct getdns_context *context) getdns_context_set_resolvconf(getdns_context *context, const char *resolvconf)
{ {
FILE *in; FILE *in;
char line[1024], domain[1024]; char line[1024], domain[1024];
@ -1202,21 +1217,18 @@ set_os_defaults(struct getdns_context *context)
getdns_list *suffix; getdns_list *suffix;
int s; int s;
if(context->fchg_resolvconf == NULL) { if (!context || !resolvconf)
context->fchg_resolvconf = return GETDNS_RETURN_INVALID_PARAMETER;
GETDNS_MALLOC(context->my_mf, struct filechg);
if(context->fchg_resolvconf == NULL)
return GETDNS_RETURN_MEMORY_ERROR;
context->fchg_resolvconf->fn = "/etc/resolv.conf";
context->fchg_resolvconf->prevstat = NULL;
context->fchg_resolvconf->changes = GETDNS_FCHG_NOCHANGES;
context->fchg_resolvconf->errors = GETDNS_FCHG_NOERROR;
}
_getdns_filechg_check(context, context->fchg_resolvconf);
in = fopen(context->fchg_resolvconf->fn, "r");
if (!in) (void) strlcpy( context->fchg_resolvconf.fn, resolvconf, _GETDNS_PATH_MAX);
return GETDNS_RETURN_GOOD; (void) memset(&context->fchg_resolvconf.prevstat, 0, sizeof(struct stat));
context->fchg_resolvconf.changes = GETDNS_FCHG_NOCHANGES;
context->fchg_resolvconf.errors = GETDNS_FCHG_NOERROR;
(void) _getdns_filechg_check(&context->fchg_resolvconf);
if (!(in = fopen(context->fchg_resolvconf.fn, "r")))
return GETDNS_RETURN_IO_ERROR;
upstream_count = 0; upstream_count = 0;
while (fgets(line, (int)sizeof(line), in)) while (fgets(line, (int)sizeof(line), in))
@ -1225,12 +1237,16 @@ set_os_defaults(struct getdns_context *context)
fclose(in); fclose(in);
suffix = getdns_list_create_with_context(context); suffix = getdns_list_create_with_context(context);
context->upstreams = upstreams_create( if (context->upstreams) {
context, upstream_count * GETDNS_UPSTREAM_TRANSPORTS); _getdns_upstreams_dereference(context->upstreams);
context->upstreams = NULL;
in = fopen(context->fchg_resolvconf->fn, "r"); }
if (!in) if (!(context->upstreams = upstreams_create(
return GETDNS_RETURN_GOOD; context, upstream_count * GETDNS_UPSTREAM_TRANSPORTS))) {
return GETDNS_RETURN_MEMORY_ERROR;
}
if (!(in = fopen(context->fchg_resolvconf.fn, "r")))
return GETDNS_RETURN_IO_ERROR;
memset(&hints, 0, sizeof(struct addrinfo)); memset(&hints, 0, sizeof(struct addrinfo));
hints.ai_family = AF_UNSPEC; /* Allow IPv4 or IPv6 */ hints.ai_family = AF_UNSPEC; /* Allow IPv4 or IPv6 */
@ -1306,10 +1322,25 @@ set_os_defaults(struct getdns_context *context)
(void )getdns_context_set_suffix(context, suffix); (void )getdns_context_set_suffix(context, suffix);
getdns_list_destroy(suffix); getdns_list_destroy(suffix);
dispatch_updated(context,
GETDNS_CONTEXT_CODE_UPSTREAM_RECURSIVE_SERVERS);
return GETDNS_RETURN_GOOD; return GETDNS_RETURN_GOOD;
} /* set_os_defaults */ } /* set_os_defaults */
#endif #endif
getdns_return_t
getdns_context_get_resolvconf(getdns_context *context, const char **resolvconf)
{
if (!context || !resolvconf)
return GETDNS_RETURN_INVALID_PARAMETER;
*resolvconf = *context->fchg_resolvconf.fn
? context->fchg_resolvconf.fn : NULL;
return GETDNS_RETURN_GOOD;
}
/* compare of transaction ids in DESCENDING order /* compare of transaction ids in DESCENDING order
so that 0 comes last so that 0 comes last
*/ */
@ -1362,11 +1393,11 @@ static void _getdns_check_expired_pending_netreqs_cb(void *arg)
_getdns_check_expired_pending_netreqs((getdns_context *)arg, &now_ms); _getdns_check_expired_pending_netreqs((getdns_context *)arg, &now_ms);
} }
static const char *_getdns_default_trust_anchors_url = static char const * const _getdns_default_trust_anchors_url =
"http://data.iana.org/root-anchors/root-anchors.xml"; "http://data.iana.org/root-anchors/root-anchors.xml";
/* The ICANN CA fetched at 24 Sep 2010. Valid to 2028 */ /* The ICANN CA fetched at 24 Sep 2010. Valid to 2028 */
static const char *_getdns_default_trust_anchors_verify_CA = static char const * const _getdns_default_trust_anchors_verify_CA =
"-----BEGIN CERTIFICATE-----\n" "-----BEGIN CERTIFICATE-----\n"
"MIIDdzCCAl+gAwIBAgIBATANBgkqhkiG9w0BAQsFADBdMQ4wDAYDVQQKEwVJQ0FO\n" "MIIDdzCCAl+gAwIBAgIBATANBgkqhkiG9w0BAQsFADBdMQ4wDAYDVQQKEwVJQ0FO\n"
"TjEmMCQGA1UECxMdSUNBTk4gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxFjAUBgNV\n" "TjEmMCQGA1UECxMdSUNBTk4gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxFjAUBgNV\n"
@ -1389,9 +1420,12 @@ static const char *_getdns_default_trust_anchors_verify_CA =
"j/Br5BZw3X/zd325TvnswzMC1+ljLzHnQGGk\n" "j/Br5BZw3X/zd325TvnswzMC1+ljLzHnQGGk\n"
"-----END CERTIFICATE-----\n"; "-----END CERTIFICATE-----\n";
static const char *_getdns_default_trust_anchors_verify_email = static char const * const _getdns_default_trust_anchors_verify_email =
"dnssec@iana.org"; "dnssec@iana.org";
static char const * const _getdns_default_tls_cipher_list =
"TLS13-AES-256-GCM-SHA384:TLS13-AES-128-GCM-SHA256:"
"TLS13-CHACHA20-POLY1305-SHA256:EECDH+AESGCM:EECDH+CHACHA20";
/* /*
* getdns_context_create * getdns_context_create
@ -1400,7 +1434,7 @@ static const char *_getdns_default_trust_anchors_verify_email =
*/ */
getdns_return_t getdns_return_t
getdns_context_create_with_extended_memory_functions( getdns_context_create_with_extended_memory_functions(
struct getdns_context ** context, getdns_context **context,
int set_from_os, int set_from_os,
void *userarg, void *userarg,
void *(*malloc)(void *userarg, size_t), void *(*malloc)(void *userarg, size_t),
@ -1498,6 +1532,9 @@ getdns_context_create_with_extended_memory_functions(
result->trust_anchors_verify_email = NULL; result->trust_anchors_verify_email = NULL;
result->trust_anchors_verify_CA = NULL; result->trust_anchors_verify_CA = NULL;
result->appdata_dir = NULL; result->appdata_dir = NULL;
result->tls_ca_path = NULL;
result->tls_ca_file = NULL;
result->tls_cipher_list = NULL;
(void) memset(&result->root_ksk, 0, sizeof(result->root_ksk)); (void) memset(&result->root_ksk, 0, sizeof(result->root_ksk));
@ -1571,17 +1608,8 @@ getdns_context_create_with_extended_memory_functions(
/* state data used to detect changes to the system config files /* state data used to detect changes to the system config files
*/ */
result->fchg_resolvconf = NULL; (void)memset(&result->fchg_resolvconf, 0, sizeof(struct filechg));
result->fchg_hosts = NULL; (void)memset(&result->fchg_hosts , 0, sizeof(struct filechg));
// resolv.conf does not exist on Windows, handle differently
#ifndef USE_WINSOCK
if ((set_from_os & 1) && (r = set_os_defaults(result)))
goto error;
#else
if ((set_from_os & 1) && (r = set_os_defaults_windows(result)))
goto error;
#endif
result->dnssec_allowed_skew = 0; result->dnssec_allowed_skew = 0;
result->edns_maximum_udp_payload_size = -1; result->edns_maximum_udp_payload_size = -1;
@ -1632,8 +1660,16 @@ getdns_context_create_with_extended_memory_functions(
_getdns_mdns_context_init(result); _getdns_mdns_context_init(result);
#endif #endif
create_local_hosts(result); // resolv.conf does not exist on Windows, handle differently
#ifndef USE_WINSOCK
if ((set_from_os & 1)) {
(void) getdns_context_set_resolvconf(result, GETDNS_FN_RESOLVCONF);
(void) getdns_context_set_hosts(result, GETDNS_FN_HOSTS);
}
#else
if ((set_from_os & 1) && (r = set_os_defaults_windows(result)))
goto error;
#endif
*context = result; *context = result;
return GETDNS_RETURN_GOOD; return GETDNS_RETURN_GOOD;
@ -1676,7 +1712,6 @@ getdns_context_create(struct getdns_context ** context, int set_from_os)
set_from_os, malloc, realloc, free); set_from_os, malloc, realloc, free);
} /* getdns_context_create */ } /* getdns_context_create */
/* /*
* getdns_context_destroy * getdns_context_destroy
* *
@ -1731,16 +1766,6 @@ getdns_context_destroy(struct getdns_context *context)
if (context->dns_transports) if (context->dns_transports)
GETDNS_FREE(context->my_mf, context->dns_transports); GETDNS_FREE(context->my_mf, context->dns_transports);
if(context->fchg_resolvconf) {
if(context->fchg_resolvconf->prevstat)
GETDNS_FREE(context->my_mf, context->fchg_resolvconf->prevstat);
GETDNS_FREE(context->my_mf, context->fchg_resolvconf);
}
if(context->fchg_hosts) {
if(context->fchg_hosts->prevstat)
GETDNS_FREE(context->my_mf, context->fchg_hosts->prevstat);
GETDNS_FREE(context->my_mf, context->fchg_hosts);
}
if (context->tls_ctx) if (context->tls_ctx)
SSL_CTX_free(context->tls_ctx); SSL_CTX_free(context->tls_ctx);
@ -1774,6 +1799,12 @@ getdns_context_destroy(struct getdns_context *context)
, context->trust_anchors_verify_email); , context->trust_anchors_verify_email);
if (context->appdata_dir) if (context->appdata_dir)
GETDNS_FREE(context->mf, context->appdata_dir); GETDNS_FREE(context->mf, context->appdata_dir);
if (context->tls_ca_path)
GETDNS_FREE(context->mf, context->tls_ca_path);
if (context->tls_ca_file)
GETDNS_FREE(context->mf, context->tls_ca_file);
if (context->tls_cipher_list)
GETDNS_FREE(context->mf, context->tls_cipher_list);
#ifdef USE_WINSOCK #ifdef USE_WINSOCK
WSACleanup(); WSACleanup();
@ -2962,16 +2993,19 @@ getdns_context_set_upstream_recursive_servers(struct getdns_context *context,
upstream->addr.ss_family = addr.ss_family; upstream->addr.ss_family = addr.ss_family;
upstream_init(upstream, upstreams, ai); upstream_init(upstream, upstreams, ai);
upstream->transport = getdns_upstream_transports[j]; upstream->transport = getdns_upstream_transports[j];
if (getdns_upstream_transports[j] == GETDNS_TRANSPORT_TLS) { if (dict && getdns_upstream_transports[j] == GETDNS_TRANSPORT_TLS) {
getdns_list *pubkey_pinset = NULL; getdns_list *pubkey_pinset = NULL;
if (dict && (r = getdns_dict_get_bindata( getdns_bindata *tls_cipher_list = NULL;
if ((r = getdns_dict_get_bindata(
dict, "tls_auth_name", &tls_auth_name)) == GETDNS_RETURN_GOOD) { dict, "tls_auth_name", &tls_auth_name)) == GETDNS_RETURN_GOOD) {
if (tls_auth_name->size >= sizeof(upstream->tls_auth_name)) { if (tls_auth_name->size >= sizeof(upstream->tls_auth_name)) {
/* tls_auth_name's are just /* tls_auth_name's are
* domain names and should * domain names in presentation
* thus not be larger than 256 * format and, taking escaping
* bytes. * into account, should not
* be larger than 1024 bytes.
*/ */
goto invalid_parameter; goto invalid_parameter;
} }
@ -2981,7 +3015,7 @@ getdns_context_set_upstream_recursive_servers(struct getdns_context *context,
upstream->tls_auth_name upstream->tls_auth_name
[tls_auth_name->size] = '\0'; [tls_auth_name->size] = '\0';
} }
if (dict && (r = getdns_dict_get_list(dict, "tls_pubkey_pinset", if ((r = getdns_dict_get_list(dict, "tls_pubkey_pinset",
&pubkey_pinset)) == GETDNS_RETURN_GOOD) { &pubkey_pinset)) == GETDNS_RETURN_GOOD) {
/* TODO: what if the user supplies tls_pubkey_pinset with /* TODO: what if the user supplies tls_pubkey_pinset with
* something other than a list? */ * something other than a list? */
@ -2991,6 +3025,12 @@ getdns_context_set_upstream_recursive_servers(struct getdns_context *context,
if (r != GETDNS_RETURN_GOOD) if (r != GETDNS_RETURN_GOOD)
goto invalid_parameter; goto invalid_parameter;
} }
(void) getdns_dict_get_bindata(
dict, "tls_cipher_list", &tls_cipher_list);
upstream->tls_cipher_list = tls_cipher_list
? _getdns_strdup2(&upstreams->mf
, tls_cipher_list)
: NULL;
} }
if ((upstream->tsig_alg = tsig_alg)) { if ((upstream->tsig_alg = tsig_alg)) {
if (tsig_name) { if (tsig_name) {
@ -3564,15 +3604,20 @@ _getdns_context_prepare_for_resolution(getdns_context *context)
# endif # endif
/* Be strict and only use the cipher suites recommended in RFC7525 /* Be strict and only use the cipher suites recommended in RFC7525
Unless we later fallback to opportunistic. */ Unless we later fallback to opportunistic. */
const char* const PREFERRED_CIPHERS = "EECDH+aRSA+AESGCM:EECDH+aECDSA+AESGCM:EDH+aRSA+AESGCM"; if (!SSL_CTX_set_cipher_list(context->tls_ctx,
if (!SSL_CTX_set_cipher_list(context->tls_ctx, PREFERRED_CIPHERS)) context->tls_cipher_list ? context->tls_cipher_list
: _getdns_default_tls_cipher_list))
return GETDNS_RETURN_BAD_CONTEXT; return GETDNS_RETURN_BAD_CONTEXT;
/* For strict authentication, we must have local root certs available /* For strict authentication, we must have local root certs available
Set up is done only when the tls_ctx is created (per getdns_context)*/ Set up is done only when the tls_ctx is created (per getdns_context)*/
if ((context->tls_ca_file || context->tls_ca_path) &&
SSL_CTX_load_verify_locations(context->tls_ctx
, context->tls_ca_file, context->tls_ca_path))
; /* pass */
# ifndef USE_WINSOCK # ifndef USE_WINSOCK
if (!SSL_CTX_set_default_verify_paths(context->tls_ctx)) { else if (!SSL_CTX_set_default_verify_paths(context->tls_ctx)) {
# else # else
if (!add_WIN_cacerts_to_openssl_store(context->tls_ctx)) { else if (!add_WIN_cacerts_to_openssl_store(context->tls_ctx)) {
# endif /* USE_WINSOCK */ # endif /* USE_WINSOCK */
if (context->tls_auth_min == GETDNS_AUTHENTICATION_REQUIRED) if (context->tls_auth_min == GETDNS_AUTHENTICATION_REQUIRED)
return GETDNS_RETURN_BAD_CONTEXT; return GETDNS_RETURN_BAD_CONTEXT;
@ -3611,7 +3656,7 @@ _getdns_context_prepare_for_resolution(getdns_context *context)
return r; return r;
} /* _getdns_context_prepare_for_resolution */ } /* _getdns_context_prepare_for_resolution */
char * static char *
_getdns_strdup(const struct mem_funcs *mfs, const char *s) _getdns_strdup(const struct mem_funcs *mfs, const char *s)
{ {
size_t sz; size_t sz;
@ -3869,6 +3914,73 @@ _get_context_settings(getdns_context* context)
(void) getdns_dict_util_set_string(result, "trust_anchors_verify_CA", str_value); (void) getdns_dict_util_set_string(result, "trust_anchors_verify_CA", str_value);
if (!getdns_context_get_trust_anchors_verify_email(context, &str_value) && str_value) if (!getdns_context_get_trust_anchors_verify_email(context, &str_value) && str_value)
(void) getdns_dict_util_set_string(result, "trust_anchors_verify_email", str_value); (void) getdns_dict_util_set_string(result, "trust_anchors_verify_email", str_value);
if (!getdns_context_get_resolvconf(context, &str_value) && str_value)
(void) getdns_dict_util_set_string(result, "resolvconf", str_value);
if (!getdns_context_get_hosts(context, &str_value) && str_value)
(void) getdns_dict_util_set_string(result, "hosts", str_value);
if (!getdns_context_get_tls_ca_path(context, &str_value) && str_value)
(void) getdns_dict_util_set_string(result, "tls_ca_path", str_value);
if (!getdns_context_get_tls_ca_file(context, &str_value) && str_value)
(void) getdns_dict_util_set_string(result, "tls_ca_file", str_value);
if (!getdns_context_get_tls_cipher_list(context, &str_value) && str_value)
(void) getdns_dict_util_set_string(result, "tls_cipher_list", str_value);
/* Default settings for extensions */
(void)getdns_dict_set_int(
result, "add_warning_for_bad_dns",
context->add_warning_for_bad_dns ? GETDNS_EXTENSION_TRUE
: GETDNS_EXTENSION_FALSE);
(void)getdns_dict_set_int(
result, "dnssec_return_all_statuses",
context->dnssec_return_all_statuses ? GETDNS_EXTENSION_TRUE
: GETDNS_EXTENSION_FALSE);
(void)getdns_dict_set_int(
result, "dnssec_return_full_validation_chain",
context->dnssec_return_full_validation_chain ? GETDNS_EXTENSION_TRUE
: GETDNS_EXTENSION_FALSE);
(void)getdns_dict_set_int(
result, "dnssec_return_only_secure",
context->dnssec_return_only_secure ? GETDNS_EXTENSION_TRUE
: GETDNS_EXTENSION_FALSE);
(void)getdns_dict_set_int(
result, "dnssec_return_status",
context->dnssec_return_status ? GETDNS_EXTENSION_TRUE
: GETDNS_EXTENSION_FALSE);
(void)getdns_dict_set_int(
result, "dnssec_return_validation_chain",
context->dnssec_return_validation_chain ? GETDNS_EXTENSION_TRUE
: GETDNS_EXTENSION_FALSE);
#if defined(DNSSEC_ROADBLOCK_AVOIDANCE) && defined(HAVE_LIBUNBOUND)
(void)getdns_dict_set_int(
result, "dnssec_roadblock_avoidance",
context->dnssec_roadblock_avoidance ? GETDNS_EXTENSION_TRUE
: GETDNS_EXTENSION_FALSE);
#endif
#ifdef EDNS_COOKIES
(void)getdns_dict_set_int(
result, "edns_cookies",
context->edns_cookies ? GETDNS_EXTENSION_TRUE
: GETDNS_EXTENSION_FALSE);
#endif
(void)getdns_dict_set_int(
result, "return_both_v4_and_v6",
context->return_both_v4_and_v6 ? GETDNS_EXTENSION_TRUE
: GETDNS_EXTENSION_FALSE);
(void)getdns_dict_set_int(
result, "return_call_reporting",
context->return_call_reporting ? GETDNS_EXTENSION_TRUE
: GETDNS_EXTENSION_FALSE);
(void)getdns_dict_set_int(result, "specify_class",
(uint32_t)context->specify_class);
if (context->add_opt_parameters)
(void)getdns_dict_set_dict(
result, "add_opt_parameters", context->add_opt_parameters);
if (context->header)
(void)getdns_dict_set_dict(
result, "header", context->add_opt_parameters);
return result; return result;
error: error:
@ -3905,6 +4017,39 @@ getdns_context_get_api_information(getdns_context* context)
&& ! getdns_dict_util_set_string( && ! getdns_dict_util_set_string(
result, "default_trust_anchor_location", TRUST_ANCHOR_FILE) result, "default_trust_anchor_location", TRUST_ANCHOR_FILE)
&& ! getdns_dict_util_set_string(
result, "default_resolvconf_location", GETDNS_FN_RESOLVCONF)
&& ! getdns_dict_util_set_string(
result, "default_hosts_location", GETDNS_FN_HOSTS)
&& ! getdns_dict_set_int(
result, "openssl_build_version_number", OPENSSL_VERSION_NUMBER)
#ifdef HAVE_OPENSSL_VERSION_NUM
&& ! getdns_dict_set_int(
result, "openssl_version_number", OpenSSL_version_num())
#endif
#ifdef HAVE_OPENSSL_VERSION
&& ! getdns_dict_util_set_string(
result, "openssl_version_string", OpenSSL_version(OPENSSL_VERSION))
&& ! getdns_dict_util_set_string(
result, "openssl_cflags", OpenSSL_version(OPENSSL_CFLAGS))
&& ! getdns_dict_util_set_string(
result, "openssl_built_on", OpenSSL_version(OPENSSL_BUILT_ON))
&& ! getdns_dict_util_set_string(
result, "openssl_platform", OpenSSL_version(OPENSSL_PLATFORM))
&& ! getdns_dict_util_set_string(
result, "openssl_dir", OpenSSL_version(OPENSSL_DIR))
&& ! getdns_dict_util_set_string(
result, "openssl_engines_dir", OpenSSL_version(OPENSSL_ENGINES_DIR))
#endif
&& ! getdns_dict_set_int( && ! getdns_dict_set_int(
result, "resolution_type", context->resolution_type) result, "resolution_type", context->resolution_type)
@ -4363,6 +4508,11 @@ getdns_context_get_upstream_recursive_servers(getdns_context *context,
break; break;
} }
} }
if (upstream->tls_cipher_list) {
(void) getdns_dict_util_set_string(
d, "tls_cipher_list",
upstream->tls_cipher_list);
}
} }
} }
if (!r) if (!r)
@ -4565,6 +4715,13 @@ _getdns_context_config_setting(getdns_context *context,
CONTEXT_SETTING_STRING(trust_anchors_verify_CA) CONTEXT_SETTING_STRING(trust_anchors_verify_CA)
CONTEXT_SETTING_STRING(trust_anchors_verify_email) CONTEXT_SETTING_STRING(trust_anchors_verify_email)
CONTEXT_SETTING_STRING(appdata_dir) CONTEXT_SETTING_STRING(appdata_dir)
#ifndef USE_WINSOCK
CONTEXT_SETTING_STRING(resolvconf)
#endif
CONTEXT_SETTING_STRING(hosts)
CONTEXT_SETTING_STRING(tls_ca_path)
CONTEXT_SETTING_STRING(tls_ca_file)
CONTEXT_SETTING_STRING(tls_cipher_list)
/**************************************/ /**************************************/
/**** ****/ /**** ****/
@ -4624,7 +4781,17 @@ _getdns_context_config_setting(getdns_context *context,
&& !_streq(setting, "api_version_number") && !_streq(setting, "api_version_number")
&& !_streq(setting, "trust_anchor_file") && !_streq(setting, "trust_anchor_file")
&& !_streq(setting, "default_trust_anchor_location") && !_streq(setting, "default_trust_anchor_location")
&& !_streq(setting, "default_resolvconf_location")
&& !_streq(setting, "default_hosts_location")
&& !_streq(setting, "compilation_comment") && !_streq(setting, "compilation_comment")
&& !_streq(setting, "openssl_build_version_number")
&& !_streq(setting, "openssl_version_number")
&& !_streq(setting, "openssl_version_string")
&& !_streq(setting, "openssl_cflags")
&& !_streq(setting, "openssl_built_on")
&& !_streq(setting, "openssl_platform")
&& !_streq(setting, "openssl_dir")
&& !_streq(setting, "openssl_engines_dir")
) { ) {
r = GETDNS_RETURN_NOT_IMPLEMENTED; r = GETDNS_RETURN_NOT_IMPLEMENTED;
} }
@ -5009,5 +5176,130 @@ getdns_context_set_appdata_dir(
return GETDNS_RETURN_GOOD; return GETDNS_RETURN_GOOD;
} }
getdns_context *_getdns_context_get_sys_ctxt(
getdns_context *context, getdns_eventloop *loop)
{
getdns_return_t r;
if (context->sys_ctxt)
return context->sys_ctxt;
if ((r = getdns_context_create_with_extended_memory_functions(
&context->sys_ctxt, 1, context->mf.mf_arg,
context->mf.mf.ext.malloc, context->mf.mf.ext.realloc,
context->mf.mf.ext.free)))
DEBUG_ANCHOR("Could not create system context: %s\n"
, getdns_get_errorstr_by_id(r));
#ifndef USE_WINSOCK
else if (*context->fchg_resolvconf.fn &&
(r = getdns_context_set_resolvconf(
context->sys_ctxt, context->fchg_resolvconf.fn)))
DEBUG_ANCHOR("Could initialize system context with resolvconf "
"\"%s\": %s\n", context->fchg_resolvconf.fn
, getdns_get_errorstr_by_id(r));
#endif
else if (*context->fchg_hosts.fn &&
(r = getdns_context_set_hosts(
context->sys_ctxt, context->fchg_hosts.fn)))
DEBUG_ANCHOR("Could initialize system context with hosts "
"\"%s\": %s\n", context->fchg_resolvconf.fn
, getdns_get_errorstr_by_id(r));
else if ((r = getdns_context_set_eventloop(
context->sys_ctxt, loop)))
DEBUG_ANCHOR("Could not configure %ssynchronous loop "
"with system context: %s\n"
, ( loop == &context->sync_eventloop.loop
? "" : "a" )
, getdns_get_errorstr_by_id(r));
else if ((r = getdns_context_set_resolution_type(
context->sys_ctxt, GETDNS_RESOLUTION_STUB)))
DEBUG_ANCHOR("Could not configure system context for "
"stub resolver: %s\n"
, getdns_get_errorstr_by_id(r));
else
return context->sys_ctxt;
getdns_context_destroy(context->sys_ctxt);
context->sys_ctxt = NULL;
return NULL;
}
getdns_return_t
getdns_context_set_tls_ca_path(getdns_context *context, const char *tls_ca_path)
{
if (!context || !tls_ca_path)
return GETDNS_RETURN_INVALID_PARAMETER;
if (context->tls_ca_path)
GETDNS_FREE(context->mf, context->tls_ca_path);
context->tls_ca_path = _getdns_strdup(&context->mf, tls_ca_path);
dispatch_updated(context, GETDNS_CONTEXT_CODE_TLS_CA_PATH);
return GETDNS_RETURN_GOOD;
}
getdns_return_t
getdns_context_get_tls_ca_path(getdns_context *context, const char **tls_ca_path)
{
if (!context || !tls_ca_path)
return GETDNS_RETURN_INVALID_PARAMETER;
*tls_ca_path = context->tls_ca_path;
return GETDNS_RETURN_GOOD;
}
getdns_return_t
getdns_context_set_tls_ca_file(getdns_context *context, const char *tls_ca_file)
{
if (!context || !tls_ca_file)
return GETDNS_RETURN_INVALID_PARAMETER;
if (context->tls_ca_file)
GETDNS_FREE(context->mf, context->tls_ca_file);
context->tls_ca_file = _getdns_strdup(&context->mf, tls_ca_file);
dispatch_updated(context, GETDNS_CONTEXT_CODE_TLS_CA_FILE);
return GETDNS_RETURN_GOOD;
}
getdns_return_t
getdns_context_get_tls_ca_file(getdns_context *context, const char **tls_ca_file)
{
if (!context || !tls_ca_file)
return GETDNS_RETURN_INVALID_PARAMETER;
*tls_ca_file = context->tls_ca_file;
return GETDNS_RETURN_GOOD;
}
getdns_return_t
getdns_context_set_tls_cipher_list(
getdns_context *context, const char *tls_cipher_list)
{
if (!context)
return GETDNS_RETURN_INVALID_PARAMETER;
if (context->tls_cipher_list)
GETDNS_FREE(context->mf, context->tls_cipher_list);
context->tls_cipher_list = tls_cipher_list
? _getdns_strdup(&context->mf, tls_cipher_list)
: NULL;
dispatch_updated(context, GETDNS_CONTEXT_CODE_TLS_CIPHER_LIST);
return GETDNS_RETURN_GOOD;
}
getdns_return_t
getdns_context_get_tls_cipher_list(
getdns_context *context, const char **tls_cipher_list)
{
if (!context || !tls_cipher_list)
return GETDNS_RETURN_INVALID_PARAMETER;
*tls_cipher_list = context->tls_cipher_list
? context->tls_cipher_list
: _getdns_default_tls_cipher_list;
return GETDNS_RETURN_GOOD;
}
/* context.c */ /* context.c */

View File

@ -54,9 +54,6 @@
struct getdns_dns_req; struct getdns_dns_req;
struct ub_ctx; struct ub_ctx;
#define GETDNS_FN_RESOLVCONF "/etc/resolv.conf"
#define GETDNS_FN_HOSTS "/etc/hosts"
enum filechgs { GETDNS_FCHG_ERRORS = -1 enum filechgs { GETDNS_FCHG_ERRORS = -1
, GETDNS_FCHG_NOERROR = 0 , GETDNS_FCHG_NOERROR = 0
, GETDNS_FCHG_NOCHANGES = 0 , GETDNS_FCHG_NOCHANGES = 0
@ -72,10 +69,10 @@ typedef void (*getdns_update_callback2) (struct getdns_context *,
/* internal use only for detecting changes to system files */ /* internal use only for detecting changes to system files */
struct filechg { struct filechg {
char *fn; char fn[_GETDNS_PATH_MAX];
int changes; int changes;
int errors; int errors;
struct stat *prevstat; struct stat prevstat;
}; };
typedef enum getdns_tls_hs_state { typedef enum getdns_tls_hs_state {
@ -208,6 +205,7 @@ typedef struct getdns_upstream {
getdns_tls_hs_state_t tls_hs_state; getdns_tls_hs_state_t tls_hs_state;
getdns_auth_state_t tls_auth_state; getdns_auth_state_t tls_auth_state;
unsigned tls_fallback_ok : 1; unsigned tls_fallback_ok : 1;
char *tls_cipher_list;
/* Auth credentials*/ /* Auth credentials*/
char tls_auth_name[256]; char tls_auth_name[256];
sha256_pin_t *tls_pubkey_pinset; sha256_pin_t *tls_pubkey_pinset;
@ -346,6 +344,10 @@ struct getdns_context {
char *appdata_dir; char *appdata_dir;
_getdns_property can_write_appdata; _getdns_property can_write_appdata;
char *tls_ca_path;
char *tls_ca_file;
char *tls_cipher_list;
getdns_upstreams *upstreams; getdns_upstreams *upstreams;
uint16_t limit_outstanding_queries; uint16_t limit_outstanding_queries;
uint32_t dnssec_allowed_skew; uint32_t dnssec_allowed_skew;
@ -455,8 +457,8 @@ struct getdns_context {
/* /*
* state data used to detect changes to the system config files * state data used to detect changes to the system config files
*/ */
struct filechg *fchg_resolvconf; struct filechg fchg_resolvconf;
struct filechg *fchg_hosts; struct filechg fchg_hosts;
uint8_t trust_anchors_spc[1024]; uint8_t trust_anchors_spc[1024];
@ -527,8 +529,6 @@ void _getdns_context_cancel_request(getdns_dns_req *dnsreq);
*/ */
void _getdns_context_request_timed_out(getdns_dns_req *dnsreq); void _getdns_context_request_timed_out(getdns_dns_req *dnsreq);
char *_getdns_strdup(const struct mem_funcs *mfs, const char *str);
struct getdns_bindata *_getdns_bindata_copy( struct getdns_bindata *_getdns_bindata_copy(
struct mem_funcs *mfs, size_t size, const uint8_t *data); struct mem_funcs *mfs, size_t size, const uint8_t *data);
@ -540,8 +540,6 @@ void _getdns_bindata_destroy(
getdns_return_t _getdns_context_local_namespace_resolve( getdns_return_t _getdns_context_local_namespace_resolve(
getdns_dns_req* req, struct getdns_dict **response); getdns_dns_req* req, struct getdns_dict **response);
int _getdns_filechg_check(struct getdns_context *context, struct filechg *fchg);
void _getdns_context_ub_read_cb(void *userarg); void _getdns_context_ub_read_cb(void *userarg);
void _getdns_upstreams_dereference(getdns_upstreams *upstreams); void _getdns_upstreams_dereference(getdns_upstreams *upstreams);
@ -557,4 +555,7 @@ int _getdns_context_write_priv_file(getdns_context *context,
int _getdns_context_can_write_appdata(getdns_context *context); int _getdns_context_can_write_appdata(getdns_context *context);
getdns_context *_getdns_context_get_sys_ctxt(
getdns_context *context, getdns_eventloop *loop);
#endif /* _GETDNS_CONTEXT_H_ */ #endif /* _GETDNS_CONTEXT_H_ */

View File

@ -1082,7 +1082,25 @@ getdns_pp_dict(gldns_buffer * buf, size_t indent,
strcmp(item->node.key, "follow_redirects") == 0 || strcmp(item->node.key, "follow_redirects") == 0 ||
strcmp(item->node.key, "transport") == 0 || strcmp(item->node.key, "transport") == 0 ||
strcmp(item->node.key, "resolution_type") == 0 || strcmp(item->node.key, "resolution_type") == 0 ||
strcmp(item->node.key, "tls_authentication") == 0 ) && strcmp(item->node.key, "tls_authentication") == 0 ||
/* extensions */
strcmp(item->node.key, "add_warning_for_bad_dns") == 0 ||
strcmp(item->node.key, "dnssec_return_all_statuses") == 0 ||
strcmp(item->node.key, "dnssec_return_full_validation_chain") == 0 ||
strcmp(item->node.key, "dnssec_return_only_secure") == 0 ||
strcmp(item->node.key, "dnssec_return_status") == 0 ||
strcmp(item->node.key, "dnssec_return_validation_chain") == 0 ||
#if defined(DNSSEC_ROADBLOCK_AVOIDANCE) && defined(HAVE_LIBUNBOUND)
strcmp(item->node.key, "dnssec_roadblock_avoidance") == 0 ||
#endif
#ifdef EDNS_COOKIES
strcmp(item->node.key, "edns_cookies") == 0 ||
#endif
strcmp(item->node.key, "return_api_information") == 0 ||
strcmp(item->node.key, "return_both_v4_and_v6") == 0 ||
strcmp(item->node.key, "return_call_reporting") == 0
) &&
(strval = (strval =
_getdns_get_const_info(item->i.data.n)->name)) { _getdns_get_const_info(item->i.data.n)->name)) {
if (gldns_buffer_printf(buf, " %s", strval) < 0) if (gldns_buffer_printf(buf, " %s", strval) < 0)

View File

@ -3160,11 +3160,19 @@ static void check_chain_complete(chain_head *chain)
_getdns_context_update_root_ksk(context,&node->dnskey); _getdns_context_update_root_ksk(context,&node->dnskey);
} else if (_getdns_bogus(dnsreq)) { } else if (_getdns_bogus(dnsreq)) {
_getdns_rrsig_iter rrsig_spc;
DEBUG_ANCHOR("Request was bogus!\n"); DEBUG_ANCHOR("Request was bogus!\n");
if ((head = chain) && (node = _to_the_root(head->parent)) if ((head = chain) && (node = _to_the_root(head->parent))
/* The root DNSKEY rrset */
&& node->dnskey.name && *node->dnskey.name == 0 && node->dnskey.name && *node->dnskey.name == 0
&& node->dnskey_req->dnssec_status == GETDNS_DNSSEC_BOGUS){ /* We queried it and had a response */
&& node->dnskey_req
/* The response was bogus */
&& node->dnskey_req->dnssec_status == GETDNS_DNSSEC_BOGUS
/* The response was bogus, but not because it has no rrsigs */
&& _getdns_rrsig_iter_init(&rrsig_spc, &node->dnskey)
){
DEBUG_ANCHOR("root DNSKEY set was bogus!\n"); DEBUG_ANCHOR("root DNSKEY set was bogus!\n");
if (!dnsreq->waiting_for_ta) { if (!dnsreq->waiting_for_ta) {
@ -3394,10 +3402,21 @@ void _getdns_validation_chain_timeout(getdns_dns_req *dnsreq)
void _getdns_cancel_validation_chain(getdns_dns_req *dnsreq) void _getdns_cancel_validation_chain(getdns_dns_req *dnsreq)
{ {
chain_head *head = dnsreq->chain, *next, *dnskey_head; chain_head *head, *next;
chain_node *node; chain_node *node;
size_t node_count; size_t node_count;
/* Clear nodes under direct DNSKEY queries.
* They share the DNSKEY lookup netreq, but _dnskey_query() can not
* be used because we're free'ing the heads.
*/
for (head = dnsreq->chain; head; head = head->next) {
if ( head->rrset.rr_type == GETDNS_RRTYPE_DNSKEY
&& head->node_count
&& head->netreq == head->parent->dnskey_req)
head->parent->dnskey_req = NULL;
}
head = dnsreq->chain;
dnsreq->chain = NULL; dnsreq->chain = NULL;
while (head) { while (head) {
next = head->next; next = head->next;
@ -3406,10 +3425,7 @@ void _getdns_cancel_validation_chain(getdns_dns_req *dnsreq)
; node_count ; node_count
; node_count--, node = node->parent ) { ; node_count--, node = node->parent ) {
if (node->dnskey_req && if (node->dnskey_req)
!( (dnskey_head = _dnskey_query(node))
&& dnskey_head->netreq == node->dnskey_req))
_getdns_context_cancel_request( _getdns_context_cancel_request(
node->dnskey_req->owner); node->dnskey_req->owner);

View File

@ -116,7 +116,7 @@ _getdns_check_dns_req_complete(getdns_dns_req *dns_req)
/* Do we have to check more suffixes on nxdomain/nodata? /* Do we have to check more suffixes on nxdomain/nodata?
*/ */
if (dns_req->is_dns_request && if (dns_req->is_dns_request == 1 &&
dns_req->suffix_appended && /* Something was appended */ dns_req->suffix_appended && /* Something was appended */
dns_req->suffix_len > 1 && /* Next suffix available */ dns_req->suffix_len > 1 && /* Next suffix available */
no_answer(dns_req)) { no_answer(dns_req)) {
@ -153,7 +153,7 @@ _getdns_check_dns_req_complete(getdns_dns_req *dns_req)
return; return;
} }
} else if ( } else if (
dns_req->is_dns_request && dns_req->is_dns_request == 1 &&
( dns_req->append_name == ( dns_req->append_name ==
GETDNS_APPEND_NAME_ONLY_TO_SINGLE_LABEL_AFTER_FAILURE || GETDNS_APPEND_NAME_ONLY_TO_SINGLE_LABEL_AFTER_FAILURE ||
dns_req->append_name == dns_req->append_name ==
@ -206,7 +206,7 @@ _getdns_check_dns_req_complete(getdns_dns_req *dns_req)
} else if (! results_found) } else if (! results_found)
_getdns_call_user_callback(dns_req, NULL); _getdns_call_user_callback(dns_req, NULL);
else if ( else if (
dns_req->is_dns_request && dns_req->is_dns_request == 1 &&
(dns_req->dnssec_return_validation_chain (dns_req->dnssec_return_validation_chain
#ifdef DNSSEC_ROADBLOCK_AVOIDANCE #ifdef DNSSEC_ROADBLOCK_AVOIDANCE
|| ( dns_req->dnssec_roadblock_avoidance || ( dns_req->dnssec_roadblock_avoidance
@ -343,7 +343,7 @@ _getdns_netreq_change_state(
if (!netreq) if (!netreq)
return; return;
if (!netreq->owner->is_dns_request) { if (netreq->owner->is_dns_request == 0) {
netreq->state = new_state; netreq->state = new_state;
return; return;
} }

View File

@ -1687,6 +1687,8 @@ getdns_context_set_dnssec_allowed_skew(getdns_context *context,
* - `value` A SHA256 hash of the `SubjectPublicKeyInfo` * - `value` A SHA256 hash of the `SubjectPublicKeyInfo`
* of the upstream, which will be used to authenticate * of the upstream, which will be used to authenticate
* it. * it.
* - `tls_cipher_list` (a bindata) that is the string
* of available ciphers specific for this upstream.
* @return GETDNS_RETURN_GOOD when successful. * @return GETDNS_RETURN_GOOD when successful.
* @return GETDNS_RETURN_INVALID_PARAMETER when `context` or `upstream_list` was `NULL` * @return GETDNS_RETURN_INVALID_PARAMETER when `context` or `upstream_list` was `NULL`
* @return GETDNS_RETURN_CONTEXT_UPDATE_FAIL when there were problems parsing * @return GETDNS_RETURN_CONTEXT_UPDATE_FAIL when there were problems parsing

View File

@ -53,6 +53,8 @@ extern "C" {
* \addtogroup returntypestext Return values and texts * \addtogroup returntypestext Return values and texts
* @{ * @{
*/ */
#define GETDNS_RETURN_IO_ERROR ((getdns_return_t) 397 )
#define GETDNS_RETURN_IO_ERROR_TEXT "An input/output error occurred. Inspect errno for details."
#define GETDNS_RETURN_NO_UPSTREAM_AVAILABLE ((getdns_return_t) 398 ) #define GETDNS_RETURN_NO_UPSTREAM_AVAILABLE ((getdns_return_t) 398 )
#define GETDNS_RETURN_NO_UPSTREAM_AVAILABLE_TEXT "None of the configured upstreams could be used to send queries on the specified transports" #define GETDNS_RETURN_NO_UPSTREAM_AVAILABLE_TEXT "None of the configured upstreams could be used to send queries on the specified transports"
#define GETDNS_RETURN_NEED_MORE_SPACE ((getdns_return_t) 399 ) #define GETDNS_RETURN_NEED_MORE_SPACE ((getdns_return_t) 399 )
@ -88,6 +90,16 @@ extern "C" {
#define GETDNS_CONTEXT_CODE_TRUST_ANCHORS_VERIFY_EMAIL_TEXT "Change related to getdns_context_set_trust_anchors_verify_email" #define GETDNS_CONTEXT_CODE_TRUST_ANCHORS_VERIFY_EMAIL_TEXT "Change related to getdns_context_set_trust_anchors_verify_email"
#define GETDNS_CONTEXT_CODE_APPDATA_DIR 628 #define GETDNS_CONTEXT_CODE_APPDATA_DIR 628
#define GETDNS_CONTEXT_CODE_APPDATA_DIR_TEXT "Change related to getdns_context_set_appdata_dir" #define GETDNS_CONTEXT_CODE_APPDATA_DIR_TEXT "Change related to getdns_context_set_appdata_dir"
#define GETDNS_CONTEXT_CODE_RESOLVCONF 629
#define GETDNS_CONTEXT_CODE_RESOLVCONF_TEXT "Change related to getdns_context_set_resolvconf"
#define GETDNS_CONTEXT_CODE_HOSTS 630
#define GETDNS_CONTEXT_CODE_HOSTS_TEXT "Change related to getdns_context_set_hosts"
#define GETDNS_CONTEXT_CODE_TLS_CA_PATH 631
#define GETDNS_CONTEXT_CODE_TLS_CA_PATH_TEXT "Change related to getdns_context_set_tls_ca_path"
#define GETDNS_CONTEXT_CODE_TLS_CA_FILE 632
#define GETDNS_CONTEXT_CODE_TLS_CA_FILE_TEXT "Change related to getdns_context_set_tls_ca_file"
#define GETDNS_CONTEXT_CODE_TLS_CIPHER_LIST 633
#define GETDNS_CONTEXT_CODE_TLS_CIPHER_LIST_TEXT "Change related to getdns_context_set_tls_cipher_list"
/** @} /** @}
*/ */
@ -680,6 +692,67 @@ getdns_return_t
getdns_context_set_trust_anchors_verify_email( getdns_context_set_trust_anchors_verify_email(
getdns_context *context, const char *verify_email); getdns_context *context, const char *verify_email);
/**
* Initialized the context's upstream recursive servers and suffixes
* with the values from the given resolv.conf file.
* @see getdns_context_get_resolvconf
* @see getdns_context_set_hosts
* @param[in] context The context to configure
* @param[in] resolvonf Defaults to /etc/resolv.conf
* @return GETDNS_RETURN_GOOD when successful and error code otherwise.
*/
getdns_return_t
getdns_context_set_resolvconf(getdns_context *context, const char *resolvconf);
/**
* Initialized the context's GETDNS_NAMESPACE_LOCALNAMES namespace with
* values from the given hosts file.
* @see getdns_context_get_hosts
* @see getdns_context_set_resolvconf
* @param[in] context The context to configure
* @param[in] hosts Defaults to /etc/hosts
* @return GETDNS_RETURN_GOOD when successful and error code otherwise.
*/
getdns_return_t
getdns_context_set_hosts(getdns_context *context, const char *hosts);
/**
* Specify where the location for CA certificates for verification purposes
* are located.
* @see getdns_context_get_tls_ca_path
* @see getdns_context_set_tls_ca_file
* @param[in] context The context to configure
* @param[in] tls_ca_path Directory with Certificate Authority certificates.
* @return GETDNS_RETURN_GOOD when successful
* @return GETDNS_RETURN_INVALID_PARAMETER when context was NULL.
*/
getdns_return_t
getdns_context_set_tls_ca_path(getdns_context *context, const char *tls_ca_path);
/**
* Specify the file with CA certificates for verification purposes.
* @see getdns_context_get_tls_ca_file
* @see getdns_context_set_tls_ca_path
* @param[in] context The context to configure
* @param[in] tls_ca_file The file with Certificate Authority certificates.
* @return GETDNS_RETURN_GOOD when successful
* @return GETDNS_RETURN_INVALID_PARAMETER when context was NULL.
*/
getdns_return_t
getdns_context_set_tls_ca_file(getdns_context *context, const char *tls_ca_file);
/**
* Sets the list of available ciphers for authenticated TLS upstreams.
* @see getdns_context_get_tls_cipher_list
* @param[in] context The context to configure
* @param[in] cipher_list The cipher list
* @return GETDNS_RETURN_GOOD when successful
* @return GETDNS_RETURN_INVALID_PARAMETER when context was NULL.
*/
getdns_return_t
getdns_context_set_tls_cipher_list(
getdns_context *context, const char *cipher_list);
/** /**
* Get the current resolution type setting from this context. * Get the current resolution type setting from this context.
* @see getdns_context_set_resolution_type * @see getdns_context_set_resolution_type
@ -1134,6 +1207,71 @@ getdns_return_t
getdns_context_get_trust_anchors_verify_email( getdns_context_get_trust_anchors_verify_email(
getdns_context *context, const char **verify_email); getdns_context *context, const char **verify_email);
/**
* Get the value with which the context's upstream recursive servers
* and suffixes were initialized.
* @see getdns_context_set_resolvconf
* @see getdns_context_get_hosts
* @param[in] context The context to configure
* @param[out] resolvonf NULL if the context was not initialized with a
* resolv.conf file.
* @return GETDNS_RETURN_GOOD when successful and error code otherwise.
*/
getdns_return_t
getdns_context_get_resolvconf(getdns_context *context, const char **resolvconf);
/**
* Get the value with which the context's GETDNS_NAMESPACE_LOCALNAMES namespace
* was initialized.
* @see getdns_context_set_hosts
* @see getdns_context_get_resolvconf
* @param[in] context The context to configure
* @param[out] hosts NULL when GETDNS_NAMESPACE_LOCALNAMES namespace
* was not initialized.
* @return GETDNS_RETURN_GOOD when successful and error code otherwise.
*/
getdns_return_t
getdns_context_get_hosts(getdns_context *context, const char **hosts);
/**
* Get the location of the directory for CA certificates for verification
* purposes.
* @see getdns_context_set_tls_ca_path
* @see getdns_context_get_tls_ca_file
* @param[in] context The context to configure
* @param[out] tls_ca_path Directory with Certificate Authority certificates
* or NULL when one was not configured.
* @return GETDNS_RETURN_GOOD when successful
* @return GETDNS_RETURN_INVALID_PARAMETER when context was NULL.
*/
getdns_return_t
getdns_context_get_tls_ca_path(getdns_context *context, const char **tls_ca_path);
/**
* Get the file location with CA certificates for verification purposes.
* @see getdns_context_set_tls_ca_file
* @see getdns_context_get_tls_ca_path
* @param[in] context The context to configure
* @param[out] tls_ca_file The file with Certificate Authority certificates
* or NULL when one was not configured.
* @return GETDNS_RETURN_GOOD when successful
* @return GETDNS_RETURN_INVALID_PARAMETER when context was NULL.
*/
getdns_return_t
getdns_context_get_tls_ca_file(getdns_context *context, const char **tls_ca_file);
/**
* Get the list of available ciphers for authenticated TLS upstreams.
* @see getdns_context_set_tls_cipher_list
* @param[in] context The context configure
* @param[out] cipher_list The cipher list
* @return GETDNS_RETURN_GOOD when successful
* @return GETDNS_RETURN_INVALID_PARAMETER when context was NULL.
*/
getdns_return_t
getdns_context_get_tls_cipher_list(
getdns_context *context, const char **cipher_list);
/** @} /** @}
*/ */

View File

@ -21,16 +21,21 @@ getdns_context_get_edns_maximum_udp_payload_size
getdns_context_get_edns_version getdns_context_get_edns_version
getdns_context_get_eventloop getdns_context_get_eventloop
getdns_context_get_follow_redirects getdns_context_get_follow_redirects
getdns_context_get_hosts
getdns_context_get_idle_timeout getdns_context_get_idle_timeout
getdns_context_get_limit_outstanding_queries getdns_context_get_limit_outstanding_queries
getdns_context_get_namespaces getdns_context_get_namespaces
getdns_context_get_num_pending_requests getdns_context_get_num_pending_requests
getdns_context_get_resolution_type getdns_context_get_resolution_type
getdns_context_get_resolvconf
getdns_context_get_round_robin_upstreams getdns_context_get_round_robin_upstreams
getdns_context_get_suffix getdns_context_get_suffix
getdns_context_get_timeout getdns_context_get_timeout
getdns_context_get_tls_authentication getdns_context_get_tls_authentication
getdns_context_get_tls_backoff_time getdns_context_get_tls_backoff_time
getdns_context_get_tls_ca_file
getdns_context_get_tls_ca_path
getdns_context_get_tls_cipher_list
getdns_context_get_tls_connection_retries getdns_context_get_tls_connection_retries
getdns_context_get_tls_query_padding_blocksize getdns_context_get_tls_query_padding_blocksize
getdns_context_get_trust_anchors_url getdns_context_get_trust_anchors_url
@ -56,6 +61,7 @@ getdns_context_set_edns_version
getdns_context_set_eventloop getdns_context_set_eventloop
getdns_context_set_extended_memory_functions getdns_context_set_extended_memory_functions
getdns_context_set_follow_redirects getdns_context_set_follow_redirects
getdns_context_set_hosts
getdns_context_set_idle_timeout getdns_context_set_idle_timeout
getdns_context_set_limit_outstanding_queries getdns_context_set_limit_outstanding_queries
getdns_context_set_listen_addresses getdns_context_set_listen_addresses
@ -63,12 +69,16 @@ getdns_context_set_logfunc
getdns_context_set_memory_functions getdns_context_set_memory_functions
getdns_context_set_namespaces getdns_context_set_namespaces
getdns_context_set_resolution_type getdns_context_set_resolution_type
getdns_context_set_resolvconf
getdns_context_set_return_dnssec_status getdns_context_set_return_dnssec_status
getdns_context_set_round_robin_upstreams getdns_context_set_round_robin_upstreams
getdns_context_set_suffix getdns_context_set_suffix
getdns_context_set_timeout getdns_context_set_timeout
getdns_context_set_tls_authentication getdns_context_set_tls_authentication
getdns_context_set_tls_backoff_time getdns_context_set_tls_backoff_time
getdns_context_set_tls_ca_file
getdns_context_set_tls_ca_path
getdns_context_set_tls_cipher_list
getdns_context_set_tls_connection_retries getdns_context_set_tls_connection_retries
getdns_context_set_tls_query_padding_blocksize getdns_context_set_tls_query_padding_blocksize
getdns_context_set_trust_anchors_url getdns_context_set_trust_anchors_url

View File

@ -84,6 +84,12 @@ getdns_dict dnssec_ok_checking_disabled_avoid_roadblocks_spc = {
getdns_dict *dnssec_ok_checking_disabled_avoid_roadblocks getdns_dict *dnssec_ok_checking_disabled_avoid_roadblocks
= &dnssec_ok_checking_disabled_avoid_roadblocks_spc; = &dnssec_ok_checking_disabled_avoid_roadblocks_spc;
getdns_dict no_dnssec_checking_disabled_opportunistic_spc = {
{ RBTREE_NULL, 0, (int (*)(const void *, const void *)) strcmp },
{ NULL, {{ NULL, NULL, NULL }}}
};
getdns_dict *no_dnssec_checking_disabled_opportunistic
= &no_dnssec_checking_disabled_opportunistic_spc;
static int static int
is_extension_set(getdns_dict *extensions, const char *name, int default_value) is_extension_set(getdns_dict *extensions, const char *name, int default_value)
@ -94,7 +100,8 @@ is_extension_set(getdns_dict *extensions, const char *name, int default_value)
if ( ! extensions if ( ! extensions
|| extensions == dnssec_ok_checking_disabled || extensions == dnssec_ok_checking_disabled
|| extensions == dnssec_ok_checking_disabled_roadblock_avoidance || extensions == dnssec_ok_checking_disabled_roadblock_avoidance
|| extensions == dnssec_ok_checking_disabled_avoid_roadblocks) || extensions == dnssec_ok_checking_disabled_avoid_roadblocks
|| extensions == no_dnssec_checking_disabled_opportunistic)
return 0; return 0;
r = getdns_dict_get_int(extensions, name, &value); r = getdns_dict_get_int(extensions, name, &value);
@ -155,8 +162,8 @@ netreq_reset(getdns_network_req *net_req)
static int static int
network_req_init(getdns_network_req *net_req, getdns_dns_req *owner, network_req_init(getdns_network_req *net_req, getdns_dns_req *owner,
uint16_t request_type, int dnssec_extension_set, int with_opt, uint16_t request_type, int checking_disabled, int opportunistic,
int edns_maximum_udp_payload_size, int with_opt, int edns_maximum_udp_payload_size,
uint8_t edns_extended_rcode, uint8_t edns_version, int edns_do_bit, uint8_t edns_extended_rcode, uint8_t edns_version, int edns_do_bit,
uint16_t opt_options_size, size_t noptions, getdns_list *options, uint16_t opt_options_size, size_t noptions, getdns_list *options,
size_t wire_data_sz, size_t max_query_sz, getdns_dict *extensions) size_t wire_data_sz, size_t max_query_sz, getdns_dict *extensions)
@ -186,6 +193,7 @@ network_req_init(getdns_network_req *net_req, getdns_dns_req *owner,
owner->context->tls_auth == GETDNS_AUTHENTICATION_REQUIRED owner->context->tls_auth == GETDNS_AUTHENTICATION_REQUIRED
&& owner->context->dns_transport_count == 1 && owner->context->dns_transport_count == 1
&& owner->context->dns_transports[0] == GETDNS_TRANSPORT_TLS && owner->context->dns_transports[0] == GETDNS_TRANSPORT_TLS
&& !opportunistic
? GETDNS_AUTHENTICATION_REQUIRED ? GETDNS_AUTHENTICATION_REQUIRED
: GETDNS_AUTHENTICATION_NONE; : GETDNS_AUTHENTICATION_NONE;
@ -240,7 +248,7 @@ network_req_init(getdns_network_req *net_req, getdns_dns_req *owner,
_getdns_reply_dict2wire(owner->context->header, &gbuf, 1); _getdns_reply_dict2wire(owner->context->header, &gbuf, 1);
gldns_buffer_rewind(&gbuf); gldns_buffer_rewind(&gbuf);
_getdns_reply_dict2wire(extensions, &gbuf, 1); _getdns_reply_dict2wire(extensions, &gbuf, 1);
if (dnssec_extension_set) /* We will do validation ourselves */ if (checking_disabled) /* We will do validation ourselves */
GLDNS_CD_SET(net_req->query); GLDNS_CD_SET(net_req->query);
if (with_opt) { if (with_opt) {
@ -762,8 +770,24 @@ _getdns_dns_req_new(getdns_context *context, getdns_eventloop *loop,
*/ */
size_t max_query_sz, max_response_sz, netreq_sz, dnsreq_base_sz; size_t max_query_sz, max_response_sz, netreq_sz, dnsreq_base_sz;
uint8_t *region, *suffixes; uint8_t *region, *suffixes;
int checking_disabled = dnssec_extension_set;
int opportunistic = 0;
if (extensions == dnssec_ok_checking_disabled || if (extensions == no_dnssec_checking_disabled_opportunistic) {
dnssec_return_status = 0;
dnssec_return_only_secure = 0;
dnssec_return_all_statuses = 0;
dnssec_return_full_validation_chain = 0;
dnssec_return_validation_chain = 0;
dnssec_extension_set = 0;
#ifdef DNSSEC_ROADBLOCK_AVOIDANCE
dnssec_roadblock_avoidance = 0;
avoid_dnssec_roadblocks = 0;
#endif
extensions = NULL;
checking_disabled = 1;
opportunistic = 1;
} else if (extensions == dnssec_ok_checking_disabled ||
extensions == dnssec_ok_checking_disabled_roadblock_avoidance || extensions == dnssec_ok_checking_disabled_roadblock_avoidance ||
extensions == dnssec_ok_checking_disabled_avoid_roadblocks) extensions == dnssec_ok_checking_disabled_avoid_roadblocks)
extensions = NULL; extensions = NULL;
@ -866,6 +890,7 @@ _getdns_dns_req_new(getdns_context *context, getdns_eventloop *loop,
if (! (region = GETDNS_XMALLOC(context->mf, uint8_t, if (! (region = GETDNS_XMALLOC(context->mf, uint8_t,
dnsreq_base_sz + (a_aaaa_query ? 2 : 1) * netreq_sz))) dnsreq_base_sz + (a_aaaa_query ? 2 : 1) * netreq_sz)))
return NULL; return NULL;
(void) memset(region, 0, sizeof(getdns_dns_req));
result = (getdns_dns_req *)region; result = (getdns_dns_req *)region;
result->netreqs[0] = (getdns_network_req *)(region + dnsreq_base_sz); result->netreqs[0] = (getdns_network_req *)(region + dnsreq_base_sz);
@ -972,8 +997,8 @@ _getdns_dns_req_new(getdns_context *context, getdns_eventloop *loop,
result->chain = NULL; result->chain = NULL;
network_req_init(result->netreqs[0], result, network_req_init(result->netreqs[0], result,
request_type, dnssec_extension_set, with_opt, request_type, checking_disabled, opportunistic,
edns_maximum_udp_payload_size, with_opt, edns_maximum_udp_payload_size,
edns_extended_rcode, edns_version, edns_do_bit, edns_extended_rcode, edns_version, edns_do_bit,
(uint16_t) opt_options_size, noptions, options, (uint16_t) opt_options_size, noptions, options,
netreq_sz - sizeof(getdns_network_req), max_query_sz, netreq_sz - sizeof(getdns_network_req), max_query_sz,
@ -983,7 +1008,7 @@ _getdns_dns_req_new(getdns_context *context, getdns_eventloop *loop,
network_req_init(result->netreqs[1], result, network_req_init(result->netreqs[1], result,
( request_type == GETDNS_RRTYPE_A ( request_type == GETDNS_RRTYPE_A
? GETDNS_RRTYPE_AAAA : GETDNS_RRTYPE_A ), ? GETDNS_RRTYPE_AAAA : GETDNS_RRTYPE_A ),
dnssec_extension_set, with_opt, checking_disabled, opportunistic, with_opt,
edns_maximum_udp_payload_size, edns_maximum_udp_payload_size,
edns_extended_rcode, edns_version, edns_do_bit, edns_extended_rcode, edns_version, edns_do_bit,
(uint16_t) opt_options_size, noptions, options, (uint16_t) opt_options_size, noptions, options,

View File

@ -151,15 +151,19 @@ calc_new_cookie(getdns_upstream *upstream, uint8_t *cookie)
static getdns_return_t static getdns_return_t
attach_edns_client_subnet_private(getdns_network_req *req) attach_edns_client_subnet_private(getdns_network_req *req)
{ {
/* see /* see https://tools.ietf.org/html/rfc7871#section-7.1.2
* https://tools.ietf.org/html/draft-ietf-dnsop-edns-client-subnet-04#section-6 */ * all-zeros is a request to not leak the data further:
/* all-zeros is a request to not leak the data further: */ * A two byte FAMILY field is a SHOULD even when SOURCE
/* "\x00\x00" FAMILY: 0 (because no address) */ * and SCOPE are 0.
/* "\x00" SOURCE PREFIX-LENGTH: 0 */ * "\x00\x02" FAMILY: 2 for IPv6 upstreams in network byte order, or
/* "\x00"; SCOPE PREFIX-LENGTH: 0 */ * "\x00\x01" FAMILY: 1 for IPv4 upstreams in network byte order, then:
return _getdns_network_req_add_upstream_option(req, * "\x00" SOURCE PREFIX-LENGTH: 0
GLDNS_EDNS_CLIENT_SUBNET, * "\x00"; SCOPE PREFIX-LENGTH: 0
4, NULL); */
return _getdns_network_req_add_upstream_option(
req, GLDNS_EDNS_CLIENT_SUBNET, 4,
( req->upstream->addr.ss_family == AF_INET6
? "\x00\x02\x00\x00" : "\x00\x01\x00\x00" ));
} }
static getdns_return_t static getdns_return_t
@ -982,9 +986,12 @@ tls_create_object(getdns_dns_req *dnsreq, int fd, getdns_upstream *upstream)
SSL_set_cipher_list(ssl, "DEFAULT"); SSL_set_cipher_list(ssl, "DEFAULT");
DEBUG_STUB("%s %-35s: WARNING: Using Oppotunistic TLS (fallback allowed)!\n", DEBUG_STUB("%s %-35s: WARNING: Using Oppotunistic TLS (fallback allowed)!\n",
STUB_DEBUG_SETUP_TLS, __FUNC__); STUB_DEBUG_SETUP_TLS, __FUNC__);
} else } else {
if (upstream->tls_cipher_list)
SSL_set_cipher_list(ssl, upstream->tls_cipher_list);
DEBUG_STUB("%s %-35s: Using Strict TLS \n", STUB_DEBUG_SETUP_TLS, DEBUG_STUB("%s %-35s: Using Strict TLS \n", STUB_DEBUG_SETUP_TLS,
__FUNC__); __FUNC__);
}
SSL_set_verify(ssl, SSL_VERIFY_PEER, tls_verify_callback); SSL_set_verify(ssl, SSL_VERIFY_PEER, tls_verify_callback);
SSL_set_connect_state(ssl); SSL_set_connect_state(ssl);

View File

@ -112,7 +112,10 @@ getdns_sync_data_cleanup(getdns_sync_data *data)
/* If statefull upstream have events scheduled against the sync loop, /* If statefull upstream have events scheduled against the sync loop,
* reschedule against the async loop. * reschedule against the async loop.
*/ */
for (i = 0; i < ctxt->upstreams->count; i++) { if (!ctxt->upstreams)
; /* pass */
else for (i = 0; i < ctxt->upstreams->count; i++) {
upstream = &ctxt->upstreams->upstreams[i]; upstream = &ctxt->upstreams->upstreams[i];
if (upstream->loop != &data->context->sync_eventloop.loop) if (upstream->loop != &data->context->sync_eventloop.loop)
continue; continue;

View File

@ -144,6 +144,8 @@
uint16_t payload_size; uint16_t payload_size;
uint8_t do_bit; uint8_t do_bit;
getdns_transport_t trans; getdns_transport_t trans;
int upstream_is_dnsmasq = 0;
getdns_bindata *version_str = NULL;
/* Note that stricly this test just establishes that the requested transport /* Note that stricly this test just establishes that the requested transport
and the reported transport are consistent, it does not guarentee which and the reported transport are consistent, it does not guarentee which
@ -156,6 +158,7 @@
ASSERT_RC(getdns_dict_set_int(extensions,"return_call_reporting", GETDNS_EXTENSION_TRUE), ASSERT_RC(getdns_dict_set_int(extensions,"return_call_reporting", GETDNS_EXTENSION_TRUE),
GETDNS_RETURN_GOOD, "Return code from getdns_dict_set_int()"); GETDNS_RETURN_GOOD, "Return code from getdns_dict_set_int()");
/* Request a response that should be truncated over UDP */ /* Request a response that should be truncated over UDP */
ASSERT_RC(getdns_context_set_dns_transport(context, GETDNS_TRANSPORT_UDP_ONLY), ASSERT_RC(getdns_context_set_dns_transport(context, GETDNS_TRANSPORT_UDP_ONLY),
GETDNS_RETURN_GOOD, "Return code from getdns_context_set_dns_transport()"); GETDNS_RETURN_GOOD, "Return code from getdns_context_set_dns_transport()");
@ -163,6 +166,15 @@
GETDNS_RETURN_GOOD, "Return code from getdns_context_get_dns_transport()"); GETDNS_RETURN_GOOD, "Return code from getdns_context_get_dns_transport()");
ck_assert_msg(trans == 541, "dns_transport should be 541(GETDNS_TRANSPORT_UDP_ONLY) but got %d", (int)trans); ck_assert_msg(trans == 541, "dns_transport should be 541(GETDNS_TRANSPORT_UDP_ONLY) but got %d", (int)trans);
ASSERT_RC(getdns_dict_set_int(extensions,"specify_class", GETDNS_RRCLASS_CH),
GETDNS_RETURN_GOOD, "Return code from getdns_dict_set_int()");
ASSERT_RC(getdns_general_sync(context, "version.bind.", GETDNS_RRTYPE_TXT, extensions, &response),
GETDNS_RETURN_GOOD, "Return code from getdns_general_sync()");
(void) getdns_dict_get_bindata(response, "/replies_tree/0/answer/0/rdata/txt_strings/0", &version_str);
upstream_is_dnsmasq = version_str && version_str->size > 7 &&
strncmp((char *)version_str->data, "dnsmasq", 7) == 0;
ASSERT_RC(getdns_dict_set_int(extensions,"specify_class", GETDNS_RRCLASS_IN),
GETDNS_RETURN_GOOD, "Return code from getdns_dict_set_int()");
ASSERT_RC(getdns_context_set_edns_maximum_udp_payload_size(context, 512), ASSERT_RC(getdns_context_set_edns_maximum_udp_payload_size(context, 512),
GETDNS_RETURN_GOOD, "Return code from getdns_context_set_edns_maximum_udp_payload_size()"); GETDNS_RETURN_GOOD, "Return code from getdns_context_set_edns_maximum_udp_payload_size()");
@ -187,35 +199,36 @@
ASSERT_RC(type, GETDNS_RESOLUTION_STUB, "Query did not use stub mode"); ASSERT_RC(type, GETDNS_RESOLUTION_STUB, "Query did not use stub mode");
ASSERT_RC(getdns_dict_get_int(response, "/replies_tree/0/header/tc", &tc), ASSERT_RC(getdns_dict_get_int(response, "/replies_tree/0/header/tc", &tc),
GETDNS_RETURN_GOOD, "Failed to extract \"tc\""); GETDNS_RETURN_GOOD, "Failed to extract \"tc\"");
ASSERT_RC(tc, 1, "Packet not trucated as expected"); if (!upstream_is_dnsmasq) {
ASSERT_RC(tc, 1, "Packet not truncated as expected");
/* Re-do over TCP */ /* Re-do over TCP */
ASSERT_RC(getdns_context_set_dns_transport(context, GETDNS_TRANSPORT_TCP_ONLY), ASSERT_RC(getdns_context_set_dns_transport(context, GETDNS_TRANSPORT_TCP_ONLY),
GETDNS_RETURN_GOOD, "Return code from getdns_context_set_dns_transport()"); GETDNS_RETURN_GOOD, "Return code from getdns_context_set_dns_transport()");
ASSERT_RC(getdns_general_sync(context, "large.getdnsapi.net", GETDNS_RRTYPE_TXT, extensions, &response),
GETDNS_RETURN_GOOD, "Return code from getdns_general_sync()");
ASSERT_RC(getdns_general_sync(context, "large.getdnsapi.net", GETDNS_RRTYPE_TXT, extensions, &response), ASSERT_RC(getdns_dict_get_int(response, "/call_reporting/0/transport", &transport),
GETDNS_RETURN_GOOD, "Return code from getdns_general_sync()"); GETDNS_RETURN_GOOD, "Failed to extract \"transport\"");
ASSERT_RC(transport, GETDNS_TRANSPORT_TCP, "Query did not go over TCP");
ASSERT_RC(getdns_dict_get_int(response, "/replies_tree/0/header/tc", &tc),
GETDNS_RETURN_GOOD, "Failed to extract \"tc\"");
ASSERT_RC(tc, 0, "Packet trucated - not as expected");
ASSERT_RC(getdns_dict_get_int(response, "/call_reporting/0/transport", &transport), /* Now let it fall back to TCP */
GETDNS_RETURN_GOOD, "Failed to extract \"transport\""); ASSERT_RC(getdns_context_set_dns_transport(context, GETDNS_TRANSPORT_UDP_FIRST_AND_FALL_BACK_TO_TCP),
ASSERT_RC(transport, GETDNS_TRANSPORT_TCP, "Query did not go over TCP"); GETDNS_RETURN_GOOD, "Return code from getdns_context_set_dns_transport()");
ASSERT_RC(getdns_dict_get_int(response, "/replies_tree/0/header/tc", &tc), ASSERT_RC(getdns_general_sync(context, "large.getdnsapi.net", GETDNS_RRTYPE_TXT, extensions, &response),
GETDNS_RETURN_GOOD, "Failed to extract \"tc\""); GETDNS_RETURN_GOOD, "Return code from getdns_general_sync()");
ASSERT_RC(tc, 0, "Packet trucated - not as expected");
/* Now let it fall back to TCP */
ASSERT_RC(getdns_context_set_dns_transport(context, GETDNS_TRANSPORT_UDP_FIRST_AND_FALL_BACK_TO_TCP),
GETDNS_RETURN_GOOD, "Return code from getdns_context_set_dns_transport()");
ASSERT_RC(getdns_general_sync(context, "large.getdnsapi.net", GETDNS_RRTYPE_TXT, extensions, &response),
GETDNS_RETURN_GOOD, "Return code from getdns_general_sync()");
ASSERT_RC(getdns_dict_get_int(response, "/call_reporting/0/transport", &transport),
GETDNS_RETURN_GOOD, "Failed to extract \"transport\"");
ASSERT_RC(transport, GETDNS_TRANSPORT_TCP, "Query did not go over TCP");
ASSERT_RC(getdns_dict_get_int(response, "/replies_tree/0/header/tc", &tc),
GETDNS_RETURN_GOOD, "Failed to extract \"tc\"");
ASSERT_RC(tc, 0, "Packet trucated - not as expected");
ASSERT_RC(getdns_dict_get_int(response, "/call_reporting/0/transport", &transport),
GETDNS_RETURN_GOOD, "Failed to extract \"transport\"");
ASSERT_RC(transport, GETDNS_TRANSPORT_TCP, "Query did not go over TCP");
ASSERT_RC(getdns_dict_get_int(response, "/replies_tree/0/header/tc", &tc),
GETDNS_RETURN_GOOD, "Failed to extract \"tc\"");
ASSERT_RC(tc, 0, "Packet trucated - not as expected");
}
ASSERT_RC(getdns_context_unset_edns_maximum_udp_payload_size(context), ASSERT_RC(getdns_context_unset_edns_maximum_udp_payload_size(context),
GETDNS_RETURN_GOOD, "Return code from getdns_context_unset_edns_maximum_udp_payload_size()"); GETDNS_RETURN_GOOD, "Return code from getdns_context_unset_edns_maximum_udp_payload_size()");

View File

@ -32,3 +32,9 @@ then
cat output cat output
exit 1 exit 1
fi fi
if ! awk '/^==.* ERROR SUMMARY/{print;if($4>0)exit(1)}' valgrind.log
then
cat valgrind.log
cat output
exit 1
fi

View File

@ -25,4 +25,4 @@ done
rm -fr "${BUILDDIR}/build-stub-only" rm -fr "${BUILDDIR}/build-stub-only"
mkdir "${BUILDDIR}/build-stub-only" mkdir "${BUILDDIR}/build-stub-only"
cd "${BUILDDIR}/build-stub-only" cd "${BUILDDIR}/build-stub-only"
"${SRCROOT}/configure" $* --enable-stub-only "${SRCROOT}/configure" $* --prefix "${BUILDDIR}/install-stub-only" --enable-stub-only

View File

@ -11,6 +11,7 @@ qwerlkjhasdfpuiqwyerm.1234kjhrqwersv.com
-G TXT bogus.nlnetlabs.nl -G TXT bogus.nlnetlabs.nl
-H 8.8.8.8 -H 8.8.8.8
-H 2a04:b900:0:100::37 -H 2a04:b900:0:100::37
-A _acme-challenge.getdnsapi.net
EOT EOT
( (
if ! "${BUILDDIR}/build-stub-only/libtool" exec valgrind -v --log-file=valgrind.log --leak-check=full --error-exitcode=1 --track-origins=yes "${GETDNS_STUB_QUERY}" -F queries -f "${TPKG_NAME}.ds" +dnssec_return_validation_chain if ! "${BUILDDIR}/build-stub-only/libtool" exec valgrind -v --log-file=valgrind.log --leak-check=full --error-exitcode=1 --track-origins=yes "${GETDNS_STUB_QUERY}" -F queries -f "${TPKG_NAME}.ds" +dnssec_return_validation_chain
@ -24,3 +25,9 @@ then
cat output cat output
exit 1 exit 1
fi fi
if ! awk '/^==.* ERROR SUMMARY/{print;if($4>0)exit(1)}' valgrind.log
then
cat valgrind.log
cat output
exit 1
fi

View File

@ -7,10 +7,10 @@
rm -fr "${BUILDDIR}/build-event-loops" rm -fr "${BUILDDIR}/build-event-loops"
mkdir "${BUILDDIR}/build-event-loops" mkdir "${BUILDDIR}/build-event-loops"
cd "${BUILDDIR}/build-event-loops" cd "${BUILDDIR}/build-event-loops"
"${SRCROOT}/configure" $* --enable-all-drafts --with-stubby --with-libevent --with-libev --with-libuv \ "${SRCROOT}/configure" $* --prefix "${BUILDDIR}/install" --enable-all-drafts --with-stubby --with-libevent --with-libev --with-libuv \
|| "${SRCROOT}/configure" $* --enable-all-drafts --with-stubby --with-libevent --with-libev \ || "${SRCROOT}/configure" $* --prefix "${BUILDDIR}/install" --enable-all-drafts --with-stubby --with-libevent --with-libev \
|| "${SRCROOT}/configure" $* --enable-all-drafts --with-stubby --with-libevent --with-libuv \ || "${SRCROOT}/configure" $* --prefix "${BUILDDIR}/install" --enable-all-drafts --with-stubby --with-libevent --with-libuv \
|| "${SRCROOT}/configure" $* --enable-all-drafts --with-stubby --with-libev --with-libuv \ || "${SRCROOT}/configure" $* --prefix "${BUILDDIR}/install" --enable-all-drafts --with-stubby --with-libev --with-libuv \
|| "${SRCROOT}/configure" $* --enable-all-drafts --with-stubby --with-libevent \ || "${SRCROOT}/configure" $* --prefix "${BUILDDIR}/install" --enable-all-drafts --with-stubby --with-libevent \
|| "${SRCROOT}/configure" $* --enable-all-drafts --with-stubby --with-libev \ || "${SRCROOT}/configure" $* --prefix "${BUILDDIR}/install" --enable-all-drafts --with-stubby --with-libev \
|| "${SRCROOT}/configure" $* --enable-all-drafts --with-stubby --with-libuv || "${SRCROOT}/configure" $* --prefix "${BUILDDIR}/install" --enable-all-drafts --with-stubby --with-libuv

View File

@ -25,11 +25,11 @@ done
rm -fr "${BUILDDIR}/build-static-analysis" rm -fr "${BUILDDIR}/build-static-analysis"
mkdir "${BUILDDIR}/build-static-analysis" mkdir "${BUILDDIR}/build-static-analysis"
cd "${BUILDDIR}/build-static-analysis" cd "${BUILDDIR}/build-static-analysis"
"${SRCROOT}/configure" $* --enable-all-drafts --with-stubby --with-libevent --with-libev --with-libuv \ "${SRCROOT}/configure" $* --prefix "${BUILDDIR}/install" --enable-all-drafts --with-stubby --with-libevent --with-libev --with-libuv \
|| "${SRCROOT}/configure" $* --enable-all-drafts --with-stubby --with-libevent --with-libev \ || "${SRCROOT}/configure" $* --prefix "${BUILDDIR}/install" --enable-all-drafts --with-stubby --with-libevent --with-libev \
|| "${SRCROOT}/configure" $* --enable-all-drafts --with-stubby --with-libevent --with-libuv \ || "${SRCROOT}/configure" $* --prefix "${BUILDDIR}/install" --enable-all-drafts --with-stubby --with-libevent --with-libuv \
|| "${SRCROOT}/configure" $* --enable-all-drafts --with-stubby --with-libev --with-libuv \ || "${SRCROOT}/configure" $* --prefix "${BUILDDIR}/install" --enable-all-drafts --with-stubby --with-libev --with-libuv \
|| "${SRCROOT}/configure" $* --enable-all-drafts --with-stubby --with-libevent \ || "${SRCROOT}/configure" $* --prefix "${BUILDDIR}/install" --enable-all-drafts --with-stubby --with-libevent \
|| "${SRCROOT}/configure" $* --enable-all-drafts --with-stubby --with-libev \ || "${SRCROOT}/configure" $* --prefix "${BUILDDIR}/install" --enable-all-drafts --with-stubby --with-libev \
|| "${SRCROOT}/configure" $* --enable-all-drafts --with-stubby --with-libuv || "${SRCROOT}/configure" $* --prefix "${BUILDDIR}/install" --enable-all-drafts --with-stubby --with-libuv

View File

@ -3,5 +3,5 @@
export SRCDIR=`dirname $0` export SRCDIR=`dirname $0`
( cd $SRCDIR ( cd $SRCDIR
./tpkg clean ./tpkg clean
rm -fr build build-stub-only build-event-loops build-static-analysis install scan-build-reports .tpkg.var.master *.info Makefile rm -fr build build-stub-only build-event-loops build-static-analysis install install-stub-only install-event-loops install-static-analysis scan-build-reports .tpkg.var.master *.info Makefile
) )

View File

@ -8,3 +8,4 @@ ONE_TEST=$1
shift shift
"${TPKG}" $* exe ${SRCDIR}/${ONE_TEST}.tpkg "${TPKG}" $* exe ${SRCDIR}/${ONE_TEST}.tpkg
"${TPKG}" -n -1 r

View File

@ -91,6 +91,10 @@ static int async = 0, interactive = 0;
static enum { GENERAL, ADDRESS, HOSTNAME, SERVICE } calltype = GENERAL; static enum { GENERAL, ADDRESS, HOSTNAME, SERVICE } calltype = GENERAL;
static int bogus_answers = 0; static int bogus_answers = 0;
static int check_dnssec = 0; static int check_dnssec = 0;
#ifndef USE_WINSOCK
static char *resolvconf = NULL;
#endif
static int print_api_info = 0, print_trust_anchors = 0;
static int get_rrtype(const char *t) static int get_rrtype(const char *t)
{ {
@ -252,9 +256,13 @@ print_usage(FILE *out, const char *progname)
fprintf(out, "\t-k\tPrint root trust anchors\n"); fprintf(out, "\t-k\tPrint root trust anchors\n");
fprintf(out, "\t-K <pin>\tPin a public key for TLS connections (can repeat)\n"); fprintf(out, "\t-K <pin>\tPin a public key for TLS connections (can repeat)\n");
fprintf(out, "\t\t(should look like '" EXAMPLE_PIN "')\n"); fprintf(out, "\t\t(should look like '" EXAMPLE_PIN "')\n");
fprintf(out, "\t-n\tSet TLS authentication mode to NONE (default)\n");
fprintf(out, "\t-m\tSet TLS authentication mode to REQUIRED\n"); fprintf(out, "\t-m\tSet TLS authentication mode to REQUIRED\n");
fprintf(out, "\t-p\tPretty print response dict\n"); fprintf(out, "\t-n\tSet TLS authentication mode to NONE (default)\n");
#ifndef USE_WINSOCK
fprintf(out, "\t-o <filename>\tSet resolver configuration file path\n");
fprintf(out, "\t\t(default = %s)\n", GETDNS_FN_RESOLVCONF);
#endif
fprintf(out, "\t-p\tPretty print response dict (default)\n");
fprintf(out, "\t-P <blocksize>\tPad TLS queries to a multiple of blocksize\n" fprintf(out, "\t-P <blocksize>\tPad TLS queries to a multiple of blocksize\n"
"\t\t(special values: 0: no padding, 1: sensible default policy)\n"); "\t\t(special values: 0: no padding, 1: sensible default policy)\n");
fprintf(out, "\t-q\tQuiet mode - don't print response\n"); fprintf(out, "\t-q\tQuiet mode - don't print response\n");
@ -592,7 +600,7 @@ getdns_return_t parse_args(int argc, char **argv)
size_t j; size_t j;
int i, klass; int i, klass;
char *arg, *c, *endptr; char *arg, *c, *endptr;
int t, print_api_info = 0, print_trust_anchors = 0; int t;
getdns_list *upstream_list = NULL; getdns_list *upstream_list = NULL;
getdns_list *tas = NULL, *hints = NULL; getdns_list *tas = NULL, *hints = NULL;
getdns_dict *pubkey_pin = NULL; getdns_dict *pubkey_pin = NULL;
@ -820,6 +828,16 @@ getdns_return_t parse_args(int argc, char **argv)
getdns_context_set_tls_authentication(context, getdns_context_set_tls_authentication(context,
GETDNS_AUTHENTICATION_REQUIRED); GETDNS_AUTHENTICATION_REQUIRED);
break; break;
#ifndef USE_WINSOCK
case 'o':
if (c[1] != 0 || ++i >= argc || !*argv[i]) {
fprintf(stderr, "<filename>"
"expected after -o\n");
return GETDNS_RETURN_GENERIC_ERROR;
}
resolvconf = argv[i];
break;
#endif
case 'P': case 'P':
if (c[1] != 0 || ++i >= argc || !*argv[i]) { if (c[1] != 0 || ++i >= argc || !*argv[i]) {
fprintf(stderr, "tls_query_padding_blocksize " fprintf(stderr, "tls_query_padding_blocksize "
@ -1102,44 +1120,6 @@ next: ;
if (upstream_list) if (upstream_list)
getdns_list_destroy(upstream_list); getdns_list_destroy(upstream_list);
if (print_api_info) {
getdns_dict *api_information =
getdns_context_get_api_information(context);
char *api_information_str;
if (listen_dict && !getdns_dict_get_list(
listen_dict, "listen_list", &listen_list)) {
(void) getdns_dict_set_list(api_information,
"listen_addresses", listen_list);
} else if (listen_list) {
(void) getdns_dict_set_list(api_information,
"listen_addresses", listen_list);
} else if ((listen_list = getdns_list_create())) {
(void) getdns_dict_set_list(api_information,
"listen_addresses", listen_list);
getdns_list_destroy(listen_list);
listen_list = NULL;
}
api_information_str =
getdns_pretty_print_dict(api_information);
fprintf(stdout, "%s\n", api_information_str);
free(api_information_str);
getdns_dict_destroy(api_information);
return CONTINUE;
}
if (print_trust_anchors) {
if (!getdns_context_get_dnssec_trust_anchors(context, &tas)) {
/* if ((tas = getdns_root_trust_anchor(NULL))) { */
char *tas_str = getdns_pretty_print_list(tas);
fprintf(stdout, "%s\n", tas_str);
free(tas_str);
getdns_list_destroy(tas);
return CONTINUE;
} else
return CONTINUE_ERROR;
}
return r; return r;
} }
@ -1757,8 +1737,67 @@ main(int argc, char **argv)
(void) getdns_context_set_logfunc(context, NULL, (void) getdns_context_set_logfunc(context, NULL,
GETDNS_LOG_UPSTREAM_STATS, GETDNS_LOG_DEBUG, stubby_log); GETDNS_LOG_UPSTREAM_STATS, GETDNS_LOG_DEBUG, stubby_log);
if ((r = parse_args(argc, argv))) if ((r = parse_args(argc, argv)) && r != CONTINUE)
goto done_destroy_context; goto done_destroy_context;
#ifndef USE_WINSOCK
if (resolvconf) {
if ((r = getdns_context_set_resolvconf(context, resolvconf))) {
fprintf(stderr, "Problem initializing with resolvconf: %d\n", (int)r);
goto done_destroy_context;
}
if ((r = parse_args(argc, argv)))
goto done_destroy_context;
}
#endif
if (print_api_info) {
getdns_dict *api_information =
getdns_context_get_api_information(context);
char *api_information_str;
if (listen_dict && !getdns_dict_get_list(
listen_dict, "listen_list", &listen_list)) {
(void) getdns_dict_set_list(api_information,
"listen_addresses", listen_list);
} else if (listen_list) {
(void) getdns_dict_set_list(api_information,
"listen_addresses", listen_list);
} else if ((listen_list = getdns_list_create())) {
(void) getdns_dict_set_list(api_information,
"listen_addresses", listen_list);
getdns_list_destroy(listen_list);
listen_list = NULL;
}
api_information_str = json
? getdns_print_json_dict(api_information, json == 1)
: getdns_pretty_print_dict(api_information);
fprintf(stdout, "%s\n", api_information_str);
free(api_information_str);
getdns_dict_destroy(api_information);
}
if (print_trust_anchors) {
getdns_list *tas = NULL;
if (!getdns_context_get_dnssec_trust_anchors(context, &tas)) {
/* if ((tas = getdns_root_trust_anchor(NULL))) { */
char *tas_str;
tas_str = json
? getdns_print_json_list(tas, json == 1)
: getdns_pretty_print_list(tas);
fprintf(stdout, "%s\n", tas_str);
free(tas_str);
getdns_list_destroy(tas);
}
}
if (!r && (print_trust_anchors || print_api_info)) {
r = CONTINUE;
}
if (r)
goto done_destroy_context;
clear_listen_list_on_arg = 0; clear_listen_list_on_arg = 0;
if (query_file) { if (query_file) {

View File

@ -425,6 +425,7 @@ typedef struct getdns_dns_req {
extern getdns_dict *dnssec_ok_checking_disabled; extern getdns_dict *dnssec_ok_checking_disabled;
extern getdns_dict *dnssec_ok_checking_disabled_roadblock_avoidance; extern getdns_dict *dnssec_ok_checking_disabled_roadblock_avoidance;
extern getdns_dict *dnssec_ok_checking_disabled_avoid_roadblocks; extern getdns_dict *dnssec_ok_checking_disabled_avoid_roadblocks;
extern getdns_dict *no_dnssec_checking_disabled_opportunistic;
/* dns request utils */ /* dns request utils */
getdns_dns_req *_getdns_dns_req_new(getdns_context *context, getdns_eventloop *loop, getdns_dns_req *_getdns_dns_req_new(getdns_context *context, getdns_eventloop *loop,

2
stubby

@ -1 +1 @@
Subproject commit a43be56e28f3a802f74b7c5b19b4b4c5fbaa908a Subproject commit f0b330454b95a07106af33b1869b7cd18cfaebf2