mirror of https://github.com/getdnsapi/getdns.git
release v0.1.8
-----BEGIN PGP SIGNATURE----- Version: GnuPG v1 iQIcBAABAgAGBQJVNB2sAAoJEOX4+CEvd6SYQVkP/1AgRoUw+5BM6gm+z5J4heXg W9EpICfKn2BTC8JVwVOzA3LHJZ95tosNv+fy0faK0n7jByvT4ySl4V/k2W9JSd/S bhDR5A1zyfYJdLTDONdkwXki9H90MW69lRGfh+zb0VHzFwi/10xQqYlUatF0IxY3 Vg4L0PBaUC4UsQevjJNxDJQkr4Q5hJph9jLyij7Zfty/rqjDIZoQpZgMeoZIr9xI v51lnlG0ss6lnSRUkM1Nta3mFsXhTDNAhe8/pPUP+lWXceXqCWK63vJGf6Lp3LN4 gw/COsGnQdiUIbfRGWWGXuqG4c52SAK+ZE9D01bOeLJHw2S8IuA8oFvXdwfGcvYQ /gax26lguWk4IrgWIHTRalZJbn+mTNG/DXqrpOuw+BWp3prdoJmyvtOc0rLX1OB2 ueDDphPg/kSiSknnMmrUgHC2elWewsZCFhx5Umy149ONQK85AQ08DAtJP5dHsXzi Om/wuvbuzhoHtPV9YZZYcTa6uSVWaMLHLVJ5K9ifTJEvIKk4pVwbsFS5XIZAVEig yGmSsngTQP4w3LdFZSCk3FRu0D+y60sG++Gs1X2X+TsLP/6ZoOL0lYEkPwGfHsvL dhgG+iNUgSKmLwrpyI7c1DD1ZlpZluomjQQ5evfogHOmZC22AJvuNQI6hJY1pvXQ AU+pzxUfo8947+nEJxMR =qFXQ -----END PGP SIGNATURE----- Merge tag 'v0.1.8' release v0.1.8
This commit is contained in:
commit
29b378ab16
|
@ -1,3 +1,8 @@
|
|||
* 2015-04-19: Version 0.1.8
|
||||
* The GETDNS_TRANSPORT_TLS_ONLY_KEEP_CONNECTIONS_OPEN and
|
||||
GETDNS_TRANSPORT_TLS_FIRST_AND_FALL_BACK_TO_TCP_KEEP_CONNECTIONS_OPEN
|
||||
DNS over TLS transport options.
|
||||
|
||||
* 2015-04-08: Version 0.1.7
|
||||
* Individual getter functions for context settings
|
||||
* Fix: --with-current-date function to make build deterministically
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
#! /bin/sh
|
||||
# Guess values for system-dependent variables and create Makefiles.
|
||||
# Generated by GNU Autoconf 2.69 for getdns 0.1.7.
|
||||
# Generated by GNU Autoconf 2.69 for getdns 0.1.8.
|
||||
#
|
||||
# Report bugs to <stub-resolver@verisignlabs.com>.
|
||||
#
|
||||
|
@ -590,8 +590,8 @@ MAKEFLAGS=
|
|||
# Identity of this package.
|
||||
PACKAGE_NAME='getdns'
|
||||
PACKAGE_TARNAME='getdns'
|
||||
PACKAGE_VERSION='0.1.7'
|
||||
PACKAGE_STRING='getdns 0.1.7'
|
||||
PACKAGE_VERSION='0.1.8'
|
||||
PACKAGE_STRING='getdns 0.1.8'
|
||||
PACKAGE_BUGREPORT='stub-resolver@verisignlabs.com'
|
||||
PACKAGE_URL='http://getdnsapi.net'
|
||||
|
||||
|
@ -1323,7 +1323,7 @@ if test "$ac_init_help" = "long"; then
|
|||
# Omit some internal or obsolete options to make the list less imposing.
|
||||
# This message is too long to be a string in the A/UX 3.1 sh.
|
||||
cat <<_ACEOF
|
||||
\`configure' configures getdns 0.1.7 to adapt to many kinds of systems.
|
||||
\`configure' configures getdns 0.1.8 to adapt to many kinds of systems.
|
||||
|
||||
Usage: $0 [OPTION]... [VAR=VALUE]...
|
||||
|
||||
|
@ -1388,7 +1388,7 @@ fi
|
|||
|
||||
if test -n "$ac_init_help"; then
|
||||
case $ac_init_help in
|
||||
short | recursive ) echo "Configuration of getdns 0.1.7:";;
|
||||
short | recursive ) echo "Configuration of getdns 0.1.8:";;
|
||||
esac
|
||||
cat <<\_ACEOF
|
||||
|
||||
|
@ -1519,7 +1519,7 @@ fi
|
|||
test -n "$ac_init_help" && exit $ac_status
|
||||
if $ac_init_version; then
|
||||
cat <<\_ACEOF
|
||||
getdns configure 0.1.7
|
||||
getdns configure 0.1.8
|
||||
generated by GNU Autoconf 2.69
|
||||
|
||||
Copyright (C) 2012 Free Software Foundation, Inc.
|
||||
|
@ -2008,7 +2008,7 @@ cat >config.log <<_ACEOF
|
|||
This file contains any messages produced by compilers while
|
||||
running configure, to aid debugging if configure makes a mistake.
|
||||
|
||||
It was created by getdns $as_me 0.1.7, which was
|
||||
It was created by getdns $as_me 0.1.8, which was
|
||||
generated by GNU Autoconf 2.69. Invocation command line was
|
||||
|
||||
$ $0 $@
|
||||
|
@ -2367,7 +2367,7 @@ else
|
|||
CURRENT_DATE="`date -u +%Y-%m-%dT%H:%M:%SZ`"
|
||||
fi
|
||||
|
||||
GETDNS_COMPILATION_COMMENT="getdns 0.1.7 configured on $CURRENT_DATE for the January 2015 version of the API"
|
||||
GETDNS_COMPILATION_COMMENT="getdns 0.1.8 configured on $CURRENT_DATE for the January 2015 version of the API"
|
||||
|
||||
# Library version
|
||||
# ---------------
|
||||
|
@ -2387,9 +2387,10 @@ GETDNS_COMPILATION_COMMENT="getdns 0.1.7 configured on $CURRENT_DATE for the Jan
|
|||
# getdns-0.1.4 had libversion 0:0:0
|
||||
# getdns-0.1.5 had libversion 1:0:0
|
||||
# getdns-0.1.6 had libversion 1:1:0
|
||||
# getdns-0.1.7 will have libversion 1:2:1
|
||||
# getdns-0.1.7 had libversion 1:2:1
|
||||
# getdns-0.1.8 will have libversion 1:3:0
|
||||
#
|
||||
GETDNS_LIBVERSION=1:2:1
|
||||
GETDNS_LIBVERSION=1:3:0
|
||||
|
||||
|
||||
|
||||
|
@ -11333,8 +11334,8 @@ $as_echo "found in $ssldir" >&6; }
|
|||
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for HMAC_CTX_init in -lcrypto" >&5
|
||||
$as_echo_n "checking for HMAC_CTX_init in -lcrypto... " >&6; }
|
||||
LIBS="$LIBS -lcrypto"
|
||||
LIBSSL_LIBS="$LIBSSL_LIBS -lcrypto"
|
||||
LIBS="$LIBS -lcrypto -lssl"
|
||||
LIBSSL_LIBS="$LIBSSL_LIBS -lcrypto -lssl"
|
||||
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||
/* end confdefs.h. */
|
||||
|
||||
|
@ -11543,6 +11544,51 @@ fi
|
|||
|
||||
done
|
||||
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for TLSv1_2_client_method in -lssl" >&5
|
||||
$as_echo_n "checking for TLSv1_2_client_method in -lssl... " >&6; }
|
||||
if ${ac_cv_lib_ssl_TLSv1_2_client_method+:} false; then :
|
||||
$as_echo_n "(cached) " >&6
|
||||
else
|
||||
ac_check_lib_save_LIBS=$LIBS
|
||||
LIBS="-lssl $LIBS"
|
||||
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||
/* end confdefs.h. */
|
||||
|
||||
/* Override any GCC internal prototype to avoid an error.
|
||||
Use char because int might match the return type of a GCC
|
||||
builtin and then its argument prototype would still apply. */
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
#endif
|
||||
char TLSv1_2_client_method ();
|
||||
int
|
||||
main ()
|
||||
{
|
||||
return TLSv1_2_client_method ();
|
||||
;
|
||||
return 0;
|
||||
}
|
||||
_ACEOF
|
||||
if ac_fn_c_try_link "$LINENO"; then :
|
||||
ac_cv_lib_ssl_TLSv1_2_client_method=yes
|
||||
else
|
||||
ac_cv_lib_ssl_TLSv1_2_client_method=no
|
||||
fi
|
||||
rm -f core conftest.err conftest.$ac_objext \
|
||||
conftest$ac_exeext conftest.$ac_ext
|
||||
LIBS=$ac_check_lib_save_LIBS
|
||||
fi
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_ssl_TLSv1_2_client_method" >&5
|
||||
$as_echo "$ac_cv_lib_ssl_TLSv1_2_client_method" >&6; }
|
||||
if test "x$ac_cv_lib_ssl_TLSv1_2_client_method" = xyes; then :
|
||||
|
||||
$as_echo "#define HAVE_LIBTLS1_2 1" >>confdefs.h
|
||||
|
||||
else
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Cannot find TLSv1_2_client_method in libssl library. TLS will not be available." >&5
|
||||
$as_echo "$as_me: WARNING: Cannot find TLSv1_2_client_method in libssl library. TLS will not be available." >&2;}
|
||||
fi
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -14277,7 +14323,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
|
|||
# report actual input values of CONFIG_FILES etc. instead of their
|
||||
# values after options handling.
|
||||
ac_log="
|
||||
This file was extended by getdns $as_me 0.1.7, which was
|
||||
This file was extended by getdns $as_me 0.1.8, which was
|
||||
generated by GNU Autoconf 2.69. Invocation command line was
|
||||
|
||||
CONFIG_FILES = $CONFIG_FILES
|
||||
|
@ -14344,7 +14390,7 @@ _ACEOF
|
|||
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
|
||||
ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
|
||||
ac_cs_version="\\
|
||||
getdns config.status 0.1.7
|
||||
getdns config.status 0.1.8
|
||||
configured by $0, generated by GNU Autoconf 2.69,
|
||||
with options \\"\$ac_cs_config\\"
|
||||
|
||||
|
|
11
configure.ac
11
configure.ac
|
@ -31,7 +31,7 @@
|
|||
|
||||
AC_PREREQ([2.56])
|
||||
|
||||
AC_INIT([getdns], [0.1.7], [stub-resolver@verisignlabs.com], [], [http://getdnsapi.net])
|
||||
AC_INIT([getdns], [0.1.8], [stub-resolver@verisignlabs.com], [], [http://getdnsapi.net])
|
||||
AC_SUBST(RELEASE_CANDIDATE, [])
|
||||
|
||||
# Set current date from system if not set
|
||||
|
@ -60,9 +60,10 @@ GETDNS_COMPILATION_COMMENT="AC_PACKAGE_STRING configured on $CURRENT_DATE for th
|
|||
# getdns-0.1.4 had libversion 0:0:0
|
||||
# getdns-0.1.5 had libversion 1:0:0
|
||||
# getdns-0.1.6 had libversion 1:1:0
|
||||
# getdns-0.1.7 will have libversion 1:2:1
|
||||
# getdns-0.1.7 had libversion 1:2:1
|
||||
# getdns-0.1.8 will have libversion 1:3:0
|
||||
#
|
||||
GETDNS_LIBVERSION=1:2:1
|
||||
GETDNS_LIBVERSION=1:3:0
|
||||
|
||||
AC_SUBST(GETDNS_COMPILATION_COMMENT)
|
||||
AC_SUBST(GETDNS_LIBVERSION)
|
||||
|
@ -741,6 +742,10 @@ unsigned char *SHA512(void* data, unsigned int data_len, unsigned char *digest);
|
|||
#include <arpa/inet.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_OPENSSL_SSL_H
|
||||
#include <openssl/ssl.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_ATTR_FORMAT
|
||||
# define ATTR_FORMAT(archetype, string_index, first_to_check) \
|
||||
__attribute__ ((format (archetype, string_index, first_to_check)))
|
||||
|
|
|
@ -48,8 +48,8 @@ AC_DEFUN([ACX_SSL_CHECKS], [
|
|||
fi
|
||||
|
||||
AC_MSG_CHECKING([for HMAC_CTX_init in -lcrypto])
|
||||
LIBS="$LIBS -lcrypto"
|
||||
LIBSSL_LIBS="$LIBSSL_LIBS -lcrypto"
|
||||
LIBS="$LIBS -lcrypto -lssl"
|
||||
LIBSSL_LIBS="$LIBSSL_LIBS -lcrypto -lssl"
|
||||
AC_TRY_LINK(, [
|
||||
int HMAC_CTX_init(void);
|
||||
(void)HMAC_CTX_init();
|
||||
|
@ -105,6 +105,8 @@ AC_DEFUN([ACX_SSL_CHECKS], [
|
|||
AC_CHECK_HEADERS([openssl/ssl.h],,, [AC_INCLUDES_DEFAULT])
|
||||
AC_CHECK_HEADERS([openssl/err.h],,, [AC_INCLUDES_DEFAULT])
|
||||
AC_CHECK_HEADERS([openssl/rand.h],,, [AC_INCLUDES_DEFAULT])
|
||||
AC_CHECK_LIB(ssl, TLSv1_2_client_method,AC_DEFINE([HAVE_LIBTLS1_2], [1],
|
||||
[Define if you have libssl with tls 1.2]),[AC_MSG_WARN([Cannot find TLSv1_2_client_method in libssl library. TLS will not be available.])])
|
||||
])dnl End of ACX_SSL_CHECKS
|
||||
|
||||
dnl Check for SSL, where SSL is mandatory
|
||||
|
|
|
@ -2193,8 +2193,10 @@ getdns_context_set_dns_transport(
|
|||
The value is <span class=default>
|
||||
<code>GETDNS_TRANSPORT_UDP_FIRST_AND_FALL_BACK_TO_TCP</code></span>,
|
||||
<code>GETDNS_TRANSPORT_UDP_ONLY</code>,
|
||||
<code>GETDNS_TRANSPORT_TCP_ONLY</code>, or
|
||||
<code>GETDNS_TRANSPORT_TCP_ONLY_KEEP_CONNECTIONS_OPEN</code>.</p>
|
||||
<code>GETDNS_TRANSPORT_TCP_ONLY</code>,
|
||||
<code>GETDNS_TRANSPORT_TCP_ONLY_KEEP_CONNECTIONS_OPEN></code>,
|
||||
<code>GETDNS_TRANSPORT_TLS_ONLY_KEEP_CONNECTIONS_OPEN></code>, or
|
||||
<code>GETDNS_TRANSPORT_TLS_FIRST_AND_FALL_BACK_TO_TCP_KEEP_CONNECTIONS_OPEN></code>
|
||||
|
||||
<div class=forh>
|
||||
getdns_return_t
|
||||
|
|
|
@ -84,6 +84,9 @@
|
|||
/* Define to 1 if you have the `ldns' library (-lldns). */
|
||||
#undef HAVE_LIBLDNS
|
||||
|
||||
/* Define if you have libssl with tls 1.2 */
|
||||
#undef HAVE_LIBTLS1_2
|
||||
|
||||
/* Define to 1 if you have the `unbound' library (-lunbound). */
|
||||
#undef HAVE_LIBUNBOUND
|
||||
|
||||
|
@ -320,6 +323,10 @@ unsigned char *SHA512(void* data, unsigned int data_len, unsigned char *digest);
|
|||
#include <arpa/inet.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_OPENSSL_SSL_H
|
||||
#include <openssl/ssl.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_ATTR_FORMAT
|
||||
# define ATTR_FORMAT(archetype, string_index, first_to_check) \
|
||||
__attribute__ ((format (archetype, string_index, first_to_check)))
|
||||
|
|
|
@ -39,6 +39,8 @@ static struct const_info consts_info[] = {
|
|||
{ 541, "GETDNS_TRANSPORT_UDP_ONLY", GETDNS_TRANSPORT_UDP_ONLY_TEXT },
|
||||
{ 542, "GETDNS_TRANSPORT_TCP_ONLY", GETDNS_TRANSPORT_TCP_ONLY_TEXT },
|
||||
{ 543, "GETDNS_TRANSPORT_TCP_ONLY_KEEP_CONNECTIONS_OPEN", GETDNS_TRANSPORT_TCP_ONLY_KEEP_CONNECTIONS_OPEN_TEXT },
|
||||
{ 544, "GETDNS_TRANSPORT_TLS_ONLY_KEEP_CONNECTIONS_OPEN", GETDNS_TRANSPORT_TLS_ONLY_KEEP_CONNECTIONS_OPEN_TEXT },
|
||||
{ 545, "GETDNS_TRANSPORT_TLS_FIRST_AND_FALL_BACK_TO_TCP_KEEP_CONNECTIONS_OPEN", GETDNS_TRANSPORT_TLS_FIRST_AND_FALL_BACK_TO_TCP_KEEP_CONNECTIONS_OPEN_TEXT },
|
||||
{ 550, "GETDNS_APPEND_NAME_ALWAYS", GETDNS_APPEND_NAME_ALWAYS_TEXT },
|
||||
{ 551, "GETDNS_APPEND_NAME_ONLY_TO_SINGLE_LABEL_AFTER_FAILURE", GETDNS_APPEND_NAME_ONLY_TO_SINGLE_LABEL_AFTER_FAILURE_TEXT },
|
||||
{ 552, "GETDNS_APPEND_NAME_ONLY_TO_MULTIPLE_LABEL_NAME_AFTER_FAILURE", GETDNS_APPEND_NAME_ONLY_TO_MULTIPLE_LABEL_NAME_AFTER_FAILURE_TEXT },
|
||||
|
|
125
src/context.c
125
src/context.c
|
@ -470,11 +470,22 @@ upstreams_resize(getdns_upstreams *upstreams, size_t size)
|
|||
return r;
|
||||
}
|
||||
|
||||
static void
|
||||
upstreams_dereference(getdns_upstreams *upstreams)
|
||||
void
|
||||
priv_getdns_upstreams_dereference(getdns_upstreams *upstreams)
|
||||
{
|
||||
if (upstreams && --upstreams->referenced == 0)
|
||||
size_t i;
|
||||
|
||||
if (upstreams && --upstreams->referenced == 0) {
|
||||
for (i = 0; i < upstreams->count; i++) {
|
||||
if (upstreams->upstreams[i].tls_obj != NULL) {
|
||||
SSL_shutdown(upstreams->upstreams[i].tls_obj);
|
||||
SSL_free(upstreams->upstreams[i].tls_obj);
|
||||
}
|
||||
if (upstreams->upstreams[i].fd != -1)
|
||||
close(upstreams->upstreams[i].fd);
|
||||
}
|
||||
GETDNS_FREE(upstreams->mf, upstreams);
|
||||
}
|
||||
}
|
||||
|
||||
static uint8_t*
|
||||
|
@ -503,7 +514,8 @@ upstream_scope_id(getdns_upstream *upstream)
|
|||
}
|
||||
|
||||
static void
|
||||
upstream_ntop_buf(getdns_upstream *upstream, char *buf, size_t len)
|
||||
upstream_ntop_buf(getdns_upstream *upstream, getdns_transport_t transport,
|
||||
char *buf, size_t len)
|
||||
{
|
||||
/* Also possible but prints scope_id by name (nor parsed by unbound)
|
||||
*
|
||||
|
@ -515,7 +527,10 @@ upstream_ntop_buf(getdns_upstream *upstream, char *buf, size_t len)
|
|||
if (upstream_scope_id(upstream))
|
||||
(void) snprintf(buf + strlen(buf), len - strlen(buf),
|
||||
"%%%d", (int)*upstream_scope_id(upstream));
|
||||
if (upstream_port(upstream) != 53 && upstream_port(upstream) != 0)
|
||||
if (transport == GETDNS_TRANSPORT_TLS_ONLY_KEEP_CONNECTIONS_OPEN)
|
||||
(void) snprintf(buf + strlen(buf), len - strlen(buf),
|
||||
"@%d", GETDNS_TLS_PORT);
|
||||
else if (upstream_port(upstream) != 53 && upstream_port(upstream) != 0)
|
||||
(void) snprintf(buf + strlen(buf), len - strlen(buf),
|
||||
"@%d", (int)upstream_port(upstream));
|
||||
}
|
||||
|
@ -541,6 +556,7 @@ upstream_init(getdns_upstream *upstream,
|
|||
|
||||
/* For sharing a socket to this upstream with TCP */
|
||||
upstream->fd = -1;
|
||||
upstream->tls_obj = NULL;
|
||||
upstream->loop = NULL;
|
||||
(void) getdns_eventloop_event_init(
|
||||
&upstream->event, upstream, NULL, NULL, NULL);
|
||||
|
@ -770,6 +786,7 @@ getdns_context_create_with_extended_memory_functions(
|
|||
result->edns_extended_rcode = 0;
|
||||
result->edns_version = 0;
|
||||
result->edns_do_bit = 0;
|
||||
result-> tls_ctx = NULL;
|
||||
|
||||
result->extension = &result->mini_event.loop;
|
||||
if ((r = getdns_mini_event_init(result, &result->mini_event)))
|
||||
|
@ -789,6 +806,9 @@ getdns_context_create_with_extended_memory_functions(
|
|||
result->return_dnssec_status = GETDNS_EXTENSION_FALSE;
|
||||
|
||||
/* unbound context is initialized here */
|
||||
/* Unbound needs SSL to be init'ed this early when TLS is used. However we
|
||||
* don't know that till later so we will have to do this every time. */
|
||||
SSL_library_init();
|
||||
result->unbound_ctx = NULL;
|
||||
if ((r = rebuild_ub_ctx(result)))
|
||||
goto error;
|
||||
|
@ -876,6 +896,9 @@ getdns_context_destroy(struct getdns_context *context)
|
|||
GETDNS_FREE(context->my_mf, context->fchg_hosts->prevstat);
|
||||
GETDNS_FREE(context->my_mf, context->fchg_hosts);
|
||||
}
|
||||
if (context->tls_ctx) {
|
||||
SSL_CTX_free(context->tls_ctx);
|
||||
}
|
||||
|
||||
getdns_list_destroy(context->dns_root_servers);
|
||||
getdns_list_destroy(context->suffix);
|
||||
|
@ -887,7 +910,7 @@ getdns_context_destroy(struct getdns_context *context)
|
|||
|
||||
getdns_traverse_postorder(&context->local_hosts,
|
||||
destroy_local_host, context);
|
||||
upstreams_dereference(context->upstreams);
|
||||
priv_getdns_upstreams_dereference(context->upstreams);
|
||||
|
||||
GETDNS_FREE(context->my_mf, context);
|
||||
} /* getdns_context_destroy */
|
||||
|
@ -1101,6 +1124,33 @@ getdns_context_set_namespaces(struct getdns_context *context,
|
|||
return GETDNS_RETURN_GOOD;
|
||||
} /* getdns_context_set_namespaces */
|
||||
|
||||
getdns_base_transport_t
|
||||
priv_get_base_transport(getdns_transport_t transport, int level) {
|
||||
if (!(level == 0 || level == 1)) return GETDNS_TRANSPORT_NONE;
|
||||
switch (transport) {
|
||||
case GETDNS_TRANSPORT_UDP_FIRST_AND_FALL_BACK_TO_TCP:
|
||||
if (level == 0) return GETDNS_TRANSPORT_UDP;
|
||||
if (level == 1) return GETDNS_TRANSPORT_TCP;
|
||||
case GETDNS_TRANSPORT_UDP_ONLY:
|
||||
if (level == 0) return GETDNS_TRANSPORT_UDP;
|
||||
if (level == 1) return GETDNS_TRANSPORT_NONE;
|
||||
case GETDNS_TRANSPORT_TCP_ONLY:
|
||||
if (level == 0) return GETDNS_TRANSPORT_TCP_SINGLE;
|
||||
if (level == 1) return GETDNS_TRANSPORT_NONE;
|
||||
case GETDNS_TRANSPORT_TCP_ONLY_KEEP_CONNECTIONS_OPEN:
|
||||
if (level == 0) return GETDNS_TRANSPORT_TCP;
|
||||
if (level == 1) return GETDNS_TRANSPORT_NONE;
|
||||
case GETDNS_TRANSPORT_TLS_ONLY_KEEP_CONNECTIONS_OPEN:
|
||||
if (level == 0) return GETDNS_TRANSPORT_TLS;
|
||||
if (level == 1) return GETDNS_TRANSPORT_NONE;
|
||||
case GETDNS_TRANSPORT_TLS_FIRST_AND_FALL_BACK_TO_TCP_KEEP_CONNECTIONS_OPEN:
|
||||
if (level == 0) return GETDNS_TRANSPORT_TLS;
|
||||
if (level == 1) return GETDNS_TRANSPORT_TCP;
|
||||
default:
|
||||
return GETDNS_TRANSPORT_NONE;
|
||||
}
|
||||
}
|
||||
|
||||
static getdns_return_t
|
||||
set_ub_dns_transport(struct getdns_context* context,
|
||||
getdns_transport_t value) {
|
||||
|
@ -1114,13 +1164,25 @@ set_ub_dns_transport(struct getdns_context* context,
|
|||
set_ub_string_opt(context, "do-tcp:", "no");
|
||||
break;
|
||||
case GETDNS_TRANSPORT_TCP_ONLY:
|
||||
case GETDNS_TRANSPORT_TCP_ONLY_KEEP_CONNECTIONS_OPEN:
|
||||
/* Note: no pipelining available directly in unbound.*/
|
||||
case GETDNS_TRANSPORT_TCP_ONLY_KEEP_CONNECTIONS_OPEN:
|
||||
set_ub_string_opt(context, "do-udp:", "no");
|
||||
set_ub_string_opt(context, "do-tcp:", "yes");
|
||||
break;
|
||||
default:
|
||||
/* TODO GETDNS_CONTEXT_TCP_ONLY_KEEP_CONNECTIONS_OPEN */
|
||||
return GETDNS_RETURN_CONTEXT_UPDATE_FAIL;
|
||||
case GETDNS_TRANSPORT_TLS_ONLY_KEEP_CONNECTIONS_OPEN:
|
||||
/* Hum. If used in recursive mode this will try TLS on port 53...
|
||||
* So we need to fix or document that or delay setting it until
|
||||
* resolution.*/
|
||||
set_ub_string_opt(context, "ssl-upstream:", "yes");
|
||||
/* Fall through*/
|
||||
case GETDNS_TRANSPORT_TLS_FIRST_AND_FALL_BACK_TO_TCP_KEEP_CONNECTIONS_OPEN:
|
||||
/* Note: no fallback to TCP available directly in unbound, so we just
|
||||
* use TCP for now to make sure the messages are sent. */
|
||||
set_ub_string_opt(context, "do-udp:", "no");
|
||||
set_ub_string_opt(context, "do-tcp:", "yes");
|
||||
break;
|
||||
default:
|
||||
return GETDNS_RETURN_CONTEXT_UPDATE_FAIL;
|
||||
}
|
||||
return GETDNS_RETURN_GOOD;
|
||||
}
|
||||
|
@ -1134,6 +1196,11 @@ getdns_context_set_dns_transport(struct getdns_context *context,
|
|||
getdns_transport_t value)
|
||||
{
|
||||
RETURN_IF_NULL(context, GETDNS_RETURN_INVALID_PARAMETER);
|
||||
/* Note that the call below does not have any effect in unbound after the
|
||||
* ctx is finalised. So will not apply for recursive mode or stub + dnssec.
|
||||
* However the method returns success as otherwise the transport could not
|
||||
* be reset for stub mode.....
|
||||
* Also, not all transport options supported in libunbound yet */
|
||||
if (set_ub_dns_transport(context, value) != GETDNS_RETURN_GOOD) {
|
||||
return GETDNS_RETURN_CONTEXT_UPDATE_FAIL;
|
||||
}
|
||||
|
@ -1447,7 +1514,7 @@ getdns_context_set_upstream_recursive_servers(struct getdns_context *context,
|
|||
upstreams->count++;
|
||||
freeaddrinfo(ai);
|
||||
}
|
||||
upstreams_dereference(context->upstreams);
|
||||
priv_getdns_upstreams_dereference(context->upstreams);
|
||||
context->upstreams = upstreams;
|
||||
dispatch_updated(context,
|
||||
GETDNS_CONTEXT_CODE_UPSTREAM_RECURSIVE_SERVERS);
|
||||
|
@ -1457,7 +1524,7 @@ getdns_context_set_upstream_recursive_servers(struct getdns_context *context,
|
|||
invalid_parameter:
|
||||
r = GETDNS_RETURN_INVALID_PARAMETER;
|
||||
error:
|
||||
upstreams_dereference(upstreams);
|
||||
priv_getdns_upstreams_dereference(upstreams);
|
||||
return GETDNS_RETURN_CONTEXT_UPDATE_FAIL;
|
||||
} /* getdns_context_set_upstream_recursive_servers */
|
||||
|
||||
|
@ -1653,17 +1720,18 @@ getdns_cancel_callback(getdns_context *context,
|
|||
} /* getdns_cancel_callback */
|
||||
|
||||
static getdns_return_t
|
||||
ub_setup_stub(struct ub_ctx *ctx, getdns_upstreams *upstreams)
|
||||
ub_setup_stub(struct ub_ctx *ctx, getdns_context *context)
|
||||
{
|
||||
getdns_return_t r = GETDNS_RETURN_GOOD;
|
||||
size_t i;
|
||||
getdns_upstream *upstream;
|
||||
char addr[1024];
|
||||
getdns_upstreams *upstreams = context->upstreams;
|
||||
|
||||
(void) ub_ctx_set_fwd(ctx, NULL);
|
||||
for (i = 0; i < upstreams->count; i++) {
|
||||
upstream = &upstreams->upstreams[i];
|
||||
upstream_ntop_buf(upstream, addr, 1024);
|
||||
upstream_ntop_buf(upstream, context->dns_transport, addr, 1024);
|
||||
ub_ctx_set_fwd(ctx, addr);
|
||||
}
|
||||
|
||||
|
@ -1735,7 +1803,7 @@ priv_getdns_ns_dns_setup(struct getdns_context *context)
|
|||
case GETDNS_RESOLUTION_STUB:
|
||||
if (!context->upstreams || !context->upstreams->count)
|
||||
return GETDNS_RETURN_GENERIC_ERROR;
|
||||
return ub_setup_stub(context->unbound_ctx, context->upstreams);
|
||||
return ub_setup_stub(context->unbound_ctx, context);
|
||||
|
||||
case GETDNS_RESOLUTION_RECURSING:
|
||||
/* TODO: use the root servers via root hints file */
|
||||
|
@ -1756,6 +1824,33 @@ getdns_context_prepare_for_resolution(struct getdns_context *context,
|
|||
if (context->destroying) {
|
||||
return GETDNS_RETURN_BAD_CONTEXT;
|
||||
}
|
||||
|
||||
/* Transport can in theory be set per query in stub mode */
|
||||
/* TODO: move this transport logic to a separate functions*/
|
||||
if (context->resolution_type == GETDNS_RESOLUTION_STUB) {
|
||||
switch (context->dns_transport) {
|
||||
case GETDNS_TRANSPORT_TLS_ONLY_KEEP_CONNECTIONS_OPEN:
|
||||
case GETDNS_TRANSPORT_TLS_FIRST_AND_FALL_BACK_TO_TCP_KEEP_CONNECTIONS_OPEN:
|
||||
if (context->tls_ctx == NULL) {
|
||||
#ifdef HAVE_LIBTLS1_2
|
||||
/* Create client context, use TLS v1.2 only for now */
|
||||
context->tls_ctx = SSL_CTX_new(TLSv1_2_client_method());
|
||||
#endif
|
||||
if(!context->tls_ctx && context->dns_transport ==
|
||||
GETDNS_TRANSPORT_TLS_ONLY_KEEP_CONNECTIONS_OPEN) {
|
||||
return GETDNS_RETURN_BAD_CONTEXT;
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
/* Block use of TLS ONLY in recursive mode as it won't work */
|
||||
if (context->resolution_type == GETDNS_RESOLUTION_RECURSING
|
||||
&& context->dns_transport == GETDNS_TRANSPORT_TLS_ONLY_KEEP_CONNECTIONS_OPEN)
|
||||
return GETDNS_RETURN_BAD_CONTEXT;
|
||||
|
||||
if (context->resolution_type_set == context->resolution_type)
|
||||
/* already set and no config changes
|
||||
* have caused this to be bad.
|
||||
|
|
|
@ -49,6 +49,7 @@ struct ub_ctx;
|
|||
|
||||
#define GETDNS_FN_RESOLVCONF "/etc/resolv.conf"
|
||||
#define GETDNS_FN_HOSTS "/etc/hosts"
|
||||
#define GETDNS_TLS_PORT 1021
|
||||
|
||||
enum filechgs { GETDNS_FCHG_ERRORS = -1
|
||||
, GETDNS_FCHG_NOERROR = 0
|
||||
|
@ -71,6 +72,14 @@ struct filechg {
|
|||
struct stat *prevstat;
|
||||
};
|
||||
|
||||
typedef enum getdns_base_transport {
|
||||
GETDNS_TRANSPORT_NONE,
|
||||
GETDNS_TRANSPORT_UDP,
|
||||
GETDNS_TRANSPORT_TCP_SINGLE,
|
||||
GETDNS_TRANSPORT_TCP,
|
||||
GETDNS_TRANSPORT_TLS
|
||||
} getdns_base_transport_t;
|
||||
|
||||
typedef struct getdns_upstream {
|
||||
struct getdns_upstreams *upstreams;
|
||||
|
||||
|
@ -83,6 +92,7 @@ typedef struct getdns_upstream {
|
|||
|
||||
/* For sharing a TCP socket to this upstream */
|
||||
int fd;
|
||||
SSL* tls_obj;
|
||||
getdns_eventloop_event event;
|
||||
getdns_eventloop *loop;
|
||||
getdns_tcp_state tcp;
|
||||
|
@ -133,6 +143,7 @@ struct getdns_context {
|
|||
uint8_t edns_version;
|
||||
uint8_t edns_do_bit;
|
||||
int edns_maximum_udp_payload_size; /* -1 is unset */
|
||||
SSL_CTX* tls_ctx;
|
||||
|
||||
getdns_update_callback update_callback;
|
||||
getdns_update_callback2 update_callback2;
|
||||
|
@ -220,4 +231,8 @@ int filechg_check(struct getdns_context *context, struct filechg *fchg);
|
|||
|
||||
void priv_getdns_context_ub_read_cb(void *userarg);
|
||||
|
||||
getdns_base_transport_t priv_get_base_transport(getdns_transport_t transport, int level);
|
||||
|
||||
void priv_getdns_upstreams_dereference(getdns_upstreams *upstreams);
|
||||
|
||||
#endif /* _GETDNS_CONTEXT_H_ */
|
||||
|
|
|
@ -163,7 +163,9 @@ typedef enum getdns_transport_t {
|
|||
GETDNS_TRANSPORT_UDP_FIRST_AND_FALL_BACK_TO_TCP = 540,
|
||||
GETDNS_TRANSPORT_UDP_ONLY = 541,
|
||||
GETDNS_TRANSPORT_TCP_ONLY = 542,
|
||||
GETDNS_TRANSPORT_TCP_ONLY_KEEP_CONNECTIONS_OPEN = 543
|
||||
GETDNS_TRANSPORT_TCP_ONLY_KEEP_CONNECTIONS_OPEN = 543,
|
||||
GETDNS_TRANSPORT_TLS_ONLY_KEEP_CONNECTIONS_OPEN = 544,
|
||||
GETDNS_TRANSPORT_TLS_FIRST_AND_FALL_BACK_TO_TCP_KEEP_CONNECTIONS_OPEN = 545
|
||||
} getdns_transport_t;
|
||||
|
||||
/**
|
||||
|
@ -174,6 +176,8 @@ typedef enum getdns_transport_t {
|
|||
#define GETDNS_TRANSPORT_UDP_ONLY_TEXT "See getdns_context_set_dns_transport()"
|
||||
#define GETDNS_TRANSPORT_TCP_ONLY_TEXT "See getdns_context_set_dns_transport()"
|
||||
#define GETDNS_TRANSPORT_TCP_ONLY_KEEP_CONNECTIONS_OPEN_TEXT "See getdns_context_set_dns_transport()"
|
||||
#define GETDNS_TRANSPORT_TLS_ONLY_KEEP_CONNECTIONS_OPEN_TEXT "See getdns_context_set_dns_transport()"
|
||||
#define GETDNS_TRANSPORT_TLS_FIRST_AND_FALL_BACK_TO_TCP_KEEP_CONNECTIONS_OPEN_TEXT "See getdns_context_set_dns_transport()"
|
||||
/** @}
|
||||
*/
|
||||
|
||||
|
|
|
@ -177,8 +177,7 @@ dns_req_free(getdns_dns_req * req)
|
|||
return;
|
||||
}
|
||||
|
||||
if (req->upstreams && --req->upstreams->referenced == 0)
|
||||
GETDNS_FREE(req->upstreams->mf, req->upstreams);
|
||||
priv_getdns_upstreams_dereference(req->upstreams);
|
||||
|
||||
/* cleanup network requests */
|
||||
for (net_req = req->netreqs; *net_req; net_req++)
|
||||
|
|
|
@ -318,6 +318,13 @@ upstream_erred(getdns_upstream *upstream)
|
|||
netreq->state = NET_REQ_FINISHED;
|
||||
priv_getdns_check_dns_req_complete(netreq->owner);
|
||||
}
|
||||
/* TODO[TLS]: When we get an error (which is probably a timeout) and are
|
||||
* using to keep connections open should we leave the connection up here? */
|
||||
if (upstream->tls_obj) {
|
||||
SSL_shutdown(upstream->tls_obj);
|
||||
SSL_free(upstream->tls_obj);
|
||||
upstream->tls_obj = NULL;
|
||||
}
|
||||
close(upstream->fd);
|
||||
upstream->fd = -1;
|
||||
}
|
||||
|
@ -521,7 +528,7 @@ stub_tcp_read(int fd, getdns_tcp_state *tcp, struct mem_funcs *mf)
|
|||
tcp->to_read -= read;
|
||||
tcp->read_pos += read;
|
||||
|
||||
if (tcp->to_read > 0)
|
||||
if ((int)tcp->to_read > 0)
|
||||
return STUB_TCP_AGAIN;
|
||||
|
||||
read = tcp->read_pos - tcp->read_buf;
|
||||
|
@ -595,6 +602,187 @@ stub_tcp_read_cb(void *userarg)
|
|||
}
|
||||
}
|
||||
|
||||
/** wait for a socket to become ready */
|
||||
static int
|
||||
sock_wait(int sockfd)
|
||||
{
|
||||
int ret;
|
||||
fd_set fds;
|
||||
FD_ZERO(&fds);
|
||||
FD_SET(FD_SET_T sockfd, &fds);
|
||||
/*TODO[TLS]: Pick up this timeout from the context*/
|
||||
struct timeval timeout = {5, 0 };
|
||||
ret = select(sockfd+1, NULL, &fds, NULL, &timeout);
|
||||
if(ret == 0)
|
||||
/* timeout expired */
|
||||
return 0;
|
||||
else if(ret == -1)
|
||||
/* error */
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
sock_connected(int sockfd)
|
||||
{
|
||||
/* wait(write) until connected or error */
|
||||
while(1) {
|
||||
int error = 0;
|
||||
socklen_t len = (socklen_t)sizeof(error);
|
||||
|
||||
if(!sock_wait(sockfd)) {
|
||||
close(sockfd);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* check if there is a pending error for nonblocking connect */
|
||||
if (getsockopt(sockfd, SOL_SOCKET, SO_ERROR, (void*)&error, &len) < 0) {
|
||||
error = errno; /* on solaris errno is error */
|
||||
}
|
||||
if (error == EINPROGRESS || error == EWOULDBLOCK)
|
||||
continue; /* try again */
|
||||
else if (error != 0) {
|
||||
close(sockfd);
|
||||
return -1;
|
||||
}
|
||||
/* connected */
|
||||
break;
|
||||
}
|
||||
return sockfd;
|
||||
}
|
||||
|
||||
/* The connection testing and handshake should be handled by integrating this
|
||||
* with the event loop framework, but for now just implement a standalone
|
||||
* handshake method.*/
|
||||
static SSL*
|
||||
do_tls_handshake(getdns_dns_req *dnsreq, getdns_upstream *upstream)
|
||||
{
|
||||
/*Lets make sure the connection is up before we try a handshake*/
|
||||
if (errno == EINPROGRESS && sock_connected(upstream->fd) == -1) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Create SSL instance */
|
||||
if (dnsreq->context->tls_ctx == NULL)
|
||||
return NULL;
|
||||
SSL* ssl = SSL_new(dnsreq->context->tls_ctx);
|
||||
if(!ssl) {
|
||||
return NULL;
|
||||
}
|
||||
/* Connect the SSL object with a file descriptor */
|
||||
if(!SSL_set_fd(ssl, upstream->fd)) {
|
||||
SSL_free(ssl);
|
||||
return NULL;
|
||||
}
|
||||
SSL_set_connect_state(ssl);
|
||||
(void) SSL_set_mode(ssl, SSL_MODE_AUTO_RETRY);
|
||||
|
||||
int r;
|
||||
int want;
|
||||
fd_set fds;
|
||||
FD_ZERO(&fds);
|
||||
FD_SET(upstream->fd, &fds);
|
||||
struct timeval timeout = {dnsreq->context->timeout/1000, 0 };
|
||||
while ((r = SSL_do_handshake(ssl)) != 1)
|
||||
{
|
||||
want = SSL_get_error(ssl, r);
|
||||
switch (want) {
|
||||
case SSL_ERROR_WANT_READ:
|
||||
if (select(upstream->fd + 1, &fds, NULL, NULL, &timeout) == 0) {
|
||||
SSL_free(ssl);
|
||||
return NULL;
|
||||
}
|
||||
break;
|
||||
case SSL_ERROR_WANT_WRITE:
|
||||
if (select(upstream->fd + 1, NULL, &fds, NULL, &timeout) == 0) {
|
||||
SSL_free(ssl);
|
||||
return NULL;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
SSL_free(ssl);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
return ssl;
|
||||
}
|
||||
|
||||
static int
|
||||
stub_tls_read(SSL* tls_obj, getdns_tcp_state *tcp, struct mem_funcs *mf)
|
||||
{
|
||||
ssize_t read;
|
||||
uint8_t *buf;
|
||||
size_t buf_size;
|
||||
|
||||
if (!tcp->read_buf) {
|
||||
/* First time tls read, create a buffer for reading */
|
||||
if (!(tcp->read_buf = GETDNS_XMALLOC(*mf, uint8_t, 4096)))
|
||||
return STUB_TCP_ERROR;
|
||||
|
||||
tcp->read_buf_len = 4096;
|
||||
tcp->read_pos = tcp->read_buf;
|
||||
tcp->to_read = 2; /* Packet size */
|
||||
}
|
||||
|
||||
ERR_clear_error();
|
||||
read = SSL_read(tls_obj, tcp->read_pos, tcp->to_read);
|
||||
if (read <= 0) {
|
||||
/* TODO[TLS]: Handle SSL_ERROR_WANT_WRITE which means handshake
|
||||
renegotiation. Need to keep handshake state to do that.*/
|
||||
int want = SSL_get_error(tls_obj, read);
|
||||
if (want == SSL_ERROR_WANT_READ) {
|
||||
return STUB_TCP_AGAIN; /* read more later */
|
||||
} else
|
||||
return STUB_TCP_ERROR;
|
||||
}
|
||||
tcp->to_read -= read;
|
||||
tcp->read_pos += read;
|
||||
|
||||
if ((int)tcp->to_read > 0)
|
||||
return STUB_TCP_AGAIN;
|
||||
|
||||
read = tcp->read_pos - tcp->read_buf;
|
||||
if (read == 2) {
|
||||
/* Read the packet size short */
|
||||
tcp->to_read = gldns_read_uint16(tcp->read_buf);
|
||||
|
||||
if (tcp->to_read < GLDNS_HEADER_SIZE)
|
||||
return STUB_TCP_ERROR;
|
||||
|
||||
/* Resize our buffer if needed */
|
||||
if (tcp->to_read > tcp->read_buf_len) {
|
||||
buf_size = tcp->read_buf_len;
|
||||
while (tcp->to_read > buf_size)
|
||||
buf_size *= 2;
|
||||
|
||||
if (!(buf = GETDNS_XREALLOC(*mf,
|
||||
tcp->read_buf, uint8_t, buf_size)))
|
||||
return STUB_TCP_ERROR;
|
||||
|
||||
tcp->read_buf = buf;
|
||||
tcp->read_buf_len = buf_size;
|
||||
}
|
||||
|
||||
/* Ready to start reading the packet */
|
||||
tcp->read_pos = tcp->read_buf;
|
||||
read = SSL_read(tls_obj, tcp->read_pos, tcp->to_read);
|
||||
if (read <= 0) {
|
||||
/* TODO[TLS]: Handle SSL_ERROR_WANT_WRITE which means handshake
|
||||
renegotiation. Need to keep handshake state to do that.*/
|
||||
int want = SSL_get_error(tls_obj, read);
|
||||
if (want == SSL_ERROR_WANT_READ) {
|
||||
return STUB_TCP_AGAIN; /* read more later */
|
||||
} else
|
||||
return STUB_TCP_ERROR;
|
||||
}
|
||||
tcp->to_read -= read;
|
||||
tcp->read_pos += read;
|
||||
if ((int)tcp->to_read > 0)
|
||||
return STUB_TCP_AGAIN;
|
||||
}
|
||||
return GLDNS_ID_WIRE(tcp->read_buf);
|
||||
}
|
||||
|
||||
static void netreq_upstream_read_cb(void *userarg);
|
||||
static void netreq_upstream_write_cb(void *userarg);
|
||||
static void
|
||||
|
@ -607,8 +795,14 @@ upstream_read_cb(void *userarg)
|
|||
uint16_t query_id;
|
||||
intptr_t query_id_intptr;
|
||||
|
||||
switch ((q = stub_tcp_read(upstream->fd, &upstream->tcp,
|
||||
&upstream->upstreams->mf))) {
|
||||
if (upstream->tls_obj)
|
||||
q = stub_tls_read(upstream->tls_obj, &upstream->tcp,
|
||||
&upstream->upstreams->mf);
|
||||
else
|
||||
q = stub_tcp_read(upstream->fd, &upstream->tcp,
|
||||
&upstream->upstreams->mf);
|
||||
|
||||
switch (q) {
|
||||
case STUB_TCP_AGAIN:
|
||||
return;
|
||||
|
||||
|
@ -617,6 +811,7 @@ upstream_read_cb(void *userarg)
|
|||
return;
|
||||
|
||||
default:
|
||||
|
||||
/* Lookup netreq */
|
||||
query_id = (uint16_t) q;
|
||||
query_id_intptr = (intptr_t) query_id;
|
||||
|
@ -705,9 +900,9 @@ stub_tcp_write(int fd, getdns_tcp_state *tcp, getdns_network_req *netreq)
|
|||
* the write_queue) for that upstream. Register this netreq
|
||||
* by query_id in the process.
|
||||
*/
|
||||
if (dnsreq->context->dns_transport !=
|
||||
GETDNS_TRANSPORT_TCP_ONLY_KEEP_CONNECTIONS_OPEN)
|
||||
|
||||
if ((dnsreq->context->dns_transport == GETDNS_TRANSPORT_TCP_ONLY) ||
|
||||
(dnsreq->context->dns_transport == GETDNS_TRANSPORT_UDP_ONLY) ||
|
||||
(dnsreq->context->dns_transport == GETDNS_TRANSPORT_UDP_FIRST_AND_FALL_BACK_TO_TCP))
|
||||
query_id = arc4random();
|
||||
else do {
|
||||
query_id = arc4random();
|
||||
|
@ -822,6 +1017,54 @@ stub_tcp_write_cb(void *userarg)
|
|||
}
|
||||
}
|
||||
|
||||
static int
|
||||
stub_tls_write(SSL* tls_obj, getdns_tcp_state *tcp, getdns_network_req *netreq)
|
||||
{
|
||||
size_t pkt_len = netreq->response - netreq->query;
|
||||
ssize_t written;
|
||||
uint16_t query_id;
|
||||
intptr_t query_id_intptr;
|
||||
|
||||
/* Do we have remaining data that we could not write before? */
|
||||
if (! tcp->write_buf) {
|
||||
/* No, this is an initial write. Try to send
|
||||
*/
|
||||
|
||||
/* Find a unique query_id not already written (or in
|
||||
* the write_queue) for that upstream. Register this netreq
|
||||
* by query_id in the process.
|
||||
*/
|
||||
do {
|
||||
query_id = ldns_get_random();
|
||||
query_id_intptr = (intptr_t)query_id;
|
||||
netreq->node.key = (void *)query_id_intptr;
|
||||
|
||||
} while (!getdns_rbtree_insert(
|
||||
&netreq->upstream->netreq_by_query_id, &netreq->node));
|
||||
|
||||
GLDNS_ID_SET(netreq->query, query_id);
|
||||
if (netreq->opt)
|
||||
/* no limits on the max udp payload size with tcp */
|
||||
gldns_write_uint16(netreq->opt + 3, 65535);
|
||||
|
||||
/* We have an initialized packet buffer.
|
||||
* Lets see how much of it we can write */
|
||||
|
||||
// TODO[TLS]: Handle error cases, partial writes, renegotiation etc.
|
||||
ERR_clear_error();
|
||||
written = SSL_write(tls_obj, netreq->query - 2, pkt_len + 2);
|
||||
if (written <= 0)
|
||||
return STUB_TCP_ERROR;
|
||||
|
||||
/* We were able to write everything! Start reading. */
|
||||
return (int) query_id;
|
||||
|
||||
}
|
||||
|
||||
return STUB_TCP_ERROR;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
upstream_write_cb(void *userarg)
|
||||
{
|
||||
|
@ -830,7 +1073,12 @@ upstream_write_cb(void *userarg)
|
|||
getdns_dns_req *dnsreq = netreq->owner;
|
||||
int q;
|
||||
|
||||
switch ((q = stub_tcp_write(upstream->fd, &upstream->tcp, netreq))) {
|
||||
if (upstream->tls_obj)
|
||||
q = stub_tls_write(upstream->tls_obj, &upstream->tcp, netreq);
|
||||
else
|
||||
q = stub_tcp_write(upstream->fd, &upstream->tcp, netreq);
|
||||
|
||||
switch (q) {
|
||||
case STUB_TCP_AGAIN:
|
||||
return;
|
||||
|
||||
|
@ -902,6 +1150,58 @@ upstream_schedule_netreq(getdns_upstream *upstream, getdns_network_req *netreq)
|
|||
}
|
||||
}
|
||||
|
||||
static in_port_t
|
||||
get_port(struct sockaddr_storage* addr)
|
||||
{
|
||||
return ntohs(addr->ss_family == AF_INET
|
||||
? ((struct sockaddr_in *)addr)->sin_port
|
||||
: ((struct sockaddr_in6*)addr)->sin6_port);
|
||||
}
|
||||
|
||||
static void
|
||||
set_port(struct sockaddr_storage* addr, in_port_t port)
|
||||
{
|
||||
addr->ss_family == AF_INET
|
||||
? (((struct sockaddr_in *)addr)->sin_port = htons(port))
|
||||
: (((struct sockaddr_in6*)addr)->sin6_port = htons(port));
|
||||
}
|
||||
|
||||
static int
|
||||
tcp_connect (getdns_upstream *upstream, getdns_base_transport_t transport) {
|
||||
|
||||
int fd =-1;
|
||||
struct sockaddr_storage connect_addr;
|
||||
struct sockaddr_storage* addr = &upstream->addr;
|
||||
socklen_t addr_len = upstream->addr_len;
|
||||
|
||||
/* TODO[TLS]: For now, override the port to a hardcoded value*/
|
||||
if (transport == GETDNS_TRANSPORT_TLS &&
|
||||
(int)get_port(addr) != GETDNS_TLS_PORT) {
|
||||
connect_addr = upstream->addr;
|
||||
addr = &connect_addr;
|
||||
set_port(addr, GETDNS_TLS_PORT);
|
||||
}
|
||||
|
||||
if ((fd = socket(addr->ss_family, SOCK_STREAM, IPPROTO_TCP)) == -1)
|
||||
return -1;
|
||||
|
||||
getdns_sock_nonblock(fd);
|
||||
#ifdef USE_TCP_FASTOPEN
|
||||
/* Leave the connect to the later call to sendto() if using TCP*/
|
||||
if (transport == GETDNS_TRANSPORT_TCP ||
|
||||
transport == GETDNS_TRANSPORT_TCP_SINGLE)
|
||||
return fd;
|
||||
#endif
|
||||
if (connect(fd, (struct sockaddr *)addr,
|
||||
addr_len) == -1) {
|
||||
if (errno != EINPROGRESS) {
|
||||
close(fd);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
return fd;
|
||||
}
|
||||
|
||||
getdns_return_t
|
||||
priv_getdns_submit_stub_request(getdns_network_req *netreq)
|
||||
{
|
||||
|
@ -911,9 +1211,13 @@ priv_getdns_submit_stub_request(getdns_network_req *netreq)
|
|||
if (!upstream)
|
||||
return GETDNS_RETURN_GENERIC_ERROR;
|
||||
|
||||
switch(dnsreq->context->dns_transport) {
|
||||
case GETDNS_TRANSPORT_UDP_ONLY:
|
||||
case GETDNS_TRANSPORT_UDP_FIRST_AND_FALL_BACK_TO_TCP:
|
||||
// Work out the primary and fallback transport options
|
||||
getdns_base_transport_t transport = priv_get_base_transport(
|
||||
dnsreq->context->dns_transport,0);
|
||||
getdns_base_transport_t fb_transport = priv_get_base_transport(
|
||||
dnsreq->context->dns_transport,1);
|
||||
switch(transport) {
|
||||
case GETDNS_TRANSPORT_UDP:
|
||||
|
||||
if ((netreq->fd = socket(
|
||||
upstream->addr.ss_family, SOCK_DGRAM, IPPROTO_UDP)) == -1)
|
||||
|
@ -929,23 +1233,10 @@ priv_getdns_submit_stub_request(getdns_network_req *netreq)
|
|||
|
||||
return GETDNS_RETURN_GOOD;
|
||||
|
||||
case GETDNS_TRANSPORT_TCP_ONLY:
|
||||
case GETDNS_TRANSPORT_TCP_SINGLE:
|
||||
|
||||
if ((netreq->fd = socket(
|
||||
upstream->addr.ss_family, SOCK_STREAM, IPPROTO_TCP)) == -1)
|
||||
if ((netreq->fd = tcp_connect(upstream, transport)) == -1)
|
||||
return GETDNS_RETURN_GENERIC_ERROR;
|
||||
|
||||
getdns_sock_nonblock(netreq->fd);
|
||||
#ifdef USE_TCP_FASTOPEN
|
||||
/* Leave the connect to the later call to sendto() */
|
||||
#else
|
||||
if (connect(netreq->fd, (struct sockaddr *)&upstream->addr,
|
||||
upstream->addr_len) == -1 && errno != EINPROGRESS) {
|
||||
|
||||
close(netreq->fd);
|
||||
return GETDNS_RETURN_GENERIC_ERROR;
|
||||
}
|
||||
#endif
|
||||
netreq->upstream = upstream;
|
||||
|
||||
GETDNS_SCHEDULE_EVENT(
|
||||
|
@ -955,34 +1246,51 @@ priv_getdns_submit_stub_request(getdns_network_req *netreq)
|
|||
|
||||
return GETDNS_RETURN_GOOD;
|
||||
|
||||
case GETDNS_TRANSPORT_TCP_ONLY_KEEP_CONNECTIONS_OPEN:
|
||||
case GETDNS_TRANSPORT_TCP:
|
||||
case GETDNS_TRANSPORT_TLS:
|
||||
|
||||
/* In coming comments, "global" means "context wide" */
|
||||
|
||||
/* Are we the first? (Is global socket initialized?) */
|
||||
if (upstream->fd == -1) {
|
||||
/* TODO[TLS]: We should remember on the context if we had to fallback
|
||||
* for this upstream so when re-connecting from a dropped TCP
|
||||
* connection we don't retry TLS. */
|
||||
int fallback = 0;
|
||||
|
||||
/* We are the first. Make global socket and connect. */
|
||||
if ((upstream->fd = socket(upstream->addr.ss_family,
|
||||
SOCK_STREAM, IPPROTO_TCP)) == -1)
|
||||
return GETDNS_RETURN_GENERIC_ERROR;
|
||||
|
||||
getdns_sock_nonblock(upstream->fd);
|
||||
#ifdef USE_TCP_FASTOPEN
|
||||
/* Leave the connect to the later call to sendto() */
|
||||
#else
|
||||
if (connect(upstream->fd,
|
||||
(struct sockaddr *)&upstream->addr,
|
||||
upstream->addr_len) == -1 && errno != EINPROGRESS){
|
||||
|
||||
close(upstream->fd);
|
||||
upstream->fd = -1;
|
||||
return GETDNS_RETURN_GENERIC_ERROR;
|
||||
if ((upstream->fd = tcp_connect(upstream, transport)) == -1) {
|
||||
if (fb_transport == GETDNS_TRANSPORT_NONE)
|
||||
return GETDNS_RETURN_GENERIC_ERROR;
|
||||
if ((upstream->fd = tcp_connect(upstream, fb_transport)) == -1)
|
||||
return GETDNS_RETURN_GENERIC_ERROR;
|
||||
fallback = 1;
|
||||
}
|
||||
|
||||
/* Now do a handshake for TLS. Note waiting for this to succeed or
|
||||
* timeout blocks the scheduling of any messages for this upstream*/
|
||||
if (transport == GETDNS_TRANSPORT_TLS && (fallback == 0)) {
|
||||
upstream->tls_obj = do_tls_handshake(dnsreq, upstream);
|
||||
if (!upstream->tls_obj) {
|
||||
if (fb_transport == GETDNS_TRANSPORT_NONE)
|
||||
return GETDNS_RETURN_GENERIC_ERROR;
|
||||
close(upstream->fd);
|
||||
if ((upstream->fd = tcp_connect(upstream, fb_transport)) == -1)
|
||||
return GETDNS_RETURN_GENERIC_ERROR;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
/* Attach to the global event loop
|
||||
* so it can do it's own scheduling
|
||||
*/
|
||||
upstream->loop = dnsreq->context->extension;
|
||||
} else {
|
||||
/* Cater for the case of the user downgrading and existing TLS
|
||||
connection to TCP for some reason...*/
|
||||
if (transport == GETDNS_TRANSPORT_TCP && upstream->tls_obj) {
|
||||
SSL_shutdown(upstream->tls_obj);
|
||||
SSL_free(upstream->tls_obj);
|
||||
upstream->tls_obj = NULL;
|
||||
}
|
||||
}
|
||||
netreq->upstream = upstream;
|
||||
|
||||
|
|
|
@ -29,9 +29,23 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <dirent.h>
|
||||
#include <getdns/getdns.h>
|
||||
#include <getdns/getdns_extra.h>
|
||||
|
||||
static int quiet = 0;
|
||||
static int batch_mode = 0;
|
||||
static char *query_file = NULL;
|
||||
static int json = 0;
|
||||
static char *the_root = ".";
|
||||
static char *name;
|
||||
static getdns_context *context;
|
||||
static getdns_dict *extensions;
|
||||
static uint16_t request_type = GETDNS_RRTYPE_NS;
|
||||
static int timeout, edns0_size;
|
||||
static int async = 0, interactive = 0;
|
||||
static enum { GENERAL, ADDRESS, HOSTNAME, SERVICE } calltype = GENERAL;
|
||||
|
||||
int get_rrtype(const char *t);
|
||||
|
||||
getdns_dict *
|
||||
|
@ -90,6 +104,7 @@ print_usage(FILE *out, const char *progname)
|
|||
fprintf(out, "\t-b <bufsize>\tSet edns0 max_udp_payload size\n");
|
||||
fprintf(out, "\t-D\tSet edns0 do bit\n");
|
||||
fprintf(out, "\t-d\tclear edns0 do bit\n");
|
||||
fprintf(out, "\t-F <filename>\tread the queries from the specified file\n");
|
||||
fprintf(out, "\t-G\tgeneral lookup\n");
|
||||
fprintf(out, "\t-H\thostname lookup. (<name> must be an IP address; <type> is ignored)\n");
|
||||
fprintf(out, "\t-h\tPrint this help\n");
|
||||
|
@ -104,29 +119,45 @@ print_usage(FILE *out, const char *progname)
|
|||
fprintf(out, "\t-t <timeout>\tSet timeout in miliseconds\n");
|
||||
fprintf(out, "\t-T\tSet transport to TCP only\n");
|
||||
fprintf(out, "\t-O\tSet transport to TCP only keep connections open\n");
|
||||
fprintf(out, "\t-L\tSet transport to TLS only keep connections open\n");
|
||||
fprintf(out, "\t-E\tSet transport to TLS with TCP fallback only keep connections open\n");
|
||||
fprintf(out, "\t-u\tSet transport to UDP with TCP fallback\n");
|
||||
fprintf(out, "\t-U\tSet transport to UDP only\n");
|
||||
fprintf(out, "\t-B\tBatch mode. Schedule all messages before processing responses.\n");
|
||||
fprintf(out, "\t-q\tQuiet mode - don't print response\n");
|
||||
}
|
||||
|
||||
void callback(getdns_context *context, getdns_callback_type_t callback_type,
|
||||
getdns_dict *response, void *userarg, getdns_transaction_t trans_id)
|
||||
{
|
||||
getdns_dict **response_ptr = (getdns_dict **)userarg;
|
||||
char *response_str;
|
||||
|
||||
if (response)
|
||||
*response_ptr = response;
|
||||
if (callback_type == GETDNS_CALLBACK_COMPLETE) {
|
||||
/* This is a callback with data */;
|
||||
if (!quiet && (response_str = json ?
|
||||
getdns_print_json_dict(response, json == 1)
|
||||
: getdns_pretty_print_dict(response))) {
|
||||
|
||||
fprintf(stdout, "ASYNC response:\n%s\n", response_str);
|
||||
free(response_str);
|
||||
}
|
||||
fprintf(stderr,
|
||||
"The callback with ID %llu was successfull.\n",
|
||||
(unsigned long long)trans_id);
|
||||
|
||||
} else if (callback_type == GETDNS_CALLBACK_CANCEL)
|
||||
fprintf(stderr,
|
||||
"The callback with ID %llu was cancelled. Exiting.\n",
|
||||
(unsigned long long)trans_id);
|
||||
else
|
||||
fprintf(stderr,
|
||||
"The callback got a callback_type of %d. Exiting.\n",
|
||||
callback_type);
|
||||
|
||||
getdns_dict_destroy(response);
|
||||
response = NULL;
|
||||
}
|
||||
|
||||
static char *the_root = ".";
|
||||
static char *name;
|
||||
static getdns_context *context;
|
||||
static getdns_dict *extensions;
|
||||
static uint16_t request_type = GETDNS_RRTYPE_NS;
|
||||
static int timeout, edns0_size;
|
||||
static int async = 0, interactive = 0;
|
||||
static enum { GENERAL, ADDRESS, HOSTNAME, SERVICE } calltype = GENERAL;
|
||||
static int json = 0;
|
||||
|
||||
#define CONTINUE ((getdns_return_t)-2)
|
||||
|
||||
static getdns_return_t set_cookie(getdns_dict *exts, char *cookie)
|
||||
|
@ -259,6 +290,15 @@ getdns_return_t parse_args(int argc, char **argv)
|
|||
case 'd':
|
||||
(void) getdns_context_set_edns_do_bit(context, 0);
|
||||
break;
|
||||
case 'F':
|
||||
if (c[1] != 0 || ++i >= argc || !*argv[i]) {
|
||||
fprintf(stderr, "file name expected "
|
||||
"after -F\n");
|
||||
return GETDNS_RETURN_GENERIC_ERROR;
|
||||
}
|
||||
query_file = argv[i];
|
||||
interactive = 1;
|
||||
break;
|
||||
case 'G':
|
||||
calltype = GENERAL;
|
||||
break;
|
||||
|
@ -282,6 +322,8 @@ getdns_return_t parse_args(int argc, char **argv)
|
|||
break;
|
||||
case 'p':
|
||||
json = 0;
|
||||
case 'q':
|
||||
quiet = 1;
|
||||
break;
|
||||
case 'r':
|
||||
getdns_context_set_resolution_type(
|
||||
|
@ -319,6 +361,14 @@ getdns_return_t parse_args(int argc, char **argv)
|
|||
getdns_context_set_dns_transport(context,
|
||||
GETDNS_TRANSPORT_TCP_ONLY_KEEP_CONNECTIONS_OPEN);
|
||||
break;
|
||||
case 'L':
|
||||
getdns_context_set_dns_transport(context,
|
||||
GETDNS_TRANSPORT_TLS_ONLY_KEEP_CONNECTIONS_OPEN);
|
||||
break;
|
||||
case 'E':
|
||||
getdns_context_set_dns_transport(context,
|
||||
GETDNS_TRANSPORT_TLS_FIRST_AND_FALL_BACK_TO_TCP_KEEP_CONNECTIONS_OPEN);
|
||||
break;
|
||||
case 'u':
|
||||
getdns_context_set_dns_transport(context,
|
||||
GETDNS_TRANSPORT_UDP_FIRST_AND_FALL_BACK_TO_TCP);
|
||||
|
@ -327,6 +377,9 @@ getdns_return_t parse_args(int argc, char **argv)
|
|||
getdns_context_set_dns_transport(context,
|
||||
GETDNS_TRANSPORT_UDP_ONLY);
|
||||
break;
|
||||
case 'B':
|
||||
batch_mode = 1;
|
||||
break;
|
||||
|
||||
|
||||
default:
|
||||
|
@ -361,6 +414,7 @@ main(int argc, char **argv)
|
|||
char *response_str;
|
||||
getdns_return_t r;
|
||||
getdns_dict *address = NULL;
|
||||
FILE *fp = NULL;
|
||||
|
||||
name = the_root;
|
||||
if ((r = getdns_context_create(&context, 1))) {
|
||||
|
@ -376,14 +430,28 @@ main(int argc, char **argv)
|
|||
if ((r = parse_args(argc, argv)))
|
||||
goto done_destroy_context;
|
||||
|
||||
if (query_file) {
|
||||
fp = fopen(query_file, "rt");
|
||||
if (fp == NULL) {
|
||||
fprintf(stderr, "Could not open query file: %s\n", query_file);
|
||||
goto done_destroy_context;
|
||||
}
|
||||
}
|
||||
|
||||
/* Make the call */
|
||||
do {
|
||||
char line[1024], *token, *linev[256];
|
||||
int linec;
|
||||
if (interactive) {
|
||||
fprintf(stdout, "> ");
|
||||
if (!fgets(line, 1024, stdin) || !*line)
|
||||
break;
|
||||
if (!query_file) {
|
||||
fprintf(stdout, "> ");
|
||||
if (!fgets(line, 1024, stdin) || !*line)
|
||||
break;
|
||||
} else {
|
||||
if (!fgets(line, 1024, fp) || !*line)
|
||||
break;
|
||||
fprintf(stdout,"Found query: %s", line);
|
||||
}
|
||||
|
||||
linev[0] = argv[0];
|
||||
linec = 1;
|
||||
|
@ -430,8 +498,8 @@ main(int argc, char **argv)
|
|||
}
|
||||
if (r)
|
||||
goto done_destroy_extensions;
|
||||
|
||||
getdns_context_run(context);
|
||||
if (!batch_mode)
|
||||
getdns_context_run(context);
|
||||
} else {
|
||||
switch (calltype) {
|
||||
case GENERAL:
|
||||
|
@ -456,22 +524,29 @@ main(int argc, char **argv)
|
|||
}
|
||||
if (r)
|
||||
goto done_destroy_extensions;
|
||||
}
|
||||
if (json)
|
||||
response_str = getdns_print_json_dict(
|
||||
response, json == 1);
|
||||
else
|
||||
response_str = getdns_pretty_print_dict(response);
|
||||
if (!quiet) {
|
||||
if ((response_str = json ?
|
||||
getdns_print_json_dict(response, json == 1)
|
||||
: getdns_pretty_print_dict(response))) {
|
||||
|
||||
if (response_str) {
|
||||
fprintf(stdout, "%s\n", response_str);
|
||||
free(response_str);
|
||||
} else {
|
||||
r = GETDNS_RETURN_MEMORY_ERROR;
|
||||
fprintf(stderr, "Could not print response\n");
|
||||
fprintf( stdout, "SYNC response:\n%s\n"
|
||||
, response_str);
|
||||
free(response_str);
|
||||
} else {
|
||||
r = GETDNS_RETURN_MEMORY_ERROR;
|
||||
fprintf( stderr
|
||||
, "Could not print response\n");
|
||||
}
|
||||
} else if (r == GETDNS_RETURN_GOOD)
|
||||
fprintf(stdout, "Response code was: GOOD\n");
|
||||
else if (interactive)
|
||||
fprintf(stderr, "An error occurred: %d\n", r);
|
||||
}
|
||||
} while (interactive);
|
||||
|
||||
if (batch_mode)
|
||||
getdns_context_run(context);
|
||||
|
||||
/* Clean up */
|
||||
done_destroy_extensions:
|
||||
getdns_dict_destroy(extensions);
|
||||
|
@ -479,6 +554,9 @@ done_destroy_context:
|
|||
if (response) getdns_dict_destroy(response);
|
||||
getdns_context_destroy(context);
|
||||
|
||||
if (fp)
|
||||
fclose(fp);
|
||||
|
||||
if (r == CONTINUE)
|
||||
return 0;
|
||||
if (r)
|
||||
|
|
|
@ -44,6 +44,8 @@
|
|||
#define TRANSPORT_UDP "udp"
|
||||
#define TRANSPORT_TCP "tcp"
|
||||
#define TRANSPORT_PIPELINE "pipeline"
|
||||
#define TRANSPORT_TLS_KEEPOPEN "tls"
|
||||
#define TRANSPORT_TLS_TCP_KEEPOPEN "dns-over-tls"
|
||||
#define RESOLUTION_STUB "stub"
|
||||
#define RESOLUTION_REC "rec"
|
||||
|
||||
|
@ -98,6 +100,10 @@ main(int argc, char** argv)
|
|||
getdns_context_set_dns_transport(this_context, GETDNS_TRANSPORT_TCP_ONLY);
|
||||
else if (strncmp(transport, TRANSPORT_PIPELINE, 8) == 0)
|
||||
getdns_context_set_dns_transport(this_context, GETDNS_TRANSPORT_TCP_ONLY_KEEP_CONNECTIONS_OPEN);
|
||||
else if (strncmp(transport, TRANSPORT_TLS_KEEPOPEN, 3) == 0)
|
||||
getdns_context_set_dns_transport(this_context, GETDNS_TRANSPORT_TLS_ONLY_KEEP_CONNECTIONS_OPEN);
|
||||
else if (strncmp(transport, TRANSPORT_TLS_TCP_KEEPOPEN, 12) == 0)
|
||||
getdns_context_set_dns_transport(this_context, GETDNS_TRANSPORT_TLS_FIRST_AND_FALL_BACK_TO_TCP_KEEP_CONNECTIONS_OPEN);
|
||||
else if (strncmp(transport, TRANSPORT_UDP, 3) != 0) {
|
||||
fprintf(stderr, "Invalid transport %s, must be one of udp, tcp or pipeline\n", transport);
|
||||
exit(EXIT_FAILURE);
|
||||
|
|
|
@ -41,6 +41,8 @@
|
|||
#define TRANSPORT_UDP "udp"
|
||||
#define TRANSPORT_TCP "tcp"
|
||||
#define TRANSPORT_PIPELINE "pipeline"
|
||||
#define TRANSPORT_TLS_KEEPOPEN "tls"
|
||||
#define TRANSPORT_TLS_TCP_KEEPOPEN "dns-over-tls"
|
||||
#define RESOLUTION_STUB "stub"
|
||||
#define RESOLUTION_REC "rec"
|
||||
|
||||
|
@ -82,6 +84,10 @@ main(int argc, char** argv)
|
|||
getdns_context_set_dns_transport(this_context, GETDNS_TRANSPORT_TCP_ONLY);
|
||||
else if (strncmp(transport, TRANSPORT_PIPELINE, 8) == 0)
|
||||
getdns_context_set_dns_transport(this_context, GETDNS_TRANSPORT_TCP_ONLY_KEEP_CONNECTIONS_OPEN);
|
||||
else if (strncmp(transport, TRANSPORT_TLS_KEEPOPEN, 3) == 0)
|
||||
getdns_context_set_dns_transport(this_context, GETDNS_TRANSPORT_TLS_ONLY_KEEP_CONNECTIONS_OPEN);
|
||||
else if (strncmp(transport, TRANSPORT_TLS_TCP_KEEPOPEN, 12) == 0)
|
||||
getdns_context_set_dns_transport(this_context, GETDNS_TRANSPORT_TLS_FIRST_AND_FALL_BACK_TO_TCP_KEEP_CONNECTIONS_OPEN);
|
||||
else if (strncmp(transport, TRANSPORT_UDP, 3) != 0) {
|
||||
fprintf(stderr, "Invalid transport %s, must be one of udp, tcp or pipeline\n", transport);
|
||||
exit(EXIT_FAILURE);
|
||||
|
|
|
@ -36,7 +36,6 @@
|
|||
#ifndef TYPES_INTERNAL_H_
|
||||
#define TYPES_INTERNAL_H_
|
||||
|
||||
#include <netinet/in.h>
|
||||
#include "getdns/getdns.h"
|
||||
#include "getdns/getdns_extra.h"
|
||||
#include "util/rbtree.h"
|
||||
|
|
Loading…
Reference in New Issue