Browse Source

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.)
Nick Mathewson 7 years ago
parent
commit
e525f5697f
5 changed files with 45 additions and 9 deletions
  1. 6 3
      src/or/or.h
  2. 22 0
      src/or/protover.c
  3. 2 1
      src/or/protover.h
  4. 2 2
      src/or/routerlist.c
  5. 13 3
      src/or/routerparse.c

+ 6 - 3
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 */

+ 22 - 0
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 *

+ 2 - 1
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);
 

+ 2 - 2
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

+ 13 - 3
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) {