ソースを参照

r11694@Kushana: nickm | 2006-12-23 23:09:20 -0500
Add a version entry to networkstatus documents; have this entry get parsed and used to calculate whether begin_dir is supported.


svn:r9181

Nick Mathewson 17 年 前
コミット
2e538d9918
6 ファイル変更51 行追加10 行削除
  1. 5 0
      ChangeLog
  2. 9 9
      doc/TODO
  3. 11 0
      src/or/dirserv.c
  4. 7 0
      src/or/or.h
  5. 8 0
      src/or/routerlist.c
  6. 11 1
      src/or/routerparse.c

+ 5 - 0
ChangeLog

@@ -7,6 +7,11 @@ Changes in version 0.1.2.5-xxxx - 200?-??-??
     - Enable write limiting as well as read limiting. Now we sacrifice
       capacity if we're pushing out lots of directory traffic, rather
       than overrunning the user's intended bandwidth limits.
+    - Authorities now include server versions in networkstatus. This adds
+      about 2% to the side of compressed networkstatus docs, and allows
+      clients to tell which servers support BEGIN_DIR and which don't.
+      The implementation is forward-compatible with a proposed future
+      protocol version scheme not tied to Tor versions.
 
   o Minor features:
     - Start using the state file to store bandwidth accounting data:

+ 9 - 9
doc/TODO

@@ -55,14 +55,14 @@ R   - turn the received socks addr:port into a digest for setting .exit
 R     - handle connect-dir streams that don't have a chosen_exit_name set.
       o include ORPort in DirServers lines so we can know where to connect.
         list the orport as 0 if it can't handle begin_dir.
-N     - list versions in status page
-        a new line in the status entry. "Tor 0.1.2.2-alpha". If it's
-        a version, treat it like one. If it's something else, assume
-        it's at least 0.1.2.x.
-        maybe we could have it be a new 'v' line in the status, with
-        key=value syntax. so we could have a 'tor' version, but we
-        could also have a 'conn' version, a 'dir' version, etc down
-        the road. and one day maybe the 'tor' key would be deprecated.
+      o List versions in status page
+        o A new line in the status entry. "Tor 0.1.2.2-alpha". If it's
+          a version, treat it like one. If it's something else, assume
+          it's at least 0.1.2.x.
+        D maybe we could have it be a new 'v' line in the status, with
+          key=value syntax. so we could have a 'tor' version, but we
+          could also have a 'conn' version, a 'dir' version, etc down
+          the road. and one day maybe the 'tor' key would be deprecated.
 
   o Document .noconnect addresses...
     A new file 'address-spec.txt' that describes .exit, .onion,
@@ -193,7 +193,7 @@ R   - "bandwidth classes", for incoming vs initiated-here conns,
       - separate config options for read vs write limiting
 
   - Forward compatibility fixes
-    - Stop requiring "opt" to ignore options in descriptors, networkstatuses,
+    o Stop requiring "opt" to ignore options in descriptors, networkstatuses,
       and so on.
     - Caches should start trying to cache consensus docs?
     - Start uploading short and long descriptors; authorities should support

+ 11 - 0
src/or/dirserv.c

@@ -1561,6 +1561,17 @@ generate_v2_networkstatus(void)
         goto done;
       }
       outp += strlen(outp);
+      if (ri->platform && !strcmpstart(ri->platform, "Tor ")) {
+        const char *eos = find_whitespace(ri->platform+4);
+        char *platform = tor_strndup(ri->platform+4, eos-(ri->platform+4));
+        if (tor_snprintf(outp, endp-outp,
+                         "opt v %s\n", platform)) {
+          log_warn(LD_BUG, "Unable to print router version.");
+          goto done;
+        }
+        tor_free(platform);
+        outp += strlen(outp);
+      }
     }
   });
 

+ 7 - 0
src/or/or.h

@@ -1013,6 +1013,13 @@ typedef struct routerstatus_t {
   unsigned int is_bad_exit:1; /**< True iff this node is a bad choice for
                                * an exit node. */
 
+  /** True iff we know version info for this router. (i.e., a "v" entry was
+   * included.)  We'll replace all these with a big tor_vesion_t or a char[]
+   * if the number of traits we care about ever becomes incredibly big. */
+  unsigned int version_known:1;
+  /** True iff this router is a version that supports BEGIN_DIR cells. */
+  unsigned int version_supports_begindir:1;
+
   /** True if we, as a directory mirror, want to download the corresponding
    * routerinfo from the authority who gave us this routerstatus.  (That is,
    * if we don't have the routerinfo, and if we haven't already tried to get it

+ 8 - 0
src/or/routerlist.c

@@ -3345,6 +3345,7 @@ routerstatus_list_update_from_networkstatus(time_t now)
   while (1) {
     int n_running=0, n_named=0, n_valid=0, n_listing=0;
     int n_v2_dir=0, n_fast=0, n_stable=0, n_exit=0, n_guard=0, n_bad_exit=0;
+    int n_version_known=0, n_supports_begindir=0;
     int n_desc_digests=0, highest_count=0;
     const char *the_name = NULL;
     local_routerstatus_t *rs_out, *rs_old;
@@ -3432,6 +3433,10 @@ routerstatus_list_update_from_networkstatus(time_t now)
         ++n_v2_dir;
       if (rs->is_bad_exit)
         ++n_bad_exit;
+      if (rs->version_known)
+        ++n_version_known;
+      if (rs->version_supports_begindir)
+        ++n_supports_begindir;
     }
     /* Go over the descriptor digests and figure out which descriptor we
      * want. */
@@ -3482,6 +3487,9 @@ routerstatus_list_update_from_networkstatus(time_t now)
     rs_out->status.is_stable = n_stable > n_statuses/2;
     rs_out->status.is_v2_dir = n_v2_dir > n_statuses/2;
     rs_out->status.is_bad_exit = n_bad_exit > n_listing_bad_exits/2;
+    rs_out->status.version_known = n_version_known > 0;
+    rs_out->status.version_supports_begindir =
+      n_supports_begindir > n_version_known/2;
     if (!rs_old || memcmp(rs_old, rs_out, sizeof(local_routerstatus_t)))
       smartlist_add(changed_list, rs_out);
   }

+ 11 - 1
src/or/routerparse.c

@@ -54,6 +54,7 @@ typedef enum {
   K_SERVER_VERSIONS,
   K_R,
   K_S,
+  K_V,
   K_EVENTDNS,
   _UNRECOGNIZED,
   _ERR,
@@ -117,6 +118,7 @@ static struct {
                                                            DIR|NETSTATUS},
   { "r",                   K_R,                   ARGS,    NO_OBJ, RTRSTATUS },
   { "s",                   K_S,                   ARGS,    NO_OBJ, RTRSTATUS },
+  { "v",                   K_V,               CONCAT_ARGS, NO_OBJ, RTRSTATUS },
   { "reject",              K_REJECT,              ARGS,    NO_OBJ,  RTR },
   { "router",              K_ROUTER,              ARGS,    NO_OBJ,  RTR },
   { "recommended-software",K_RECOMMENDED_SOFTWARE,ARGS,    NO_OBJ,  DIR },
@@ -1075,7 +1077,15 @@ routerstatus_parse_entry_from_string(const char **s, smartlist_t *tokens)
         rs->is_possible_guard = 1;
       else if (!strcmp(tok->args[i], "BadExit"))
         rs->is_bad_exit = 1;
-
+    }
+  }
+  if ((tok = find_first_by_keyword(tokens, K_V))) {
+    rs->version_known = 1;
+    if (strcmpstart(tok->args[0], "Tor ")) {
+      rs->version_supports_begindir = 1;
+    } else {
+      rs->version_supports_begindir =
+        tor_version_as_new_as(tok->args[0], "0.1.2.2-alpha");
     }
   }