mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2024-11-10 13:13:44 +01:00
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
This commit is contained in:
parent
d663bfa306
commit
4130460f8e
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user