[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;