diff options
author | Nick Mathewson <nickm@torproject.org> | 2006-04-02 23:02:52 +0000 |
---|---|---|
committer | Nick Mathewson <nickm@torproject.org> | 2006-04-02 23:02:52 +0000 |
commit | 4130460f8e94eeec9248af84041e27ecebfa1cff (patch) | |
tree | 79ba265a4107c30795a125546fe744da7d271d40 /src | |
parent | d663bfa3060a08c20bb38a5f19cf7afeb1f3441c (diff) | |
download | tor-4130460f8e94eeec9248af84041e27ecebfa1cff.tar.gz tor-4130460f8e94eeec9248af84041e27ecebfa1cff.zip |
Change networkstatus dl logic: try to have all networkstatuses live; insist on having all of them live or tried-at-least-once. Also, answer a XXXX comment.
svn:r6297
Diffstat (limited to 'src')
-rw-r--r-- | src/or/routerlist.c | 109 |
1 files changed, 65 insertions, 44 deletions
diff --git a/src/or/routerlist.c b/src/or/routerlist.c index 5e3c3b37cf..a574c1c4ae 100644 --- a/src/or/routerlist.c +++ b/src/or/routerlist.c @@ -2102,10 +2102,9 @@ router_set_networkstatus(const char *s, time_t arrived_at, if (!trusted_dir) { if (!skewed && get_options()->DirPort) { - /* XXX This is great as a first cut, but it looks like - * any old person can give us an untrusted network-status and - * we'll write it to disk as the newest one we have? - * Also, there is no limit on the number that we'll store? -RD */ + /* We got a non-trusted networkstatus, and we're a directory cache. + * This means that we asked an authority, and it told us about another + * authority we didn't recognize. */ add_networkstatus_to_cache(s, source, ns); networkstatus_free(ns); } @@ -2335,19 +2334,21 @@ update_networkstatus_cache_downloads(time_t now) static void update_networkstatus_client_downloads(time_t now) { - int n_live = 0, needed = 0, n_running_dirservers, n_dirservers, i; + int n_live = 0, n_dirservers, n_running_dirservers, needed = 0; + int fetch_latest = 0; int most_recent_idx = -1; trusted_dir_server_t *most_recent = NULL; time_t most_recent_received = 0; char *resource, *cp; size_t resource_len; + smartlist_t *missing; if (connection_get_by_type_purpose(CONN_TYPE_DIR, DIR_PURPOSE_FETCH_NETWORKSTATUS)) return; /* This is a little tricky. We want to download enough network-status - * objects so that we have at least half of them under + * objects so that we have all of them under * NETWORKSTATUS_MAX_AGE publication time. We want to download a new * *one* if the most recent one's publication time is under * NETWORKSTATUS_CLIENT_DL_INTERVAL. @@ -2355,77 +2356,82 @@ update_networkstatus_client_downloads(time_t now) if (!trusted_dir_servers || !smartlist_len(trusted_dir_servers)) return; n_dirservers = n_running_dirservers = smartlist_len(trusted_dir_servers); + missing = smartlist_create(); 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_AGE) + if (ns && ns->published_on > now-NETWORKSTATUS_MAX_AGE) ++n_live; - if (!most_recent || ns->received_on > most_recent_received) { + else + smartlist_add(missing, ds->digest); + if (ns && (!most_recent || ns->received_on > most_recent_received)) { most_recent_idx = ds_sl_idx; /* magic variable from FOREACH */ most_recent = ds; most_recent_received = ns->received_on; } }); - /* Download enough so we have at least half live, but no more than all the - * trusted dirservers we know. - */ - if (n_live < (n_dirservers/2)+1) - needed = (n_dirservers/2)+1-n_live; - if (needed > n_running_dirservers) - needed = n_running_dirservers; - - if (needed) - log_info(LD_DIR, "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 (n_running_dirservers && - most_recent_received < now-NETWORKSTATUS_CLIENT_DL_INTERVAL && - needed < 1) { + if (!smartlist_len(missing) && + most_recent_received < now-NETWORKSTATUS_CLIENT_DL_INTERVAL) { log_info(LD_DIR, "Our most recent network-status document (from %s) " "is %d seconds old; downloading another.", most_recent?most_recent->description:"nobody", (int)(now-most_recent_received)); + fetch_latest = 1; needed = 1; - } - - if (!needed) + } else if (smartlist_len(missing)) { + log_info(LD_DIR, "For %d/%d running directory servers, we have %d live" + " network-status documents. Downloading %d.", + n_running_dirservers, n_dirservers, n_live, + smartlist_len(missing)); + needed = smartlist_len(missing); + } else { + smartlist_free(missing); return; + } /* If no networkstatus was found, choose a dirserver at random as "most * recent". */ if (most_recent_idx<0) most_recent_idx = crypto_rand_int(n_dirservers); + if (fetch_latest) { + int i; + for (i = most_recent_idx + 1; i; ++i) { + trusted_dir_server_t *ds; + if (i >= n_dirservers) + i = 0; + ds = smartlist_get(trusted_dir_servers, i); + if (ds->n_networkstatus_failures > NETWORKSTATUS_N_ALLOWABLE_FAILURES) + continue; + smartlist_add(missing, ds->digest); + break; + } + } + /* Build a request string for all the resources we want. */ - resource_len = needed * (HEX_DIGEST_LEN+1) + 6; + resource_len = smartlist_len(missing) * (HEX_DIGEST_LEN+1) + 6; resource = tor_malloc(resource_len); memcpy(resource, "fp/", 3); cp = resource+3; - for (i = most_recent_idx+1; needed; ++i) { - trusted_dir_server_t *ds; - 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; - if (needed) - *cp++ = '+'; - } + needed = smartlist_len(missing); + SMARTLIST_FOREACH(missing, const char *, d, + { + base16_encode(cp, HEX_DIGEST_LEN+1, d, DIGEST_LEN); + cp += HEX_DIGEST_LEN; + --needed; + if (needed) + *cp++ = '+'; + }); memcpy(cp, ".z", 3); directory_get_from_dirserver(DIR_PURPOSE_FETCH_NETWORKSTATUS, resource, 1); tor_free(resource); + smartlist_free(missing); } /** Launch requests for networkstatus documents as appropriate. */ @@ -3525,7 +3531,8 @@ int router_have_minimum_dir_info(void) { int tot = 0, num_running = 0; - int n_ns, n_authorities, res, avg; + int n_ns, n_tried, n_authorities, res, avg; + static int have_ever_tried_all = 0; static int have_enough = 0; if (!networkstatus_list || !routerlist) { res = 0; @@ -3540,6 +3547,20 @@ router_have_minimum_dir_info(void) res = 0; goto done; } + if (!have_ever_tried_all) { + n_tried=n_ns; + SMARTLIST_FOREACH(trusted_dir_servers, trusted_dir_server_t *, ds, + if (ds->n_networkstatus_failures) ++n_tried); + if (n_tried < n_authorities) { + log_info(LD_DIR, + "We have only tried downloading %d/%d network statuses.", + n_tried, n_authorities); + res = 0; + goto done; + } else { + have_ever_tried_all = 1; + } + } SMARTLIST_FOREACH(networkstatus_list, networkstatus_t *, ns, tot += smartlist_len(ns->entries)); avg = tot / n_ns; |