[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]

[or-cvs] Fix bug 236: caches should cache up to 16 unrecognized netw...



Update of /home/or/cvsroot/tor/src/or
In directory moria:/tmp/cvs-serv24089/src/or

Modified Files:
	dirserv.c routerlist.c 
Log Message:
Fix bug 236: caches should cache up to 16 unrecognized network-status docs.

Index: dirserv.c
===================================================================
RCS file: /home/or/cvsroot/tor/src/or/dirserv.c,v
retrieving revision 1.286
retrieving revision 1.287
diff -u -p -d -r1.286 -r1.287
--- dirserv.c	4 Jan 2006 06:43:03 -0000	1.286
+++ dirserv.c	8 Jan 2006 21:26:33 -0000	1.287
@@ -17,6 +17,9 @@ const char dirserv_c_id[] =
 #define ROUTER_ALLOW_SKEW (60*60*12) /* 12 hours */
 /** How many seconds do we wait before regenerating the directory? */
 #define DIR_REGEN_SLACK_TIME 30
+/** If we're a cache, keep this many networkstatuses around from non-trusted
+ * directory authorities. */
+#define MAX_UNTRUSTED_NETWORKSTATUSES 16
 
 extern long stats_n_seconds_working;
 
@@ -984,28 +987,60 @@ dirserv_set_cached_directory(const char 
  * the cache.
  */
 void
-dirserv_set_cached_networkstatus_v2(const char *directory,
+dirserv_set_cached_networkstatus_v2(const char *networkstatus,
                                     const char *identity,
                                     time_t published)
 {
   cached_dir_t *d;
+  smartlist_t *trusted_dirs;
   if (!cached_v2_networkstatus)
     cached_v2_networkstatus = digestmap_new();
 
   if (!(d = digestmap_get(cached_v2_networkstatus, identity))) {
-    if (!directory)
+    if (!networkstatus)
       return;
     d = tor_malloc_zero(sizeof(cached_dir_t));
     digestmap_set(cached_v2_networkstatus, identity, d);
   }
 
   tor_assert(d);
-  if (directory) {
-    set_cached_dir(d, tor_strdup(directory), published);
+  if (networkstatus) {
+    if (published > d->published) {
+      set_cached_dir(d, tor_strdup(networkstatus), published);
+    } else {
+      networkstatus_free(networkstatus);
+    }
   } else {
     free_cached_dir(d);
     digestmap_remove(cached_v2_networkstatus, identity);
   }
+
+  router_get_trusted_dir_servers(&trusted_dirs);
+  if (digestmap_size(cached_v2_networkstatus) >
+      smartlist_len(trusted_dirs) + MAX_UNTRUSTED_NETWORKSTATUSES) {
+    /* We need to remove the oldest untrusted networkstatus. */
+    const char *oldest = NULL;
+    time_t oldest_published = TIME_MAX;
+    digestmap_iter_t *iter;
+
+    for (iter = digestmap_iter_init(cached_v2_networkstatus);
+         !digestmap_iter_done(iter);
+         iter = digestmap_iter_next(cached_v2_networkstatus, iter)) {
+      const char *ident;
+      void *val;
+      digestmap_iter_get(iter, &ident, &val);
+      d = val;
+      if (d->published < oldest_published &&
+          !router_get_trusteddirserver_by_digest(ident)) {
+        oldest = ident;
+        oldest_published = d->published;
+      }
+    }
+    tor_assert(oldest);
+    d = digestmap_remove(cached_v2_networkstatus, oldest);
+    if (d)
+      free_cached_dir(d);
+  }
 }
 
 /** Helper: If we're an authority for the right directory version (the

Index: routerlist.c
===================================================================
RCS file: /home/or/cvsroot/tor/src/or/routerlist.c,v
retrieving revision 1.418
retrieving revision 1.419
diff -u -p -d -r1.418 -r1.419
--- routerlist.c	6 Jan 2006 18:19:17 -0000	1.418
+++ routerlist.c	8 Jan 2006 21:26:33 -0000	1.419
@@ -1938,6 +1938,30 @@ _compare_networkstatus_published_on(cons
     return 0;
 }
 
+/** Add the parsed neworkstatus in <b>ns</b> (with original document in
+ * <b>s</b> to the disk cache (and the in-memory directory server cache) as
+ * appropriate. */
+static int
+add_networkstatus_to_cache(const char *s,
+                           networkstatus_source_t source,
+                           networkstatus_t *ns)
+{
+  if (source != NS_FROM_CACHE) {
+    char *fn = networkstatus_get_cache_filename(ns);
+    if (write_str_to_file(fn, s, 0)<0) {
+      notice(LD_FS, "Couldn't write cached network status to \"%s\"", fn);
+    }
+    tor_free(fn);
+  }
+
+  if (get_options()->DirPort)
+    dirserv_set_cached_networkstatus_v2(s,
+                                        ns->identity_digest,
+                                        ns->published_on);
+
+  return 0;
+}
+
 /** How far in the future do we allow a network-status to get before removing
  * it? (seconds) */
 #define NETWORKSTATUS_ALLOW_SKEW (48*60*60)
@@ -1969,7 +1993,8 @@ router_set_networkstatus(const char *s, 
   int i, found;
   time_t now;
   int skewed = 0;
-  trusted_dir_server_t *trusted_dir;
+  trusted_dir_server_t *trusted_dir = NULL;
+  const char *source_desc = NULL;
   char fp[HEX_DIGEST_LEN+1];
   char published[ISO_TIME_LEN+1];
 
@@ -1978,12 +2003,18 @@ router_set_networkstatus(const char *s, 
     warn(LD_DIR, "Couldn't parse network status.");
     return -1;
   }
+  base16_encode(fp, HEX_DIGEST_LEN+1, ns->identity_digest, DIGEST_LEN);
   if (!(trusted_dir =
         router_get_trusteddirserver_by_digest(ns->identity_digest))) {
     info(LD_DIR, "Network status was signed, but not by an authoritative "
          "directory we recognize.");
-    networkstatus_free(ns);
-    return -1;
+    if (!get_options()->DirPort) {
+      networkstatus_free(ns);
+      return 0;
+    }
+    source_desc = fp;
+  } else {
+    source_desc = trusted_dir->description;
   }
   now = time(NULL);
   if (arrived_at > now)
@@ -1996,7 +2027,7 @@ router_set_networkstatus(const char *s, 
   if (ns->published_on > now + NETWORKSTATUS_ALLOW_SKEW) {
     warn(LD_GENERAL, "Network status from %s was published in the future "
          "(%s GMT). Somebody is skewed here: check your clock. Not caching.",
-         trusted_dir->description, published);
+         source_desc, published);
     skewed = 1;
   }
 
@@ -2009,8 +2040,6 @@ router_set_networkstatus(const char *s, 
     return 0;
   }
 
-  base16_encode(fp, HEX_DIGEST_LEN+1, ns->identity_digest, DIGEST_LEN);
-
   if (requested_fingerprints) {
     if (smartlist_string_isin(requested_fingerprints, fp)) {
       smartlist_string_remove(requested_fingerprints, fp);
@@ -2025,7 +2054,15 @@ router_set_networkstatus(const char *s, 
     }
   }
 
-  if (source != NS_FROM_CACHE)
+  if (!trusted_dir) {
+    if (!skewed && get_options()->DirPort) {
+      add_networkstatus_to_cache(s, source, ns);
+      networkstatus_free(ns);
+    }
+    return 0;
+  }
+
+  if (source != NS_FROM_CACHE && trusted_dir)
     trusted_dir->n_networkstatus_failures = 0;
 
   found = 0;
@@ -2075,8 +2112,8 @@ router_set_networkstatus(const char *s, 
 
   SMARTLIST_FOREACH(ns->entries, routerstatus_t *, rs,
     {
-       if (!router_get_by_descriptor_digest(rs->descriptor_digest))
-         rs->need_to_mirror = 1;
+      if (!router_get_by_descriptor_digest(rs->descriptor_digest))
+        rs->need_to_mirror = 1;
     });
 
   info(LD_DIR, "Setting networkstatus %s %s (published %s)",
@@ -2087,21 +2124,11 @@ router_set_networkstatus(const char *s, 
 
   smartlist_sort(networkstatus_list, _compare_networkstatus_published_on);
 
-  if (source != NS_FROM_CACHE && !skewed) {
-    char *fn = networkstatus_get_cache_filename(ns);
-    if (write_str_to_file(fn, s, 0)<0) {
-      notice(LD_FS, "Couldn't write cached network status to \"%s\"", fn);
-    }
-    tor_free(fn);
-  }
+  if (!skewed)
+    add_networkstatus_to_cache(s, source, ns);
 
   networkstatus_list_update_recent(now);
 
-  if (get_options()->DirPort && !skewed)
-    dirserv_set_cached_networkstatus_v2(s,
-                                        ns->identity_digest,
-                                        ns->published_on);
-
   return 0;
 }