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

[or-cvs] On directory servers, old_routers was wasting hundreds of b...



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

Modified Files:
	circuitbuild.c connection_edge.c connection_or.c control.c 
	directory.c dirserv.c or.h rendservice.c router.c routerlist.c 
	routerparse.c test.c 
Log Message:
On directory servers, old_routers was wasting hundreds of bytes per superseded router descriptor.  Roll the signed descriptor info and identifying info into a cache_info struct, and use only that for old_routers.

Index: circuitbuild.c
===================================================================
RCS file: /home/or/cvsroot/tor/src/or/circuitbuild.c,v
retrieving revision 1.157
retrieving revision 1.158
diff -u -d -r1.157 -r1.158
--- circuitbuild.c	29 Oct 2005 19:13:48 -0000	1.157
+++ circuitbuild.c	5 Nov 2005 20:15:26 -0000	1.158
@@ -179,20 +179,20 @@
   if (server_mode(get_options())) {
     routerinfo_t *me = router_get_my_routerinfo();
     tor_assert(me);
-    prev_digest = me->identity_digest;
+    prev_digest = me->cache_info.identity_digest;
   }
   do {
     router = router_get_by_digest(hop->extend_info->identity_digest);
     if (router) {
       if (prev_digest) {
         if (hop->state == CPATH_STATE_OPEN)
-          rep_hist_note_extend_succeeded(prev_digest, router->identity_digest);
+          rep_hist_note_extend_succeeded(prev_digest, router->cache_info.identity_digest);
         else {
-          rep_hist_note_extend_failed(prev_digest, router->identity_digest);
+          rep_hist_note_extend_failed(prev_digest, router->cache_info.identity_digest);
           break;
         }
       }
-      prev_digest = router->identity_digest;
+      prev_digest = router->cache_info.identity_digest;
     } else {
       prev_digest = NULL;
     }
@@ -1567,7 +1567,7 @@
   tor_assert(r);
   info = tor_malloc_zero(sizeof(extend_info_t));
   strlcpy(info->nickname, r->nickname, sizeof(info->nickname));
-  memcpy(info->identity_digest, r->identity_digest, DIGEST_LEN);
+  memcpy(info->identity_digest, r->cache_info.identity_digest, DIGEST_LEN);
   info->onion_key = crypto_pk_dup_key(r->onion_pkey);
   info->addr = r->addr;
   info->port = r->or_port;
@@ -1656,7 +1656,7 @@
     /* XXXX Downgrade this to info before release. NM */
     notice(LD_CIRC, "Chose '%s' as helper node.", entry->nickname);
     strlcpy(helper->nickname, entry->nickname, sizeof(helper->nickname));
-    memcpy(helper->identity, entry->identity_digest, DIGEST_LEN);
+    memcpy(helper->identity, entry->cache_info.identity_digest, DIGEST_LEN);
     smartlist_add(helper_nodes, helper);
     changed = 1;
   }

Index: connection_edge.c
===================================================================
RCS file: /home/or/cvsroot/tor/src/or/connection_edge.c,v
retrieving revision 1.359
retrieving revision 1.360
diff -u -d -r1.359 -r1.360
--- connection_edge.c	25 Oct 2005 18:01:01 -0000	1.359
+++ connection_edge.c	5 Nov 2005 20:15:26 -0000	1.360
@@ -1066,7 +1066,7 @@
           /* use the hex digest, not nickname, in case there are two
              routers with this nickname */
           conn->chosen_exit_name =
-            tor_strdup(hex_str(r->identity_digest, DIGEST_LEN));
+            tor_strdup(hex_str(r->cache_info.identity_digest, DIGEST_LEN));
         }
       }
 

Index: connection_or.c
===================================================================
RCS file: /home/or/cvsroot/tor/src/or/connection_or.c,v
retrieving revision 1.195
retrieving revision 1.196
diff -u -d -r1.195 -r1.196
--- connection_or.c	25 Oct 2005 18:01:01 -0000	1.195
+++ connection_or.c	5 Nov 2005 20:15:26 -0000	1.196
@@ -326,7 +326,7 @@
   tor_assert(id_digest);
 
   if (server_mode(options) && (me=router_get_my_routerinfo()) &&
-      !memcmp(me->identity_digest, id_digest,DIGEST_LEN)) {
+      router_digest_is_me(id_digest)) {
     info(LD_PROTOCOL,"Client asked me to connect to myself. Refusing.");
     return NULL;
   }
@@ -500,7 +500,7 @@
   router = router_get_by_nickname(nickname, 0);
   if (router && /* we know this nickname */
       router->is_named && /* make sure it's the right guy */
-      memcmp(digest_rcvd, router->identity_digest, DIGEST_LEN) != 0) {
+      memcmp(digest_rcvd, router->cache_info.identity_digest,DIGEST_LEN) !=0) {
     log_fn(severity, LD_OR,
            "Identity key not as expected for router claiming to be '%s' (%s:%d)",
            nickname, conn->address, conn->port);

Index: control.c
===================================================================
RCS file: /home/or/cvsroot/tor/src/or/control.c,v
retrieving revision 1.146
retrieving revision 1.147
diff -u -d -r1.146 -r1.147
--- control.c	25 Oct 2005 18:01:01 -0000	1.146
+++ control.c	5 Nov 2005 20:15:26 -0000	1.147
@@ -1255,12 +1255,12 @@
     *answer = list_getinfo_options();
   } else if (!strcmpstart(question, "desc/id/")) {
     routerinfo_t *ri = router_get_by_hexdigest(question+strlen("desc/id/"));
-    if (ri && ri->signed_descriptor)
-      *answer = tor_strdup(ri->signed_descriptor);
+    if (ri && ri->cache_info.signed_descriptor)
+      *answer = tor_strdup(ri->cache_info.signed_descriptor);
   } else if (!strcmpstart(question, "desc/name/")) {
     routerinfo_t *ri = router_get_by_nickname(question+strlen("desc/name/"),1);
-    if (ri && ri->signed_descriptor)
-      *answer = tor_strdup(ri->signed_descriptor);
+    if (ri && ri->cache_info.signed_descriptor)
+      *answer = tor_strdup(ri->cache_info.signed_descriptor);
   } else if (!strcmpstart(question, "unregistered-servers-")) {
     *answer = dirserver_getinfo_unregistered(question +
                                              strlen("unregistered-servers-"));
@@ -2557,7 +2557,7 @@
   identities = smartlist_create();
   SMARTLIST_FOREACH(routers, routerinfo_t *, r,
   {
-    base16_encode(buf,sizeof(buf),r->identity_digest,DIGEST_LEN);
+    base16_encode(buf,sizeof(buf),r->cache_info.identity_digest,DIGEST_LEN);
     smartlist_add(identities, tor_strdup(buf));
   });
   if (EVENT_IS_INTERESTING0(EVENT_NEW_DESC)) {

Index: directory.c
===================================================================
RCS file: /home/or/cvsroot/tor/src/or/directory.c,v
retrieving revision 1.317
retrieving revision 1.318
diff -u -d -r1.317 -r1.318
--- directory.c	1 Nov 2005 06:13:12 -0000	1.317
+++ directory.c	5 Nov 2005 20:15:27 -0000	1.318
@@ -250,9 +250,9 @@
                                   const char *payload, size_t payload_len)
 {
   directory_initiate_command(router->address, router->addr, router->dir_port,
-                             router->platform, router->identity_digest,
-                             purpose, private_connection, resource,
-                             payload, payload_len);
+                         router->platform, router->cache_info.identity_digest,
+                         purpose, private_connection, resource,
+                         payload, payload_len);
 }
 
 /** As directory_initiate_command_router, but send the command to a trusted
@@ -1043,7 +1043,7 @@
       /* this might have been a dirport reachability test. see if it is. */
       routerinfo_t *me = router_get_my_routerinfo();
       if (me &&
-          !memcmp(me->identity_digest, conn->identity_digest, DIGEST_LEN) &&
+          router_digest_is_me(conn->identity_digest) &&
           me->addr == conn->addr &&
           me->dir_port == conn->port)
         router_dirport_found_reachable();
@@ -1340,14 +1340,14 @@
     else {
       size_t len = 0;
       format_rfc1123_time(date, time(NULL));
-      SMARTLIST_FOREACH(descs, routerinfo_t *, ri,
+      SMARTLIST_FOREACH(descs, signed_descriptor_t *, ri,
                         len += ri->signed_descriptor_len);
       if (deflated) {
         size_t compressed_len;
         char *compressed;
         char *inp = tor_malloc(len+smartlist_len(descs)+1);
         char *cp = inp;
-        SMARTLIST_FOREACH(descs, routerinfo_t *, ri,
+        SMARTLIST_FOREACH(descs, signed_descriptor_t *, ri,
            {
              memcpy(cp, ri->signed_descriptor,
                     ri->signed_descriptor_len);
@@ -1375,7 +1375,7 @@
                      date,
                      (int)len);
         connection_write_to_buf(tmp, strlen(tmp), conn);
-        SMARTLIST_FOREACH(descs, routerinfo_t *, ri,
+        SMARTLIST_FOREACH(descs, signed_descriptor_t *, ri,
                           connection_write_to_buf(ri->signed_descriptor,
                                                   ri->signed_descriptor_len,
                                                   conn));

Index: dirserv.c
===================================================================
RCS file: /home/or/cvsroot/tor/src/or/dirserv.c,v
retrieving revision 1.265
retrieving revision 1.266
diff -u -d -r1.265 -r1.266
--- dirserv.c	1 Nov 2005 03:48:51 -0000	1.265
+++ dirserv.c	5 Nov 2005 20:15:27 -0000	1.266
@@ -376,17 +376,17 @@
 
   /* Is there too much clock skew? */
   now = time(NULL);
-  if (ri->published_on > now+ROUTER_ALLOW_SKEW) {
+  if (ri->cache_info.published_on > now+ROUTER_ALLOW_SKEW) {
     notice(LD_DIRSERV, "Publication time for nickname '%s' is too far (%d minutes) in the future; possible clock skew. Not adding (ContactInfo '%s', platform '%s').",
-           ri->nickname, (int)((ri->published_on-now)/60),
+           ri->nickname, (int)((ri->cache_info.published_on-now)/60),
            ri->contact_info ? ri->contact_info : "",
            ri->platform ? ri->platform : "");
     *msg = "Rejected: Your clock is set too far in the future, or your timezone is not correct.";
     return -1;
   }
-  if (ri->published_on < now-ROUTER_MAX_AGE) {
+  if (ri->cache_info.published_on < now-ROUTER_MAX_AGE) {
     notice(LD_DIRSERV, "Publication time for router with nickname '%s' is too far (%d minutes) in the past. Not adding (ContactInfo '%s', platform '%s').",
-           ri->nickname, (int)((now-ri->published_on)/60),
+           ri->nickname, (int)((now-ri->cache_info.published_on)/60),
            ri->contact_info ? ri->contact_info : "",
            ri->platform ? ri->platform : "");
     *msg = "Rejected: Server is expired, or your clock is too far in the past, or your timezone is not correct.";
@@ -448,9 +448,9 @@
    * from this server.  (We do this here and not in router_add_to_routerlist
    * because we want to be able to accept the newest router descriptor that
    * another authority has, so we all converge on the same one.) */
-  ri_old = router_get_by_digest(ri->identity_digest);
-  if (ri_old && ri_old->published_on < ri->published_on &&
-      router_differences_are_cosmetic(ri_old, ri)) {
+  ri_old = router_get_by_digest(ri->cache_info.identity_digest);
+  if (ri_old && ri_old->cache_info.published_on < ri->cache_info.published_on
+      && router_differences_are_cosmetic(ri_old, ri)) {
     info(LD_DIRSERV,
          "Not replacing descriptor from '%s'; differences are cosmetic.",
          ri->nickname);
@@ -599,7 +599,7 @@
     *cp++ = '=';
   }
   *cp++ = '$';
-  base16_encode(cp, HEX_DIGEST_LEN+1, desc->identity_digest,
+  base16_encode(cp, HEX_DIGEST_LEN+1, desc->cache_info.identity_digest,
                 DIGEST_LEN);
   return tor_strdup(buf);
 }
@@ -616,7 +616,7 @@
   connection_t *conn;
   if (router_is_me(router) && !we_are_hibernating())
     return 1;
-  conn = connection_get_by_identity_digest(router->identity_digest,
+  conn = connection_get_by_identity_digest(router->cache_info.identity_digest,
                                            CONN_TYPE_OR);
   if (conn && conn->state == OR_CONN_STATE_OPEN)
     return get_options()->AssumeReachable ||
@@ -633,7 +633,7 @@
   connection_t *conn;
   if (router->is_hibernating)
     return 0;
-  conn = connection_get_by_identity_digest(router->identity_digest,
+  conn = connection_get_by_identity_digest(router->cache_info.identity_digest,
                                            CONN_TYPE_OR);
   if (conn && conn->state == OR_CONN_STATE_OPEN &&
       now >= router->last_reachable + 2*REACHABLE_TIMEOUT &&
@@ -763,7 +763,7 @@
   buf_len = 2048+strlen(recommended_versions)+
     strlen(router_status);
   SMARTLIST_FOREACH(rl->routers, routerinfo_t *, ri,
-                    buf_len += ri->signed_descriptor_len+1);
+                    buf_len += ri->cache_info.signed_descriptor_len+1);
   buf = tor_malloc(buf_len);
   /* We'll be comparing against buf_len throughout the rest of the
      function, though strictly speaking we shouldn't be able to exceed
@@ -786,10 +786,11 @@
   cp = buf + strlen(buf);
   SMARTLIST_FOREACH(rl->routers, routerinfo_t *, ri,
     {
-      if (cp+ri->signed_descriptor_len+1 >= buf+buf_len)
+      size_t len = ri->cache_info.signed_descriptor_len;
+      if (cp+len+1 >= buf+buf_len)
         goto truncated;
-      memcpy(cp, ri->signed_descriptor, ri->signed_descriptor_len);
-      cp += ri->signed_descriptor_len;
+      memcpy(cp, ri->cache_info.signed_descriptor, len);
+      cp += len;
       *cp++ = '\n'; /* add an extra newline in case somebody was depending on
                      * it. */
     });
@@ -1226,7 +1227,8 @@
       int f_stable = !router_is_unreliable(ri, 1, 0);
       int f_fast = !router_is_unreliable(ri, 0, 1);
       int f_running;
-      int f_authority = router_digest_is_trusted_dir(ri->identity_digest);
+      int f_authority = router_digest_is_trusted_dir(
+                                      ri->cache_info.identity_digest);
       int f_named = naming && ri->is_named;
       int f_valid = ri->is_verified;
       char identity64[BASE64_DIGEST_LEN+1];
@@ -1236,10 +1238,10 @@
       }
       f_running = ri->is_running;
 
-      format_iso_time(published, ri->published_on);
+      format_iso_time(published, ri->cache_info.published_on);
 
-      digest_to_base64(identity64, ri->identity_digest);
-      digest_to_base64(digest64, ri->signed_descriptor_digest);
+      digest_to_base64(identity64, ri->cache_info.identity_digest);
+      digest_to_base64(digest64, ri->cache_info.signed_descriptor_digest);
 
       in.s_addr = htonl(ri->addr);
       tor_inet_ntoa(&in, ipaddr, sizeof(ipaddr));
@@ -1367,7 +1369,7 @@
   return 0;
 }
 
-/** Add a routerinfo_t to <b>descs_out</b> for each router matching
+/** Add a signed_descriptor_t to <b>descs_out</b> for each router matching
  * <b>key</b>.  The key should be either
  *   - "/tor/server/authority" for our own routerinfo;
  *   - "/tor/server/all" for all the routerinfos we have, concatenated;
@@ -1390,20 +1392,21 @@
 
   if (!strcmp(key, "/tor/server/all")) {
     routerlist_t *rl = router_get_routerlist();
-    smartlist_add_all(descs_out, rl->routers);
+    SMARTLIST_FOREACH(rl->routers, routerinfo_t *, r,
+                      smartlist_add(descs_out, &(r->cache_info)));
   } else if (!strcmp(key, "/tor/server/authority")) {
     routerinfo_t *ri = router_get_my_routerinfo();
     if (ri)
-      smartlist_add(descs_out, ri);
+      smartlist_add(descs_out, &(ri->cache_info));
   } else if (!strcmpstart(key, "/tor/server/d/")) {
     smartlist_t *digests = smartlist_create();
     key += strlen("/tor/server/d/");
     dir_split_resource_into_fingerprints(key, digests, NULL, 1);
     SMARTLIST_FOREACH(digests, const char *, d,
        {
-         routerinfo_t *ri = router_get_by_descriptor_digest(d);
-         if (ri)
-           smartlist_add(descs_out,ri);
+         signed_descriptor_t *sd = router_get_by_descriptor_digest(d);
+         if (sd)
+           smartlist_add(descs_out,sd);
        });
     SMARTLIST_FOREACH(digests, char *, d, tor_free(d));
     smartlist_free(digests);
@@ -1414,11 +1417,11 @@
     SMARTLIST_FOREACH(digests, const char *, d,
        {
          if (router_digest_is_me(d)) {
-           smartlist_add(descs_out, router_get_my_routerinfo());
+           smartlist_add(descs_out, &(router_get_my_routerinfo()->cache_info));
          } else {
            routerinfo_t *ri = router_get_by_digest(d);
            if (ri)
-             smartlist_add(descs_out,ri);
+             smartlist_add(descs_out, &(ri->cache_info));
          }
        });
     SMARTLIST_FOREACH(digests, char *, d, tor_free(d));
@@ -1471,7 +1474,8 @@
         notice(LD_DIRSERV, "Dropping descriptor: nickname '%s' does not match nickname '%s' in cert from %s:%d",
                ri->nickname, nickname_rcvd, address, or_port);
         drop = 1;
-      } else if (memcmp(ri->identity_digest, digest_rcvd, DIGEST_LEN)) {
+      } else if (memcmp(ri->cache_info.identity_digest, digest_rcvd,
+                        DIGEST_LEN)) {
         notice(LD_DIRSERV, "Dropping descriptor: identity key does not match key in cert from %s:%d",
                address, or_port);
         drop = 1;

Index: or.h
===================================================================
RCS file: /home/or/cvsroot/tor/src/or/or.h,v
retrieving revision 1.730
retrieving revision 1.731
diff -u -d -r1.730 -r1.731
--- or.h	1 Nov 2005 17:34:17 -0000	1.730
+++ or.h	5 Nov 2005 20:15:27 -0000	1.731
@@ -735,11 +735,18 @@
   time_t published; /**< When was this object published */
 } cached_dir_t;
 
+/** Information need to cache an onion router's descriptor. */
+typedef struct signed_descriptor_t {
+  char *signed_descriptor;
+  size_t signed_descriptor_len;
+  char signed_descriptor_digest[DIGEST_LEN];
+  char identity_digest[DIGEST_LEN];
+  time_t published_on;
+} signed_descriptor_t;
+
 /** Information about another onion router in the network. */
 typedef struct {
-  char *signed_descriptor; /**< The original signed descriptor for this router*/
-  size_t signed_descriptor_len; /**< The length of signed_descriptor */
-  char signed_descriptor_digest[DIGEST_LEN]; /**< The digest of the signed descriptor. */
+  signed_descriptor_t cache_info;
 
   char *address; /**< Location of OR: either a hostname or an IP address. */
   char *nickname; /**< Human-readable OR name. */
@@ -748,12 +755,8 @@
   uint16_t or_port; /**< Port for OR-to-OR and OP-to-OR connections. */
   uint16_t dir_port; /**< Port for HTTP directory connections. */
 
-  time_t published_on; /**< When was the information in this routerinfo_t
-                        * published? */
-
   crypto_pk_env_t *onion_pkey; /**< Public RSA key for onions. */
   crypto_pk_env_t *identity_pkey;  /**< Public RSA key for signing. */
-  char identity_digest[DIGEST_LEN]; /**< Digest of identity key */
 
   char *platform; /**< What software/operating system is this OR using? */
 
@@ -871,12 +874,13 @@
 typedef struct {
   /** Map from server identity digest to a member of routers. */
   digestmap_t *identity_map;
-  /** Map from server descriptor digest to a member of routers or of
-   * old_routers. */
+  /** Map from server descriptor digest to a signed_descritptor_t from
+   * routers or old_routers. */
   digestmap_t *desc_digest_map;
   /** List of routerinfo_t for all currently live routers we know. */
   smartlist_t *routers;
-  /** List of routerinfo_t for older router descriptors we're caching. */
+  /** List of signed_descriptor_t for older router descriptors we're
+   * caching. */
   smartlist_t *old_routers;
 } routerlist_t;
 
@@ -2146,7 +2150,7 @@
                                      int warn_if_unnamed);
 routerinfo_t *router_get_by_hexdigest(const char *hexdigest);
 routerinfo_t *router_get_by_digest(const char *digest);
-routerinfo_t *router_get_by_descriptor_digest(const char *digest);
+signed_descriptor_t *router_get_by_descriptor_digest(const char *digest);
 int router_digest_is_trusted_dir(const char *digest);
 routerlist_t *router_get_routerlist(void);
 void routerlist_reset_warnings(void);

Index: rendservice.c
===================================================================
RCS file: /home/or/cvsroot/tor/src/or/rendservice.c,v
retrieving revision 1.146
retrieving revision 1.147
diff -u -d -r1.146 -r1.147
--- rendservice.c	25 Oct 2005 18:01:01 -0000	1.146
+++ rendservice.c	5 Nov 2005 20:15:27 -0000	1.147
@@ -975,7 +975,8 @@
       changed = 1;
       hex_digest = tor_malloc_zero(HEX_DIGEST_LEN+2);
       hex_digest[0] = '$';
-      base16_encode(hex_digest+1, HEX_DIGEST_LEN+1, router->identity_digest,
+      base16_encode(hex_digest+1, HEX_DIGEST_LEN+1,
+                    router->cache_info.identity_digest,
                     DIGEST_LEN);
       smartlist_add(intro_routers, router);
       smartlist_add(exclude_routers, router);

Index: router.c
===================================================================
RCS file: /home/or/cvsroot/tor/src/or/router.c,v
retrieving revision 1.228
retrieving revision 1.229
diff -u -d -r1.228 -r1.229
--- router.c	1 Nov 2005 03:48:51 -0000	1.228
+++ router.c	5 Nov 2005 20:15:27 -0000	1.229
@@ -623,7 +623,7 @@
     if (!clique_mode(options) && !router_is_clique_mode(router))
       continue;
     if (force ||
-        !connection_get_by_identity_digest(router->identity_digest,
+        !connection_get_by_identity_digest(router->cache_info.identity_digest,
                                            CONN_TYPE_OR)) {
       debug(LD_OR,"%sconnecting to %s at %s:%u.",
              clique_mode(options) ? "(forced) " : "",
@@ -631,7 +631,8 @@
       /* Remember when we started trying to determine reachability */
       if (!router->testing_since)
         router->testing_since = now;
-      connection_or_connect(router->addr, router->or_port, router->identity_digest);
+      connection_or_connect(router->addr, router->or_port,
+                            router->cache_info.identity_digest);
     }
   });
 }
@@ -641,7 +642,7 @@
 int
 router_is_clique_mode(routerinfo_t *router)
 {
-  if (router_digest_is_trusted_dir(router->identity_digest))
+  if (router_digest_is_trusted_dir(router->cache_info.identity_digest))
     return 1;
   return 0;
 }
@@ -701,7 +702,7 @@
 router_digest_is_me(const char *digest)
 {
   routerinfo_t *me = router_get_my_routerinfo();
-  if (!me || memcmp(me->identity_digest, digest, DIGEST_LEN))
+  if (!me || memcmp(me->cache_info.identity_digest, digest, DIGEST_LEN))
     return 0;
   return 1;
 }
@@ -710,7 +711,7 @@
 int
 router_is_me(routerinfo_t *router)
 {
-  return router_digest_is_me(router->identity_digest);
+  return router_digest_is_me(router->cache_info.identity_digest);
 }
 
 /** Return true iff <b>fp</b> is a hex fingerprint of my identity digest. */
@@ -750,8 +751,9 @@
     if (router_rebuild_descriptor(1))
       return NULL;
   }
-  debug(LD_GENERAL,"my desc is '%s'",desc_routerinfo->signed_descriptor);
-  return desc_routerinfo->signed_descriptor;
+  debug(LD_GENERAL,"my desc is '%s'",
+        desc_routerinfo->cache_info.signed_descriptor);
+  return desc_routerinfo->cache_info.signed_descriptor;
 }
 
 /*DOCDOC*/
@@ -784,10 +786,11 @@
   ri->addr = addr;
   ri->or_port = options->ORPort;
   ri->dir_port = options->DirPort;
-  ri->published_on = time(NULL);
+  ri->cache_info.published_on = time(NULL);
   ri->onion_pkey = crypto_pk_dup_key(get_onion_key()); /* must invoke from main thread */
   ri->identity_pkey = crypto_pk_dup_key(get_identity_key());
-  if (crypto_pk_get_digest(ri->identity_pkey, ri->identity_digest)<0) {
+  if (crypto_pk_get_digest(ri->identity_pkey,
+                           ri->cache_info.identity_digest)<0) {
     routerinfo_free(ri);
     return -1;
   }
@@ -838,7 +841,7 @@
          char *fp = tor_malloc(HEX_DIGEST_LEN+2);
          fp[0] = '$';
          base16_encode(fp+1,HEX_DIGEST_LEN+1,
-                       member->identity_digest, DIGEST_LEN);
+                       member->cache_info.identity_digest, DIGEST_LEN);
          smartlist_add(ri->declared_family, fp);
          if (smartlist_string_isin(warned_nonexistent_family, name))
            smartlist_string_remove(warned_nonexistent_family, name);
@@ -847,15 +850,17 @@
      });
     smartlist_free(family);
   }
-  ri->signed_descriptor = tor_malloc(8192);
-  if (router_dump_router_to_string(ri->signed_descriptor, 8192,
+  ri->cache_info.signed_descriptor = tor_malloc(8192);
+  if (router_dump_router_to_string(ri->cache_info.signed_descriptor, 8192,
                                    ri, get_identity_key())<0) {
     warn(LD_BUG, "Couldn't allocate string for descriptor.");
     return -1;
   }
-  ri->signed_descriptor_len = strlen(ri->signed_descriptor);
-  crypto_digest(ri->signed_descriptor_digest,
-                ri->signed_descriptor, ri->signed_descriptor_len);
+  ri->cache_info.signed_descriptor_len =
+    strlen(ri->cache_info.signed_descriptor);
+  crypto_digest(ri->cache_info.signed_descriptor_digest,
+                ri->cache_info.signed_descriptor,
+                ri->cache_info.signed_descriptor_len);
 
   if (desc_routerinfo)
     routerinfo_free(desc_routerinfo);
@@ -1029,7 +1034,7 @@
   }
 
   /* Encode the publication time. */
-  format_iso_time(published, router->published_on);
+  format_iso_time(published, router->cache_info.published_on);
 
   /* How busy have we been? */
   bandwidth_usage = rep_hist_get_bandwidth_lines();

Index: routerlist.c
===================================================================
RCS file: /home/or/cvsroot/tor/src/or/routerlist.c,v
retrieving revision 1.361
retrieving revision 1.362
diff -u -d -r1.361 -r1.362
--- routerlist.c	4 Nov 2005 16:47:26 -0000	1.361
+++ routerlist.c	5 Nov 2005 20:15:27 -0000	1.362
@@ -209,17 +209,18 @@
 
   for (i = 0; i < 2; ++i) {
     smartlist_t *lst = (i == 0) ? routerlist->old_routers : routerlist->routers;
-    SMARTLIST_FOREACH(lst, routerinfo_t *, ri,
+    SMARTLIST_FOREACH(lst, void *, ptr,
     {
+      signed_descriptor_t *sd = (i==0) ?
+        ((signed_descriptor_t*)ptr): &((routerinfo_t*)ptr)->cache_info;
       sized_chunk_t *c;
-      if (!ri->signed_descriptor) {
-        warn(LD_BUG, "Bug! No descriptor stored for router '%s'.",
-             ri->nickname);
+      if (!sd->signed_descriptor) {
+        warn(LD_BUG, "Bug! No descriptor stored for router.");
         goto done;
       }
       c = tor_malloc(sizeof(sized_chunk_t));
-      c->bytes = ri->signed_descriptor;
-      c->len = ri->signed_descriptor_len;
+      c->bytes = sd->signed_descriptor;
+      c->len = sd->signed_descriptor_len;
       smartlist_add(chunk_list, c);
     });
   }
@@ -427,7 +428,7 @@
      */
     if (for_v2_directory &&
         !(tor_version_as_new_as(router->platform,"0.1.1.7-alpha") ||
-          router_digest_is_trusted_dir(router->identity_digest)))
+          router_digest_is_trusted_dir(router->cache_info.identity_digest)))
       continue;
     smartlist_add(sl, router);
   });
@@ -464,9 +465,8 @@
       if (!d->is_running) continue;
       if (need_v1_support && !d->supports_v1_protocol)
         continue;
-      if (requireother && me &&
-          !memcmp(me->identity_digest, d->digest, DIGEST_LEN))
-        continue;
+      if (requireother && me && router_digest_is_me(d->digest))
+          continue;
       if (fascistfirewall) {
         if (!fascist_firewall_allows_address(d->addr, d->dir_port))
           continue;
@@ -485,10 +485,10 @@
 {
   if (routerlist) {
     SMARTLIST_FOREACH(routerlist->routers, routerinfo_t *, router,
-                 if (router_digest_is_trusted_dir(router->identity_digest) &&
-                     router->dir_port > 0) {
-                   router->is_running = 1;
-                 });
+       if (router_digest_is_trusted_dir(router->cache_info.identity_digest) &&
+         router->dir_port > 0) {
+         router->is_running = 1;
+       });
   }
   if (trusted_dir_servers) {
     SMARTLIST_FOREACH(trusted_dir_servers, trusted_dir_server_t *, dir,
@@ -847,10 +847,11 @@
   if (hexdigest[0] == '$')
     ++hexdigest;
 
+  /* XXXXNM Any place that uses this inside a loop could probably do better. */
   if (strlen(hexdigest) != HEX_DIGEST_LEN ||
       base16_decode(digest, DIGEST_LEN, hexdigest, HEX_DIGEST_LEN)<0)
     return 0;
-  return (!memcmp(digest, router->identity_digest, DIGEST_LEN));
+  return (!memcmp(digest, router->cache_info.identity_digest, DIGEST_LEN));
 }
 
 /** Return true if <b>router</b>'s nickname matches <b>nickname</b>
@@ -899,7 +900,7 @@
         best_match = router;
       }
     } else if (maybedigest &&
-               !memcmp(digest, router->identity_digest, DIGEST_LEN)) {
+               !memcmp(digest, router->cache_info.identity_digest, DIGEST_LEN)) {
       return router;
     }
   });
@@ -916,12 +917,12 @@
           char fp[HEX_DIGEST_LEN+1];
           if (strcasecmp(router->nickname, nickname))
             continue;
-          rs=router_get_combined_status_by_digest(router->identity_digest);
+          rs=router_get_combined_status_by_digest(router->cache_info.identity_digest);
           if (!rs->name_lookup_warned) {
             rs->name_lookup_warned = 1;
             any_unwarned = 1;
           }
-          base16_encode(fp, sizeof(fp), router->identity_digest, DIGEST_LEN);
+          base16_encode(fp, sizeof(fp), router->cache_info.identity_digest, DIGEST_LEN);
           dlen = 32 + HEX_DIGEST_LEN + strlen(router->address);
           desc = tor_malloc(dlen);
           tor_snprintf(desc, dlen, "\"$%s\" for the one at %s:%d",
@@ -940,10 +941,10 @@
       smartlist_free(fps);
     } else if (warn_if_unnamed) {
       local_routerstatus_t *rs =
-        router_get_combined_status_by_digest(best_match->identity_digest);
+        router_get_combined_status_by_digest(best_match->cache_info.identity_digest);
       if (rs && !rs->name_lookup_warned) {
         char fp[HEX_DIGEST_LEN+1];
-        base16_encode(fp, sizeof(fp), best_match->identity_digest, DIGEST_LEN);
+        base16_encode(fp, sizeof(fp), best_match->cache_info.identity_digest, DIGEST_LEN);
         warn(LD_CONFIG, "You specified a server \"%s\" by name, but the "
                "directory authorities do not have a listing for this name. "
                "To make sure you get the same server in the future, refer to "
@@ -1004,20 +1005,14 @@
 
 /** Return the router in our routerlist whose 20-byte descriptor
  * is <b>digest</b>.  Return NULL if no such router is known. */
-routerinfo_t *
+signed_descriptor_t *
 router_get_by_descriptor_digest(const char *digest)
 {
   tor_assert(digest);
 
   if (!routerlist) return NULL;
 
-  SMARTLIST_FOREACH(routerlist->routers, routerinfo_t*, router,
-  {
-    if (0 == memcmp(router->signed_descriptor_digest, digest, DIGEST_LEN))
-      return router;
-  });
-
-  return NULL;
+  return digestmap_get(routerlist->desc_digest_map, digest);
 }
 
 /** Return the current list of all known routers. */
@@ -1041,7 +1036,7 @@
   if (!router)
     return;
 
-  tor_free(router->signed_descriptor);
+  tor_free(router->cache_info.signed_descriptor);
   tor_free(router->address);
   tor_free(router->nickname);
   tor_free(router->platform);
@@ -1058,6 +1053,24 @@
   tor_free(router);
 }
 
+static void
+signed_descriptor_free(signed_descriptor_t *sd)
+{
+  tor_free(sd->signed_descriptor);
+  tor_free(sd);
+}
+
+/** frees ri. DOCDOC */
+static signed_descriptor_t *
+signed_descriptor_from_routerinfo(routerinfo_t *ri)
+{
+  signed_descriptor_t *sd = tor_malloc_zero(sizeof(signed_descriptor_t));
+  memcpy(sd, &(ri->cache_info), sizeof(signed_descriptor_t));
+  ri->cache_info.signed_descriptor = NULL;
+  routerinfo_free(ri);
+  return sd;
+}
+
 /** Allocate a fresh copy of <b>router</b> */
 routerinfo_t *
 routerinfo_copy(const routerinfo_t *router)
@@ -1071,8 +1084,8 @@
   r->address = tor_strdup(r->address);
   r->nickname = tor_strdup(r->nickname);
   r->platform = tor_strdup(r->platform);
-  if (r->signed_descriptor)
-    r->signed_descriptor = tor_strdup(r->signed_descriptor);
+  if (r->cache_info.signed_descriptor)
+    r->cache_info.signed_descriptor = tor_strdup(r->cache_info.signed_descriptor);
   if (r->onion_pkey)
     r->onion_pkey = crypto_pk_dup_key(r->onion_pkey);
   if (r->identity_pkey)
@@ -1102,15 +1115,15 @@
   digestmap_free(rl->desc_digest_map, NULL);
   SMARTLIST_FOREACH(rl->routers, routerinfo_t *, r,
                     routerinfo_free(r));
-  SMARTLIST_FOREACH(rl->old_routers, routerinfo_t *, r,
-                    routerinfo_free(r));
+  SMARTLIST_FOREACH(rl->old_routers, signed_descriptor_t *, sd,
+                    signed_descriptor_free(sd));
   smartlist_free(rl->routers);
   smartlist_free(rl->old_routers);
   tor_free(rl);
 }
 
 static INLINE int
-_routerlist_find_elt(smartlist_t *sl, routerinfo_t *ri, int idx)
+_routerlist_find_elt(smartlist_t *sl, void *ri, int idx)
 {
   if (idx < 0 || smartlist_get(sl, idx) != ri) {
     idx = -1;
@@ -1128,8 +1141,9 @@
 static void
 routerlist_insert(routerlist_t *rl, routerinfo_t *ri)
 {
-  digestmap_set(rl->identity_map, ri->identity_digest, ri);
-  digestmap_set(rl->desc_digest_map, ri->signed_descriptor_digest, ri);
+  digestmap_set(rl->identity_map, ri->cache_info.identity_digest, ri);
+  digestmap_set(rl->desc_digest_map, ri->cache_info.signed_descriptor_digest,
+                &(ri->cache_info));
   smartlist_add(rl->routers, ri);
   // routerlist_assert_ok(rl);
 }
@@ -1138,8 +1152,9 @@
 routerlist_insert_old(routerlist_t *rl, routerinfo_t *ri)
 {
   if (get_options()->DirPort) {
-    digestmap_set(rl->desc_digest_map, ri->signed_descriptor_digest, ri);
-    smartlist_add(rl->old_routers, ri);
+    signed_descriptor_t *sd = signed_descriptor_from_routerinfo(ri);
+    digestmap_set(rl->desc_digest_map, sd->signed_descriptor_digest, sd);
+    smartlist_add(rl->old_routers, sd);
   } else {
     routerinfo_free(ri);
   }
@@ -1159,13 +1174,15 @@
   if (idx < 0)
     return;
   smartlist_del(rl->routers, idx);
-  ri_tmp = digestmap_remove(rl->identity_map, ri->identity_digest);
+  ri_tmp = digestmap_remove(rl->identity_map, ri->cache_info.identity_digest);
   tor_assert(ri_tmp == ri);
   if (make_old && get_options()->DirPort) {
-    smartlist_add(rl->old_routers, ri);
+    signed_descriptor_t *sd = signed_descriptor_from_routerinfo(ri);
+    smartlist_add(rl->old_routers, sd);
+    digestmap_set(rl->desc_digest_map, sd->signed_descriptor_digest, sd);
   } else {
     ri_tmp = digestmap_remove(rl->desc_digest_map,
-                              ri->signed_descriptor_digest);
+                              ri->cache_info.signed_descriptor_digest);
     tor_assert(ri_tmp == ri);
     routerinfo_free(ri);
   }
@@ -1173,17 +1190,17 @@
 }
 
 static void
-routerlist_remove_old(routerlist_t *rl, routerinfo_t *ri, int idx)
+routerlist_remove_old(routerlist_t *rl, signed_descriptor_t *sd, int idx)
 {
-  routerinfo_t *ri_tmp;
-  idx = _routerlist_find_elt(rl->old_routers, ri, idx);
+  signed_descriptor_t *sd_tmp;
+  idx = _routerlist_find_elt(rl->old_routers, sd, idx);
   if (idx < 0)
     return;
   smartlist_del(rl->old_routers, idx);
-  ri_tmp = digestmap_remove(rl->desc_digest_map,
-                            ri->signed_descriptor_digest);
-  tor_assert(ri_tmp == ri);
-  routerinfo_free(ri);
+  sd_tmp = digestmap_remove(rl->desc_digest_map,
+                            sd->signed_descriptor_digest);
+  tor_assert(sd_tmp == sd);
+  signed_descriptor_free(sd);
   routerlist_assert_ok(rl);
 }
 
@@ -1205,21 +1222,23 @@
     routerlist_insert(rl, ri_new);
     return;
   }
-  if (memcmp(ri_old->identity_digest, ri_new->identity_digest, DIGEST_LEN)) {
+  if (memcmp(ri_old->cache_info.identity_digest, ri_new->cache_info.identity_digest, DIGEST_LEN)) {
     /* digests don't match; digestmap_set won't replace */
-    digestmap_remove(rl->identity_map, ri_old->identity_digest);
+    digestmap_remove(rl->identity_map, ri_old->cache_info.identity_digest);
   }
-  digestmap_set(rl->identity_map, ri_new->identity_digest, ri_new);
-  digestmap_set(rl->desc_digest_map, ri_new->signed_descriptor_digest, ri_new);
+  digestmap_set(rl->identity_map, ri_new->cache_info.identity_digest, ri_new);
+  digestmap_set(rl->desc_digest_map, ri_new->cache_info.signed_descriptor_digest, &(ri_new->cache_info));
 
   if (make_old && get_options()->DirPort) {
-    smartlist_add(rl->old_routers, ri_old);
+    signed_descriptor_t *sd = signed_descriptor_from_routerinfo(ri_old);
+    smartlist_add(rl->old_routers, sd);
+    digestmap_set(rl->desc_digest_map, sd->signed_descriptor_digest, sd);
   } else {
-    if (memcmp(ri_old->signed_descriptor_digest,
-               ri_new->signed_descriptor_digest,
+    if (memcmp(ri_old->cache_info.signed_descriptor_digest,
+               ri_new->cache_info.signed_descriptor_digest,
                DIGEST_LEN)) {
       /* digests don't match; digestmap_set didn't replace */
-      digestmap_remove(rl->desc_digest_map, ri_old->signed_descriptor_digest);
+      digestmap_remove(rl->desc_digest_map, ri_old->cache_info.signed_descriptor_digest);
     }
     routerinfo_free(ri_old);
   }
@@ -1376,11 +1395,11 @@
   /* XXXX NM If this assert doesn't trigger, we should remove the id_digest
    * local. */
   crypto_pk_get_digest(router->identity_pkey, id_digest);
-  tor_assert(!memcmp(id_digest, router->identity_digest, DIGEST_LEN));
+  tor_assert(!memcmp(id_digest, router->cache_info.identity_digest, DIGEST_LEN));
 
   /* Make sure that we haven't already got this exact descriptor. */
   if (digestmap_get(routerlist->desc_digest_map,
-                    router->signed_descriptor_digest)) {
+                    router->cache_info.signed_descriptor_digest)) {
     info(LD_DIR, "Dropping descriptor that we already have for router '%s'",
          router->nickname);
     *msg = "Router descriptor was not new.";
@@ -1411,7 +1430,8 @@
   for (i = 0; i < smartlist_len(routerlist->routers); ++i) {
     routerinfo_t *old_router = smartlist_get(routerlist->routers, i);
     if (!crypto_pk_cmp_keys(router->identity_pkey,old_router->identity_pkey)) {
-      if (router->published_on <= old_router->published_on) {
+      if (router->cache_info.published_on <=
+          old_router->cache_info.published_on) {
         /* Same key, but old */
         debug(LD_DIR, "Skipping not-new descriptor for router '%s'",
                router->nickname);
@@ -1446,8 +1466,8 @@
         }
         routerlist_replace(routerlist, old_router, router, i, 1);
         if (!from_cache)
-          router_append_to_journal(router->signed_descriptor,
-                                   router->signed_descriptor_len);
+          router_append_to_journal(router->cache_info.signed_descriptor,
+                                   router->cache_info.signed_descriptor_len);
         directory_set_dirty();
         *msg = unreachable ? "Dirserver believes your ORPort is unreachable" :
                authdir_verified ? "Verified server updated" :
@@ -1466,7 +1486,7 @@
          */
         connection_t *conn;
         while ((conn = connection_get_by_identity_digest(
-                                old_router->identity_digest, CONN_TYPE_OR))) {
+                      old_router->cache_info.identity_digest, CONN_TYPE_OR))) {
           // And LD_OR? XXXXNM
           info(LD_DIR,"Closing conn to router '%s'; there is now a named router with that name.",
                  old_router->nickname);
@@ -1487,8 +1507,8 @@
    * the list. */
   routerlist_insert(routerlist, router);
   if (!from_cache)
-    router_append_to_journal(router->signed_descriptor,
-                             router->signed_descriptor_len);
+    router_append_to_journal(router->cache_info.signed_descriptor,
+                             router->cache_info.signed_descriptor_len);
   directory_set_dirty();
   return 0;
 }
@@ -1499,7 +1519,7 @@
 _compare_old_routers_by_identity(const void **_a, const void **_b)
 {
   int i;
-  const routerinfo_t *r1 = *_a, *r2 = *_b;
+  const signed_descriptor_t *r1 = *_a, *r2 = *_b;
   if ((i = memcmp(r1->identity_digest, r2->identity_digest, DIGEST_LEN)))
     return i;
   return r1->published_on - r2->published_on;
@@ -1539,9 +1559,9 @@
   const char *ident;
   tor_assert(hi < smartlist_len(lst));
   tor_assert(lo <= hi);
-  ident = ((routerinfo_t*)smartlist_get(lst, lo))->identity_digest;
+  ident = ((signed_descriptor_t*)smartlist_get(lst, lo))->identity_digest;
   for (i = lo+1; i <= hi; ++i) {
-    routerinfo_t *r = smartlist_get(lst, i);
+    signed_descriptor_t *r = smartlist_get(lst, i);
     tor_assert(!memcmp(ident, r->identity_digest, DIGEST_LEN));
   }
 #endif
@@ -1551,19 +1571,18 @@
   if (n_extra <= 0)
     return;
 
-
   lifespans = tor_malloc_zero(sizeof(struct duration_idx_t)*n);
   rmv = tor_malloc_zero(sizeof(uint8_t)*n);
   /* Set lifespans to contain the lifespan and index of each server. */
   /* Set rmv[i-lo]=1 if we're going to remove a server for being too old. */
   for (i = lo; i <= hi; ++i) {
-    routerinfo_t *r = smartlist_get(lst, i);
-    routerinfo_t *r_next;
+    signed_descriptor_t *r = smartlist_get(lst, i);
+    signed_descriptor_t *r_next;
     lifespans[i-lo].idx = i;
     if (i < hi) {
       r_next = smartlist_get(lst, i+1);
       tor_assert(r->published_on <= r_next->published_on);
-      lifespans[i-lo].duration = r_next->published_on - r->published_on;
+      lifespans[i-lo].duration = (r_next->published_on - r->published_on);
     } else {
       r_next = NULL;
       lifespans[i-lo].duration = INT_MAX;
@@ -1616,7 +1635,7 @@
   /* Remove old members of routerlist->routers. */
   for (i = 0; i < smartlist_len(routerlist->routers); ++i) {
     router = smartlist_get(routerlist->routers, i);
-    if (router->published_on <= cutoff) {
+    if (router->cache_info.published_on <= cutoff) {
       /* Too old.  Remove it. */
       info(LD_DIR, "Forgetting obsolete (too old) routerinfo for router '%s'",
            router->nickname);
@@ -1638,7 +1657,7 @@
   /* Iterate through the list from back to front, so when we remove descriptors
    * we don't mess up groups we haven't gotten to. */
   for (i = smartlist_len(routerlist->old_routers)-1; i >= 0; --i) {
-    routerinfo_t *r = smartlist_get(routerlist->old_routers, i);
+    signed_descriptor_t *r = smartlist_get(routerlist->old_routers, i);
     if (!cur_id) {
       cur_id = r->identity_digest;
       hi = i;
@@ -1726,7 +1745,7 @@
 
   SMARTLIST_FOREACH(routers, routerinfo_t *, ri,
   {
-    base16_encode(fp, sizeof(fp), ri->identity_digest, DIGEST_LEN);
+    base16_encode(fp, sizeof(fp), ri->cache_info.identity_digest, DIGEST_LEN);
     if (requested_fingerprints) {
       if (smartlist_string_isin(requested_fingerprints, fp)) {
         smartlist_string_remove(requested_fingerprints, fp);
@@ -2486,7 +2505,7 @@
       if (ns->received_on + SELF_OPINION_INTERVAL < now)
         continue;
       ++n_recent;
-      if (!(rs = networkstatus_find_entry(ns, me->identity_digest)))
+      if (!(rs = networkstatus_find_entry(ns, me->cache_info.identity_digest)))
         continue;
       ++n_listing;
       if (rs->is_valid)
@@ -2830,8 +2849,8 @@
 
   SMARTLIST_FOREACH(routers, routerinfo_t *, router,
   {
-    rs = router_get_combined_status_by_digest(router->identity_digest);
-    ds = router_get_trusteddirserver_by_digest(router->identity_digest);
+    rs = router_get_combined_status_by_digest(router->cache_info.identity_digest);
+    ds = router_get_trusteddirserver_by_digest(router->cache_info.identity_digest);
 
     if (!rs)
       continue;
@@ -2852,9 +2871,9 @@
     } else {
       if (!router->xx_is_recognized) {
         router->xx_is_recognized = routerdesc_digest_is_recognized(
-                router->identity_digest, router->signed_descriptor_digest);
+                router->cache_info.identity_digest, router->cache_info.signed_descriptor_digest);
       }
-      router->xx_is_extra_new = router->published_on > rs->status.published_on;
+      router->xx_is_extra_new = router->cache_info.published_on > rs->status.published_on;
     }
     if (reset_failures && router->xx_is_recognized) {
       rs->n_download_failures = 0;
@@ -2943,7 +2962,7 @@
     SMARTLIST_FOREACH(routerlist->routers, routerinfo_t *, ri,
     {
       local_routerstatus_t *rs;
-      if (!(rs = router_get_combined_status_by_digest(ri->identity_digest)) ||
+      if (!(rs = router_get_combined_status_by_digest(ri->cache_info.identity_digest)) ||
           !rs->should_download) {
         // log_fn(LOG_NOTICE, "No status for %s", fp);
         continue;
@@ -2959,16 +2978,16 @@
       /* Change this "or" to be an "and" once dirs generate hashes right.
        * Remove the version check once older versions are uncommon.
        * XXXXX. NM */
-      if (!memcmp(ri->signed_descriptor_digest, rs->status.descriptor_digest,
+      if (!memcmp(ri->cache_info.signed_descriptor_digest, rs->status.descriptor_digest,
                   DIGEST_LEN) ||
-          rs->status.published_on <= ri->published_on) {
+          rs->status.published_on <= ri->cache_info.published_on) {
         ++n_uptodate;
         rs->should_download = 0;
         --n_downloadable;
       } else if (!mirror &&
                  ri->platform &&
                  !tor_version_as_new_as(ri->platform, "0.1.1.6-alpha") &&
-                 ri->published_on + MAX_OLD_SERVER_DOWNLOAD_RATE > now)  {
+                 ri->cache_info.published_on + MAX_OLD_SERVER_DOWNLOAD_RATE > now)  {
         /* Same digest, or date is up-to-date, or we have a comparatively recent
          * server with an old version.
          * No need to download it. */
@@ -2985,7 +3004,7 @@
         format_iso_time(t2, ri->published_on);
         log_fn(LOG_NOTICE, "Out-of-date status for %s %s (%d %d) [%s %s]", fp,
                ri->nickname,
-               !memcmp(ri->signed_descriptor_digest,rs->status.descriptor_digest,
+               !memcmp(ri->cache_info.signed_descriptor_digest,rs->status.descriptor_digest,
                        DIGEST_LEN),
                rs->published_on < ri->published_on,
                t1, t2);
@@ -3157,7 +3176,7 @@
     return 0;
 
   /* r1 should be the one that was published first. */
-  if (r1->published_on > r2->published_on) {
+  if (r1->cache_info.published_on > r2->cache_info.published_on) {
     routerinfo_t *ri_tmp = r2;
     r2 = r1;
     r1 = ri_tmp;
@@ -3197,12 +3216,12 @@
     return 0;
 
   /* Did more than 12 hours pass? */
-  if (r1->published_on + 12*60*60 < r2->published_on)
+  if (r1->cache_info.published_on + 12*60*60 < r2->cache_info.published_on)
     return 0;
 
   /* Did uptime fail to increase by approximately the amount we would think,
    * give or take 30 minutes? */
-  if (abs(r2->uptime - (r1->uptime + (r2->published_on-r1->published_on)))>30*60)
+  if (abs(r2->uptime - (r1->uptime + (r2->cache_info.published_on-r1->cache_info.published_on)))>30*60)
     return 0;
 
   /* Otherwise, the difference is cosmetic. */
@@ -3214,21 +3233,22 @@
 {
   digestmap_iter_t *iter;
   routerinfo_t *r2;
+  signed_descriptor_t *sd2;
   if (!routerlist)
     return;
   SMARTLIST_FOREACH(rl->routers, routerinfo_t *, r,
   {
-    r2 = digestmap_get(rl->identity_map, r->identity_digest);
-    tor_assert(r == r2);
-    r2 = digestmap_get(rl->desc_digest_map, r->signed_descriptor_digest);
+    r2 = digestmap_get(rl->identity_map, r->cache_info.identity_digest);
     tor_assert(r == r2);
+    sd2 = digestmap_get(rl->desc_digest_map, r->cache_info.signed_descriptor_digest);
+    tor_assert(&(r->cache_info) == sd2);
   });
-  SMARTLIST_FOREACH(rl->old_routers, routerinfo_t *, r,
+  SMARTLIST_FOREACH(rl->old_routers, signed_descriptor_t *, sd,
   {
-    r2 = digestmap_get(rl->identity_map, r->identity_digest);
-    tor_assert(r != r2);
-    r2 = digestmap_get(rl->desc_digest_map, r->signed_descriptor_digest);
-    tor_assert(r == r2);
+    r2 = digestmap_get(rl->identity_map, sd->identity_digest);
+    tor_assert(sd != &(r2->cache_info));
+    sd2 = digestmap_get(rl->desc_digest_map, sd->signed_descriptor_digest);
+    tor_assert(sd == sd2);
   });
   iter = digestmap_iter_init(rl->identity_map);
   while (!digestmap_iter_done(iter)) {
@@ -3237,17 +3257,17 @@
     routerinfo_t *r;
     digestmap_iter_get(iter, &d, &_r);
     r = _r;
-    tor_assert(!memcmp(r->identity_digest, d, DIGEST_LEN));
+    tor_assert(!memcmp(r->cache_info.identity_digest, d, DIGEST_LEN));
     iter = digestmap_iter_next(rl->identity_map, iter);
   }
   iter = digestmap_iter_init(rl->desc_digest_map);
   while (!digestmap_iter_done(iter)) {
     const char *d;
-    void *_r;
-    routerinfo_t *r;
-    digestmap_iter_get(iter, &d, &_r);
-    r = _r;
-    tor_assert(!memcmp(r->signed_descriptor_digest, d, DIGEST_LEN));
+    void *_sd;
+    signed_descriptor_t *sd;
+    digestmap_iter_get(iter, &d, &_sd);
+    sd = _sd;
+    tor_assert(!memcmp(sd->signed_descriptor_digest, d, DIGEST_LEN));
     iter = digestmap_iter_next(rl->desc_digest_map, iter);
   }
 }

Index: routerparse.c
===================================================================
RCS file: /home/or/cvsroot/tor/src/or/routerparse.c,v
retrieving revision 1.158
retrieving revision 1.159
diff -u -d -r1.158 -r1.159
--- routerparse.c	28 Oct 2005 15:56:19 -0000	1.158
+++ routerparse.c	5 Nov 2005 20:15:27 -0000	1.159
@@ -743,9 +743,9 @@
   }
 
   router = tor_malloc_zero(sizeof(routerinfo_t));
-  router->signed_descriptor = tor_strndup(s, end-s);
-  router->signed_descriptor_len = end-s;
-  memcpy(router->signed_descriptor_digest, digest, DIGEST_LEN);
+  router->cache_info.signed_descriptor = tor_strndup(s, end-s);
+  router->cache_info.signed_descriptor_len = end-s;
+  memcpy(router->cache_info.signed_descriptor_digest, digest, DIGEST_LEN);
   ports_set = bw_set = 0;
 
   if (tok->n_args == 2 || tok->n_args == 5 || tok->n_args == 6) {
@@ -822,7 +822,7 @@
     warn(LD_DIR, "Missing published time"); goto err;
   }
   tor_assert(tok->n_args == 1);
-  if (parse_iso_time(tok->args[0], &router->published_on) < 0)
+  if (parse_iso_time(tok->args[0], &router->cache_info.published_on) < 0)
     goto err;
 
   if (!(tok = find_first_by_keyword(tokens, K_ONION_KEY))) {
@@ -846,7 +846,8 @@
   }
   router->identity_pkey = tok->key;
   tok->key = NULL; /* Prevent free */
-  if (crypto_pk_get_digest(router->identity_pkey,router->identity_digest)) {
+  if (crypto_pk_get_digest(router->identity_pkey,
+                           router->cache_info.identity_digest)) {
     warn(LD_DIR, "Couldn't calculate key digest"); goto err;
   }
 

Index: test.c
===================================================================
RCS file: /home/or/cvsroot/tor/src/or/test.c,v
retrieving revision 1.210
retrieving revision 1.211
diff -u -d -r1.210 -r1.211
--- test.c	25 Oct 2005 18:01:01 -0000	1.210
+++ test.c	5 Nov 2005 20:15:27 -0000	1.211
@@ -1187,7 +1187,7 @@
   memset(&r2,0,sizeof(r2));
   r1.address = tor_strdup("18.244.0.1");
   r1.addr = 0xc0a80001u; /* 192.168.0.1 */
-  r1.published_on = 0;
+  r1.cache_info.published_on = 0;
   r1.or_port = 9000;
   r1.dir_port = 9003;
   r1.onion_pkey = pk1;
@@ -1213,7 +1213,7 @@
   r2.address = tor_strdup("1.1.1.1");
   r2.addr = 0x0a030201u; /* 10.3.2.1 */
   r2.platform = tor_strdup(platform);
-  r2.published_on = 5;
+  r2.cache_info.published_on = 5;
   r2.or_port = 9005;
   r2.dir_port = 0;
   r2.onion_pkey = pk2;
@@ -1314,8 +1314,8 @@
     add_fingerprint_to_dir("Fred", buf, fingerprint_list);
   }
   /* Make sure routers aren't too far in the past any more. */
-  r1.published_on = time(NULL);
-  r2.published_on = time(NULL)-3*60*60;
+  r1.cache_info.published_on = time(NULL);
+  r2.cache_info.published_on = time(NULL)-3*60*60;
   test_assert(router_dump_router_to_string(buf, 2048, &r1, pk2)>0);
   test_eq(dirserv_add_descriptor(buf,&m), 2);
   test_assert(router_dump_router_to_string(buf, 2048, &r2, pk1)>0);