Merge branch 'features/resolvconf' into release/1.2.2

This commit is contained in:
Willem Toorop 2017-12-13 14:44:06 +01:00
commit cfeaefbe3f
11 changed files with 400 additions and 193 deletions

View File

@ -1,4 +1,15 @@
* 2017-12-??: Version 1.2.2
* 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

View File

@ -266,7 +266,7 @@ esac
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)]))
case "$enable_poll_eventloop" in
no)
@ -346,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])
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],
[Set maximum file descriptor number that can be used by select]),
[], [withval="no"])
@ -392,7 +408,7 @@ fi
AC_CHECK_HEADERS([openssl/conf.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_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_INCLUDES_DEFAULT
#ifdef HAVE_OPENSSL_ERR_H
@ -1501,6 +1517,10 @@ static inline int _gldns_custom_vsnprintf(char *str, size_t size, const char *fo
#include <sys/types.h>
#endif
#ifdef HAVE_SYS_STAT_H
#include <sys/stat.h>
#endif
#ifdef HAVE_NETINET_IN_H
#include <netinet/in.h>
#endif

View File

@ -1517,6 +1517,7 @@ void _getdns_start_fetching_ta(getdns_context *context, getdns_eventloop *loop)
char tas_hostname[256];
const char *verify_CA;
const char *verify_email;
getdns_context *sys_ctxt;
if ((r = _getdns_get_tas_url_hostname(context, tas_hostname, NULL))) {
DEBUG_ANCHOR("ERROR %s(): Could not get_tas_url_hostname"
@ -1557,32 +1558,7 @@ void _getdns_start_fetching_ta(getdns_context *context, getdns_eventloop *loop)
DEBUG_ANCHOR("%s on the %ssynchronous loop\n", __FUNC__,
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;
if (!(sys_ctxt = _getdns_context_get_sys_ctxt(context, loop))) {
DEBUG_ANCHOR("Fatal error fetching trust anchor: "
"missing system context\n");
context->trust_anchors_source = GETDNS_TASRC_FAILED;
@ -1592,7 +1568,7 @@ void _getdns_start_fetching_ta(getdns_context *context, getdns_eventloop *loop)
scheduled = 0;
#if 1
context->a.state = TAS_LOOKUP_ADDRESSES;
if ((r = _getdns_general_loop(context->sys_ctxt, loop,
if ((r = _getdns_general_loop(sys_ctxt, loop,
tas_hostname, GETDNS_RRTYPE_A, NULL, context,
&context->a.req, NULL, _tas_hostname_lookup_cb))) {
DEBUG_ANCHOR("Error scheduling A lookup for %s: %s\n"
@ -1603,7 +1579,7 @@ void _getdns_start_fetching_ta(getdns_context *context, getdns_eventloop *loop)
#if 1
context->aaaa.state = TAS_LOOKUP_ADDRESSES;
if ((r = _getdns_general_loop(context->sys_ctxt, loop,
if ((r = _getdns_general_loop(sys_ctxt, loop,
tas_hostname, GETDNS_RRTYPE_AAAA, NULL, context,
&context->aaaa.req, NULL, _tas_hostname_lookup_cb))) {
DEBUG_ANCHOR("Error scheduling AAAA lookup for %s: %s\n"

View File

@ -30,6 +30,7 @@ static struct const_info consts_info[] = {
{ 310, "GETDNS_RETURN_MEMORY_ERROR", GETDNS_RETURN_MEMORY_ERROR_TEXT },
{ 311, "GETDNS_RETURN_INVALID_PARAMETER", GETDNS_RETURN_INVALID_PARAMETER_TEXT },
{ 312, "GETDNS_RETURN_NOT_IMPLEMENTED", GETDNS_RETURN_NOT_IMPLEMENTED_TEXT },
{ 397, "GETDNS_RETURN_IO_ERROR", GETDNS_RETURN_IO_ERROR_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 },
{ 400, "GETDNS_DNSSEC_SECURE", GETDNS_DNSSEC_SECURE_TEXT },
@ -86,6 +87,8 @@ static struct const_info consts_info[] = {
{ 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 },
{ 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 },
{ 700, "GETDNS_CALLBACK_COMPLETE", GETDNS_CALLBACK_COMPLETE_TEXT },
{ 701, "GETDNS_CALLBACK_CANCEL", GETDNS_CALLBACK_CANCEL_TEXT },
{ 702, "GETDNS_CALLBACK_TIMEOUT", GETDNS_CALLBACK_TIMEOUT_TEXT },
@ -166,12 +169,14 @@ static struct const_name_info consts_name_info[] = {
{ "GETDNS_CONTEXT_CODE_EDNS_MAXIMUM_UDP_PAYLOAD_SIZE", 610 },
{ "GETDNS_CONTEXT_CODE_EDNS_VERSION", 612 },
{ "GETDNS_CONTEXT_CODE_FOLLOW_REDIRECTS", 602 },
{ "GETDNS_CONTEXT_CODE_HOSTS", 630 },
{ "GETDNS_CONTEXT_CODE_IDLE_TIMEOUT", 617 },
{ "GETDNS_CONTEXT_CODE_LIMIT_OUTSTANDING_QUERIES", 606 },
{ "GETDNS_CONTEXT_CODE_MEMORY_FUNCTIONS", 615 },
{ "GETDNS_CONTEXT_CODE_NAMESPACES", 600 },
{ "GETDNS_CONTEXT_CODE_PUBKEY_PINSET", 621 },
{ "GETDNS_CONTEXT_CODE_RESOLUTION_TYPE", 601 },
{ "GETDNS_CONTEXT_CODE_RESOLVCONF", 629 },
{ "GETDNS_CONTEXT_CODE_ROUND_ROBIN_UPSTREAMS", 622 },
{ "GETDNS_CONTEXT_CODE_SUFFIX", 608 },
{ "GETDNS_CONTEXT_CODE_TIMEOUT", 616 },
@ -248,6 +253,7 @@ static struct const_name_info consts_name_info[] = {
{ "GETDNS_RETURN_GENERIC_ERROR", 1 },
{ "GETDNS_RETURN_GOOD", 0 },
{ "GETDNS_RETURN_INVALID_PARAMETER", 311 },
{ "GETDNS_RETURN_IO_ERROR", 397 },
{ "GETDNS_RETURN_MEMORY_ERROR", 310 },
{ "GETDNS_RETURN_NEED_MORE_SPACE", 399 },
{ "GETDNS_RETURN_NOT_IMPLEMENTED", 312 },

View File

@ -57,6 +57,9 @@ typedef unsigned short in_port_t;
#include <shlobj.h>
#endif
#include <openssl/opensslv.h>
#include <openssl/crypto.h>
#include <sys/stat.h>
#include <string.h>
#include <stdio.h>
@ -495,8 +498,45 @@ str_addr_dict(getdns_context *context, const char *str)
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 */
char buf[1024];
@ -505,11 +545,21 @@ create_local_hosts(getdns_context *context)
int start_of_line = 1;
getdns_dict *address = NULL;
#ifdef USE_WINSOCK
in = fopen("c:\\WINDOWS\\system32\\drivers\\etc\\hosts", "r");
#else
in = fopen("/etc/hosts", "r");
#endif
if (!context || !hosts)
return GETDNS_RETURN_INVALID_PARAMETER;
if (!(in = fopen(hosts, "r")))
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)) {
pos = buf;
/* Break out of for to read more */
@ -589,59 +639,19 @@ read_more: ;
address = NULL;
getdns_dict_destroy(address);
}
return GETDNS_RETURN_GOOD;
}
/**
* 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)
*/
int
_getdns_filechg_check(struct getdns_context *context, struct filechg *fchg)
getdns_return_t
getdns_context_get_hosts(getdns_context *context, const char **hosts)
{
struct stat *finfo;
if (!context || !hosts)
return GETDNS_RETURN_INVALID_PARAMETER;
if(fchg == NULL)
return 0;
*hosts = *context->fchg_hosts.fn ? context->fchg_hosts.fn : NULL;
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 *
upstreams_create(getdns_context *context, size_t size)
@ -1094,7 +1104,7 @@ static int get_dns_suffix_windows(getdns_list *suffix, char* domain)
static getdns_return_t
set_os_defaults_windows(struct getdns_context *context)
set_os_defaults_windows(getdns_context *context)
{
char domain[1024] = "";
size_t upstreams_limit = 10;
@ -1106,19 +1116,8 @@ set_os_defaults_windows(struct getdns_context *context)
int s;
uint32_t info_err = 0;
if (context->fchg_resolvconf == NULL) {
context->fchg_resolvconf =
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);
if (!(context->upstreams = upstreams_create(context, upstreams_limit)))
return GETDNS_RETURN_MEMORY_ERROR;
memset(&hints, 0, sizeof(struct addrinfo));
hints.ai_family = AF_UNSPEC; /* Allow IPv4 or IPv6 */
@ -1189,8 +1188,8 @@ set_os_defaults_windows(struct getdns_context *context)
#else
static getdns_return_t
set_os_defaults(struct getdns_context *context)
getdns_return_t
getdns_context_set_resolvconf(getdns_context *context, const char *resolvconf)
{
FILE *in;
char line[1024], domain[1024];
@ -1202,21 +1201,18 @@ set_os_defaults(struct getdns_context *context)
getdns_list *suffix;
int s;
if(context->fchg_resolvconf == NULL) {
context->fchg_resolvconf =
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);
if (!context || !resolvconf)
return GETDNS_RETURN_INVALID_PARAMETER;
in = fopen(context->fchg_resolvconf->fn, "r");
if (!in)
return GETDNS_RETURN_GOOD;
(void) strlcpy( context->fchg_resolvconf.fn, resolvconf, _GETDNS_PATH_MAX);
(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;
while (fgets(line, (int)sizeof(line), in))
@ -1225,12 +1221,16 @@ set_os_defaults(struct getdns_context *context)
fclose(in);
suffix = getdns_list_create_with_context(context);
context->upstreams = upstreams_create(
context, upstream_count * GETDNS_UPSTREAM_TRANSPORTS);
in = fopen(context->fchg_resolvconf->fn, "r");
if (!in)
return GETDNS_RETURN_GOOD;
if (context->upstreams) {
_getdns_upstreams_dereference(context->upstreams);
context->upstreams = NULL;
}
if (!(context->upstreams = upstreams_create(
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));
hints.ai_family = AF_UNSPEC; /* Allow IPv4 or IPv6 */
@ -1306,10 +1306,25 @@ set_os_defaults(struct getdns_context *context)
(void )getdns_context_set_suffix(context, suffix);
getdns_list_destroy(suffix);
dispatch_updated(context,
GETDNS_CONTEXT_CODE_UPSTREAM_RECURSIVE_SERVERS);
return GETDNS_RETURN_GOOD;
} /* set_os_defaults */
#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
so that 0 comes last
*/
@ -1400,7 +1415,7 @@ static const char *_getdns_default_trust_anchors_verify_email =
*/
getdns_return_t
getdns_context_create_with_extended_memory_functions(
struct getdns_context ** context,
getdns_context **context,
int set_from_os,
void *userarg,
void *(*malloc)(void *userarg, size_t),
@ -1571,8 +1586,8 @@ getdns_context_create_with_extended_memory_functions(
/* state data used to detect changes to the system config files
*/
result->fchg_resolvconf = NULL;
result->fchg_hosts = NULL;
(void)memset(&result->fchg_resolvconf, 0, sizeof(struct filechg));
(void)memset(&result->fchg_hosts , 0, sizeof(struct filechg));
result->dnssec_allowed_skew = 0;
result->edns_maximum_udp_payload_size = -1;
@ -1623,12 +1638,12 @@ getdns_context_create_with_extended_memory_functions(
_getdns_mdns_context_init(result);
#endif
create_local_hosts(result);
// resolv.conf does not exist on Windows, handle differently
#ifndef USE_WINSOCK
if ((set_from_os & 1) && (r = set_os_defaults(result)))
goto error;
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;
@ -1675,7 +1690,6 @@ getdns_context_create(struct getdns_context ** context, int set_from_os)
set_from_os, malloc, realloc, free);
} /* getdns_context_create */
/*
* getdns_context_destroy
*
@ -1730,16 +1744,6 @@ getdns_context_destroy(struct getdns_context *context)
if (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)
SSL_CTX_free(context->tls_ctx);
@ -3868,7 +3872,10 @@ _get_context_settings(getdns_context* context)
(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)
(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);
return result;
error:
getdns_dict_destroy(result);
@ -3904,6 +3911,39 @@ getdns_context_get_api_information(getdns_context* context)
&& ! getdns_dict_util_set_string(
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(
result, "resolution_type", context->resolution_type)
@ -4564,6 +4604,8 @@ _getdns_context_config_setting(getdns_context *context,
CONTEXT_SETTING_STRING(trust_anchors_verify_CA)
CONTEXT_SETTING_STRING(trust_anchors_verify_email)
CONTEXT_SETTING_STRING(appdata_dir)
CONTEXT_SETTING_STRING(resolvconf)
CONTEXT_SETTING_STRING(hosts)
/**************************************/
/**** ****/
@ -4623,7 +4665,17 @@ _getdns_context_config_setting(getdns_context *context,
&& !_streq(setting, "api_version_number")
&& !_streq(setting, "trust_anchor_file")
&& !_streq(setting, "default_trust_anchor_location")
&& !_streq(setting, "default_resolvconf_location")
&& !_streq(setting, "default_hosts_location")
&& !_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;
}
@ -5008,5 +5060,54 @@ getdns_context_set_appdata_dir(
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));
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));
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;
}
/* context.c */

View File

@ -54,9 +54,6 @@
struct getdns_dns_req;
struct ub_ctx;
#define GETDNS_FN_RESOLVCONF "/etc/resolv.conf"
#define GETDNS_FN_HOSTS "/etc/hosts"
enum filechgs { GETDNS_FCHG_ERRORS = -1
, GETDNS_FCHG_NOERROR = 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 */
struct filechg {
char *fn;
char fn[_GETDNS_PATH_MAX];
int changes;
int errors;
struct stat *prevstat;
struct stat prevstat;
};
typedef enum getdns_tls_hs_state {
@ -455,8 +452,8 @@ struct getdns_context {
/*
* state data used to detect changes to the system config files
*/
struct filechg *fchg_resolvconf;
struct filechg *fchg_hosts;
struct filechg fchg_resolvconf;
struct filechg fchg_hosts;
uint8_t trust_anchors_spc[1024];
@ -540,8 +537,6 @@ void _getdns_bindata_destroy(
getdns_return_t _getdns_context_local_namespace_resolve(
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_upstreams_dereference(getdns_upstreams *upstreams);
@ -557,4 +552,7 @@ int _getdns_context_write_priv_file(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_ */

View File

@ -53,6 +53,8 @@ extern "C" {
* \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_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 )
@ -88,6 +90,11 @@ 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_APPDATA_DIR 628
#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"
/** @}
*/
@ -680,6 +687,30 @@ getdns_return_t
getdns_context_set_trust_anchors_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);
/**
* Get the current resolution type setting from this context.
* @see getdns_context_set_resolution_type
@ -1134,6 +1165,31 @@ getdns_return_t
getdns_context_get_trust_anchors_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);
/** @}
*/

View File

@ -21,11 +21,13 @@ getdns_context_get_edns_maximum_udp_payload_size
getdns_context_get_edns_version
getdns_context_get_eventloop
getdns_context_get_follow_redirects
getdns_context_get_hosts
getdns_context_get_idle_timeout
getdns_context_get_limit_outstanding_queries
getdns_context_get_namespaces
getdns_context_get_num_pending_requests
getdns_context_get_resolution_type
getdns_context_get_resolvconf
getdns_context_get_round_robin_upstreams
getdns_context_get_suffix
getdns_context_get_timeout
@ -56,6 +58,7 @@ getdns_context_set_edns_version
getdns_context_set_eventloop
getdns_context_set_extended_memory_functions
getdns_context_set_follow_redirects
getdns_context_set_hosts
getdns_context_set_idle_timeout
getdns_context_set_limit_outstanding_queries
getdns_context_set_listen_addresses
@ -63,6 +66,7 @@ getdns_context_set_logfunc
getdns_context_set_memory_functions
getdns_context_set_namespaces
getdns_context_set_resolution_type
getdns_context_set_resolvconf
getdns_context_set_return_dnssec_status
getdns_context_set_round_robin_upstreams
getdns_context_set_suffix

View File

@ -112,7 +112,10 @@ getdns_sync_data_cleanup(getdns_sync_data *data)
/* If statefull upstream have events scheduled against the sync 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];
if (upstream->loop != &data->context->sync_eventloop.loop)
continue;

View File

@ -91,6 +91,8 @@ static int async = 0, interactive = 0;
static enum { GENERAL, ADDRESS, HOSTNAME, SERVICE } calltype = GENERAL;
static int bogus_answers = 0;
static int check_dnssec = 0;
static char *resolvconf = NULL;
static int print_api_info = 0, print_trust_anchors = 0;
static int get_rrtype(const char *t)
{
@ -252,9 +254,11 @@ print_usage(FILE *out, const char *progname)
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\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-p\tPretty print response dict\n");
fprintf(out, "\t-n\tSet TLS authentication mode to NONE (default)\n");
fprintf(out, "\t-o <filename>\tSet resolver configuration file path\n");
fprintf(out, "\t\t(default = %s)\n", GETDNS_FN_RESOLVCONF);
fprintf(out, "\t-p\tPretty print response dict (default)\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");
fprintf(out, "\t-q\tQuiet mode - don't print response\n");
@ -592,7 +596,7 @@ getdns_return_t parse_args(int argc, char **argv)
size_t j;
int i, klass;
char *arg, *c, *endptr;
int t, print_api_info = 0, print_trust_anchors = 0;
int t;
getdns_list *upstream_list = NULL;
getdns_list *tas = NULL, *hints = NULL;
getdns_dict *pubkey_pin = NULL;
@ -820,6 +824,14 @@ getdns_return_t parse_args(int argc, char **argv)
getdns_context_set_tls_authentication(context,
GETDNS_AUTHENTICATION_REQUIRED);
break;
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;
case 'P':
if (c[1] != 0 || ++i >= argc || !*argv[i]) {
fprintf(stderr, "tls_query_padding_blocksize "
@ -1102,44 +1114,6 @@ next: ;
if (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;
}
@ -1757,8 +1731,66 @@ main(int argc, char **argv)
(void) getdns_context_set_logfunc(context, NULL,
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;
fprintf(stderr, "resolvconf: %s\n", resolvconf);
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;
}
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;
if (query_file) {

2
stubby

@ -1 +1 @@
Subproject commit a43be56e28f3a802f74b7c5b19b4b4c5fbaa908a
Subproject commit d9bba5a018943abb548aa0795ef9c0529bc2c328