diff --git a/src/or/circuituse.c b/src/or/circuituse.c index 664f3ac8c4..69723d64cc 100644 --- a/src/or/circuituse.c +++ b/src/or/circuituse.c @@ -870,6 +870,10 @@ circuit_get_open_circ_or_launch(connection_t *conn, if (!has_fetched_directory) { if (!connection_get_by_type(CONN_TYPE_DIR)) { log(LOG_NOTICE,"Application request when we're believed to be offline. Optimistically trying again."); + router_reset_status_download_failures(); + router_reset_descriptor_download_failures(); + update_networkstatus_downloads(time(NULL)); + /* XXXX011 NM This should be a generic "retry all directory fetches". */ directory_get_from_dirserver(DIR_PURPOSE_FETCH_DIR, NULL, 1); /*XXXX011NM*/ } diff --git a/src/or/main.c b/src/or/main.c index f5b1d3fc26..3171a69211 100644 --- a/src/or/main.c +++ b/src/or/main.c @@ -752,10 +752,7 @@ run_scheduled_events(time_t now) /* Also, once per minute, check whether we want to download any * networkstatus documents. */ - if (server_mode(options) && options->DirPort) - update_networkstatus_cache_downloads(now); - else - update_networkstatus_client_downloads(now); + update_networkstatus_downloads(now); } /** 3a. Every second, we examine pending circuits and prune the @@ -946,8 +943,14 @@ do_hup(void) log_fn(LOG_NOTICE, "Error reloading fingerprints. Continuing with old list."); } } - /* XXXX011 NM This should be a generic "retry all directory fetches". */ - directory_get_from_dirserver(DIR_PURPOSE_FETCH_DIR, NULL, 1); /*XXXX011NM*/ + /* retry appropriate downloads */ + router_reset_status_download_failures(); + router_reset_descriptor_download_failures(); + update_networkstatus_downloads(time(NULL)); + + /* We'll retry routerstatus downloads in about 10 seconds; no need to + * force a retry there. */ + if (server_mode(options)) { const char *descriptor; /* Restart cpuworker and dnsworker processes, so they get up-to-date diff --git a/src/or/or.h b/src/or/or.h index d897d2be5e..5802c560eb 100644 --- a/src/or/or.h +++ b/src/or/or.h @@ -2146,8 +2146,7 @@ void add_trusted_dir_server(const char *nickname, void clear_trusted_dir_servers(void); networkstatus_t *networkstatus_get_by_digest(const char *digest); local_routerstatus_t *router_get_combined_status_by_digest(const char *digest); -void update_networkstatus_cache_downloads(time_t now); -void update_networkstatus_client_downloads(time_t now); +void update_networkstatus_downloads(time_t now); void update_router_descriptor_downloads(time_t now); void routers_update_all_from_networkstatus(void); void routers_update_status_from_networkstatus(smartlist_t *routers, @@ -2156,6 +2155,7 @@ smartlist_t *router_list_superseded(void); int router_have_minimum_dir_info(void); void networkstatus_list_update_recent(time_t now); void router_reset_descriptor_download_failures(void); +void router_reset_status_download_failures(void); /********************************* routerparse.c ************************/ diff --git a/src/or/routerlist.c b/src/or/routerlist.c index 810279b1b1..0acd089d30 100644 --- a/src/or/routerlist.c +++ b/src/or/routerlist.c @@ -31,6 +31,9 @@ static int router_nickname_is_in_list(routerinfo_t *router, const char *list); static int router_nickname_matches(routerinfo_t *router, const char *nickname); static void routerstatus_list_update_from_networkstatus(time_t now); static void local_routerstatus_free(local_routerstatus_t *rs); +static void trusted_dir_server_free(trusted_dir_server_t *ds); +static void update_networkstatus_cache_downloads(time_t now); +static void update_networkstatus_client_downloads(time_t now); /****************************************************************************/ @@ -63,6 +66,11 @@ static smartlist_t *warned_nicknames = NULL; * and that are still conflicted. */ static smartlist_t *warned_conflicts = NULL; +/* DOCDOC */ +static time_t last_routerdesc_download_attempted = 0; +/* DOCDOC */ +static time_t last_networkstatus_download_attempted = 0; + /*DOCDOC*/ static int have_warned_about_unverified_status = 0; static int have_warned_about_old_version = 0; @@ -482,6 +490,15 @@ mark_all_trusteddirservers_up(void) dir->n_networkstatus_failures = 0; }); } + last_networkstatus_download_attempted = 0; +} + +/** Reset all internal variables used to count failed downloads of network + * status objects. */ +void +router_reset_status_download_failures(void) +{ + mark_all_trusteddirservers_up(); } /** Return 0 if \\exists an authoritative dirserver that's currently @@ -1078,7 +1095,7 @@ routerlist_free_all(void) } if (trusted_dir_servers) { SMARTLIST_FOREACH(trusted_dir_servers, trusted_dir_server_t *, ds, - { tor_free(ds->address); tor_free(ds); }); + trusted_dir_server_free(ds)); smartlist_free(trusted_dir_servers); trusted_dir_servers = NULL; } @@ -1679,20 +1696,19 @@ router_get_combined_status_by_digest(const char *digest) * asking each trusted directory for its network-status. For caches, this means * asking a random authority for all network-statuses. */ -void +static void update_networkstatus_cache_downloads(time_t now) { - static time_t last_downloaded = 0; int authority = authdir_mode(get_options()); int interval = authority ? AUTHORITY_NS_CACHE_INTERVAL : NONAUTHORITY_NS_CACHE_INTERVAL; - if (last_downloaded + interval >= now) + if (last_networkstatus_download_attempted + interval >= now) return; if (!trusted_dir_servers) return; - last_downloaded = now; + last_networkstatus_download_attempted = now; if (authority) { /* An authority launches a separate connection for everybody. */ @@ -1734,7 +1750,7 @@ update_networkstatus_cache_downloads(time_t now) * by launching a new directory fetch for enough network-status documents "as * necessary". See function comments for implementation details. */ -void +static void update_networkstatus_client_downloads(time_t now) { int n_live = 0, needed = 0, n_running_dirservers, n_dirservers, i; @@ -1829,6 +1845,17 @@ update_networkstatus_client_downloads(time_t now) tor_free(resource); } +/*DOCDOC*/ +void +update_networkstatus_downloads(time_t now) +{ + or_options_t *options = get_options(); + if (server_mode(options) && options->DirPort) + update_networkstatus_cache_downloads(time(NULL)); + else + update_networkstatus_client_downloads(time(NULL)); +} + /** Decide whether a given addr:port is definitely accepted, * definitely rejected, probably accepted, or probably rejected by a * given policy. If addr is 0, we don't know the IP of the @@ -2069,18 +2096,23 @@ add_trusted_dir_server(const char *nickname, const char *address, smartlist_add(trusted_dir_servers, ent); } +/** Free storage held in ds */ +void +trusted_dir_server_free(trusted_dir_server_t *ds) +{ + tor_free(ds->nickname); + tor_free(ds->description); + tor_free(ds->address); + tor_free(ds); +} + /** Remove all members from the list of trusted dir servers. */ void clear_trusted_dir_servers(void) { if (trusted_dir_servers) { SMARTLIST_FOREACH(trusted_dir_servers, trusted_dir_server_t *, ent, - { - tor_free(ent->nickname); - tor_free(ent->description); - tor_free(ent->address); - tor_free(ent); - }); + trusted_dir_server_free(ent)); smartlist_clear(trusted_dir_servers); } else { trusted_dir_servers = smartlist_create(); @@ -2655,13 +2687,12 @@ update_router_descriptor_downloads(time_t now) int get_all = 0; int dirserv = server_mode(get_options()) && get_options()->DirPort; int should_delay, n_downloadable; - static time_t last_download_attempted = 0; if (!networkstatus_list || smartlist_len(networkstatus_list)<2) get_all = 1; if (get_all) { log_fn(LOG_NOTICE, "Launching request for all routers"); - last_download_attempted = now; + last_routerdesc_download_attempted = now; directory_get_from_dirserver(DIR_PURPOSE_FETCH_SERVERDESC,"all.z",1); return; } @@ -2673,10 +2704,10 @@ update_router_descriptor_downloads(time_t now) else if (n_downloadable == 0) should_delay = 1; else if (dirserv) - should_delay = (last_download_attempted + + should_delay = (last_routerdesc_download_attempted + MAX_SERVER_INTERVAL_WITHOUT_REQUEST) < now; else - should_delay = (last_download_attempted + + should_delay = (last_routerdesc_download_attempted + MAX_CLIENT_INTERVAL_WITHOUT_REQUEST) < now; if (! should_delay) { @@ -2707,7 +2738,7 @@ update_router_descriptor_downloads(time_t now) memcpy(cp-1, ".z", 3); directory_get_from_dirserver(DIR_PURPOSE_FETCH_SERVERDESC,resource,1); } - last_download_attempted = now; + last_routerdesc_download_attempted = now; tor_free(resource); } SMARTLIST_FOREACH(downloadable, char *, c, tor_free(c)); @@ -2743,5 +2774,6 @@ router_reset_descriptor_download_failures(void) rs->n_download_failures = 0; rs->next_attempt_at = 0; }); + last_routerdesc_download_attempted = 0; }