summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/TODO3
-rw-r--r--src/or/config.c8
-rw-r--r--src/or/dns.c86
-rw-r--r--src/or/eventdns.c9
-rw-r--r--src/or/main.c2
-rw-r--r--src/or/or.h3
6 files changed, 84 insertions, 27 deletions
diff --git a/doc/TODO b/doc/TODO
index bd67e6fc42..3198574003 100644
--- a/doc/TODO
+++ b/doc/TODO
@@ -100,7 +100,8 @@ N . Improve memory usage on tight-memory machines.
reload.
o Fail when we have no configured nameservers!
o Make it the default on platforms where it works.
- - Make resolv.conf (or local equivalent) get checked on reload,
+ - Document SearchDomains, ResolvConf options
+ o Make resolv.conf (or local equivalent) get checked on reload,
settable while running, etc.
- Add ipv6 support; make API closer to getaddrinfo(). (i.e., allow a
single AAAA/A query, return cname as well)
diff --git a/src/or/config.c b/src/or/config.c
index d33b556191..86fd8066f9 100644
--- a/src/or/config.c
+++ b/src/or/config.c
@@ -802,8 +802,13 @@ options_act(or_options_t *old_options)
inform_testing_reachability();
}
cpuworkers_rotate();
- dnsworkers_rotate();
+ dns_reset();
}
+#ifdef USE_EVENTDNS
+ else {
+ dns_reset();
+ }
+#endif
}
/* Check if we need to parse and add the EntryNodes config option. */
@@ -2555,6 +2560,7 @@ options_transition_affects_workers(or_options_t *old_options,
if (!opt_streq(old_options->DataDirectory, new_options->DataDirectory) ||
old_options->NumCpus != new_options->NumCpus ||
old_options->ORPort != new_options->ORPort ||
+ old_options->SearchDomains != new_options->SearchDomains ||
old_options->SafeLogging != new_options->SafeLogging ||
!config_lines_eq(old_options->Logs, new_options->Logs))
return 1;
diff --git a/src/or/dns.c b/src/or/dns.c
index 57ead60295..17b63b27aa 100644
--- a/src/or/dns.c
+++ b/src/or/dns.c
@@ -101,20 +101,28 @@ static void dns_found_answer(const char *address, uint32_t addr, char outcome,
static void send_resolved_cell(edge_connection_t *conn, uint8_t answer_type);
static int launch_resolve(edge_connection_t *exitconn);
#ifndef USE_EVENTDNS
+static void dnsworkers_rotate(void);
static int dnsworker_main(void *data);
static int spawn_dnsworker(void);
static int spawn_enough_dnsworkers(void);
#else
-static int configure_nameservers(void);
+static int configure_nameservers(int force);
#endif
#ifdef DEBUG_DNS_CACHE
static void _assert_cache_ok(void);
#define assert_cache_ok() _assert_cache_ok()
#else
-#define assert_cache_ok() do {} while(0)
+#define assert_cache_ok() do {} while (0)
#endif
static void assert_resolve_ok(cached_resolve_t *resolve);
+#ifdef USE_EVENTDNS
+/* DOCDOC */
+static int nameservers_configured = 0;
+static char *resolv_conf_fname = NULL;
+static time_t resolv_conf_mtime = 0;
+#endif
+
/** Hash table of cached_resolve objects. */
static HT_HEAD(cache_map, cached_resolve_t) cache_root;
@@ -164,14 +172,37 @@ int
dns_init(void)
{
init_cache_map();
- dnsworkers_rotate();
#ifdef USE_EVENTDNS
if (server_mode(get_options()))
- return configure_nameservers();
+ return configure_nameservers(1);
+#else
+ dnsworkers_rotate();
#endif
return 0;
}
+/* DOCDOC */
+void
+dns_reset(void)
+{
+#ifdef USE_EVENTDNS
+ or_options_t *options = get_options();
+ if (! server_mode(options)) {
+ eventdns_clear_nameservers_and_suspend();
+ eventdns_search_clear();
+ nameservers_configured = 0;
+ tor_free(resolv_conf_fname);
+ resolv_conf_mtime = 0;
+ } else {
+ if (configure_nameservers(0) < 0)
+ /* XXXX */
+ return;
+ }
+#else
+ dnsworkers_rotate();
+#endif
+}
+
uint32_t
dns_clip_ttl(uint32_t ttl)
{
@@ -910,7 +941,7 @@ connection_dns_process_inbuf(connection_t *conn)
/** Close and re-open all idle dnsworkers; schedule busy ones to be closed
* and re-opened once they're no longer busy.
**/
-void
+static void
dnsworkers_rotate(void)
{
connection_t *dnsconn;
@@ -1162,10 +1193,6 @@ eventdns_err_is_transient(int err)
return 0;
}
}
-void
-dnsworkers_rotate(void)
-{
-}
int
connection_dns_finished_flushing(connection_t *conn)
{
@@ -1187,26 +1214,37 @@ connection_dns_reached_eof(connection_t *conn)
tor_assert(0);
return 0;
}
-static int nameservers_configured = 0;
/* DOCDOC */
static int
-configure_nameservers(void)
+configure_nameservers(int force)
{
or_options_t *options;
const char *conf_fname;
struct stat st;
- if (nameservers_configured)
- return 0;
options = get_options();
- eventdns_set_log_fn(eventdns_log_cb);
-
conf_fname = options->ResolvConf;
#ifndef MS_WINDOWS
- if (!conf_fname) conf_fname = "/etc/resolv.conf";
+ if (!conf_fname)
+ conf_fname = "/etc/resolv.conf";
#endif
+ eventdns_set_log_fn(eventdns_log_cb);
if (conf_fname) {
+ if (stat(conf_fname, &st)) {
+ log_warn(LD_EXIT, "Unable to stat resolver configuration in '%s'",
+ conf_fname);
+ return -1;
+ }
+ if (!force && resolv_conf_fname && !strcmp(conf_fname,resolv_conf_fname)
+ && st.st_mtime == resolv_conf_mtime) {
+ log_info(LD_EXIT, "No change to '%s'", conf_fname);
+ return 0;
+ }
+ if (nameservers_configured) {
+ eventdns_search_clear();
+ eventdns_clear_nameservers_and_suspend();
+ }
log_info(LD_EXIT, "Parsing resolver configuration in '%s'", conf_fname);
if (eventdns_resolv_conf_parse(DNS_OPTIONS_ALL, conf_fname))
return -1;
@@ -1214,9 +1252,18 @@ configure_nameservers(void)
log_warn(LD_EXIT, "Unable to find any nameservers in '%s'.", conf_fname);
return -1;
}
+ tor_free(resolv_conf_fname);
+ resolv_conf_fname = tor_strdup(resolv_conf_fname);
+ resolv_conf_mtime = st.st_mtime;
+ if (nameservers_configured)
+ eventdns_resume();
}
#ifdef MS_WINDOWS
else {
+ if (nameservers_configured) {
+ eventdns_search_clear();
+ eventdns_clear_nameservers_and_suspend();
+ }
if (eventdns_config_windows_nameservers())
return -1;
if (eventdns_count_nameservers() == 0) {
@@ -1225,6 +1272,10 @@ configure_nameservers(void)
"ResolvConf file in your torrc?");
return -1;
}
+ if (nameservers_configured)
+ eventdns_resume();
+ tor_free(resolv_conf_fname);
+ resolv_conf_mtime = 0;
}
#endif
@@ -1275,7 +1326,7 @@ launch_resolve(edge_connection_t *exitconn)
int r;
int options = get_options()->SearchDomains ? 0 : DNS_QUERY_NO_SEARCH;
if (!nameservers_configured)
- if (configure_nameservers() < 0)
+ if (configure_nameservers(1) < 0)
return -1;
log_info(LD_EXIT, "Launching eventdns request for %s",
escaped_safe_str(exitconn->_base.address));
@@ -1338,3 +1389,4 @@ _assert_cache_ok(void)
_compare_cached_resolves_by_expiry);
}
#endif
+
diff --git a/src/or/eventdns.c b/src/or/eventdns.c
index 9b75868222..f3fdafa635 100644
--- a/src/or/eventdns.c
+++ b/src/or/eventdns.c
@@ -553,7 +553,7 @@ nameserver_failed(struct nameserver *const ns, const char *msg) {
global_good_nameservers--;
assert(global_good_nameservers >= 0);
if (global_good_nameservers == 0) {
- log("All nameservers have failed");
+ log(1,"All nameservers have failed");
}
ns->state = 0;
@@ -561,8 +561,8 @@ nameserver_failed(struct nameserver *const ns, const char *msg) {
evtimer_set(&ns->timeout_event, nameserver_prod_callback, ns);
if (evtimer_add(&ns->timeout_event, (struct timeval *) &global_nameserver_timeouts[0]) < 0) {
- log("Error from libevent when adding timer event for %s",
- debug_ntoa(ns->address));
+ log(1,"Error from libevent when adding timer event for %s",
+ debug_ntoa(ns->address));
// ???? Do more?
}
@@ -910,7 +910,7 @@ reply_parse(u8 *packet, int length) {
}
// XXXX do something sane with malformed A answers.
addrcount = datalength >> 2; // each IP address is 4 bytes
- addrtocopy = MIN(MAX_ADDRS - reply.data.a.addrcount, addrcount);
+ addrtocopy = MIN(MAX_ADDRS - reply.data.a.addrcount, (unsigned)addrcount);
ttl_r = MIN(ttl_r, ttl);
// we only bother with the first four addresses.
if (j + 4*addrtocopy > length) return -1;
@@ -1390,7 +1390,6 @@ eventdns_clear_nameservers_and_suspend(void)
return 0;
}
-
// exported function
int
eventdns_resume(void)
diff --git a/src/or/main.c b/src/or/main.c
index 80645779e9..b54417e422 100644
--- a/src/or/main.c
+++ b/src/or/main.c
@@ -1081,7 +1081,7 @@ do_hup(void)
/* Restart cpuworker and dnsworker processes, so they get up-to-date
* configuration options. */
cpuworkers_rotate();
- dnsworkers_rotate();
+ dns_reset();
#if 0
/* Write out a fresh descriptor, but leave old one on failure. */
router_rebuild_descriptor(1);
diff --git a/src/or/or.h b/src/or/or.h
index 8a4013aee0..61c0bc4b4f 100644
--- a/src/or/or.h
+++ b/src/or/or.h
@@ -710,7 +710,6 @@ typedef struct edge_connection_t {
* circuit? */
int deliver_window; /**< How many more relay cells can end at me? */
-
/** Nickname of planned exit node -- used with .exit support. */
char *chosen_exit_name;
@@ -2133,7 +2132,7 @@ uint32_t dns_clip_ttl(uint32_t ttl);
int connection_dns_finished_flushing(connection_t *conn);
int connection_dns_reached_eof(connection_t *conn);
int connection_dns_process_inbuf(connection_t *conn);
-void dnsworkers_rotate(void);
+void dns_reset(void);
void connection_dns_remove(edge_connection_t *conn);
void assert_connection_edge_not_dns_pending(edge_connection_t *conn);
void assert_all_pending_dns_resolves_ok(void);