mirror of
https://github.com/cuberite/libevent.git
synced 2025-09-10 04:50:37 -04:00
evdns: add DNS_OPTION_NAMESERVERS_NO_DEFAULT/EVDNS_BASE_NAMESERVERS_NO_DEFAULT
- DNS_OPTION_NAMESERVERS_NO_DEFAULT Do not "default" nameserver (i.e. "127.0.0.1:53") if there is no nameservers in resolv.conf, (iff DNS_OPTION_NAMESERVERS is set) - EVDNS_BASE_NAMESERVERS_NO_DEFAULT If EVDNS_BASE_INITIALIZE_NAMESERVERS isset, do not add default nameserver if there are no nameservers in resolv.conf (just set DNS_OPTION_NAMESERVERS_NO_DEFAULT internally) Fixes: #569 (cherry picked from commit e5b8f4c1925867d8e4cd7dc0390e5141d7ef1106)
This commit is contained in:
parent
aa5a65d194
commit
58e81106ad
31
evdns.c
31
evdns.c
@ -3327,10 +3327,16 @@ search_request_finished(struct evdns_request *const handle) {
|
|||||||
|
|
||||||
static void
|
static void
|
||||||
evdns_resolv_set_defaults(struct evdns_base *base, int flags) {
|
evdns_resolv_set_defaults(struct evdns_base *base, int flags) {
|
||||||
|
int add_default = flags & DNS_OPTION_NAMESERVERS;
|
||||||
|
if (flags & DNS_OPTION_NAMESERVERS_NO_DEFAULT)
|
||||||
|
add_default = 0;
|
||||||
|
|
||||||
/* if the file isn't found then we assume a local resolver */
|
/* if the file isn't found then we assume a local resolver */
|
||||||
ASSERT_LOCKED(base);
|
ASSERT_LOCKED(base);
|
||||||
if (flags & DNS_OPTION_SEARCH) search_set_from_hostname(base);
|
if (flags & DNS_OPTION_SEARCH)
|
||||||
if (flags & DNS_OPTION_NAMESERVERS) evdns_base_nameserver_ip_add(base,"127.0.0.1");
|
search_set_from_hostname(base);
|
||||||
|
if (add_default)
|
||||||
|
evdns_base_nameserver_ip_add(base, "127.0.0.1");
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef EVENT__HAVE_STRTOK_R
|
#ifndef EVENT__HAVE_STRTOK_R
|
||||||
@ -3626,9 +3632,14 @@ evdns_base_resolv_conf_parse_impl(struct evdns_base *base, int flags, const char
|
|||||||
char *resolv;
|
char *resolv;
|
||||||
char *start;
|
char *start;
|
||||||
int err = 0;
|
int err = 0;
|
||||||
|
int add_default;
|
||||||
|
|
||||||
log(EVDNS_LOG_DEBUG, "Parsing resolv.conf file %s", filename);
|
log(EVDNS_LOG_DEBUG, "Parsing resolv.conf file %s", filename);
|
||||||
|
|
||||||
|
add_default = flags & DNS_OPTION_NAMESERVERS;
|
||||||
|
if (flags & DNS_OPTION_NAMESERVERS_NO_DEFAULT)
|
||||||
|
add_default = 0;
|
||||||
|
|
||||||
if (flags & DNS_OPTION_HOSTSFILE) {
|
if (flags & DNS_OPTION_HOSTSFILE) {
|
||||||
char *fname = evdns_get_default_hosts_filename();
|
char *fname = evdns_get_default_hosts_filename();
|
||||||
evdns_base_load_hosts(base, fname);
|
evdns_base_load_hosts(base, fname);
|
||||||
@ -3664,7 +3675,7 @@ evdns_base_resolv_conf_parse_impl(struct evdns_base *base, int flags, const char
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!base->server_head && (flags & DNS_OPTION_NAMESERVERS)) {
|
if (!base->server_head && add_default) {
|
||||||
/* no nameservers were configured. */
|
/* no nameservers were configured. */
|
||||||
evdns_base_nameserver_ip_add(base, "127.0.0.1");
|
evdns_base_nameserver_ip_add(base, "127.0.0.1");
|
||||||
err = 6;
|
err = 6;
|
||||||
@ -3965,7 +3976,12 @@ evdns_base_new(struct event_base *event_base, int flags)
|
|||||||
|
|
||||||
TAILQ_INIT(&base->hostsdb);
|
TAILQ_INIT(&base->hostsdb);
|
||||||
|
|
||||||
#define EVDNS_BASE_ALL_FLAGS (0x8001)
|
#define EVDNS_BASE_ALL_FLAGS ( \
|
||||||
|
EVDNS_BASE_INITIALIZE_NAMESERVERS | \
|
||||||
|
EVDNS_BASE_DISABLE_WHEN_INACTIVE | \
|
||||||
|
EVDNS_BASE_NAMESERVERS_NO_DEFAULT | \
|
||||||
|
0)
|
||||||
|
|
||||||
if (flags & ~EVDNS_BASE_ALL_FLAGS) {
|
if (flags & ~EVDNS_BASE_ALL_FLAGS) {
|
||||||
flags = EVDNS_BASE_INITIALIZE_NAMESERVERS;
|
flags = EVDNS_BASE_INITIALIZE_NAMESERVERS;
|
||||||
log(EVDNS_LOG_WARN,
|
log(EVDNS_LOG_WARN,
|
||||||
@ -3976,10 +3992,15 @@ evdns_base_new(struct event_base *event_base, int flags)
|
|||||||
|
|
||||||
if (flags & EVDNS_BASE_INITIALIZE_NAMESERVERS) {
|
if (flags & EVDNS_BASE_INITIALIZE_NAMESERVERS) {
|
||||||
int r;
|
int r;
|
||||||
|
int opts = DNS_OPTIONS_ALL;
|
||||||
|
if (flags & EVDNS_BASE_NAMESERVERS_NO_DEFAULT) {
|
||||||
|
opts |= DNS_OPTION_NAMESERVERS_NO_DEFAULT;
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
r = evdns_base_config_windows_nameservers(base);
|
r = evdns_base_config_windows_nameservers(base);
|
||||||
#else
|
#else
|
||||||
r = evdns_base_resolv_conf_parse(base, DNS_OPTIONS_ALL, "/etc/resolv.conf");
|
r = evdns_base_resolv_conf_parse(base, opts, "/etc/resolv.conf");
|
||||||
#endif
|
#endif
|
||||||
if (r == -1) {
|
if (r == -1) {
|
||||||
evdns_base_free_and_unlock(base, 0);
|
evdns_base_free_and_unlock(base, 0);
|
||||||
|
@ -209,6 +209,9 @@ extern "C" {
|
|||||||
DNS_OPTION_HOSTSFILE | \
|
DNS_OPTION_HOSTSFILE | \
|
||||||
0 \
|
0 \
|
||||||
)
|
)
|
||||||
|
/* Do not "default" nameserver (i.e. "127.0.0.1:53") if there is no nameservers
|
||||||
|
* in resolv.conf, (iff DNS_OPTION_NAMESERVERS is set) */
|
||||||
|
#define DNS_OPTION_NAMESERVERS_NO_DEFAULT 16
|
||||||
|
|
||||||
/* Obsolete name for DNS_QUERY_NO_SEARCH */
|
/* Obsolete name for DNS_QUERY_NO_SEARCH */
|
||||||
#define DNS_NO_SEARCH DNS_QUERY_NO_SEARCH
|
#define DNS_NO_SEARCH DNS_QUERY_NO_SEARCH
|
||||||
@ -233,6 +236,10 @@ struct event_base;
|
|||||||
/** Flag for evdns_base_new: Do not prevent the libevent event loop from
|
/** Flag for evdns_base_new: Do not prevent the libevent event loop from
|
||||||
* exiting when we have no active dns requests. */
|
* exiting when we have no active dns requests. */
|
||||||
#define EVDNS_BASE_DISABLE_WHEN_INACTIVE 0x8000
|
#define EVDNS_BASE_DISABLE_WHEN_INACTIVE 0x8000
|
||||||
|
/** Flag for evdns_base_new: If EVDNS_BASE_INITIALIZE_NAMESERVERS isset, do not
|
||||||
|
* add default nameserver if there are no nameservers in resolv.conf
|
||||||
|
* @see DNS_OPTION_NAMESERVERS_NO_DEFAULT */
|
||||||
|
#define EVDNS_BASE_NAMESERVERS_NO_DEFAULT 0x10000
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Initialize the asynchronous DNS library.
|
Initialize the asynchronous DNS library.
|
||||||
@ -243,7 +250,7 @@ struct event_base;
|
|||||||
|
|
||||||
@param event_base the event base to associate the dns client with
|
@param event_base the event base to associate the dns client with
|
||||||
@param flags any of EVDNS_BASE_INITIALIZE_NAMESERVERS|
|
@param flags any of EVDNS_BASE_INITIALIZE_NAMESERVERS|
|
||||||
EVDNS_BASE_DISABLE_WHEN_INACTIVE
|
EVDNS_BASE_DISABLE_WHEN_INACTIVE|EVDNS_BASE_NAMESERVERS_NO_DEFAULT
|
||||||
@return evdns_base object if successful, or NULL if an error occurred.
|
@return evdns_base object if successful, or NULL if an error occurred.
|
||||||
@see evdns_base_free()
|
@see evdns_base_free()
|
||||||
*/
|
*/
|
||||||
@ -478,7 +485,7 @@ int evdns_base_set_option(struct evdns_base *base, const char *option, const cha
|
|||||||
|
|
||||||
@param base the evdns_base to which to apply this operation
|
@param base the evdns_base to which to apply this operation
|
||||||
@param flags any of DNS_OPTION_NAMESERVERS|DNS_OPTION_SEARCH|DNS_OPTION_MISC|
|
@param flags any of DNS_OPTION_NAMESERVERS|DNS_OPTION_SEARCH|DNS_OPTION_MISC|
|
||||||
DNS_OPTION_HOSTSFILE|DNS_OPTIONS_ALL
|
DNS_OPTION_HOSTSFILE|DNS_OPTIONS_ALL|DNS_OPTION_NAMESERVERS_NO_DEFAULT
|
||||||
@param filename the path to the resolv.conf file
|
@param filename the path to the resolv.conf file
|
||||||
@return 0 if successful, or various positive error codes if an error
|
@return 0 if successful, or various positive error codes if an error
|
||||||
occurred (see above)
|
occurred (see above)
|
||||||
|
@ -204,7 +204,7 @@ dns_resolve_reverse(void *ptr)
|
|||||||
{
|
{
|
||||||
struct in_addr in;
|
struct in_addr in;
|
||||||
struct event_base *base = event_base_new();
|
struct event_base *base = event_base_new();
|
||||||
struct evdns_base *dns = evdns_base_new(base, 1/* init name servers */);
|
struct evdns_base *dns = evdns_base_new(base, EVDNS_BASE_INITIALIZE_NAMESERVERS);
|
||||||
struct evdns_request *req = NULL;
|
struct evdns_request *req = NULL;
|
||||||
|
|
||||||
tt_assert(base);
|
tt_assert(base);
|
||||||
@ -1004,6 +1004,59 @@ end:
|
|||||||
event_base_free(inactive_base);
|
event_base_free(inactive_base);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
dns_initialize_nameservers_test(void *arg)
|
||||||
|
{
|
||||||
|
struct basic_test_data *data = arg;
|
||||||
|
struct event_base *base = data->base;
|
||||||
|
struct evdns_base *dns = NULL;
|
||||||
|
|
||||||
|
dns = evdns_base_new(base, 0);
|
||||||
|
tt_assert(dns);
|
||||||
|
tt_int_op(evdns_base_get_nameserver_addr(dns, 0, NULL, 0), ==, -1);
|
||||||
|
evdns_base_free(dns, 0);
|
||||||
|
|
||||||
|
dns = evdns_base_new(base, EVDNS_BASE_INITIALIZE_NAMESERVERS);
|
||||||
|
tt_assert(dns);
|
||||||
|
tt_int_op(evdns_base_get_nameserver_addr(dns, 0, NULL, 0), ==, sizeof(struct sockaddr));
|
||||||
|
|
||||||
|
end:
|
||||||
|
if (dns)
|
||||||
|
evdns_base_free(dns, 0);
|
||||||
|
}
|
||||||
|
#ifndef _WIN32
|
||||||
|
#define RESOLV_FILE "empty-resolv.conf"
|
||||||
|
static void
|
||||||
|
dns_nameservers_no_default_test(void *arg)
|
||||||
|
{
|
||||||
|
struct basic_test_data *data = arg;
|
||||||
|
struct event_base *base = data->base;
|
||||||
|
struct evdns_base *dns = NULL;
|
||||||
|
int ok = access(RESOLV_FILE, R_OK);
|
||||||
|
|
||||||
|
tt_assert(ok);
|
||||||
|
|
||||||
|
dns = evdns_base_new(base, 0);
|
||||||
|
tt_assert(dns);
|
||||||
|
tt_int_op(evdns_base_get_nameserver_addr(dns, 0, NULL, 0), ==, -1);
|
||||||
|
|
||||||
|
/* We cannot test
|
||||||
|
* EVDNS_BASE_INITIALIZE_NAMESERVERS|EVDNS_BASE_NAMESERVERS_NO_DEFAULT
|
||||||
|
* because we cannot mock "/etc/resolv.conf" (yet). */
|
||||||
|
|
||||||
|
evdns_base_resolv_conf_parse(dns,
|
||||||
|
DNS_OPTIONS_ALL|DNS_OPTION_NAMESERVERS_NO_DEFAULT, RESOLV_FILE);
|
||||||
|
tt_int_op(evdns_base_get_nameserver_addr(dns, 0, NULL, 0), ==, -1);
|
||||||
|
|
||||||
|
evdns_base_resolv_conf_parse(dns, DNS_OPTIONS_ALL, RESOLV_FILE);
|
||||||
|
tt_int_op(evdns_base_get_nameserver_addr(dns, 0, NULL, 0), ==, sizeof(struct sockaddr));
|
||||||
|
|
||||||
|
end:
|
||||||
|
if (dns)
|
||||||
|
evdns_base_free(dns, 0);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/* === Test for bufferevent_socket_connect_hostname */
|
/* === Test for bufferevent_socket_connect_hostname */
|
||||||
|
|
||||||
static int total_connected_or_failed = 0;
|
static int total_connected_or_failed = 0;
|
||||||
@ -2332,6 +2385,13 @@ struct testcase_t dns_testcases[] = {
|
|||||||
{ "disable_when_inactive_no_ns", dns_disable_when_inactive_no_ns_test,
|
{ "disable_when_inactive_no_ns", dns_disable_when_inactive_no_ns_test,
|
||||||
TT_FORK|TT_NEED_BASE, &basic_setup, NULL },
|
TT_FORK|TT_NEED_BASE, &basic_setup, NULL },
|
||||||
|
|
||||||
|
{ "initialize_nameservers", dns_initialize_nameservers_test,
|
||||||
|
TT_FORK|TT_NEED_BASE, &basic_setup, NULL },
|
||||||
|
#ifndef _WIN32
|
||||||
|
{ "nameservers_no_default", dns_nameservers_no_default_test,
|
||||||
|
TT_FORK|TT_NEED_BASE, &basic_setup, NULL },
|
||||||
|
#endif
|
||||||
|
|
||||||
{ "getaddrinfo_async", test_getaddrinfo_async,
|
{ "getaddrinfo_async", test_getaddrinfo_async,
|
||||||
TT_FORK|TT_NEED_BASE, &basic_setup, (char*)"" },
|
TT_FORK|TT_NEED_BASE, &basic_setup, (char*)"" },
|
||||||
{ "getaddrinfo_cancel_stress", test_getaddrinfo_async_cancel_stress,
|
{ "getaddrinfo_cancel_stress", test_getaddrinfo_async_cancel_stress,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user