diff options
-rw-r--r-- | doc/TODO | 3 | ||||
-rw-r--r-- | src/or/config.c | 8 | ||||
-rw-r--r-- | src/or/dns.c | 86 | ||||
-rw-r--r-- | src/or/eventdns.c | 9 | ||||
-rw-r--r-- | src/or/main.c | 2 | ||||
-rw-r--r-- | src/or/or.h | 3 |
6 files changed, 84 insertions, 27 deletions
@@ -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); |