Browse Source

If we are an authoritative dirserver, check out the fingerprint list when setting connection nicknames

svn:r2389
Nick Mathewson 21 years ago
parent
commit
d20d10f360
3 changed files with 49 additions and 19 deletions
  1. 11 3
      src/or/connection_or.c
  2. 37 16
      src/or/dirserv.c
  3. 1 0
      src/or/or.h

+ 11 - 3
src/or/connection_or.c

@@ -120,6 +120,7 @@ connection_or_init_conn_from_address(connection_t *conn,
 {
   routerinfo_t *r;
   struct in_addr in;
+  const char *n;
   r = router_get_by_digest(id_digest);
   if (r) {
     connection_or_init_conn_from_router(conn,r);
@@ -130,9 +131,16 @@ connection_or_init_conn_from_address(connection_t *conn,
   /* This next part isn't really right, but it's good enough for now. */
   conn->receiver_bucket = conn->bandwidth = options.BandwidthBurst;
   memcpy(conn->identity_digest, id_digest, DIGEST_LEN);
-  conn->nickname = tor_malloc(HEX_DIGEST_LEN+1);
-  base16_encode(conn->nickname, HEX_DIGEST_LEN+1,
-                conn->identity_digest, DIGEST_LEN);
+  /* If we're an authoritative directory server, we may know a
+   * nickname for this router. */
+  n = dirserv_get_nickname_by_digest(id_digest);
+  if (n) {
+    conn->nickname = tor_strdup(n);
+  } else {
+    conn->nickname = tor_malloc(HEX_DIGEST_LEN+1);
+    base16_encode(conn->nickname, HEX_DIGEST_LEN+1,
+                  conn->identity_digest, DIGEST_LEN);
+  }
   tor_free(conn->address);
   in.s_addr = htonl(addr);
   conn->address = tor_strdup(inet_ntoa(in));

+ 37 - 16
src/or/dirserv.c

@@ -23,6 +23,7 @@ static int runningrouters_is_dirty = 1;
 static int list_running_servers(char **nicknames_out);
 static void directory_remove_unrecognized(void);
 static int dirserv_regenerate_directory(void);
+static void encode_digest_to_fingerprint(char *fp, const char *digest);
 
 /************** Fingerprint handling code ************/
 
@@ -181,17 +182,32 @@ dirserv_router_fingerprint_is_known(const routerinfo_t *router)
   }
 }
 
-/** Return true iff any router named <b>nickname</b> with <b>digest</b>
- * is in the verified fingerprint list. */
-static int
-router_nickname_is_approved(const char *nickname, const char *digest)
+/** If we are an authoritative directory, and the list of approved
+ * servers contains one whose identity key digest is <b>digest</b>,
+ * return that router's nickname.  Otherwise return NULL. */
+const char *dirserv_get_nickname_by_digest(const char *digest)
 {
-  int i,j;
-  fingerprint_entry_t *ent;
   char fp[FINGERPRINT_LEN+1];
-  char hexdigest[HEX_DIGEST_LEN+1];
   if (!fingerprint_list)
-    return 0;
+    return NULL;
+  tor_assert(digest);
+  encode_digest_to_fingerprint(fp, digest);
+
+  SMARTLIST_FOREACH(fingerprint_list, fingerprint_entry_t*, ent,
+                    { if (!strcasecmp(fp, ent->fingerprint))
+                         return ent->nickname; } );
+  return NULL;
+}
+
+/** Set fp to contain the hex encoding of <b>digest</b>, with every 4
+ * hex digits separated by a space.  The digest must be DIGEST_LEN bytes long;
+ * fp must have FINGERPRINT_LEN+1 bytes free. */
+static void encode_digest_to_fingerprint(char *fp, const char *digest)
+{
+  char hexdigest[HEX_DIGEST_LEN+1];
+  int i,j;
+
+  tor_assert(fp&&digest);
 
   base16_encode(hexdigest, sizeof(hexdigest), digest, DIGEST_LEN);
   for (i=j=0;j<HEX_DIGEST_LEN;++i,++j) {
@@ -200,15 +216,20 @@ router_nickname_is_approved(const char *nickname, const char *digest)
       fp[++i]=' ';
   }
   fp[i]='\0';
+}
 
-  for (i=0;i<smartlist_len(fingerprint_list);++i) {
-    ent = smartlist_get(fingerprint_list, i);
-    if (!strcasecmp(nickname,ent->nickname) &&
-        !strcasecmp(fp,ent->fingerprint)) {
-      return 1;
-    }
-  }
-  return 0;
+/** Return true iff any router named <b>nickname</b> with <b>digest</b>
+ * is in the verified fingerprint list. */
+static int
+router_nickname_is_approved(const char *nickname, const char *digest)
+{
+  const char *n;
+
+  n = dirserv_get_nickname_by_digest(digest);
+  if (n && !strcasecmp(n,nickname))
+    return 1;
+  else
+    return 0;
 }
 
 /** Clear the current fingerprint list. */

+ 1 - 0
src/or/or.h

@@ -1177,6 +1177,7 @@ int dirserv_add_own_fingerprint(const char *nickname, crypto_pk_env_t *pk);
 int dirserv_parse_fingerprint_file(const char *fname);
 int dirserv_router_fingerprint_is_known(const routerinfo_t *router);
 void dirserv_free_fingerprint_list();
+const char *dirserv_get_nickname_by_digest(const char *digest);
 int dirserv_add_descriptor(const char **desc);
 int dirserv_load_from_directory_string(const char *dir);
 void dirserv_free_descriptors();