From a7a6240202f6e780c9828648a8fb632199d83fe4 Mon Sep 17 00:00:00 2001 From: Willem Toorop Date: Wed, 22 Nov 2017 15:01:38 +0100 Subject: [PATCH 1/8] Set default resolvconf and hosts during configure --- configure.ac | 16 ++++++++++++++++ src/context.c | 18 ++++++++++++------ src/context.h | 3 --- 3 files changed, 28 insertions(+), 9 deletions(-) diff --git a/configure.ac b/configure.ac index 01dcbdb9..2337754a 100644 --- a/configure.ac +++ b/configure.ac @@ -345,6 +345,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"]) diff --git a/src/context.c b/src/context.c index 62678873..6db0745d 100644 --- a/src/context.c +++ b/src/context.c @@ -505,11 +505,7 @@ 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 + in = fopen(GETDNS_FN_HOSTS, "r"); while (fgets(pos, (int)(sizeof(buf) - (pos - buf)), in)) { pos = buf; /* Break out of for to read more */ @@ -1207,7 +1203,7 @@ set_os_defaults(struct getdns_context *context) 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->fn = GETDNS_FN_RESOLVCONF; context->fchg_resolvconf->prevstat = NULL; context->fchg_resolvconf->changes = GETDNS_FCHG_NOCHANGES; context->fchg_resolvconf->errors = GETDNS_FCHG_NOERROR; @@ -3869,6 +3865,8 @@ _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); return result; error: @@ -3905,6 +3903,12 @@ 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, "resolution_type", context->resolution_type) @@ -4624,6 +4628,8 @@ _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") ) { r = GETDNS_RETURN_NOT_IMPLEMENTED; diff --git a/src/context.h b/src/context.h index 1a6d93a4..048137b5 100644 --- a/src/context.h +++ b/src/context.h @@ -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 From ed6c7a6b586c9cb5aa61013a5a7d5f1031d24391 Mon Sep 17 00:00:00 2001 From: Willem Toorop Date: Wed, 22 Nov 2017 15:49:30 +0100 Subject: [PATCH 2/8] getdns_context_create2 and family that set an ... ... alternative resolvconf file --- src/context.c | 59 ++++++++++++++++++++++++++-------- src/context.h | 2 +- src/getdns/getdns_extra.h.in | 61 ++++++++++++++++++++++++++++++++++++ src/libgetdns.symbols | 3 ++ 4 files changed, 111 insertions(+), 14 deletions(-) diff --git a/src/context.c b/src/context.c index 6db0745d..e12f4c04 100644 --- a/src/context.c +++ b/src/context.c @@ -1090,7 +1090,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(getdns_context *context, const char *resolvconf_file) { char domain[1024] = ""; size_t upstreams_limit = 10; @@ -1107,7 +1107,7 @@ set_os_defaults_windows(struct getdns_context *context) 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->fn = resolvconf_file; context->fchg_resolvconf->prevstat = NULL; context->fchg_resolvconf->changes = GETDNS_FCHG_NOCHANGES; context->fchg_resolvconf->errors = GETDNS_FCHG_NOERROR; @@ -1186,7 +1186,7 @@ set_os_defaults_windows(struct getdns_context *context) #else static getdns_return_t -set_os_defaults(struct getdns_context *context) +set_os_defaults(getdns_context *context, const char *resolvconf_file) { FILE *in; char line[1024], domain[1024]; @@ -1203,7 +1203,7 @@ set_os_defaults(struct getdns_context *context) GETDNS_MALLOC(context->my_mf, struct filechg); if(context->fchg_resolvconf == NULL) return GETDNS_RETURN_MEMORY_ERROR; - context->fchg_resolvconf->fn = GETDNS_FN_RESOLVCONF; + 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; @@ -1395,9 +1395,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_functions( - struct getdns_context ** context, - int set_from_os, +getdns_context_create_with_extended_memory_functions2( + getdns_context **context, + const char *resolvconf_file, void *userarg, void *(*malloc)(void *userarg, size_t), void *(*realloc)(void *userarg, void *, size_t), @@ -1571,13 +1571,8 @@ getdns_context_create_with_extended_memory_functions( result->fchg_hosts = NULL; // resolv.conf does not exist on Windows, handle differently -#ifndef USE_WINSOCK - if ((set_from_os & 1) && (r = set_os_defaults(result))) + if (resolvconf_file && (r = set_os_defaults(result, resolvconf_file))) goto error; -#else - if ((set_from_os & 1) && (r = set_os_defaults_windows(result))) - goto error; -#endif result->dnssec_allowed_skew = 0; result->edns_maximum_udp_payload_size = -1; @@ -1638,6 +1633,21 @@ 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 * @@ -1672,6 +1682,29 @@ 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 diff --git a/src/context.h b/src/context.h index 048137b5..54a46306 100644 --- a/src/context.h +++ b/src/context.h @@ -69,7 +69,7 @@ typedef void (*getdns_update_callback2) (struct getdns_context *, /* internal use only for detecting changes to system files */ struct filechg { - char *fn; + const char *fn; int changes; int errors; struct stat *prevstat; diff --git a/src/getdns/getdns_extra.h.in b/src/getdns/getdns_extra.h.in index ca62b2fb..b2e362ee 100644 --- a/src/getdns/getdns_extra.h.in +++ b/src/getdns/getdns_extra.h.in @@ -377,6 +377,67 @@ 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 diff --git a/src/libgetdns.symbols b/src/libgetdns.symbols index 3f26578a..46199c59 100644 --- a/src/libgetdns.symbols +++ b/src/libgetdns.symbols @@ -3,8 +3,11 @@ 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 From 3e1607556397145b9ecc9d70275540d4fd9998bf Mon Sep 17 00:00:00 2001 From: Willem Toorop Date: Thu, 23 Nov 2017 12:26:40 +0100 Subject: [PATCH 3/8] Test getdns_context_create2 with getdns_query --- src/sync.c | 5 +- src/tools/getdns_query.c | 118 +++++++++++++++++++++++++-------------- 2 files changed, 80 insertions(+), 43 deletions(-) diff --git a/src/sync.c b/src/sync.c index debf904b..e592e7d1 100644 --- a/src/sync.c +++ b/src/sync.c @@ -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; diff --git a/src/tools/getdns_query.c b/src/tools/getdns_query.c index a9b4b96d..8bc2c231 100644 --- a/src/tools/getdns_query.c +++ b/src/tools/getdns_query.c @@ -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 \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 \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 \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, "" + "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,68 @@ 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) { + getdns_context_destroy(context); + if ((r = getdns_context_create2(&context, resolvconf))) { + fprintf(stderr, "Create context failed: %d\n", (int)r); + context = NULL; + 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) { From c0a3babe0a51580e3b1e7072fc0d7d1dd3281bc4 Mon Sep 17 00:00:00 2001 From: Willem Toorop Date: Thu, 23 Nov 2017 12:39:07 +0100 Subject: [PATCH 4/8] Separate sys_ctxt for meta queries --- src/anchor.c | 32 ++++---------------------------- src/context.c | 35 +++++++++++++++++++++++++++++++++++ src/context.h | 3 +++ 3 files changed, 42 insertions(+), 28 deletions(-) diff --git a/src/anchor.c b/src/anchor.c index 006e5da4..a374ab78 100644 --- a/src/anchor.c +++ b/src/anchor.c @@ -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" diff --git a/src/context.c b/src/context.c index e12f4c04..1fc188ff 100644 --- a/src/context.c +++ b/src/context.c @@ -5048,5 +5048,40 @@ 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 ((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 */ diff --git a/src/context.h b/src/context.h index 54a46306..5fc0ff38 100644 --- a/src/context.h +++ b/src/context.h @@ -554,4 +554,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_ */ From c3cdf496e3d0ce7fc2d000054492c440544d6043 Mon Sep 17 00:00:00 2001 From: Willem Toorop Date: Thu, 23 Nov 2017 12:48:48 +0100 Subject: [PATCH 5/8] Meta queries to upstreams from resolvconf setting --- src/context.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/context.c b/src/context.c index 1fc188ff..a104e8cd 100644 --- a/src/context.c +++ b/src/context.c @@ -5056,10 +5056,11 @@ getdns_context *_getdns_context_get_sys_ctxt( 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))) + if ((r = getdns_context_create_with_extended_memory_functions2( + ( 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))) DEBUG_ANCHOR("Could not create system context: %s\n" , getdns_get_errorstr_by_id(r)); From 27847b9a0a74bc719388bc37b6604c88544f9b06 Mon Sep 17 00:00:00 2001 From: Willem Toorop Date: Thu, 23 Nov 2017 13:23:00 +0100 Subject: [PATCH 6/8] Initialize context->sys_ctxt! --- src/context.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/context.c b/src/context.c index a104e8cd..09718efb 100644 --- a/src/context.c +++ b/src/context.c @@ -5056,7 +5056,7 @@ getdns_context *_getdns_context_get_sys_ctxt( if (context->sys_ctxt) return context->sys_ctxt; - if ((r = getdns_context_create_with_extended_memory_functions2( + 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, From 96ed06c6a96a7b00794042014abab954b6d74b51 Mon Sep 17 00:00:00 2001 From: Willem Toorop Date: Tue, 12 Dec 2017 12:24:31 +0100 Subject: [PATCH 7/8] 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() --- ChangeLog | 10 ++ configure.ac | 2 +- src/const-info.c | 6 + src/context.c | 325 +++++++++++++++++++---------------- src/context.h | 10 +- src/getdns/getdns_extra.h.in | 117 ++++++------- src/libgetdns.symbols | 7 +- src/tools/getdns_query.c | 6 +- stubby | 2 +- 9 files changed, 257 insertions(+), 228 deletions(-) diff --git a/ChangeLog b/ChangeLog index 133ccbdb..a9d48429 100644 --- a/ChangeLog +++ b/ChangeLog @@ -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 diff --git a/configure.ac b/configure.ac index 2337754a..ed14463f 100644 --- a/configure.ac +++ b/configure.ac @@ -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 diff --git a/src/const-info.c b/src/const-info.c index 2c582ed1..f1bfd891 100644 --- a/src/const-info.c +++ b/src/const-info.c @@ -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 }, diff --git a/src/context.c b/src/context.c index 9f84248a..fc33fec2 100644 --- a/src/context.c +++ b/src/context.c @@ -57,6 +57,9 @@ typedef unsigned short in_port_t; #include #endif +#include +#include + #include #include #include @@ -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 " diff --git a/src/context.h b/src/context.h index 5fc0ff38..bc85d65a 100644 --- a/src/context.h +++ b/src/context.h @@ -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); diff --git a/src/getdns/getdns_extra.h.in b/src/getdns/getdns_extra.h.in index b2e362ee..2f8fa8cd 100644 --- a/src/getdns/getdns_extra.h.in +++ b/src/getdns/getdns_extra.h.in @@ -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); /** @} */ diff --git a/src/libgetdns.symbols b/src/libgetdns.symbols index 46199c59..d2b7900a 100644 --- a/src/libgetdns.symbols +++ b/src/libgetdns.symbols @@ -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 diff --git a/src/tools/getdns_query.c b/src/tools/getdns_query.c index 8bc2c231..4722e07f 100644 --- a/src/tools/getdns_query.c +++ b/src/tools/getdns_query.c @@ -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))) diff --git a/stubby b/stubby index a43be56e..d9bba5a0 160000 --- a/stubby +++ b/stubby @@ -1 +1 @@ -Subproject commit a43be56e28f3a802f74b7c5b19b4b4c5fbaa908a +Subproject commit d9bba5a018943abb548aa0795ef9c0529bc2c328 From 26877d44944ceb33fd9992f397382fec6b6bcc00 Mon Sep 17 00:00:00 2001 From: Willem Toorop Date: Tue, 12 Dec 2017 12:38:55 +0100 Subject: [PATCH 8/8] Include sys/stat.h (from config.h) + + introduce GETDNS_RETURN_IO_ERROR return code (forgot to mention that in previous commit) --- ChangeLog | 1 + configure.ac | 6 +++++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index a9d48429..7f5cf497 100644 --- a/ChangeLog +++ b/ChangeLog @@ -9,6 +9,7 @@ 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 diff --git a/configure.ac b/configure.ac index ed14463f..dd499b90 100644 --- a/configure.ac +++ b/configure.ac @@ -265,7 +265,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) @@ -1516,6 +1516,10 @@ static inline int _gldns_custom_vsnprintf(char *str, size_t size, const char *fo #include #endif +#ifdef HAVE_SYS_STAT_H +#include +#endif + #ifdef HAVE_NETINET_IN_H #include #endif