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

[or-cvs] r9970: Code to generate extrainfo whenever routerdesc is regenerate (in tor/trunk: . src/or)



Author: nickm
Date: 2007-04-16 13:55:08 -0400 (Mon, 16 Apr 2007)
New Revision: 9970

Modified:
   tor/trunk/
   tor/trunk/src/or/or.h
   tor/trunk/src/or/router.c
   tor/trunk/src/or/routerlist.c
   tor/trunk/src/or/routerparse.c
   tor/trunk/src/or/test.c
Log:
 r12403@catbus:  nickm | 2007-04-16 13:55:03 -0400
 Code to generate extrainfo whenever routerdesc is regenerated; code to check extrainfo against routerdesc.



Property changes on: tor/trunk
___________________________________________________________________
 svk:merge ticket from /tor/trunk [r12403] on 8246c3cf-6607-4228-993b-4d95d33730f1

Modified: tor/trunk/src/or/or.h
===================================================================
--- tor/trunk/src/or/or.h	2007-04-16 16:33:46 UTC (rev 9969)
+++ tor/trunk/src/or/or.h	2007-04-16 17:55:08 UTC (rev 9970)
@@ -2892,6 +2892,7 @@
 void router_new_address_suggestion(const char *suggestion);
 int router_compare_to_my_exit_policy(edge_connection_t *conn);
 routerinfo_t *router_get_my_routerinfo(void);
+const char *router_get_my_extrainfo(void);
 const char *router_get_my_descriptor(void);
 int router_digest_is_me(const char *digest);
 int router_is_me(routerinfo_t *router);
@@ -2900,6 +2901,8 @@
 int router_rebuild_descriptor(int force);
 int router_dump_router_to_string(char *s, size_t maxlen, routerinfo_t *router,
                                  crypto_pk_env_t *ident_key);
+int extrainfo_dump_to_string(char *s, size_t maxlen, extrainfo_t *extrainfo,
+                             crypto_pk_env_t *ident_key);
 int is_legal_nickname(const char *s);
 int is_legal_nickname_or_hexdigest(const char *s);
 int is_legal_hexdigest(const char *s);
@@ -3048,6 +3051,7 @@
 void router_reset_descriptor_download_failures(void);
 void router_reset_status_download_failures(void);
 int router_differences_are_cosmetic(routerinfo_t *r1, routerinfo_t *r2);
+int routerinfo_incompatible_with_extrainfo(routerinfo_t *ri, extrainfo_t *ei);
 const char *esc_router_info(routerinfo_t *router);
 
 char *networkstatus_getinfo_helper_single(routerstatus_t *rs);

Modified: tor/trunk/src/or/router.c
===================================================================
--- tor/trunk/src/or/router.c	2007-04-16 16:33:46 UTC (rev 9969)
+++ tor/trunk/src/or/router.c	2007-04-16 17:55:08 UTC (rev 9970)
@@ -710,6 +710,8 @@
 
 /** My routerinfo. */
 static routerinfo_t *desc_routerinfo = NULL;
+/** DOCDOC */
+static extrainfo_t *desc_extrainfo = NULL;
 /** Since when has our descriptor been "clean"?  0 if we need to regenerate it
  * now. */
 static time_t desc_clean_since = 0;
@@ -812,6 +814,17 @@
   return body;
 }
 
+/** DOCDOC */
+const char *
+router_get_my_extrainfo(void)
+{
+  if (!server_mode(get_options()))
+    return NULL;
+  if (router_rebuild_descriptor(0))
+    return NULL;
+  return desc_extrainfo->cache_info.signed_descriptor_body;
+}
+
 /** A list of nicknames that we've warned about including in our family
  * declaration verbatim rather than as digests. */
 static smartlist_t *warned_nonexistent_family = NULL;
@@ -839,11 +852,13 @@
 /** If <b>force</b> is true, or our descriptor is out-of-date, rebuild
  * a fresh routerinfo and signed server descriptor for this OR.
  * Return 0 on success, -1 on temporary error.
+ * DOCDOC extrainfo.
  */
 int
 router_rebuild_descriptor(int force)
 {
   routerinfo_t *ri;
+  extrainfo_t *ei;
   uint32_t addr;
   char platform[256];
   int hibernating = we_are_hibernating();
@@ -946,6 +961,27 @@
 
     smartlist_free(family);
   }
+
+  /* Now generate the extrainfo. */
+  ei = tor_malloc_zero(sizeof(extrainfo_t));
+  strlcpy(ei->nickname, get_options()->Nickname, sizeof(ei->nickname));
+  ei->cache_info.published_on = ri->cache_info.published_on;
+  memcpy(ei->cache_info.identity_digest, ri->cache_info.identity_digest,
+         DIGEST_LEN);
+  ei->cache_info.signed_descriptor_body = tor_malloc(8192);
+  if (extrainfo_dump_to_string(ei->cache_info.signed_descriptor_body, 8192,
+                               ei, get_identity_key()) < 0) {
+    log_warn(LD_BUG, "Couldn't generate extra-info descriptor.");
+    return -1;
+  }
+  ei->cache_info.signed_descriptor_len =
+    strlen(ei->cache_info.signed_descriptor_body);
+  router_get_extrainfo_hash(ei->cache_info.signed_descriptor_body,
+                            ei->cache_info.signed_descriptor_digest);
+
+  /* Now finish the router descriptor. */
+  memcpy(ri->extra_info_digest, ei->cache_info.signed_descriptor_digest,
+         DIGEST_LEN);
   ri->cache_info.signed_descriptor_body = tor_malloc(8192);
   if (router_dump_router_to_string(ri->cache_info.signed_descriptor_body, 8192,
                                    ri, get_identity_key())<0) {
@@ -954,13 +990,19 @@
   }
   ri->cache_info.signed_descriptor_len =
     strlen(ri->cache_info.signed_descriptor_body);
+  /* XXXX020 router_get_router_hash??? */
   crypto_digest(ri->cache_info.signed_descriptor_digest,
                 ri->cache_info.signed_descriptor_body,
                 ri->cache_info.signed_descriptor_len);
 
+  tor_assert(! routerinfo_incompatible_with_extrainfo(ri, ei));
+
   if (desc_routerinfo)
     routerinfo_free(desc_routerinfo);
   desc_routerinfo = ri;
+  if (desc_extrainfo)
+    extrainfo_free(desc_extrainfo);
+  desc_extrainfo = ei;
 
   desc_clean_since = time(NULL);
   desc_needs_upload = 1;
@@ -1161,17 +1203,13 @@
   char digest[DIGEST_LEN];
   char published[ISO_TIME_LEN+1];
   char fingerprint[FINGERPRINT_LEN+1];
+  char extra_info_digest[HEX_DIGEST_LEN+1];
   size_t onion_pkeylen, identity_pkeylen;
   size_t written;
   int result=0;
   addr_policy_t *tmpe;
   char *bandwidth_usage;
   char *family_line;
-#ifdef DEBUG_ROUTER_DUMP_ROUTER_TO_STRING
-  char *s_dup;
-  const char *cp;
-  routerinfo_t *ri_tmp;
-#endif
   or_options_t *options = get_options();
 
   /* Make sure the identity key matches the one in the routerinfo. */
@@ -1219,6 +1257,9 @@
     family_line = tor_strdup("");
   }
 
+  base16_encode(extra_info_digest, sizeof(extra_info_digest),
+                router->extra_info_digest, DIGEST_LEN);
+
   /* Generate the easy portion of the router descriptor. */
   result = tor_snprintf(s, maxlen,
                     "router %s %s %d 0 %d\n"
@@ -1227,6 +1268,7 @@
                     "opt fingerprint %s\n"
                     "uptime %ld\n"
                     "bandwidth %d %d %d\n"
+                    "opt extra-info-digest %s\n"
                     "onion-key\n%s"
                     "signing-key\n%s"
                     "%s%s%s",
@@ -1241,6 +1283,7 @@
     (int) router->bandwidthrate,
     (int) router->bandwidthburst,
     (int) router->bandwidthcapacity,
+    extra_info_digest,
     onion_pkey, identity_pkey,
     family_line, bandwidth_usage,
     we_are_hibernating() ? "opt hibernating 1\n" : "");
@@ -1319,21 +1362,78 @@
   s[written+1] = 0;
 
 #ifdef DEBUG_ROUTER_DUMP_ROUTER_TO_STRING
-  cp = s_dup = tor_strdup(s);
-  ri_tmp = router_parse_entry_from_string(cp, NULL, 1);
-  if (!ri_tmp) {
-    log_err(LD_BUG,
-            "We just generated a router descriptor we can't parse.");
-    log_err(LD_BUG, "Descriptor was: <<%s>>", s);
-    return -1;
+  {
+    char *s_dup;
+    const char *cp;
+    routerinfo_t *ri_tmp;
+    cp = s_dup = tor_strdup(s);
+    ri_tmp = router_parse_entry_from_string(cp, NULL, 1);
+    if (!ri_tmp) {
+      log_err(LD_BUG,
+              "We just generated a router descriptor we can't parse.");
+      log_err(LD_BUG, "Descriptor was: <<%s>>", s);
+      return -1;
+    }
+    tor_free(s_dup);
+    routerinfo_free(ri_tmp);
   }
-  tor_free(s_dup);
-  routerinfo_free(ri_tmp);
 #endif
 
   return written+1;
 }
 
+/** DOCDOC */
+int
+extrainfo_dump_to_string(char *s, size_t maxlen, extrainfo_t *extrainfo,
+                         crypto_pk_env_t *ident_key)
+{
+  char identity[HEX_DIGEST_LEN+1];
+  char published[ISO_TIME_LEN+1];
+  char digest[DIGEST_LEN];
+  char *bandwidth_usage;
+  int result;
+  size_t len;
+
+  base16_encode(identity, sizeof(identity),
+                extrainfo->cache_info.identity_digest, DIGEST_LEN);
+  format_iso_time(published, extrainfo->cache_info.published_on);
+  bandwidth_usage = rep_hist_get_bandwidth_lines();
+
+  result = tor_snprintf(s, maxlen,
+                        "extra-info %s %s\n"
+                        "published %s\n%s"
+                        "router-signature\n",
+                        extrainfo->nickname, identity,
+                        published, bandwidth_usage);
+  tor_free(bandwidth_usage);
+  if (result<0)
+    return -1;
+  len = strlen(s);
+  if (router_get_extrainfo_hash(s, digest)<0)
+    return -1;
+  if (router_append_dirobj_signature(s+len, maxlen-len, digest, ident_key)<0)
+    return -1;
+
+#ifdef DEBUG_ROUTER_DUMP_ROUTER_TO_STRING
+  {
+    char *cp, *s_dup;
+    extrainfo_t *ei_tmp;
+    cp = s_dup = tor_strdup(s);
+    ei_tmp = extrainfo_parse_entry_from_string(cp, NULL, 1, NULL);
+    if (!ei_tmp) {
+      log_err(LD_BUG,
+              "We just generated an extrainfo descriptor we can't parse.");
+      log_err(LD_BUG, "Descriptor was: <<%s>>", s);
+      return -1;
+    }
+    tor_free(s_dup);
+    extrainfo_free(ei_tmp);
+  }
+#endif
+
+  return strlen(s)+1;
+}
+
 /** Return true iff <b>s</b> is a legally valid server nickname. */
 int
 is_legal_nickname(const char *s)
@@ -1420,6 +1520,9 @@
     tor_mutex_free(key_lock);
   if (desc_routerinfo)
     routerinfo_free(desc_routerinfo);
+  if (desc_extrainfo)
+    extrainfo_free(desc_extrainfo);
+
   if (warned_nonexistent_family) {
     SMARTLIST_FOREACH(warned_nonexistent_family, char *, cp, tor_free(cp));
     smartlist_free(warned_nonexistent_family);

Modified: tor/trunk/src/or/routerlist.c
===================================================================
--- tor/trunk/src/or/routerlist.c	2007-04-16 16:33:46 UTC (rev 9969)
+++ tor/trunk/src/or/routerlist.c	2007-04-16 17:55:08 UTC (rev 9970)
@@ -4422,6 +4422,37 @@
   return 1;
 }
 
+/** DOCDOC */
+int
+routerinfo_incompatible_with_extrainfo(routerinfo_t *ri, extrainfo_t *ei)
+{
+  tor_assert(ri);
+  tor_assert(ei);
+
+  if (strcmp(ri->nickname, ei->nickname) ||
+      memcmp(ri->cache_info.identity_digest, ei->cache_info.identity_digest,
+             DIGEST_LEN))
+    return 1; /* different servers */
+
+  if (ei->pending_sig) {
+    char signed_digest[128];
+    if (crypto_pk_public_checksig(ri->identity_pkey, signed_digest,
+                                  ei->pending_sig, 128) != 20 ||
+        memcmp(signed_digest, ei->cache_info.signed_descriptor_digest,
+               DIGEST_LEN))
+      return 1; /* Bad signature, or no match. */
+
+    tor_free(ei->pending_sig);
+  }
+
+  if (ei->cache_info.published_on < ei->cache_info.published_on)
+    return 1;
+  else if (ei->cache_info.published_on > ei->cache_info.published_on)
+    return -1;
+
+  return 0;
+}
+
 /** Generate networkstatus lines for a single routerstatus_t object, and
  * return the result in a newly allocated string.  Used only by controller
  * interface (for now.) */

Modified: tor/trunk/src/or/routerparse.c
===================================================================
--- tor/trunk/src/or/routerparse.c	2007-04-16 16:33:46 UTC (rev 9969)
+++ tor/trunk/src/or/routerparse.c	2007-04-16 17:55:08 UTC (rev 9970)
@@ -835,7 +835,6 @@
   router->cache_info.signed_descriptor_len = end-s;
   memcpy(router->cache_info.signed_descriptor_digest, digest, DIGEST_LEN);
 
-
   router->nickname = tor_strdup(tok->args[0]);
   if (!is_legal_nickname(router->nickname)) {
     log_warn(LD_DIR,"Router nickname is invalid");
@@ -1070,6 +1069,7 @@
     extrainfo->cache_info.signed_descriptor_body = tor_strndup(s, end-s);
   extrainfo->cache_info.signed_descriptor_len = end-s;
   memcpy(extrainfo->cache_info.signed_descriptor_digest, digest, DIGEST_LEN);
+
   tor_assert(tok->n_args >= 2);
   if (!is_legal_nickname(tok->args[0])) {
     log_warn(LD_DIR,"Bad nickname %s on \"extra-info\"",escaped(tok->args[0]));

Modified: tor/trunk/src/or/test.c
===================================================================
--- tor/trunk/src/or/test.c	2007-04-16 16:33:46 UTC (rev 9969)
+++ tor/trunk/src/or/test.c	2007-04-16 17:55:08 UTC (rev 9970)
@@ -1743,6 +1743,7 @@
    * uptime, that still wouldn't make it right, because the two
    * descriptors might be made on different seconds... hm. */
          "bandwidth 1000 5000 10000\n"
+          "opt extra-info-digest 0000000000000000000000000000000000000000\n"
           "onion-key\n", sizeof(buf2));
   strlcat(buf2, pk1_str, sizeof(buf2));
   strlcat(buf2, "signing-key\n", sizeof(buf2));