[or-cvs] r12051: Client-side implementation for proposal 122. (in tor/trunk: . doc doc/spec/proposals src/or)

nickm at seul.org nickm at seul.org
Fri Oct 19 18:56:24 UTC 2007


Author: nickm
Date: 2007-10-19 14:56:24 -0400 (Fri, 19 Oct 2007)
New Revision: 12051

Modified:
   tor/trunk/
   tor/trunk/ChangeLog
   tor/trunk/doc/TODO
   tor/trunk/doc/spec/proposals/122-unnamed-flag.txt
   tor/trunk/src/or/networkstatus.c
   tor/trunk/src/or/or.h
   tor/trunk/src/or/routerlist.c
   tor/trunk/src/or/routerparse.c
Log:
 r15965 at catbus:  nickm | 2007-10-19 13:32:11 -0400
 Client-side implementation for proposal 122.



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

Modified: tor/trunk/ChangeLog
===================================================================
--- tor/trunk/ChangeLog	2007-10-19 18:56:21 UTC (rev 12050)
+++ tor/trunk/ChangeLog	2007-10-19 18:56:24 UTC (rev 12051)
@@ -16,6 +16,9 @@
       that it shouldn't be considered to exist at all anymore. Now we
       clear all the flags for routers that fall out of the networkstatus
       consensus. Fixes bug 529.
+    - If the consensus list a router as "Unnamed", the name is assigned
+      to a different router: do not identify the router by that name.
+      (Partially implements proposal 122.)
 
   o Minor features (v3 directory protocol):
     - Allow tor-gencert to generate a new certificate without replacing the

Modified: tor/trunk/doc/TODO
===================================================================
--- tor/trunk/doc/TODO	2007-10-19 18:56:21 UTC (rev 12050)
+++ tor/trunk/doc/TODO	2007-10-19 18:56:24 UTC (rev 12051)
@@ -93,11 +93,11 @@
     - 105: Version negotiation for the Tor protocol
     . 111: Prioritize local traffic over relayed.
       - Merge into tor-spec.txt.
-    - 122: Network status entries need an Unnamed flag
+    . 122: Network status entries need an Unnamed flag
       - Merge into dir-spec.txt
       - Implement voting side
       - Implement consensus side
-      - Implement client side
+      o Implement client side
 
   - Refactoring:
     . Make cells get buffered on circuit, not on the or_conn.

Modified: tor/trunk/doc/spec/proposals/122-unnamed-flag.txt
===================================================================
--- tor/trunk/doc/spec/proposals/122-unnamed-flag.txt	2007-10-19 18:56:21 UTC (rev 12050)
+++ tor/trunk/doc/spec/proposals/122-unnamed-flag.txt	2007-10-19 18:56:24 UTC (rev 12051)
@@ -4,7 +4,7 @@
 Last-Modified: $Date$
 Author: Roger Dingledine
 Created: 04-Oct-2007
-Status: Open
+Status: Accepted
 
 1. Overview:
 

Modified: tor/trunk/src/or/networkstatus.c
===================================================================
--- tor/trunk/src/or/networkstatus.c	2007-10-19 18:56:21 UTC (rev 12050)
+++ tor/trunk/src/or/networkstatus.c	2007-10-19 18:56:24 UTC (rev 12051)
@@ -25,8 +25,11 @@
  * time we called download_status_map_update_from_v2_networkstatus() */
 static int networkstatus_v2_list_has_changed = 0;
 
-/** Map from lowercase nickname to digest of named server, if any. */
+/** Map from lowercase nickname to identity digest of named server, if any. */
 static strmap_t *named_server_map = NULL;
+/** Map from lowercase nickname to (void*)1 for all names that are listed
+ * as unnamed for some server in the consensus. */
+static strmap_t *unnamed_server_map = NULL;
 
 /** Most recently received and validated v3 consensus network status. */
 static networkstatus_vote_t *current_consensus = NULL;
@@ -579,6 +582,7 @@
   routerstatus_t *best=NULL;
   smartlist_t *matches=NULL;
   const char *named_id=NULL;
+  int any_unnamed=0;
 
   if (!current_consensus || !nickname)
     return NULL;
@@ -597,6 +601,10 @@
   if (named_id)
     return networkstatus_vote_find_entry(current_consensus, named_id);
 
+  if (unnamed_server_map &&
+      strmap_get_lc(named_server_map, nickname))
+    return NULL; /* XXXX020 should we warn? */
+
   /*XXXX020 is this behavior really what we want? */
   matches = smartlist_create();
   SMARTLIST_FOREACH(current_consensus->routerstatus_list,
@@ -604,16 +612,22 @@
     {
       if (!strcasecmp(lrs->nickname, nickname)) {
         if (lrs->is_named) {
+          /* XXXX020 this should never happen. */
           smartlist_free(matches);
           return lrs;
         } else {
+          if (lrs->is_unnamed)
+            smartlist_free(matches); /* nor should this. */
           smartlist_add(matches, lrs);
           best = lrs;
         }
       }
     });
 
-  if (smartlist_len(matches)>1 && warn_if_unnamed) {
+  if (any_unnamed) {
+    /* XXXX020 should we warn? */
+    return NULL;
+  } else if (smartlist_len(matches)>1 && warn_if_unnamed) {
     int any_unwarned=0;
     SMARTLIST_FOREACH(matches, routerstatus_t *, lrs,
       {
@@ -654,6 +668,13 @@
   return strmap_get_lc(named_server_map, nickname);
 }
 
+/** DOCDOC */
+int
+networkstatus_nickname_is_unnamed(const char *nickname)
+{
+  return strmap_get_lc(named_server_map, nickname) != NULL;
+}
+
 /** How frequently do directory authorities re-download fresh networkstatus
  * documents? */
 #define AUTHORITY_NS_CACHE_INTERVAL (5*60)
@@ -1061,6 +1082,11 @@
       log_info(LD_GENERAL, "The latest consensus does not list us."
                "Are you misconfigured?");
       have_warned_about_invalid_status = 1;
+    } else if (rs->is_unnamed) {
+      /* XXXX020 this isn't a useful warning. */
+      log_info(LD_GENERAL,  "The directory have assigned the nickname "
+               "you're using to a different identity.");
+      have_warned_about_invalid_status = 1;
     } else if (!rs->is_named) {
       /*XXXX020 this isn't a correct warning. */
       log_info(LD_GENERAL,  "The directory authorities do not recognize "
@@ -1150,12 +1176,18 @@
   if (named_server_map)
     strmap_free(named_server_map, _tor_free);
   named_server_map = strmap_new();
+  if (unnamed_server_map)
+    strmap_free(unnamed_server_map, NULL);
+  named_server_map = strmap_new();
   SMARTLIST_FOREACH(current_consensus->routerstatus_list, routerstatus_t *, rs,
     {
       if (rs->is_named) {
-        strmap_set(named_server_map, rs->nickname,
-                   tor_memdup(rs->identity_digest, DIGEST_LEN));
+        strmap_set_lc(named_server_map, rs->nickname,
+                      tor_memdup(rs->identity_digest, DIGEST_LEN));
       }
+      if (rs->is_unnamed) {
+        strmap_set_lc(unnamed_server_map, rs->nickname, (void*)1);
+      }
     });
 }
 
@@ -1348,5 +1380,8 @@
   if (named_server_map) {
     strmap_free(named_server_map, _tor_free);
   }
+  if (unnamed_server_map) {
+    strmap_free(unnamed_server_map, NULL);
+  }
 }
 

Modified: tor/trunk/src/or/or.h
===================================================================
--- tor/trunk/src/or/or.h	2007-10-19 18:56:21 UTC (rev 12050)
+++ tor/trunk/src/or/or.h	2007-10-19 18:56:24 UTC (rev 12051)
@@ -1221,6 +1221,8 @@
   unsigned int is_fast:1; /**< True iff this router has good bandwidth. */
   unsigned int is_running:1; /**< True iff this router is up. */
   unsigned int is_named:1; /**< True iff "nickname" belongs to this router. */
+  unsigned int is_unnamed:1; /**< True iff "nickname" belongs to another
+                              * router. */
   unsigned int is_valid:1; /**< True iff this router is validated. */
   unsigned int is_v2_dir:1; /**< True iff this router can serve directory
                              * information with v2 of the directory
@@ -1349,6 +1351,11 @@
   time_t valid_until; /**< Time after which this vote or consensus should not
                        * be used. */
 
+  /** Consensus only: what method was used to produce this consensus? */
+  int consensus_method;
+  /** Vote only: what methods is this voter willing to use? */
+  smartlist_t *supported_methods;
+
   /** How long does this vote/consensus claim that authorities take to
    * distribute their votes to one another? */
   int vote_seconds;
@@ -3091,6 +3098,7 @@
 routerstatus_t *router_get_consensus_status_by_nickname(const char *nickname,
                                                        int warn_if_unnamed);
 const char *networkstatus_get_router_digest_by_nickname(const char *nickname);
+int networkstatus_nickname_is_unnamed(const char *nickname);
 void networkstatus_consensus_download_failed(int status_code);
 int should_delay_dir_fetches(or_options_t *options);
 void update_networkstatus_downloads(time_t now);

Modified: tor/trunk/src/or/routerlist.c
===================================================================
--- tor/trunk/src/or/routerlist.c	2007-10-19 18:56:21 UTC (rev 12050)
+++ tor/trunk/src/or/routerlist.c	2007-10-19 18:56:24 UTC (rev 12051)
@@ -1701,6 +1701,8 @@
   if ((named_digest = networkstatus_get_router_digest_by_nickname(nickname))) {
     return rimap_get(routerlist->identity_map, named_digest);
   }
+  if (networkstatus_nickname_is_unnamed(nickname))
+    return NULL;
 
   /* If we reach this point, there's no canonical value for the nickname. */
 

Modified: tor/trunk/src/or/routerparse.c
===================================================================
--- tor/trunk/src/or/routerparse.c	2007-10-19 18:56:21 UTC (rev 12050)
+++ tor/trunk/src/or/routerparse.c	2007-10-19 18:56:24 UTC (rev 12051)
@@ -1534,12 +1534,17 @@
  * router status.  Return NULL and advance *<b>s</b> on error.
  *
  * If <b>vote</b> and <b>vote_rs</b> are provided, don't allocate a fresh
- * routerstatus but use <b>vote_rs</b> instead
+ * routerstatus but use <b>vote_rs</b> instead.
+ *
+ * If <b>consensus_method</b> is nonzero, this routerstatus is part of a
+ * consensus, and we should parse it according to the method used to
+ * make that consensus.
  **/
 static routerstatus_t *
 routerstatus_parse_entry_from_string(const char **s, smartlist_t *tokens,
                                      networkstatus_vote_t *vote,
-                                     vote_routerstatus_t *vote_rs)
+                                     vote_routerstatus_t *vote_rs,
+                                     int consensus_method)
 {
   const char *eos;
   routerstatus_t *rs = NULL;
@@ -1645,6 +1650,11 @@
         rs->is_bad_directory = 1;
       else if (!strcmp(tok->args[i], "Authority"))
         rs->is_authority = 1;
+      else if (!strcmp(tok->args[i], "Unnamed") &&
+               consensus_method >= 2) {
+        /* Unnamed is computed right by consensus method 2 and later. */
+        rs->is_unnamed = 1;
+      }
     }
   }
   if ((tok = find_first_by_keyword(tokens, K_V))) {
@@ -1830,7 +1840,7 @@
   smartlist_clear(tokens);
   while (!strcmpstart(s, "r ")) {
     routerstatus_t *rs;
-    if ((rs = routerstatus_parse_entry_from_string(&s, tokens, NULL, NULL)))
+    if ((rs = routerstatus_parse_entry_from_string(&s, tokens, NULL, NULL, 0)))
       smartlist_add(ns->entries, rs);
   }
   smartlist_sort(ns->entries, _compare_routerstatus_entries);
@@ -1936,6 +1946,26 @@
     tok = find_first_by_keyword(tokens, K_PUBLISHED);
     if (parse_iso_time(tok->args[0], &ns->published))
       goto err;
+
+    ns->supported_methods = smartlist_create();
+    tok = find_first_by_keyword(tokens, K_CONSENSUS_METHODS);
+    if (tok) {
+      for (i=0; i < tok->n_args; ++i)
+        smartlist_add(ns->supported_methods, tok->args[i]);
+      tok->n_args = 0; /* Prevent double free. */
+    } else {
+      smartlist_add(ns->supported_methods, tor_strdup("1"));
+    }
+  } else {
+    tok = find_first_by_keyword(tokens, K_CONSENSUS_METHOD);
+    if (tok) {
+      ns->consensus_method = (int)tor_parse_long(tok->args[0], 10, 1, INT_MAX,
+                                                 &ok, NULL);
+      if (!ok)
+        goto err;
+    } else {
+      ns->consensus_method = 1;
+    }
   }
 
   tok = find_first_by_keyword(tokens, K_VALID_AFTER);
@@ -2086,7 +2116,7 @@
   while (!strcmpstart(s, "r ")) {
     if (is_vote) {
       vote_routerstatus_t *rs = tor_malloc_zero(sizeof(vote_routerstatus_t));
-      if (routerstatus_parse_entry_from_string(&s, tokens, ns, rs))
+      if (routerstatus_parse_entry_from_string(&s, tokens, ns, rs, 0))
         smartlist_add(ns->routerstatus_list, rs);
       else {
         tor_free(rs->version);
@@ -2094,7 +2124,8 @@
       }
     } else {
       routerstatus_t *rs;
-      if ((rs =routerstatus_parse_entry_from_string(&s, tokens, NULL, NULL)))
+      if ((rs = routerstatus_parse_entry_from_string(&s, tokens, NULL, NULL,
+                                                     ns->consensus_method)))
         smartlist_add(ns->routerstatus_list, rs);
     }
   }



More information about the tor-commits mailing list