diff options
Diffstat (limited to 'src/or/routerlist.c')
-rw-r--r-- | src/or/routerlist.c | 102 |
1 files changed, 92 insertions, 10 deletions
diff --git a/src/or/routerlist.c b/src/or/routerlist.c index 161d7959e4..f9a41d4c12 100644 --- a/src/or/routerlist.c +++ b/src/or/routerlist.c @@ -47,6 +47,11 @@ extern int has_fetched_directory; /**< from main.c */ /** Global list of all of the current network_status documents that we know * about. This list is kept sorted by published_on. */ static smartlist_t *networkstatus_list = NULL; +/** True iff networkstatus_list has changed since the last time we called + * routers_update_all_from_networkstatus. Set by router_set_networkstatus; + * cleared by routers_update_all_from_networkstatus. + */ +static int networkstatus_list_has_changed = 0; /** * Reload the most recent cached directory (if present). @@ -116,6 +121,7 @@ router_reload_networkstatus(void) tor_free(s); } }); + routers_update_all_from_networkstatus(); return 0; } @@ -437,7 +443,10 @@ mark_all_trusteddirservers_up(void) } if (trusted_dir_servers) { SMARTLIST_FOREACH(trusted_dir_servers, trusted_dir_server_t *, dir, - dir->is_running = 1); + { + dir->is_running = 1; + dir->n_networkstatus_failures = 0; + }); } } @@ -971,7 +980,6 @@ routerlist_free(routerlist_t *rl) SMARTLIST_FOREACH(rl->routers, routerinfo_t *, r, routerinfo_free(r)); smartlist_free(rl->routers); - running_routers_free(rl->running_routers); tor_free(rl->software_versions); tor_free(rl); } @@ -1235,12 +1243,16 @@ router_load_single_router(const char *s, const char **msg) routerinfo_free(ri); return 0; } +#if 0 if (routerlist && routerlist->running_routers) { running_routers_t *rr = routerlist->running_routers; router_update_status_from_smartlist(ri, rr->published_on, rr->running_routers); } +#endif + /* XXXX011 update router status from networkstatus!! */ + if (router_add_to_routerlist(ri, msg)<0) { log_fn(LOG_WARN, "Couldn't add router to list: %s Dropping.", *msg?*msg:"(No message)."); @@ -1422,11 +1434,13 @@ router_set_networkstatus(const char *s, time_t arrived_at, ns->networkstatus_digest, DIGEST_LEN)) { /* Same one we had before. */ networkstatus_free(ns); + log_fn(LOG_NOTICE, "Dropping network-status (%s); already have it.",fp); if (old_ns->received_on < arrived_at) + /* XXXX We should touch the cache file. NM */ old_ns->received_on = arrived_at; return 0; } else if (old_ns->published_on >= ns->published_on) { - log_fn(LOG_INFO, "Dropping network-status; we have a newer one for this authority."); + log_fn(LOG_NOTICE, "Dropping network-status (%s); we have a newer one for this authority.", fp); networkstatus_free(ns); return 0; } else { @@ -1441,6 +1455,13 @@ router_set_networkstatus(const char *s, time_t arrived_at, if (!found) smartlist_add(networkstatus_list, ns); + /*XXXX011 downgrade to INFO NM */ + log_fn(LOG_NOTICE, "New networkstatus %s (%s).", + source == NS_FROM_CACHE?"from our cache": + (source==NS_FROM_DIR?"from a directory server":"from this authority"), + fp); + networkstatus_list_has_changed = 1; + smartlist_sort(networkstatus_list, _compare_networkstatus_published_on); if (source != NS_FROM_CACHE && !skewed) { @@ -1561,12 +1582,14 @@ update_networkstatus_cache_downloads(time_t now) } /*XXXX Should these be configurable? NM*/ -/** How old (in seconds) can a network-status be before we stop believing it? */ +/** How old (in seconds) can a network-status be before we try replacing it? */ #define NETWORKSTATUS_MAX_VALIDITY (48*60*60) /** How long (in seconds) does a client wait after getting a network status * before downloading the next in sequence? */ #define NETWORKSTATUS_CLIENT_DL_INTERVAL (30*60) - +/* How many times do we allow a networkstatus download to fail before we + * assume that the authority isn't publishing? */ +#define NETWORKSTATUS_N_ALLOWABLE_FAILURES 3 /** We are not a directory cache or authority. Update our network-status list * by launching a new directory fetch for enough network-status documents "as * necessary". See function comments for implementation details. @@ -1574,7 +1597,7 @@ update_networkstatus_cache_downloads(time_t now) void update_networkstatus_client_downloads(time_t now) { - int n_live = 0, needed = 0, n_dirservers, i; + int n_live = 0, needed = 0, n_running_dirservers, n_dirservers, i; int most_recent_idx = -1; trusted_dir_server_t *most_recent = NULL; time_t most_recent_received = 0; @@ -1593,12 +1616,16 @@ update_networkstatus_client_downloads(time_t now) */ if (!trusted_dir_servers || !smartlist_len(trusted_dir_servers)) return; - n_dirservers = smartlist_len(trusted_dir_servers); + n_dirservers = n_running_dirservers = smartlist_len(trusted_dir_servers); SMARTLIST_FOREACH(trusted_dir_servers, trusted_dir_server_t *, ds, { networkstatus_t *ns = networkstatus_get_by_digest(ds->digest); if (!ns) continue; + if (ds->n_networkstatus_failures > NETWORKSTATUS_N_ALLOWABLE_FAILURES) { + --n_running_dirservers; + continue; + } if (ns->published_on > now-NETWORKSTATUS_MAX_VALIDITY) ++n_live; if (!most_recent || ns->received_on > most_recent_received) { @@ -1613,11 +1640,22 @@ update_networkstatus_client_downloads(time_t now) */ if (n_live < (n_dirservers/2)+1) needed = (n_dirservers/2)+1-n_live; - if (needed > n_dirservers) - needed = n_dirservers; + if (needed > n_running_dirservers) + needed = n_running_dirservers; + + if (needed) + /* XXXX001 Downgrade to info NM */ + log_fn(LOG_NOTICE, "For %d/%d running directory servers, we have %d live" + " network-status documents. Downloading %d.", + n_running_dirservers, n_dirservers, n_live, needed); + /* Also, download at least 1 every NETWORKSTATUS_CLIENT_DL_INTERVAL. */ - if (most_recent_received < now-NETWORKSTATUS_CLIENT_DL_INTERVAL && needed < 1) + if (n_running_dirservers && + most_recent_received < now-NETWORKSTATUS_CLIENT_DL_INTERVAL && needed < 1) { + log_fn(LOG_NOTICE, "Our most recent network-status document is %d" + " seconds old; downloading another.", (int)(now-most_recent_received)); needed = 1; + } if (!needed) return; @@ -1637,6 +1675,8 @@ update_networkstatus_client_downloads(time_t now) if (i >= n_dirservers) i = 0; ds = smartlist_get(trusted_dir_servers, i); + if (ds->n_networkstatus_failures > NETWORKSTATUS_N_ALLOWABLE_FAILURES) + continue; base16_encode(cp, HEX_DIGEST_LEN+1, ds->digest, DIGEST_LEN); cp += HEX_DIGEST_LEN; --needed; @@ -1860,6 +1900,7 @@ router_exit_policy_rejects_all(routerinfo_t *router) == ADDR_POLICY_REJECTED; } +#if 0 /** Release all space held in <b>rr</b>. */ void running_routers_free(running_routers_t *rr) @@ -2047,6 +2088,7 @@ router_update_status_from_smartlist(routerinfo_t *router, smartlist_free(rl); return 0; } +#endif /** Add to the list of authorized directory servers one at * <b>address</b>:<b>port</b>, with identity key <b>digest</b>. If @@ -2111,6 +2153,40 @@ networkstatus_get_by_digest(const char *digest) return NULL; } +/** If the network-status list has changed since the last time we called this + * function, update the status of every router from the network-status list. + */ +void +routers_update_all_from_networkstatus(void) +{ + static int have_warned_about_unverified_status = 0; + routerinfo_t *me; + if (!routerlist || !networkstatus_list || !networkstatus_list_has_changed) + return; + + routers_update_status_from_networkstatus(routerlist->routers); + + me = router_get_my_routerinfo(); + if (me) { + /* We could be more sophisticated about this whole business. How many + * dirservers list us as named, valid, etc. */ + smartlist_t *lst = smartlist_create(); + smartlist_add(lst, me); + routers_update_status_from_networkstatus(lst); + if (me->is_verified == 0) { + log_fn(LOG_WARN, "Many directory servers list us as unverified. Please consider sending your identity fingerprint to the tor-ops."); + have_warned_about_unverified_status = 1; + } else if (me->is_named == 0) { + log_fn(LOG_WARN, "Many directory servers list us as unnamed. Please consider sending your identity fingerprint to the tor-ops."); + have_warned_about_unverified_status = 1; + } + } + + helper_nodes_set_status_from_directory(); + + networkstatus_list_has_changed = 0; +} + /** Allow any network-status newer than this to influence our view of who's * running. */ #define DEFAULT_RUNNING_INTERVAL 60*60 @@ -2127,6 +2203,7 @@ routers_update_status_from_networkstatus(smartlist_t *routers) n_recent; int i; time_t now = time(NULL); + trusted_dir_server_t *ds; if (authdir_mode(get_options())) { /* An authoritative directory should never believer someone else about @@ -2164,6 +2241,7 @@ routers_update_status_from_networkstatus(smartlist_t *routers) SMARTLIST_FOREACH(routers, routerinfo_t *, router, { + ds = router_get_trusteddirserver_by_digest(router->identity_digest); n_listing = n_valid = n_naming = n_named = n_running = 0; SMARTLIST_FOREACH(networkstatus_list, networkstatus_t *, ns, @@ -2194,6 +2272,10 @@ routers_update_status_from_networkstatus(smartlist_t *routers) router->is_named = (n_named > n_naming/2); router->is_verified = (n_valid > n_statuses/2); router->is_running = (n_running > n_recent/2); + + if (router->is_running && ds) + /*Hm. What about authorities? When do they reset n_networkstatus_failures?*/ + ds->n_networkstatus_failures = 0; }); } |