[tor-commits] [tor/master] protover: Add node functions for IPv6 extend support

nickm at torproject.org nickm at torproject.org
Tue Jun 9 19:45:23 UTC 2020


commit c7f085d9bdf4196b04054f5812e29137d1789ad7
Author: teor <teor at riseup.net>
Date:   Mon May 11 12:25:41 2020 +1000

    protover: Add node functions for IPv6 extend support
    
    Part of 33226.
---
 src/core/or/or.h                | 12 ++++++++++
 src/core/or/versions.c          |  7 ++++++
 src/feature/nodelist/nodelist.c | 52 ++++++++++++++++++++++++++++++++++++++++-
 src/feature/nodelist/nodelist.h |  5 ++++
 src/feature/relay/router.c      | 17 +++++++++++++-
 5 files changed, 91 insertions(+), 2 deletions(-)

diff --git a/src/core/or/or.h b/src/core/or/or.h
index 28211b48c..7e02da664 100644
--- a/src/core/or/or.h
+++ b/src/core/or/or.h
@@ -815,6 +815,18 @@ typedef struct protover_summary_flags_t {
    * accept EXTEND2 cells. This requires Relay=2. */
   unsigned int supports_extend2_cells:1;
 
+  /** True iff this router has a version or protocol list that allows it to
+   * accept IPv6 connections. This requires Relay=2 or Relay=3. */
+  unsigned int supports_accepting_ipv6_extends:1;
+
+  /** True iff this router has a version or protocol list that allows it to
+   * initiate IPv6 connections. This requires Relay=3. */
+  unsigned int supports_initiating_ipv6_extends:1;
+
+  /** True iff this router has a version or protocol list that allows it to
+   * consider IPv6 connections canonical. This requires Relay=3. */
+  unsigned int supports_canonical_ipv6_conns:1;
+
   /** True iff this router has a protocol list that allows it to negotiate
    * ed25519 identity keys on a link handshake with us. This
    * requires LinkAuth=3. */
diff --git a/src/core/or/versions.c b/src/core/or/versions.c
index 2a33bf68f..a8dfe7e61 100644
--- a/src/core/or/versions.c
+++ b/src/core/or/versions.c
@@ -437,6 +437,13 @@ memoize_protover_summary(protover_summary_flags_t *out,
 
   out->supports_extend2_cells =
     protocol_list_supports_protocol(protocols, PRT_RELAY, 2);
+  out->supports_accepting_ipv6_extends = (
+    protocol_list_supports_protocol(protocols, PRT_RELAY, 2) ||
+    protocol_list_supports_protocol(protocols, PRT_RELAY, 3));
+  out->supports_initiating_ipv6_extends =
+    protocol_list_supports_protocol(protocols, PRT_RELAY, 3);
+  out->supports_canonical_ipv6_conns =
+    protocol_list_supports_protocol(protocols, PRT_RELAY, 3);
 
   out->supports_ed25519_link_handshake_compat =
     protocol_list_supports_protocol(protocols, PRT_LINKAUTH, 3);
diff --git a/src/feature/nodelist/nodelist.c b/src/feature/nodelist/nodelist.c
index 6a8e1723d..a55339062 100644
--- a/src/feature/nodelist/nodelist.c
+++ b/src/feature/nodelist/nodelist.c
@@ -1133,7 +1133,7 @@ node_ed25519_id_matches(const node_t *node, const ed25519_public_key_t *id)
 /** Dummy object that should be unreturnable.  Used to ensure that
  * node_get_protover_summary_flags() always returns non-NULL. */
 static const protover_summary_flags_t zero_protover_flags = {
-  0,0,0,0,0,0,0,0,0
+  0,0,0,0,0,0,0,0,0,0,0,0
 };
 
 /** Return the protover_summary_flags for a given node. */
@@ -1219,6 +1219,56 @@ node_supports_establish_intro_dos_extension(const node_t *node)
                            supports_establish_intro_dos_extension;
 }
 
+/** Return true iff <b>node</b> can initiate IPv6 extends (Relay=3).
+ *
+ * This check should only be performed by client path selection code.
+ *
+ * Extending relays should check their own IPv6 support using
+ * router_can_extend_over_ipv6(). Like other extends, they should not verify
+ * the link specifiers in the extend cell against the consensus, because it
+ * may be out of date. */
+bool
+node_supports_initiating_ipv6_extends(const node_t *node)
+{
+  tor_assert(node);
+
+  /* Relays can't initiate an IPv6 extend, unless they have an IPv6 ORPort. */
+  if (!node_has_ipv6_orport(node)) {
+    return 0;
+  }
+
+  /* Initiating relays also need to support the relevant protocol version. */
+  return
+    node_get_protover_summary_flags(node)->supports_initiating_ipv6_extends;
+}
+
+/** Return true iff <b>node</b> can accept IPv6 extends (Relay=2 or Relay=3)
+ * from other relays. If <b>need_canonical_ipv6_conn</b> is true, also check
+ * if the relay supports canonical IPv6 connections (Relay=3 only).
+ *
+ * This check should only be performed by client path selection code.
+ */
+bool
+node_supports_accepting_ipv6_extends(const node_t *node,
+                                            bool need_canonical_ipv6_conn)
+{
+  tor_assert(node);
+
+  /* Relays can't accept an IPv6 extend, unless they have an IPv6 ORPort. */
+  if (!node_has_ipv6_orport(node)) {
+    return 0;
+  }
+
+  /* Accepting relays also need to support the relevant protocol version. */
+  if (need_canonical_ipv6_conn) {
+    return
+      node_get_protover_summary_flags(node)->supports_canonical_ipv6_conns;
+  } else {
+    return
+      node_get_protover_summary_flags(node)->supports_accepting_ipv6_extends;
+  }
+}
+
 /** Return the RSA ID key's SHA1 digest for the provided node. */
 const uint8_t *
 node_get_rsa_id_digest(const node_t *node)
diff --git a/src/feature/nodelist/nodelist.h b/src/feature/nodelist/nodelist.h
index 57ab2d591..991cec319 100644
--- a/src/feature/nodelist/nodelist.h
+++ b/src/feature/nodelist/nodelist.h
@@ -81,6 +81,11 @@ int node_supports_v3_hsdir(const node_t *node);
 int node_supports_ed25519_hs_intro(const node_t *node);
 int node_supports_v3_rendezvous_point(const node_t *node);
 int node_supports_establish_intro_dos_extension(const node_t *node);
+bool node_supports_initiating_ipv6_extends(const node_t *node);
+bool node_supports_accepting_ipv6_extends(
+                                             const node_t *node,
+                                             bool need_canonical_ipv6_conn);
+
 const uint8_t *node_get_rsa_id_digest(const node_t *node);
 MOCK_DECL(smartlist_t *,node_get_link_specifier_smartlist,(const node_t *node,
                                                            bool direct_conn));
diff --git a/src/feature/relay/router.c b/src/feature/relay/router.c
index 1a35e27e1..85788c07e 100644
--- a/src/feature/relay/router.c
+++ b/src/feature/relay/router.c
@@ -1499,7 +1499,22 @@ router_has_advertised_ipv6_orport(const or_options_t *options)
   return tor_addr_port_is_valid_ap(&ipv6_ap, 0);
 }
 
-/** Returns true if this router has an advertised IPv6 ORPort. */
+/** Returns true if this router can extend over IPv6.
+ *
+ * This check should only be performed by relay extend code.
+ *
+ * Clients should check if relays can initiate and accept IPv6 extends using
+ * node_supports_initiating_ipv6_extends() and
+ * node_supports_accepting_ipv6_extends().
+ *
+ * As with other extends, relays should assume the client has already
+ * performed the relevant checks for the next hop. (Otherwise, relays that
+ * have just added IPv6 ORPorts won't be able to self-test those ORPorts.)
+ *
+ * Accepting relays don't need to perform any IPv6-specific checks before
+ * accepting a connection, because having an IPv6 ORPort implies support for
+ * the relevant protocol version.
+ */
 MOCK_IMPL(bool,
 router_can_extend_over_ipv6,(const or_options_t *options))
 {





More information about the tor-commits mailing list