mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2025-02-24 22:58:50 +01:00
Merge remote-tracking branch 'tor-github/pr/425'
This commit is contained in:
commit
30d853a906
6 changed files with 152 additions and 18 deletions
4
changes/bug21900
Normal file
4
changes/bug21900
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
o Minor bugfixes (DNS):
|
||||||
|
- Gracefully handle empty or absent resolve.conf file by falling
|
||||||
|
back to using localhost DNS service and hoping it works. Fixes
|
||||||
|
bug 21900; bugfix on 0.2.1.10-alpha.
|
|
@ -812,6 +812,8 @@ fi
|
||||||
dnl Now check for particular libevent functions.
|
dnl Now check for particular libevent functions.
|
||||||
AC_CHECK_FUNCS([evutil_secure_rng_set_urandom_device_file \
|
AC_CHECK_FUNCS([evutil_secure_rng_set_urandom_device_file \
|
||||||
evutil_secure_rng_add_bytes \
|
evutil_secure_rng_add_bytes \
|
||||||
|
evdns_base_get_nameserver_addr \
|
||||||
|
|
||||||
])
|
])
|
||||||
|
|
||||||
LIBS="$save_LIBS"
|
LIBS="$save_LIBS"
|
||||||
|
|
|
@ -2211,7 +2211,8 @@ is non-zero):
|
||||||
__filename__. The file format is the same as the standard Unix
|
__filename__. The file format is the same as the standard Unix
|
||||||
"**resolv.conf**" file (7). This option, like all other ServerDNS options,
|
"**resolv.conf**" file (7). This option, like all other ServerDNS options,
|
||||||
only affects name lookups that your server does on behalf of clients.
|
only affects name lookups that your server does on behalf of clients.
|
||||||
(Defaults to use the system DNS configuration.)
|
(Defaults to use the system DNS configuration or a localhost DNS service
|
||||||
|
in case no nameservers are found in a given configuration.)
|
||||||
|
|
||||||
[[ServerDNSAllowBrokenConfig]] **ServerDNSAllowBrokenConfig** **0**|**1**::
|
[[ServerDNSAllowBrokenConfig]] **ServerDNSAllowBrokenConfig** **0**|**1**::
|
||||||
If this option is false, Tor exits immediately if there are problems
|
If this option is false, Tor exits immediately if there are problems
|
||||||
|
|
|
@ -1357,6 +1357,41 @@ evdns_err_is_transient(int err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return number of configured nameservers in <b>the_evdns_base</b>.
|
||||||
|
*/
|
||||||
|
size_t
|
||||||
|
number_of_configured_nameservers(void)
|
||||||
|
{
|
||||||
|
return evdns_base_count_nameservers(the_evdns_base);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef HAVE_EVDNS_BASE_GET_NAMESERVER_ADDR
|
||||||
|
/**
|
||||||
|
* Return address of configured nameserver in <b>the_evdns_base</b>
|
||||||
|
* at index <b>idx</b>.
|
||||||
|
*/
|
||||||
|
tor_addr_t *
|
||||||
|
configured_nameserver_address(const size_t idx)
|
||||||
|
{
|
||||||
|
struct sockaddr_storage sa;
|
||||||
|
ev_socklen_t sa_len = sizeof(sa);
|
||||||
|
|
||||||
|
if (evdns_base_get_nameserver_addr(the_evdns_base, (int)idx,
|
||||||
|
(struct sockaddr *)&sa,
|
||||||
|
sa_len) > 0) {
|
||||||
|
tor_addr_t *tor_addr = tor_malloc(sizeof(tor_addr_t));
|
||||||
|
if (tor_addr_from_sockaddr(tor_addr,
|
||||||
|
(const struct sockaddr *)&sa,
|
||||||
|
NULL) == 0) {
|
||||||
|
return tor_addr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/** Configure eventdns nameservers if force is true, or if the configuration
|
/** Configure eventdns nameservers if force is true, or if the configuration
|
||||||
* has changed since the last time we called this function, or if we failed on
|
* has changed since the last time we called this function, or if we failed on
|
||||||
* our last attempt. On Unix, this reads from /etc/resolv.conf or
|
* our last attempt. On Unix, this reads from /etc/resolv.conf or
|
||||||
|
@ -1388,16 +1423,23 @@ configure_nameservers(int force)
|
||||||
evdns_set_log_fn(evdns_log_cb);
|
evdns_set_log_fn(evdns_log_cb);
|
||||||
if (conf_fname) {
|
if (conf_fname) {
|
||||||
log_debug(LD_FS, "stat()ing %s", conf_fname);
|
log_debug(LD_FS, "stat()ing %s", conf_fname);
|
||||||
if (stat(sandbox_intern_string(conf_fname), &st)) {
|
int missing_resolv_conf = 0;
|
||||||
|
int stat_res = stat(sandbox_intern_string(conf_fname), &st);
|
||||||
|
|
||||||
|
if (stat_res) {
|
||||||
log_warn(LD_EXIT, "Unable to stat resolver configuration in '%s': %s",
|
log_warn(LD_EXIT, "Unable to stat resolver configuration in '%s': %s",
|
||||||
conf_fname, strerror(errno));
|
conf_fname, strerror(errno));
|
||||||
goto err;
|
missing_resolv_conf = 1;
|
||||||
}
|
} else if (!force && resolv_conf_fname &&
|
||||||
if (!force && resolv_conf_fname && !strcmp(conf_fname,resolv_conf_fname)
|
!strcmp(conf_fname,resolv_conf_fname)
|
||||||
&& st.st_mtime == resolv_conf_mtime) {
|
&& st.st_mtime == resolv_conf_mtime) {
|
||||||
log_info(LD_EXIT, "No change to '%s'", conf_fname);
|
log_info(LD_EXIT, "No change to '%s'", conf_fname);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (stat_res == 0 && st.st_size == 0)
|
||||||
|
missing_resolv_conf = 1;
|
||||||
|
|
||||||
if (nameservers_configured) {
|
if (nameservers_configured) {
|
||||||
evdns_base_search_clear(the_evdns_base);
|
evdns_base_search_clear(the_evdns_base);
|
||||||
evdns_base_clear_nameservers_and_suspend(the_evdns_base);
|
evdns_base_clear_nameservers_and_suspend(the_evdns_base);
|
||||||
|
@ -1410,20 +1452,34 @@ configure_nameservers(int force)
|
||||||
sandbox_intern_string("/etc/hosts"));
|
sandbox_intern_string("/etc/hosts"));
|
||||||
}
|
}
|
||||||
#endif /* defined(DNS_OPTION_HOSTSFILE) && defined(USE_LIBSECCOMP) */
|
#endif /* defined(DNS_OPTION_HOSTSFILE) && defined(USE_LIBSECCOMP) */
|
||||||
log_info(LD_EXIT, "Parsing resolver configuration in '%s'", conf_fname);
|
|
||||||
if ((r = evdns_base_resolv_conf_parse(the_evdns_base, flags,
|
if (!missing_resolv_conf) {
|
||||||
sandbox_intern_string(conf_fname)))) {
|
log_info(LD_EXIT, "Parsing resolver configuration in '%s'", conf_fname);
|
||||||
log_warn(LD_EXIT, "Unable to parse '%s', or no nameservers in '%s' (%d)",
|
if ((r = evdns_base_resolv_conf_parse(the_evdns_base, flags,
|
||||||
conf_fname, conf_fname, r);
|
sandbox_intern_string(conf_fname)))) {
|
||||||
goto err;
|
log_warn(LD_EXIT, "Unable to parse '%s', or no nameservers "
|
||||||
|
"in '%s' (%d)", conf_fname, conf_fname, r);
|
||||||
|
|
||||||
|
if (r != 6) // "r = 6" means "no DNS servers were in resolv.conf" -
|
||||||
|
goto err; // in which case we expect libevent to add 127.0.0.1 as
|
||||||
|
// fallback.
|
||||||
|
}
|
||||||
|
if (evdns_base_count_nameservers(the_evdns_base) == 0) {
|
||||||
|
log_warn(LD_EXIT, "Unable to find any nameservers in '%s'.",
|
||||||
|
conf_fname);
|
||||||
|
}
|
||||||
|
|
||||||
|
tor_free(resolv_conf_fname);
|
||||||
|
resolv_conf_fname = tor_strdup(conf_fname);
|
||||||
|
resolv_conf_mtime = st.st_mtime;
|
||||||
|
} else {
|
||||||
|
log_warn(LD_EXIT, "Could not read your DNS config from '%s' - "
|
||||||
|
"please investigate your DNS configuration. "
|
||||||
|
"This is possibly a problem. Meanwhile, falling"
|
||||||
|
" back to local DNS at 127.0.0.1.", conf_fname);
|
||||||
|
evdns_base_nameserver_ip_add(the_evdns_base, "127.0.0.1");
|
||||||
}
|
}
|
||||||
if (evdns_base_count_nameservers(the_evdns_base) == 0) {
|
|
||||||
log_warn(LD_EXIT, "Unable to find any nameservers in '%s'.", conf_fname);
|
|
||||||
goto err;
|
|
||||||
}
|
|
||||||
tor_free(resolv_conf_fname);
|
|
||||||
resolv_conf_fname = tor_strdup(conf_fname);
|
|
||||||
resolv_conf_mtime = st.st_mtime;
|
|
||||||
if (nameservers_configured)
|
if (nameservers_configured)
|
||||||
evdns_base_resume(the_evdns_base);
|
evdns_base_resume(the_evdns_base);
|
||||||
}
|
}
|
||||||
|
|
|
@ -45,6 +45,11 @@ size_t dns_cache_handle_oom(time_t now, size_t min_remove_bytes);
|
||||||
#ifdef DNS_PRIVATE
|
#ifdef DNS_PRIVATE
|
||||||
#include "feature/relay/dns_structs.h"
|
#include "feature/relay/dns_structs.h"
|
||||||
|
|
||||||
|
size_t number_of_configured_nameservers(void);
|
||||||
|
#ifdef HAVE_EVDNS_BASE_GET_NAMESERVER_ADDR
|
||||||
|
tor_addr_t *configured_nameserver_address(const size_t idx);
|
||||||
|
#endif
|
||||||
|
|
||||||
MOCK_DECL(STATIC int,dns_resolve_impl,(edge_connection_t *exitconn,
|
MOCK_DECL(STATIC int,dns_resolve_impl,(edge_connection_t *exitconn,
|
||||||
int is_resolve,or_circuit_t *oncirc, char **hostname_out,
|
int is_resolve,or_circuit_t *oncirc, char **hostname_out,
|
||||||
int *made_connection_pending_out, cached_resolve_t **resolve_out));
|
int *made_connection_pending_out, cached_resolve_t **resolve_out));
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
/* Copyright (c) 2015-2018, The Tor Project, Inc. */
|
/* Copyright (c) 2015-2018, The Tor Project, Inc. */
|
||||||
/* See LICENSE for licensing information */
|
/* See LICENSE for licensing information */
|
||||||
|
|
||||||
|
#include "orconfig.h"
|
||||||
#include "core/or/or.h"
|
#include "core/or/or.h"
|
||||||
#include "test/test.h"
|
#include "test/test.h"
|
||||||
|
|
||||||
|
@ -13,9 +14,71 @@
|
||||||
|
|
||||||
#include "core/or/edge_connection_st.h"
|
#include "core/or/edge_connection_st.h"
|
||||||
#include "core/or/or_circuit_st.h"
|
#include "core/or/or_circuit_st.h"
|
||||||
|
#include "app/config/or_options_st.h"
|
||||||
|
#include "app/config/config.h"
|
||||||
|
|
||||||
|
#include <event2/event.h>
|
||||||
|
#include <event2/dns.h>
|
||||||
|
|
||||||
#define NS_MODULE dns
|
#define NS_MODULE dns
|
||||||
|
|
||||||
|
#ifdef HAVE_EVDNS_BASE_GET_NAMESERVER_ADDR
|
||||||
|
#define NS_SUBMODULE configure_nameservers_fallback
|
||||||
|
|
||||||
|
static or_options_t options = {
|
||||||
|
.ORPort_set = 1,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const or_options_t *
|
||||||
|
mock_get_options(void)
|
||||||
|
{
|
||||||
|
return &options;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
NS(test_main)(void *arg)
|
||||||
|
{
|
||||||
|
(void)arg;
|
||||||
|
tor_addr_t *nameserver_addr = NULL;
|
||||||
|
|
||||||
|
MOCK(get_options, mock_get_options);
|
||||||
|
|
||||||
|
options.ServerDNSResolvConfFile = (char *)"no_such_file!!!";
|
||||||
|
|
||||||
|
dns_init(); // calls configure_nameservers()
|
||||||
|
|
||||||
|
tt_int_op(number_of_configured_nameservers(), OP_EQ, 1);
|
||||||
|
|
||||||
|
nameserver_addr = configured_nameserver_address(0);
|
||||||
|
|
||||||
|
tt_assert(tor_addr_family(nameserver_addr) == AF_INET);
|
||||||
|
tt_assert(tor_addr_eq_ipv4h(nameserver_addr, 0x7f000001));
|
||||||
|
|
||||||
|
#ifndef _WIN32
|
||||||
|
tor_free(nameserver_addr);
|
||||||
|
|
||||||
|
options.ServerDNSResolvConfFile = (char *)"/dev/null";
|
||||||
|
|
||||||
|
dns_init();
|
||||||
|
|
||||||
|
tt_int_op(number_of_configured_nameservers(), OP_EQ, 1);
|
||||||
|
|
||||||
|
nameserver_addr = configured_nameserver_address(0);
|
||||||
|
|
||||||
|
tt_assert(tor_addr_family(nameserver_addr) == AF_INET);
|
||||||
|
tt_assert(tor_addr_eq_ipv4h(nameserver_addr, 0x7f000001));
|
||||||
|
#endif
|
||||||
|
|
||||||
|
UNMOCK(get_options);
|
||||||
|
|
||||||
|
done:
|
||||||
|
tor_free(nameserver_addr);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
#undef NS_SUBMODULE
|
||||||
|
#endif
|
||||||
|
|
||||||
#define NS_SUBMODULE clip_ttl
|
#define NS_SUBMODULE clip_ttl
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -736,6 +799,9 @@ NS(test_main)(void *arg)
|
||||||
#undef NS_SUBMODULE
|
#undef NS_SUBMODULE
|
||||||
|
|
||||||
struct testcase_t dns_tests[] = {
|
struct testcase_t dns_tests[] = {
|
||||||
|
#ifdef HAVE_EVDNS_BASE_GET_NAMESERVER_ADDR
|
||||||
|
TEST_CASE(configure_nameservers_fallback),
|
||||||
|
#endif
|
||||||
TEST_CASE(clip_ttl),
|
TEST_CASE(clip_ttl),
|
||||||
TEST_CASE(resolve),
|
TEST_CASE(resolve),
|
||||||
TEST_CASE_ASPECT(resolve_impl, addr_is_ip_no_need_to_resolve),
|
TEST_CASE_ASPECT(resolve_impl, addr_is_ip_no_need_to_resolve),
|
||||||
|
|
Loading…
Add table
Reference in a new issue