[or-cvs] r10533: Refactor v3 vote generation code into "build a networkstatus (in tor/trunk: . src/or)

nickm at seul.org nickm at seul.org
Fri Jun 8 18:41:09 UTC 2007


Author: nickm
Date: 2007-06-08 14:41:09 -0400 (Fri, 08 Jun 2007)
New Revision: 10533

Modified:
   tor/trunk/
   tor/trunk/src/or/dirserv.c
   tor/trunk/src/or/dirvote.c
   tor/trunk/src/or/or.h
   tor/trunk/src/or/routerparse.c
Log:
 r13313 at catbus:  nickm | 2007-06-08 14:23:11 -0400
 Refactor v3 vote generation code into "build a networkstatus_vote_t" and "format a networkstatus_vote_t".  This should make testing possible.



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

Modified: tor/trunk/src/or/dirserv.c
===================================================================
--- tor/trunk/src/or/dirserv.c	2007-06-08 10:51:06 UTC (rev 10532)
+++ tor/trunk/src/or/dirserv.c	2007-06-08 18:41:09 UTC (rev 10533)
@@ -1556,11 +1556,31 @@
   smartlist_free(bandwidths_excluding_exits);
 }
 
+/** DOCDOC */
+static char *
+version_from_platform(const char *platform)
+{
+  if (platform && !strcmpstart(platform, "Tor ")) {
+    const char *eos = find_whitespace(platform+4);
+    if (eos && !strcmpstart(eos, " (r")) {
+      /* XXXX020 Unify this logic with the other version extraction
+       * logic */
+      eos = find_whitespace(eos+1);
+    }
+    if (eos) {
+      return tor_strndup(platform, eos-platform);
+    }
+  }
+  return NULL;
+}
+
+
 /** Helper: write the router-status information in <b>rs</b> into <b>buf</b>,
  * which has at least <b>buf_len</b> free characters.  Do NUL-termination.
  * Use the same format as in network-status documents.  If <b>platform</b> is
  * non-NULL, add a "v" line for the platform.  Return 0 on success, -1 on
- * failure. */
+ * failure.
+ * DOCDOC new arguments */
 int
 routerstatus_format_entry(char *buf, size_t buf_len,
                           routerstatus_t *rs, const char *platform,
@@ -1569,6 +1589,7 @@
   int r;
   struct in_addr in;
   char *cp;
+  char *v;
 
   int f_authority;
   char published[ISO_TIME_LEN+1];
@@ -1617,25 +1638,14 @@
     log_warn(LD_BUG, "Not enough space in buffer.");
     return -1;
   }
-  if (platform && !strcmpstart(platform, "Tor ")) {
-    const char *eos = find_whitespace(platform+4);
-    if (eos && !strcmpstart(eos, " (r")) {
-      /* XXXX020 Unify this logic with the other version extraction
-       * logic */
-      eos = find_whitespace(eos+1);
+
+  if (platform && (v = version_from_platform(platform))) {
+    if (tor_snprintf(buf, buf_len, "opt v %s\n", v)<0) {
+      tor_free(v);
+      log_warn(LD_BUG, "Unable to print router version.");
+      return -1;
     }
-    if (eos) {
-      char *p = tor_strndup(platform, eos-platform);
-      size_t ln = strlen(buf);
-      buf += ln;
-      buf_len -= ln;
-      if (tor_snprintf(buf, buf_len, "opt v %s\n", p)<0) {
-        tor_free(p);
-        log_warn(LD_BUG, "Unable to print router version.");
-        return -1;
-      }
-      tor_free(p);
-    }
+    tor_free(v);
   }
 
   return 0;
@@ -1652,6 +1662,379 @@
                 DIGEST_LEN);
 }
 
+/** DOCDOC */
+static void
+set_routerstatus_from_routerinfo(routerstatus_t *rs,
+                                 routerinfo_t *ri, time_t now,
+                                 int naming, int exits_can_be_guards,
+                                 int listbadexits)
+{
+  int unstable_version =
+    tor_version_as_new_as(ri->platform,"0.1.1.10-alpha") &&
+    !tor_version_as_new_as(ri->platform,"0.1.1.16-rc-cvs");
+  memset(rs, 0, sizeof(routerstatus_t));
+
+  /* Already set by compute_performance_thresholds. */
+  rs->is_exit = ri->is_exit;
+  rs->is_stable = ri->is_stable =
+    router_is_active(ri, now) &&
+    !dirserv_thinks_router_is_unreliable(now, ri, 1, 0) &&
+    !unstable_version;
+  rs->is_fast = ri->is_fast =
+    router_is_active(ri, now) &&
+    !dirserv_thinks_router_is_unreliable(now, ri, 0, 1);
+  rs->is_running = ri->is_running; /* computed above */
+  /*
+    int f_authority = router_digest_is_trusted_dir(
+    ri->cache_info.identity_digest);
+  */
+  rs->is_named = naming && ri->is_named;
+  rs->is_valid = ri->is_valid;
+  rs->is_possible_guard = rs->is_fast && rs->is_stable &&
+    (!rs->is_exit || exits_can_be_guards) &&
+    router_get_advertised_bandwidth(ri) >=
+    (exits_can_be_guards ? guard_bandwidth_including_exits :
+     guard_bandwidth_excluding_exits);
+  rs->is_bad_exit = listbadexits && ri->is_bad_exit;
+  /* 0.1.1.9-alpha is the first version to support fetch by descriptor
+   * hash. */
+  rs->is_v2_dir = ri->dir_port &&
+    tor_version_as_new_as(ri->platform,"0.1.1.9-alpha");
+
+  if (!strcasecmp(ri->nickname, UNNAMED_ROUTER_NICKNAME))
+    rs->is_named = 0;
+
+  rs->published_on = ri->cache_info.published_on;
+  memcpy(rs->identity_digest, ri->cache_info.identity_digest, DIGEST_LEN);
+  memcpy(rs->descriptor_digest, ri->cache_info.signed_descriptor_digest,
+         DIGEST_LEN);
+  rs->addr = ri->addr;
+  strlcpy(rs->nickname, ri->nickname, sizeof(rs->nickname));
+  rs->or_port = ri->or_port;
+  rs->dir_port = ri->dir_port;
+}
+
+/** DOCDOC */
+static networkstatus_vote_t *
+generate_networkstatus_vote_obj(crypto_pk_env_t *private_key,
+                                authority_cert_t *cert)
+{
+  or_options_t *options = get_options();
+  networkstatus_vote_t *v3_out = NULL;
+  uint32_t addr;
+  char *hostname = NULL, *client_versions = NULL, *server_versions = NULL;
+  const char *contact;
+  smartlist_t *routers, *routerstatuses;
+  char identity_digest[DIGEST_LEN];
+  char signing_key_digest[DIGEST_LEN];
+  int naming = options->NamingAuthoritativeDir;
+  int listbadexits = options->AuthDirListBadExits;
+  int exits_can_be_guards;
+  routerlist_t *rl = router_get_routerlist();
+  time_t now = time(NULL);
+  time_t cutoff = now - ROUTER_MAX_AGE_TO_PUBLISH;
+  networkstatus_voter_info_t *voter = NULL;
+
+  /* check that everything is deallocated XXXX020 */
+
+  tor_assert(private_key);
+  tor_assert(cert);
+
+  if (resolve_my_address(LOG_WARN, options, &addr, &hostname)<0) {
+    log_warn(LD_NET, "Couldn't resolve my hostname");
+    return NULL;
+  }
+  if (crypto_pk_get_digest(private_key, signing_key_digest)<0) {
+    log_err(LD_BUG, "Error computing signing key digest");
+    return NULL;
+  }
+  if (crypto_pk_get_digest(cert->identity_key, identity_digest)<0) {
+    log_err(LD_BUG, "Error computing identity key digest");
+    return NULL;
+  }
+
+  if (options->VersioningAuthoritativeDir) {
+    client_versions = format_versions_list(options->RecommendedClientVersions);
+    server_versions = format_versions_list(options->RecommendedServerVersions);
+  }
+
+  contact = get_options()->ContactInfo;
+  if (!contact)
+    contact = "(none)";
+
+  /* precompute this part, since we need it to decide what "stable"
+   * means. */
+  SMARTLIST_FOREACH(rl->routers, routerinfo_t *, ri, {
+    ri->is_running = dirserv_thinks_router_is_reachable(ri, now);
+  });
+
+  dirserv_compute_performance_thresholds(rl);
+
+  /* XXXX We should take steps to keep this from oscillating if
+   * total_exit_bandwidth is close to total_bandwidth/3. */
+  exits_can_be_guards = total_exit_bandwidth >= (total_bandwidth / 3);
+
+  routers = smartlist_create();
+  smartlist_add_all(routers, rl->routers);
+  smartlist_sort(routers, _compare_routerinfo_by_id_digest);
+
+  routerstatuses = smartlist_create();
+
+  SMARTLIST_FOREACH(routers, routerinfo_t *, ri, {
+    if (ri->cache_info.published_on >= cutoff) {
+      routerstatus_t *rs;
+      vote_routerstatus_t *vrs;
+
+      vrs = tor_malloc_zero(sizeof(vote_routerstatus_t));
+      rs = &vrs->status;
+      set_routerstatus_from_routerinfo(rs, ri, now,
+                                       naming, exits_can_be_guards,
+                                       listbadexits);
+
+      vrs->version = version_from_platform(ri->platform);
+      smartlist_add(routerstatuses, vrs);
+    }
+  });
+  smartlist_free(routers);
+
+  tor_assert(v3_out);
+  memset(v3_out, 0, sizeof(networkstatus_vote_t));
+  v3_out->is_vote = 1;
+  v3_out->published = time(NULL);
+  v3_out->valid_after = time(NULL); /* XXXX020 not right. */
+  v3_out->fresh_until = time(NULL); /* XXXX020 not right. */
+  v3_out->valid_until = time(NULL); /* XXXX020 not right. */
+  v3_out->vote_seconds = 600; /* XXXX020 not right. */
+  v3_out->dist_seconds = 600; /* XXXX020 not right. */
+
+  v3_out->client_versions = client_versions;
+  v3_out->server_versions = server_versions;
+  v3_out->known_flags = smartlist_create();
+  smartlist_split_string(v3_out->known_flags,
+                "Authority Exit Fast Guard Running Stable Valid V2Dir",
+                0, SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 0);
+  if (listbadexits)
+    smartlist_add(v3_out->known_flags, tor_strdup("BadExit"));
+  if (naming)
+    smartlist_add(v3_out->known_flags, tor_strdup("Named"));
+  smartlist_sort_strings(v3_out->known_flags);
+
+  voter = tor_malloc_zero(sizeof(networkstatus_voter_info_t));
+  voter->nickname = tor_strdup(options->Nickname);
+  memcpy(voter->identity_digest, identity_digest, DIGEST_LEN);
+  voter->address = hostname;
+  voter->addr = addr;
+  voter->dir_port = options->DirPort;
+  voter->or_port = options->ORPort;
+  voter->contact = tor_strdup(contact);
+  memcpy(voter->signing_key_digest, signing_key_digest, DIGEST_LEN);
+  v3_out->voters = smartlist_create();
+  smartlist_add(v3_out->voters, voter);
+  v3_out->cert = authority_cert_dup(cert);
+  /* ????? networkstatus_digest is unset. */
+  v3_out->routerstatus_list = routerstatuses;
+
+  return v3_out;
+}
+
+static char *
+format_networkstatus_vote(crypto_pk_env_t *private_key,
+                          networkstatus_vote_t *v3_ns)
+{
+/** Longest status flag name that we generate. */
+#define LONGEST_STATUS_FLAG_NAME_LEN 9
+/** Maximum number of status flags we'll apply to one router. */
+#define N_STATUS_FLAGS 10
+/** Amount of space to allocate for each entry. (r line and s line.) */
+#define RS_ENTRY_LEN                                                    \
+  ( /* first line */                                                    \
+   MAX_NICKNAME_LEN+BASE64_DIGEST_LEN*2+ISO_TIME_LEN+INET_NTOA_BUF_LEN+ \
+   5*2 /* ports */ + 10 /* punctuation */ +                             \
+   /* second line */                                                    \
+   (LONGEST_STATUS_FLAG_NAME_LEN+1)*N_STATUS_FLAGS + 2)
+
+  size_t len;
+  char *status = NULL, *client_versions = NULL, *server_versions = NULL;
+  char *outp, *endp;
+  // or_options_t *options = get_options();
+  char fingerprint[FINGERPRINT_LEN+1];
+  char ipaddr[INET_NTOA_BUF_LEN];
+  char digest[DIGEST_LEN];
+  struct in_addr in;
+  uint32_t addr;
+  routerlist_t *rl = router_get_routerlist();
+  // time_t now = time(NULL);
+  // time_t cutoff = now - ROUTER_MAX_AGE_TO_PUBLISH;
+  /*
+  int naming = options->NamingAuthoritativeDir;
+  int listbadexits = options->AuthDirListBadExits;
+  int exits_can_be_guards;
+  */
+  char *version_lines = NULL;
+  networkstatus_voter_info_t *voter;
+  /* XXX check that everything gets freed */
+
+  tor_assert(private_key);
+
+  voter = smartlist_get(v3_ns->voters, 0);
+
+  addr = voter->addr;
+  in.s_addr = htonl(addr);
+  tor_inet_ntoa(&in, ipaddr, sizeof(ipaddr));
+
+  base16_encode(fingerprint, sizeof(fingerprint),
+                v3_ns->cert->cache_info.identity_digest, DIGEST_LEN);
+  client_versions = v3_ns->client_versions;
+  server_versions = v3_ns->server_versions;
+
+  if (client_versions || server_versions) {
+    size_t v_len = 64;
+    char *cp;
+    if (client_versions)
+      v_len += strlen(client_versions);
+    if (client_versions)
+      v_len += strlen(server_versions);
+    version_lines = tor_malloc(v_len);
+    cp = version_lines;
+    if (client_versions) {
+      tor_snprintf(cp, v_len-(cp-version_lines),
+                   "client-versions %s\n", client_versions);
+      cp += strlen(cp);
+    }
+    if (server_versions)
+      tor_snprintf(cp, v_len-(cp-version_lines),
+                   "server-versions %s\n", server_versions);
+  } else {
+    version_lines = tor_strdup("");
+  }
+
+  len = 8192;
+  len += strlen(version_lines);
+  len += (RS_ENTRY_LEN)*smartlist_len(rl->routers);
+  len += v3_ns->cert->cache_info.signed_descriptor_len;
+
+  status = tor_malloc(len);
+  {
+    char published[ISO_TIME_LEN+1];
+    char va[ISO_TIME_LEN+1];
+    char fu[ISO_TIME_LEN+1];
+    char vu[ISO_TIME_LEN+1];
+    char *flags = smartlist_join_strings(v3_ns->known_flags, " ", 0, NULL);
+    authority_cert_t *cert = v3_ns->cert;
+    format_iso_time(published, v3_ns->published);
+    format_iso_time(va, v3_ns->valid_after);
+    format_iso_time(fu, v3_ns->fresh_until);
+    format_iso_time(vu, v3_ns->valid_until);
+
+    tor_assert(cert);
+    tor_snprintf(status, len,
+                 "network-status-version 3\n"
+                 "vote-status vote\n"
+                 "published %s\n"
+                 "valid-after %s\n"
+                 "fresh-until %s\n"
+                 "valid-until %s\n"
+                 "%s" /* versions */
+                 "known-flags %s"
+                 "dir-source %s %s %s %s %d %d\n"
+                 "contact %s\n",
+                 published, va, fu, vu,
+                 version_lines,
+                 flags,
+                 voter->nickname, fingerprint, voter->address,
+                   ipaddr, voter->dir_port, voter->or_port, voter->contact);
+
+    tor_free(flags);
+    outp = status + strlen(status);
+    endp = status + len;
+    tor_assert(outp + cert->cache_info.signed_descriptor_len < endp);
+    memcpy(outp, cert->cache_info.signed_descriptor_body,
+           cert->cache_info.signed_descriptor_len);
+
+    outp += cert->cache_info.signed_descriptor_len;
+  }
+
+  SMARTLIST_FOREACH(v3_ns->routerstatus_list, vote_routerstatus_t *, vrs,
+  {
+    /* XXXX020 ri->platform!!!.  Also, version-from-platform. */
+    if (routerstatus_format_entry(outp, endp-outp, &vrs->status,
+                                  vrs->version, 0) < 0) {
+      log_warn(LD_BUG, "Unable to print router status.");
+      goto err;
+    }
+    outp += strlen(outp);
+  });
+
+  {
+    char signing_key_fingerprint[FINGERPRINT_LEN+1];
+    if (tor_snprintf(outp, endp-outp, "directory-signature ")<0) {
+      log_warn(LD_BUG, "Unable to start signature line.");
+      goto err;
+    }
+    outp += strlen(outp);
+
+    if (crypto_pk_get_fingerprint(private_key, signing_key_fingerprint, 0)<0) {
+      log_warn(LD_BUG, "Unable to get fingerprint for signing key");
+      goto err;
+    }
+    if (tor_snprintf(outp, endp-outp, "%s %s\n", fingerprint,
+                     signing_key_fingerprint)<0) {
+      log_warn(LD_BUG, "Unable to end signature line.");
+      goto err;
+    }
+    outp += strlen(outp);
+  }
+
+  note_crypto_pk_op(SIGN_DIR);
+  if (router_append_dirobj_signature(outp,endp-outp,digest,private_key)<0) {
+    log_warn(LD_BUG, "Unable to sign router status.");
+    goto err;
+  }
+
+  goto done;
+
+ err:
+  tor_free(status);
+ done:
+  tor_free(version_lines);
+  return status;
+}
+
+static cached_dir_t *
+generate_v3_networkstatus(void)
+{
+  crypto_pk_env_t *key = get_my_v3_authority_signing_key();
+  authority_cert_t *cert = get_my_v3_authority_cert();
+  networkstatus_vote_t *ns;
+  char *status;
+  time_t now = time(NULL);
+
+  if (!cert || !key) {
+    log_warn(LD_NET, "Didn't find key/certificate to generate v3 vote");
+    return NULL;
+  }
+
+  if (!(ns = generate_networkstatus_vote_obj(key, cert)))
+    return NULL;
+
+  status = format_networkstatus_vote(key, ns);
+  networkstatus_vote_free(ns);
+  if (!status)
+    return NULL;
+
+  {
+    cached_dir_t **ns_ptr =
+      &the_v3_networkstatus_vote;
+    if (*ns_ptr)
+      cached_dir_decref(*ns_ptr);
+    *ns_ptr = new_cached_dir(status, now);
+    status = NULL; /* So it doesn't get double-freed. */
+    router_set_networkstatus((*ns_ptr)->dir, now, NS_GENERATED, NULL);
+  }
+
+  return the_v3_networkstatus_vote;
+}
+
 /** For v2 and v3 authoritative directories only: If <b>v2</b> is set, replace
  * the contents of <b>the_v2_networkstatus</b> with a newly generated network
  * status object.  If <b>v2</b> is zero, replace the contents of
@@ -1693,21 +2076,14 @@
   int listbadexits = options->AuthDirListBadExits;
   int exits_can_be_guards;
   const char *contact;
-  authority_cert_t *cert = NULL;
   char *version_lines = NULL;
   smartlist_t *routers = NULL;
 
-  if (v2) {
-    private_key = get_identity_key();
-  } else {
-    private_key = get_my_v3_authority_signing_key();
-    cert = get_my_v3_authority_cert();
-    if (!private_key || !cert) {
-      log_warn(LD_NET, "Didn't find key/certificate to generate v3 vote");
-      goto done;
-    }
-  }
+  if (!v2)
+    return generate_v3_networkstatus();
 
+  private_key = get_identity_key();
+
   if (resolve_my_address(LOG_WARN, options, &addr, &hostname)<0) {
     log_warn(LD_NET, "Couldn't resolve my hostname");
     goto done;
@@ -1726,14 +2102,9 @@
     goto done;
   }
 
-  if (v2) {
-    if (crypto_pk_get_fingerprint(private_key, fingerprint, 0)<0) {
-      log_err(LD_BUG, "Error computing fingerprint");
-      goto done;
-    }
-  } else {
-    base16_encode(fingerprint, sizeof(fingerprint),
-                  cert->cache_info.identity_digest, DIGEST_LEN);
+  if (crypto_pk_get_fingerprint(private_key, fingerprint, 0)<0) {
+    log_err(LD_BUG, "Error computing fingerprint");
+    goto done;
   }
 
   contact = get_options()->ContactInfo;
@@ -1753,13 +2124,9 @@
   len = 4096+strlen(client_versions)+strlen(server_versions);
   len += identity_pkey_len*2;
   len += (RS_ENTRY_LEN)*smartlist_len(rl->routers);
-  if (!v2) {
-    len += cert->cache_info.signed_descriptor_len;
-  }
 
   status = tor_malloc(len);
-  if (v2) {
-    tor_snprintf(status, len,
+  tor_snprintf(status, len,
                "network-status-version 2\n"
                "dir-source %s %s %d\n"
                "fingerprint %s\n"
@@ -1777,38 +2144,8 @@
                versioning ? " Versions" : "",
                version_lines,
                identity_pkey);
-    outp = status + strlen(status);
-    endp = status + len;
-  } else {
-    tor_snprintf(status, len,
-                 "network-status-version 3\n"
-                 "vote-status vote\n"
-                 "published %s\n"
-                 "valid-after %s\n"
-                 "fresh-until %s\n"
-                 "valid-until %s\n"
-                 "%s" /* versions */
-                 "known-flags Authority%s Exit Fast Guard%s Running Stable "
-                               "Valid V2Dir\n"
-                 "dir-source %s %s %s %s %d %d\n"
-                 "contact %s\n",
-                 published,
-                 published, /* XXXX020 should be valid-after*/
-                 published, /* XXXX020 should be fresh-until*/
-                 published, /* XXXX020 should be valid-until*/
-                 version_lines,
-                 listbadexits ? " BadExit" : "",
-                 naming ? " Named" : "",
-                 options->Nickname, fingerprint, options->Address,
-                   ipaddr, (int)options->DirPort, (int)options->ORPort,
-                 contact);
-    outp = status + strlen(status);
-    endp = status + len;
-    tor_assert(outp + cert->cache_info.signed_descriptor_len < endp);
-    memcpy(outp, cert->cache_info.signed_descriptor_body,
-           cert->cache_info.signed_descriptor_len);
-    outp += cert->cache_info.signed_descriptor_len;
-  }
+  outp = status + strlen(status);
+  endp = status + len;
 
   /* precompute this part, since we need it to decide what "stable"
    * means. */
@@ -1830,52 +2167,11 @@
     if (ri->cache_info.published_on >= cutoff) {
 
       routerstatus_t rs;
-      /* These versions dump connections with idle live circuits
-         sometimes. D'oh!*/
-      int unstable_version =
-        tor_version_as_new_as(ri->platform,"0.1.1.10-alpha") &&
-        !tor_version_as_new_as(ri->platform,"0.1.1.16-rc-cvs");
-      memset(&rs, 0, sizeof(rs));
 
-      /* Already set by compute_performance_thresholds. */
-      rs.is_exit = ri->is_exit;
-      rs.is_stable = ri->is_stable =
-        router_is_active(ri, now) &&
-        !dirserv_thinks_router_is_unreliable(now, ri, 1, 0) &&
-        !unstable_version;
-      rs.is_fast = ri->is_fast =
-        router_is_active(ri, now) &&
-        !dirserv_thinks_router_is_unreliable(now, ri, 0, 1);
-      rs.is_running = ri->is_running; /* computed above */
-      /*
-      int f_authority = router_digest_is_trusted_dir(
-                                      ri->cache_info.identity_digest);
-      */
-      rs.is_named = naming && ri->is_named;
-      rs.is_valid = ri->is_valid;
-      rs.is_possible_guard = rs.is_fast && rs.is_stable &&
-        (!rs.is_exit || exits_can_be_guards) &&
-        router_get_advertised_bandwidth(ri) >=
-          (exits_can_be_guards ? guard_bandwidth_including_exits :
-                                 guard_bandwidth_excluding_exits);
-      rs.is_bad_exit = listbadexits && ri->is_bad_exit;
-      /* 0.1.1.9-alpha is the first version to support fetch by descriptor
-       * hash. */
-      rs.is_v2_dir = ri->dir_port &&
-        tor_version_as_new_as(ri->platform,"0.1.1.9-alpha");
+      set_routerstatus_from_routerinfo(&rs, ri, now,
+                                       naming, exits_can_be_guards,
+                                       listbadexits);
 
-      if (!strcasecmp(ri->nickname, UNNAMED_ROUTER_NICKNAME))
-        rs.is_named = 0;
-
-      rs.published_on = ri->cache_info.published_on;
-      memcpy(rs.identity_digest, ri->cache_info.identity_digest, DIGEST_LEN);
-      memcpy(rs.descriptor_digest, ri->cache_info.signed_descriptor_digest,
-             DIGEST_LEN);
-      rs.addr = ri->addr;
-      strlcpy(rs.nickname, ri->nickname, sizeof(rs.nickname));
-      rs.or_port = ri->or_port;
-      rs.dir_port = ri->dir_port;
-
       if (routerstatus_format_entry(outp, endp-outp, &rs,
                                     ri->platform, 0) < 0) {
         log_warn(LD_BUG, "Unable to print router status.");
@@ -1885,36 +2181,16 @@
     }
   });
 
-  if (v2) {
-    if (tor_snprintf(outp, endp-outp, "directory-signature %s\n",
-                     get_options()->Nickname)<0) {
-      log_warn(LD_BUG, "Unable to write signature line.");
-      goto done;
-    }
-    if (router_get_networkstatus_v2_hash(status, digest)<0) {
-      log_warn(LD_BUG, "Unable to hash network status");
-      goto done;
-    }
-    outp += strlen(outp);
-  } else {
-    char signing_key_fingerprint[FINGERPRINT_LEN+1];
-    if (tor_snprintf(outp, endp-outp, "directory-signature ")<0) {
-      log_warn(LD_BUG, "Unable to start signature line.");
-      goto done;
-    }
-    outp += strlen(outp);
-
-    if (crypto_pk_get_fingerprint(private_key, signing_key_fingerprint, 0)<0) {
-      log_warn(LD_BUG, "Unable to get fingerprint for signing key");
-      goto done;
-    }
-    if (tor_snprintf(outp, endp-outp, "%s %s\n", fingerprint,
-                     signing_key_fingerprint)<0) {
-      log_warn(LD_BUG, "Unable to end signature line.");
-      goto done;
-    }
-    outp += strlen(outp);
+  if (tor_snprintf(outp, endp-outp, "directory-signature %s\n",
+                   get_options()->Nickname)<0) {
+    log_warn(LD_BUG, "Unable to write signature line.");
+    goto done;
   }
+  if (router_get_networkstatus_v2_hash(status, digest)<0) {
+    log_warn(LD_BUG, "Unable to hash network status");
+    goto done;
+  }
+  outp += strlen(outp);
 
   note_crypto_pk_op(SIGN_DIR);
   if (router_append_dirobj_signature(outp,endp-outp,digest,private_key)<0) {
@@ -1923,14 +2199,12 @@
   }
 
   {
-    cached_dir_t **ns_ptr =
-      v2 ? &the_v2_networkstatus : &the_v3_networkstatus_vote;
+    cached_dir_t **ns_ptr = &the_v2_networkstatus;
     if (*ns_ptr)
       cached_dir_decref(*ns_ptr);
     *ns_ptr = new_cached_dir(status, now);
     status = NULL; /* So it doesn't get double-freed. */
-    if (v2)
-      the_v2_networkstatus_is_dirty = 0;
+    the_v2_networkstatus_is_dirty = 0;
     router_set_networkstatus((*ns_ptr)->dir, now, NS_GENERATED, NULL);
     r = *ns_ptr;
   }

Modified: tor/trunk/src/or/dirvote.c
===================================================================
--- tor/trunk/src/or/dirvote.c	2007-06-08 10:51:06 UTC (rev 10532)
+++ tor/trunk/src/or/dirvote.c	2007-06-08 18:41:09 UTC (rev 10533)
@@ -15,16 +15,14 @@
 void
 networkstatus_vote_free(networkstatus_vote_t *ns)
 {
-  int i;
   if (!ns)
     return;
 
   tor_free(ns->client_versions);
   tor_free(ns->server_versions);
   if (ns->known_flags) {
-    for (i=0; ns->known_flags[i]; ++i)
-      tor_free(ns->known_flags[i]);
-    tor_free(ns->known_flags);
+    SMARTLIST_FOREACH(ns->known_flags, char *, c, tor_free(c));
+    smartlist_free(ns->known_flags);
   }
   if (ns->voters) {
     SMARTLIST_FOREACH(ns->voters, networkstatus_voter_info_t *, voter,
@@ -317,8 +315,8 @@
         smartlist_add_all(combined_server_versions, sv);
         smartlist_free(sv); /* elements get freed later. */
       }
-      for (j=0; v->known_flags[j]; ++j)
-        smartlist_add(flags, tor_strdup(v->known_flags[j]));
+      SMARTLIST_FOREACH(v->known_flags, const char *, cp,
+                        smartlist_add(flags, tor_strdup(cp)));
     });
     valid_after = median_time(va_times);
     fresh_until = median_time(fu_times);
@@ -444,18 +442,18 @@
       named_flag[i] = -1;
     SMARTLIST_FOREACH(votes, networkstatus_vote_t *, v,
     {
-      for (i = 0; v->known_flags[i]; ++i) {
-        int p = smartlist_string_pos(flags, v->known_flags[i]);
+      SMARTLIST_FOREACH(v->known_flags, const char *, fl,
+      {
+        int p = smartlist_string_pos(flags, fl);
         tor_assert(p >= 0);
-        flag_map[v_sl_idx][i] = p;
+        flag_map[v_sl_idx][fl_sl_idx] = p;
         ++n_flag_voters[p];
-        if (!strcmp(v->known_flags[i], "Named"))
-          named_flag[v_sl_idx] = i;
+        if (!strcmp(fl, "Named"))
+          named_flag[v_sl_idx] = fl_sl_idx;
         /* XXXX020 somebody needs to make sure that there are no duplicate
          * entries in anybody's flag list. */
-      }
-      tor_assert(!v->known_flags[i]);
-      n_voter_flags[v_sl_idx] = i;
+      });
+      n_voter_flags[v_sl_idx] = smartlist_len(v->known_flags);
       size[v_sl_idx] = smartlist_len(v->routerstatus_list);
     });
 
@@ -691,3 +689,37 @@
   return 0;
 }
 
+/** Free storage held in <b>cert</b>. */
+void
+authority_cert_free(authority_cert_t *cert)
+{
+  if (!cert)
+    return;
+
+  tor_free(cert->cache_info.signed_descriptor_body);
+  if (cert->signing_key)
+    crypto_free_pk_env(cert->signing_key);
+  if (cert->identity_key)
+    crypto_free_pk_env(cert->identity_key);
+
+  tor_free(cert);
+}
+
+/** DOCDOC */
+authority_cert_t *
+authority_cert_dup(authority_cert_t *cert)
+{
+  authority_cert_t *out = tor_malloc(sizeof(authority_cert_t));
+  tor_assert(cert);
+
+  memcpy(out, cert, sizeof(authority_cert_t));
+  /* Now copy pointed-to things. */
+  out->cache_info.signed_descriptor_body =
+    tor_strndup(cert->cache_info.signed_descriptor_body,
+                cert->cache_info.signed_descriptor_len);
+  out->cache_info.saved_location = SAVED_NOWHERE;
+  out->identity_key = crypto_pk_dup_key(cert->identity_key);
+  out->signing_key = crypto_pk_dup_key(cert->signing_key);
+
+  return out;
+}

Modified: tor/trunk/src/or/or.h
===================================================================
--- tor/trunk/src/or/or.h	2007-06-08 10:51:06 UTC (rev 10532)
+++ tor/trunk/src/or/or.h	2007-06-08 18:41:09 UTC (rev 10533)
@@ -1333,7 +1333,7 @@
 
   char *client_versions;
   char *server_versions;
-  char **known_flags; /* NULL-terminated */
+  smartlist_t *known_flags;
 
   smartlist_t *voters; /* list of networkstatus_voter_info_t */
 
@@ -2743,6 +2743,9 @@
                                        const char *identity);
 int networkstatus_check_consensus_signature(networkstatus_vote_t *consensus);
 
+void authority_cert_free(authority_cert_t *cert);
+authority_cert_t *authority_cert_dup(authority_cert_t *cert);
+
 /********************************* dns.c ***************************/
 
 int dns_init(void);
@@ -3410,7 +3413,6 @@
 networkstatus_vote_t *networkstatus_parse_vote_from_string(const char *s,
                                                            int is_vote);
 
-void authority_cert_free(authority_cert_t *cert);
 authority_cert_t *authority_cert_parse_from_string(const char *s,
                                                    const char **end_of_string);
 

Modified: tor/trunk/src/or/routerparse.c
===================================================================
--- tor/trunk/src/or/routerparse.c	2007-06-08 10:51:06 UTC (rev 10532)
+++ tor/trunk/src/or/routerparse.c	2007-06-08 18:41:09 UTC (rev 10533)
@@ -1287,22 +1287,6 @@
   return extrainfo;
 }
 
-/** Free storage held in <b>cert</b>. */
-void
-authority_cert_free(authority_cert_t *cert)
-{
-  if (!cert)
-    return;
-
-  tor_free(cert->cache_info.signed_descriptor_body);
-  if (cert->signing_key)
-    crypto_free_pk_env(cert->signing_key);
-  if (cert->identity_key)
-    crypto_free_pk_env(cert->identity_key);
-
-  tor_free(cert);
-}
-
 /** Parse a key certificate from <b>s</b>; point <b>end-of-string</b> to
  * the first character after the certificate. */
 authority_cert_t *
@@ -1515,14 +1499,13 @@
 
   tok = find_first_by_keyword(tokens, K_S);
   if (tok && vote) {
-    int i, j;
+    int i;
     vote_rs->flags = 0;
     for (i=0; i < tok->n_args; ++i) {
-      for (j=0; vote->known_flags[j]; ++j) {
-        if (!strcmp(tok->args[i], vote->known_flags[j])) {
-          vote_rs->flags |= (1<<j);
-          break;
-        }
+      int p = smartlist_string_pos(vote->known_flags, tok->args[i]);
+      if (p >= 0) {
+        vote_rs->flags |= (1<<p);
+        break;
       }
     }
   } else if (tok) {
@@ -1869,9 +1852,9 @@
   }
 
   tok = find_first_by_keyword(tokens, K_KNOWN_FLAGS);
-  ns->known_flags = tor_malloc(sizeof(char*)*(tok->n_args+1));
-  memcpy(ns->known_flags, tok->args, sizeof(char*)*(tok->n_args));
-  ns->known_flags[tok->n_args] = NULL;
+  ns->known_flags = smartlist_create();
+  for (i = 0; i < tok->n_args; ++i)
+    smartlist_add(ns->known_flags, tok->args[i]);
   tok->n_args = 0; /* suppress free of args members, but not of args itself. */
 
   ns->voters = smartlist_create();



More information about the tor-commits mailing list