[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]
[or-cvs] Change networkstatus dl logic: try to have all networkstatu...
Update of /home/or/cvsroot/tor/src/or
In directory moria:/tmp/cvs-serv16216/src/or
Modified Files:
routerlist.c
Log Message:
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.
Index: routerlist.c
===================================================================
RCS file: /home/or/cvsroot/tor/src/or/routerlist.c,v
retrieving revision 1.475
retrieving revision 1.476
diff -u -p -d -r1.475 -r1.476
--- routerlist.c 28 Mar 2006 12:01:58 -0000 1.475
+++ routerlist.c 2 Apr 2006 23:02:52 -0000 1.476
@@ -2102,10 +2102,9 @@ router_set_networkstatus(const char *s,
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(tim
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(ti
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;