[tor-commits] [tor/master] Use protocols to see when EXTEND2 support exists.

nickm at torproject.org nickm at torproject.org
Mon Sep 26 18:03:40 UTC 2016


commit e525f5697f9a0682b2cc24fa9779ebe9f0f3c233
Author: Nick Mathewson <nickm at torproject.org>
Date:   Fri Aug 26 12:49:00 2016 -0400

    Use protocols to see when EXTEND2 support exists.
    
    (Technically, we could just remove extend2 cell checking entirely,
    since all Tor versions on our network are required to have it, but
    let's keep this around as an example of How To Do It.)
---
 src/or/or.h          |  9 ++++++---
 src/or/protover.c    | 22 ++++++++++++++++++++++
 src/or/protover.h    |  3 ++-
 src/or/routerlist.c  |  4 ++--
 src/or/routerparse.c | 16 +++++++++++++---
 5 files changed, 45 insertions(+), 9 deletions(-)

diff --git a/src/or/or.h b/src/or/or.h
index 5085139..befbf71 100644
--- a/src/or/or.h
+++ b/src/or/or.h
@@ -2198,9 +2198,12 @@ typedef struct routerstatus_t {
    * if the number of traits we care about ever becomes incredibly big. */
   unsigned int version_known:1;
 
-  /** True iff this router has a version that allows it to accept EXTEND2
-   * cells */
-  unsigned int version_supports_extend2_cells:1;
+  /** True iff we have a proto line for this router.*/
+  unsigned int protocols_known:1;
+
+  /** True iff this router has a version or protocol list that allows it to
+   * accept EXTEND2 cells */
+  unsigned int supports_extend2_cells:1;
 
   unsigned int has_bandwidth:1; /**< The vote/consensus had bw info */
   unsigned int has_exitsummary:1; /**< The vote/consensus had exit summaries */
diff --git a/src/or/protover.c b/src/or/protover.c
index 7feec0c..ca03a71 100644
--- a/src/or/protover.c
+++ b/src/or/protover.c
@@ -235,6 +235,28 @@ protover_is_supported_here(protocol_type_t pr, uint32_t ver)
   return protocol_list_contains(ours, pr, ver);
 }
 
+/**
+ * Return true iff "list" encodes a protocol list that includes support for
+ * the indicated protocol and version.
+ */
+int
+protocol_list_supports_protocol(const char *list, protocol_type_t tp,
+                                uint32_t version)
+{
+  /* NOTE: This is a pretty inefficient implementation. If it ever shows
+   * up in profiles, we should memoize it.
+   */
+  smartlist_t *protocols = parse_protocol_list(list);
+  if (!protocols) {
+    return 0;
+  }
+  int contains = protocol_list_contains(protocols, tp, version);
+
+  SMARTLIST_FOREACH(protocols, proto_entry_t *, ent, proto_entry_free(ent));
+  smartlist_free(protocols);
+  return contains;
+}
+
 /** Return the canonical string containing the list of protocols
  * that we support. */
 const char *
diff --git a/src/or/protover.h b/src/or/protover.h
index d378627..352fa7c 100644
--- a/src/or/protover.h
+++ b/src/or/protover.h
@@ -33,7 +33,8 @@ const char *get_supported_protocols(void);
 char * compute_protover_vote(const smartlist_t *list_of_proto_strings,
                              int threshold);
 const char *protover_compute_for_old_tor(const char *version);
-
+int protocol_list_supports_protocol(const char *list, protocol_type_t tp,
+                                    uint32_t version);
 
 void protover_free_all(void);
 
diff --git a/src/or/routerlist.c b/src/or/routerlist.c
index 56e2385..0a03f13 100644
--- a/src/or/routerlist.c
+++ b/src/or/routerlist.c
@@ -5536,11 +5536,11 @@ routerstatus_version_supports_ntor(const routerstatus_t *rs,
     return allow_unknown_versions;
   }
 
-  if (!rs->version_known) {
+  if (!rs->version_known && !rs->protocols_known) {
     return allow_unknown_versions;
   }
 
-  return rs->version_supports_extend2_cells;
+  return rs->supports_extend2_cells;
 }
 
 /** Assert that the internal representation of <b>rl</b> is
diff --git a/src/or/routerparse.c b/src/or/routerparse.c
index 9428e45..459a939 100644
--- a/src/or/routerparse.c
+++ b/src/or/routerparse.c
@@ -17,6 +17,7 @@
 #include "dirserv.h"
 #include "dirvote.h"
 #include "policies.h"
+#include "protover.h"
 #include "rendcommon.h"
 #include "router.h"
 #include "routerlist.h"
@@ -2904,12 +2905,21 @@ routerstatus_parse_entry_from_string(memarea_t *area,
       }
     }
   }
+  int found_protocol_list = 0;
+  if ((tok = find_opt_by_keyword(tokens, K_PROTO))) {
+    found_protocol_list = 1;
+    rs->protocols_known = 1;
+    rs->supports_extend2_cells =
+      protocol_list_supports_protocol(tok->args[0], PRT_RELAY, 2);
+  }
   if ((tok = find_opt_by_keyword(tokens, K_V))) {
     tor_assert(tok->n_args == 1);
     rs->version_known = 1;
-    if (strcmpstart(tok->args[0], "Tor ")) {
-    } else {
-      rs->version_supports_extend2_cells =
+    if (!strcmpstart(tok->args[0], "Tor ") && !found_protocol_list) {
+      /* We only do version checks like this in the case where
+       * the version is a "Tor" version, and where there is no
+       * list of protocol versions that we should be looking at instead. */
+      rs->supports_extend2_cells =
         tor_version_as_new_as(tok->args[0], "0.2.4.8-alpha");
     }
     if (vote_rs) {





More information about the tor-commits mailing list