diff options
author | Nick Mathewson <nickm@torproject.org> | 2008-12-14 17:48:37 +0000 |
---|---|---|
committer | Nick Mathewson <nickm@torproject.org> | 2008-12-14 17:48:37 +0000 |
commit | 746980bba7239fd16c5aee82a7e5b079028d5bf1 (patch) | |
tree | a0faa41045b450a6729d5a4f31aa28b65da6467c | |
parent | cc93490e7c84d30d91e4620a5eb3655afb7285cb (diff) | |
download | tor-746980bba7239fd16c5aee82a7e5b079028d5bf1.tar.gz tor-746980bba7239fd16c5aee82a7e5b079028d5bf1.zip |
Backport bug 691 fix: do not shutdown Tor servers right away if the network is down.
svn:r17623
-rw-r--r-- | ChangeLog | 4 | ||||
-rw-r--r-- | src/or/config.c | 2 | ||||
-rw-r--r-- | src/or/dns.c | 48 | ||||
-rw-r--r-- | src/or/main.c | 18 | ||||
-rw-r--r-- | src/or/or.h | 1 | ||||
-rw-r--r-- | src/or/router.c | 2 |
6 files changed, 58 insertions, 17 deletions
@@ -12,6 +12,10 @@ Changes in version 0.2.0.33 - 200?-??-?? Bugfix on 0.2.0.3-alpha. - Fix a hard-to-trigger resource leak when logging credential status. CID 349. + - When we can't initialize DNS because the network is down, do not + automatically stop Tor from starting. Instead, we retry failed + dns_inits() every 10 minutes, and change the exit policy to reject *:* + until one succeeds. Fixes bug 691. o Minor features: - Report the case where all signatures in a detached set are rejected diff --git a/src/or/config.c b/src/or/config.c index 71bab432e2..9e9bccc88b 100644 --- a/src/or/config.c +++ b/src/or/config.c @@ -271,7 +271,7 @@ static config_var_t _option_vars[] = { V(RunTesting, BOOL, "0"), V(SafeLogging, BOOL, "1"), V(SafeSocks, BOOL, "0"), - V(ServerDNSAllowBrokenResolvConf, BOOL, "0"), + V(ServerDNSAllowBrokenResolvConf, BOOL, "1"), V(ServerDNSAllowNonRFC953Hostnames, BOOL,"0"), V(ServerDNSDetectHijacking, BOOL, "1"), V(ServerDNSResolvConfFile, STRING, NULL), diff --git a/src/or/dns.c b/src/or/dns.c index 041ae74bc0..db52651ce3 100644 --- a/src/or/dns.c +++ b/src/or/dns.c @@ -33,6 +33,8 @@ const char dns_c_id[] = /** Have we currently configured nameservers with eventdns? */ static int nameservers_configured = 0; +/** Did our most recent attempt to configure nameservers with eventdns fail? */ +static int nameserver_config_failed = 0; /** What was the resolv_conf fname we last used when configuring the * nameservers? Used to check whether we need to reconfigure. */ static char *resolv_conf_fname = NULL; @@ -214,12 +216,20 @@ dns_reset(void) tor_free(resolv_conf_fname); resolv_conf_mtime = 0; } else { - if (configure_nameservers(0) < 0) + if (configure_nameservers(0) < 0) { return -1; + } } return 0; } +/**DOCDOC*/ +int +has_dns_init_failed(void) +{ + return nameserver_config_failed; +} + /** Helper: Given a TTL from a DNS response, determine what TTL to give the * OP that asked us to resolve it. */ uint32_t @@ -1100,10 +1110,11 @@ evdns_err_is_transient(int err) } /** Configure eventdns nameservers if force is true, or if the configuration - * has changed since the last time we called this function. On Unix, this - * reads from options->ServerDNSResolvConfFile or /etc/resolv.conf; on - * Windows, this reads from options->ServerDNSResolvConfFile or the registry. - * Return 0 on success or -1 on failure. */ + * 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 + * options->ServerDNSResolvConfFile; on Windows, this reads from + * options->ServerDNSResolvConfFile or the registry. Return 0 on success or + * -1 on failure. */ static int configure_nameservers(int force) { @@ -1123,7 +1134,7 @@ configure_nameservers(int force) if (stat(conf_fname, &st)) { log_warn(LD_EXIT, "Unable to stat resolver configuration in '%s': %s", conf_fname, strerror(errno)); - return options->ServerDNSAllowBrokenResolvConf ? 0 : -1; + goto err; } if (!force && resolv_conf_fname && !strcmp(conf_fname,resolv_conf_fname) && st.st_mtime == resolv_conf_mtime) { @@ -1138,11 +1149,11 @@ configure_nameservers(int force) if ((r = evdns_resolv_conf_parse(DNS_OPTIONS_ALL, conf_fname))) { log_warn(LD_EXIT, "Unable to parse '%s', or no nameservers in '%s' (%d)", conf_fname, conf_fname, r); - return options->ServerDNSAllowBrokenResolvConf ? 0 : -1; + goto err; } if (evdns_count_nameservers() == 0) { log_warn(LD_EXIT, "Unable to find any nameservers in '%s'.", conf_fname); - return options->ServerDNSAllowBrokenResolvConf ? 0 : -1; + goto err; } tor_free(resolv_conf_fname); resolv_conf_fname = tor_strdup(conf_fname); @@ -1158,13 +1169,12 @@ configure_nameservers(int force) } if (evdns_config_windows_nameservers()) { log_warn(LD_EXIT,"Could not config nameservers."); - return options->ServerDNSAllowBrokenResolvConf ? 0 : -1; + goto err; } if (evdns_count_nameservers() == 0) { log_warn(LD_EXIT, "Unable to find any platform nameservers in " - "your Windows configuration. Perhaps you should list a " - "ServerDNSResolvConfFile file in your torrc?"); - return options->ServerDNSAllowBrokenResolvConf ? 0 : -1; + "your Windows configuration."); + goto err; } if (nameservers_configured) evdns_resume(); @@ -1184,7 +1194,18 @@ configure_nameservers(int force) dns_servers_relaunch_checks(); nameservers_configured = 1; + if (nameserver_config_failed) { + nameserver_config_failed = 0; + mark_my_descriptor_dirty(); + } return 0; + err: + nameservers_configured = 0; + if (! nameserver_config_failed) { + nameserver_config_failed = 1; + mark_my_descriptor_dirty(); + } + return -1; } /** For eventdns: Called when we get an answer for a request we launched. @@ -1275,8 +1296,9 @@ launch_resolve(edge_connection_t *exitconn) if (!nameservers_configured) { log_warn(LD_EXIT, "(Harmless.) Nameservers not configured, but resolve " "launched. Configuring."); - if (configure_nameservers(1) < 0) + if (configure_nameservers(1) < 0) { return -1; + } } r = parse_inaddr_arpa_address(exitconn->_base.address, &in); diff --git a/src/or/main.c b/src/or/main.c index dfb01c3cdb..165babaa75 100644 --- a/src/or/main.c +++ b/src/or/main.c @@ -832,6 +832,7 @@ run_scheduled_events(time_t now) static time_t time_to_clean_caches = 0; static time_t time_to_recheck_bandwidth = 0; static time_t time_to_check_for_expired_networkstatus = 0; + static time_t time_to_retry_dns_init = 0; or_options_t *options = get_options(); int i; int have_dir_info; @@ -994,6 +995,14 @@ run_scheduled_events(time_t now) time_to_clean_caches = now + CLEAN_CACHES_INTERVAL; } +#define RETRY_DNS_INTERVAL (10*60) + /* If we're a server and initializing dns failed, retry periodically. */ + if (time_to_retry_dns_init < now) { + time_to_retry_dns_init = now + RETRY_DNS_INTERVAL; + if (server_mode(options) && has_dns_init_failed()) + dns_init(); + } + /** How often do we check whether part of our router info has changed in a way * that would require an upload? */ #define CHECK_DESCRIPTOR_INTERVAL (60) @@ -1377,8 +1386,13 @@ do_main_loop(void) /* initialize dns resolve map, spawn workers if needed */ if (dns_init() < 0) { - log_err(LD_GENERAL,"Error initializing dns subsystem; exiting"); - return -1; + if (get_options()->ServerDNSAllowBrokenResolvConf) + log_warn(LD_GENERAL, "Couldn't set up any working nameservers. " + "Network not up yet? Will try again soon."); + else { + log_err(LD_GENERAL,"Error initializing dns subsystem; exiting. To " + "retry instead, set the ServerDNSAllowBrokenResolvConf option."); + } } handle_signals(1); diff --git a/src/or/or.h b/src/or/or.h index 3f470b187c..e67ca2cbab 100644 --- a/src/or/or.h +++ b/src/or/or.h @@ -3244,6 +3244,7 @@ format_networkstatus_vote(crypto_pk_env_t *private_key, /********************************* dns.c ***************************/ int dns_init(void); +int has_dns_init_failed(void); void dns_free_all(void); uint32_t dns_clip_ttl(uint32_t ttl); int dns_reset(void); diff --git a/src/or/router.c b/src/or/router.c index e74822924c..6d0428cdd9 100644 --- a/src/or/router.c +++ b/src/or/router.c @@ -1717,7 +1717,7 @@ router_dump_router_to_string(char *s, size_t maxlen, routerinfo_t *router, } /* Write the exit policy to the end of 's'. */ - if (dns_seems_to_be_broken() || + if (dns_seems_to_be_broken() || has_dns_init_failed() || !router->exit_policy || !smartlist_len(router->exit_policy)) { /* DNS is screwed up; don't claim to be an exit. */ strlcat(s+written, "reject *:*\n", maxlen-written); |