Initialize context with given resolv.conf and hosts files

- getdns_context_create with set_from_os set will simply call these
  functions with the defaults

+ filechg_check is simplified somewhat (reducting memory management)
+ get OpenSSL version version via get_api_information()
This commit is contained in:
Willem Toorop 2017-12-12 12:24:31 +01:00
parent 01197f10ff
commit 96ed06c6a9
9 changed files with 257 additions and 228 deletions

View File

@ -1,4 +1,14 @@
* 201?-??-??: Version 1.?.?
* 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()
* Bugfix #359: edns_client_subnet_private should set family
Thanks Daniel Areiza

View File

@ -407,7 +407,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

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,7 +545,21 @@ create_local_hosts(getdns_context *context)
int start_of_line = 1;
getdns_dict *address = NULL;
in = fopen(GETDNS_FN_HOSTS, "r");
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 */
@ -585,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)
@ -1090,7 +1104,7 @@ static int get_dns_suffix_windows(getdns_list *suffix, char* domain)
static getdns_return_t
set_os_defaults(getdns_context *context, const char *resolvconf_file)
set_os_defaults_windows(getdns_context *context)
{
char domain[1024] = "";
size_t upstreams_limit = 10;
@ -1102,19 +1116,8 @@ set_os_defaults(getdns_context *context, const char *resolvconf_file)
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 = resolvconf_file;
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 */
@ -1185,8 +1188,8 @@ set_os_defaults(getdns_context *context, const char *resolvconf_file)
#else
static getdns_return_t
set_os_defaults(getdns_context *context, const char *resolvconf_file)
getdns_return_t
getdns_context_set_resolvconf(getdns_context *context, const char *resolvconf)
{
FILE *in;
char line[1024], domain[1024];
@ -1198,21 +1201,18 @@ set_os_defaults(getdns_context *context, const char *resolvconf_file)
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 = resolvconf_file;
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))
@ -1221,12 +1221,16 @@ set_os_defaults(getdns_context *context, const char *resolvconf_file)
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 */
@ -1302,10 +1306,25 @@ set_os_defaults(getdns_context *context, const char *resolvconf_file)
(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
*/
@ -1395,9 +1414,9 @@ static const char *_getdns_default_trust_anchors_verify_email =
* Call this to initialize the context that is used in other getdns calls.
*/
getdns_return_t
getdns_context_create_with_extended_memory_functions2(
getdns_context_create_with_extended_memory_functions(
getdns_context **context,
const char *resolvconf_file,
int set_from_os,
void *userarg,
void *(*malloc)(void *userarg, size_t),
void *(*realloc)(void *userarg, void *, size_t),
@ -1567,8 +1586,8 @@ getdns_context_create_with_extended_memory_functions2(
/* 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;
@ -1619,12 +1638,12 @@ getdns_context_create_with_extended_memory_functions2(
_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, resolvconf_file)))
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;
@ -1637,21 +1656,6 @@ error:
return r;
} /* getdns_context_create_with_extended_memory_functions */
getdns_return_t
getdns_context_create_with_extended_memory_functions(
getdns_context **context,
int set_from_os,
void *userarg,
void *(*malloc)(void *userarg, size_t),
void *(*realloc)(void *userarg, void *, size_t),
void (*free)(void *userarg, void *)
)
{
return getdns_context_create_with_extended_memory_functions2(context,
((set_from_os & 1) ? GETDNS_FN_RESOLVCONF : NULL), userarg,
malloc, realloc, free);
}
/*
* getdns_context_create
*
@ -1686,30 +1690,6 @@ getdns_context_create(struct getdns_context ** context, int set_from_os)
set_from_os, malloc, realloc, free);
} /* getdns_context_create */
getdns_return_t
getdns_context_create_with_memory_functions2(getdns_context **context,
const char *resolvconf_file,
void *(*malloc)(size_t),
void *(*realloc)(void *, size_t),
void (*free)(void *)
)
{
mf_union mf;
mf.pln.malloc = malloc;
mf.pln.realloc = realloc;
mf.pln.free = free;
return getdns_context_create_with_extended_memory_functions2(
context, resolvconf_file, MF_PLAIN,
mf.ext.malloc, mf.ext.realloc, mf.ext.free);
}
getdns_return_t
getdns_context_create2(getdns_context **context, const char *resolvconf_file)
{
return getdns_context_create_with_memory_functions2(context,
resolvconf_file, malloc, realloc, free);
}
/*
* getdns_context_destroy
*
@ -1764,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);
@ -3902,9 +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 (context->fchg_resolvconf && context->fchg_resolvconf->fn)
(void) getdns_dict_util_set_string(result, "resolvconf_file", context->fchg_resolvconf->fn);
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);
@ -3946,6 +3917,33 @@ getdns_context_get_api_information(getdns_context* context)
&& ! 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)
@ -4606,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)
/**************************************/
/**** ****/
@ -4668,6 +4668,14 @@ _getdns_context_config_setting(getdns_context *context,
&& !_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;
}
@ -5060,14 +5068,27 @@ getdns_context *_getdns_context_get_sys_ctxt(
if (context->sys_ctxt)
return context->sys_ctxt;
if ((r = getdns_context_create_with_extended_memory_functions2(&context->sys_ctxt,
( context->fchg_resolvconf && context->fchg_resolvconf->fn
? context->fchg_resolvconf->fn : NULL ),
context->mf.mf_arg, context->mf.mf.ext.malloc,
context->mf.mf.ext.realloc, context->mf.mf.ext.free)))
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 "

View File

@ -69,10 +69,10 @@ typedef void (*getdns_update_callback2) (struct getdns_context *,
/* internal use only for detecting changes to system files */
struct filechg {
const char *fn;
char fn[_GETDNS_PATH_MAX];
int changes;
int errors;
struct stat *prevstat;
struct stat prevstat;
};
typedef enum getdns_tls_hs_state {
@ -452,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];
@ -537,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);

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"
/** @}
*/
@ -377,67 +384,6 @@ getdns_context_run(getdns_context *context);
* @{
*/
/**
* creates a new getdns context with default settings.
* If used multi-threaded, user must define appropriate OpenSSL callback locking functions
* (e.g. CRYPTO_THREADID_set_call) depending on the library version used.
* @param context context that can be used immediately with other API calls
* @param resolvconf is the location of the resolv.conf file from which to
* read the OS settings. When NULL, the context will not be
* initialized with the settings herein.
* @return GETDNS_RETURN_GOOD on success
*/
getdns_return_t
getdns_context_create2(getdns_context ** context, const char *resolvconf);
/**
* creates a new getdns context with default settings using custom memory functions.
* If used multi-threaded, user must define appropriate OpenSSL callback locking functions
* (e.g. CRYPTO_THREADID_set_call) depending on the library version used.
* @param context context that can be used immediately with other API calls
* @param resolvconf is the location of the resolv.conf file from which to
* read the OS settings. When NULL, the context will not be
* initialized with the settings herein.
* @param malloc custom malloc function
* @param realloc custom realloc function
* @param free custom free function
* @return GETDNS_RETURN_GOOD on success
*/
getdns_return_t
getdns_context_create_with_memory_functions2(
getdns_context ** context,
const char *resolvconf,
void *(*malloc) (size_t),
void *(*realloc) (void *, size_t),
void (*free) (void *)
);
/**
* creates a new getdns context with default settings using extended custom memory functions.
* If used multi-threaded, user must define appropriate OpenSSL callback locking functions
* (e.g. CRYPTO_THREADID_set_call) depending on the library version used.
* @param context context that can be used immediately with other API calls
* @param resolvconf is the location of the resolv.conf file from which to
* read the OS settings. When NULL, the context will not be
* initialized with the settings herein.
* @param userarg parameter passed to the custom malloc, realloc and free functions
* @param malloc custom malloc function
* @param realloc custom realloc function
* @param free custom free function
* @return GETDNS_RETURN_GOOD on success
*/
getdns_return_t
getdns_context_create_with_extended_memory_functions2(
getdns_context **context,
const char *resolvconf,
void *userarg,
void *(*malloc) (void *userarg, size_t),
void *(*realloc) (void *userarg, void *, size_t),
void (*free) (void *userarg, void *)
);
/**
* Register a callback function for context changes.
* @see getdns_context_set_context_update_callback
@ -741,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
@ -1195,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

@ -3,11 +3,8 @@ getdns_address_sync
getdns_cancel_callback
getdns_context_config
getdns_context_create
getdns_context_create2
getdns_context_create_with_extended_memory_functions
getdns_context_create_with_extended_memory_functions2
getdns_context_create_with_memory_functions
getdns_context_create_with_memory_functions2
getdns_context_destroy
getdns_context_detach_eventloop
getdns_context_get_api_information
@ -24,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
@ -59,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
@ -66,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

@ -1735,10 +1735,8 @@ main(int argc, char **argv)
goto done_destroy_context;
fprintf(stderr, "resolvconf: %s\n", resolvconf);
if (resolvconf) {
getdns_context_destroy(context);
if ((r = getdns_context_create2(&context, resolvconf))) {
fprintf(stderr, "Create context failed: %d\n", (int)r);
context = NULL;
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)))

2
stubby

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