[tor-commits] [tor/master] routerlist: Choose nodes that can initiate IPv6 extends

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


commit 1c1faf586ab7083221e02da4315679c5cf13d151
Author: teor <teor at riseup.net>
Date:   Mon May 11 17:00:25 2020 +1000

    routerlist: Choose nodes that can initiate IPv6 extends
    
    Part of 33226.
---
 src/core/or/circuitbuild.c         | 17 ++++++++-----
 src/feature/nodelist/node_select.c | 49 ++++++++++++++++++++++----------------
 src/feature/nodelist/node_select.h |  2 ++
 src/feature/nodelist/routerlist.c  |  9 ++++---
 src/feature/nodelist/routerlist.h  |  3 ++-
 5 files changed, 50 insertions(+), 30 deletions(-)

diff --git a/src/core/or/circuitbuild.c b/src/core/or/circuitbuild.c
index ba70c4753..1cf9e588f 100644
--- a/src/core/or/circuitbuild.c
+++ b/src/core/or/circuitbuild.c
@@ -1796,12 +1796,13 @@ pick_restricted_middle_node(router_crn_flags_t flags,
 
   /* Add all running nodes to all_live_nodes */
   router_add_running_nodes_to_smartlist(all_live_nodes,
-                                        (flags & CRN_NEED_UPTIME) != 0,
-                                        (flags & CRN_NEED_CAPACITY) != 0,
-                                        (flags & CRN_NEED_GUARD) != 0,
-                                        (flags & CRN_NEED_DESC) != 0,
-                                        (flags & CRN_PREF_ADDR) != 0,
-                                        (flags & CRN_DIRECT_CONN) != 0);
+                                    (flags & CRN_NEED_UPTIME) != 0,
+                                    (flags & CRN_NEED_CAPACITY) != 0,
+                                    (flags & CRN_NEED_GUARD) != 0,
+                                    (flags & CRN_NEED_DESC) != 0,
+                                    (flags & CRN_PREF_ADDR) != 0,
+                                    (flags & CRN_DIRECT_CONN) != 0,
+                                    (flags & CRN_INITIATE_IPV6_EXTEND) != 0);
 
   /* Filter all_live_nodes to only add live *and* whitelisted middles
    * to the list whitelisted_live_middles. */
@@ -2306,6 +2307,10 @@ choose_good_middle_server(uint8_t purpose,
     flags |= CRN_NEED_UPTIME;
   if (state->need_capacity)
     flags |= CRN_NEED_CAPACITY;
+  /* Picking the second-last node. (The last node is the relay doing the
+   * self-test.) */
+  if (state->is_ipv6_selftest && cur_len == state->desired_path_len - 2)
+    flags |= CRN_INITIATE_IPV6_EXTEND;
 
   /** If a hidden service circuit wants a specific middle node, pin it. */
   if (middle_node_must_be_vanguard(options, purpose, cur_len)) {
diff --git a/src/feature/nodelist/node_select.c b/src/feature/nodelist/node_select.c
index 40d0f2a5b..8e7da1ae2 100644
--- a/src/feature/nodelist/node_select.c
+++ b/src/feature/nodelist/node_select.c
@@ -930,25 +930,33 @@ nodelist_subtract(smartlist_t *sl, const smartlist_t *excluded)
   bitarray_free(excluded_idx);
 }
 
-/** Return a random running node from the nodelist. Never
- * pick a node that is in
- * <b>excludedsmartlist</b>, or which matches <b>excludedset</b>,
- * even if they are the only nodes available.
- * If <b>CRN_NEED_UPTIME</b> is set in flags and any router has more than
- * a minimum uptime, return one of those.
- * If <b>CRN_NEED_CAPACITY</b> is set in flags, weight your choice by the
- * advertised capacity of each router.
- * If <b>CRN_NEED_GUARD</b> is set in flags, consider only Guard routers.
- * If <b>CRN_WEIGHT_AS_EXIT</b> is set in flags, we weight bandwidths as if
- * picking an exit node, otherwise we weight bandwidths for picking a relay
- * node (that is, possibly discounting exit nodes).
- * If <b>CRN_NEED_DESC</b> is set in flags, we only consider nodes that
- * have a routerinfo or microdescriptor -- that is, enough info to be
- * used to build a circuit.
- * If <b>CRN_PREF_ADDR</b> is set in flags, we only consider nodes that
- * have an address that is preferred by the ClientPreferIPv6ORPort setting
- * (regardless of this flag, we exclude nodes that aren't allowed by the
- * firewall, including ClientUseIPv4 0 and fascist_firewall_use_ipv6() == 0).
+/** Return a random running node from the nodelist. Never pick a node that is
+ * in <b>excludedsmartlist</b>, or which matches <b>excludedset</b>, even if
+ * they are the only nodes available.
+ *
+ * If the following <b>flags</b> are set:
+ *  - <b>CRN_NEED_UPTIME</b>: if any router has more than a minimum uptime,
+ *                            return one of those;
+ *  - <b>CRN_NEED_CAPACITY</b>: weight your choice by the advertised capacity
+ *                              of each router;
+ *  - <b>CRN_NEED_GUARD</b>: only consider Guard routers;
+ *  - <b>CRN_WEIGHT_AS_EXIT</b>: we weight bandwidths as if picking an exit
+ *                               node, otherwise we weight bandwidths for
+ *                               picking a relay node (that is, possibly
+ *                               discounting exit nodes);
+ *  - <b>CRN_NEED_DESC</b>: only consider nodes that have a routerinfo or
+ *                          microdescriptor -- that is, enough info to be
+ *                          used to build a circuit;
+ *  - <b>CRN_DIRECT_CONN</b>: only consider nodes that are suitable for direct
+ *                            connections. Check ReachableAddresses,
+ *                            ClientUseIPv4 0, and
+ *                            fascist_firewall_use_ipv6() == 0);
+ *  - <b>CRN_PREF_ADDR</b>: only consider nodes that have an address that is
+ *                          preferred by the ClientPreferIPv6ORPort setting.
+ *  - <b>CRN_RENDEZVOUS_V3</b>: only consider nodes that can become v3 onion
+ *                              service rendezvous points.
+ *  - <b>CRN_INITIATE_IPV6_EXTEND</b>: only consider routers than can initiate
+ *                                     IPv6 extends.
  */
 const node_t *
 router_choose_random_node(smartlist_t *excludedsmartlist,
@@ -963,6 +971,7 @@ router_choose_random_node(smartlist_t *excludedsmartlist,
   const int pref_addr = (flags & CRN_PREF_ADDR) != 0;
   const int direct_conn = (flags & CRN_DIRECT_CONN) != 0;
   const int rendezvous_v3 = (flags & CRN_RENDEZVOUS_V3) != 0;
+  const bool initiate_ipv6_extend = (flags & CRN_INITIATE_IPV6_EXTEND) != 0;
 
   const smartlist_t *node_list = nodelist_get_list();
   smartlist_t *sl=smartlist_new(),
@@ -997,7 +1006,7 @@ router_choose_random_node(smartlist_t *excludedsmartlist,
 
   router_add_running_nodes_to_smartlist(sl, need_uptime, need_capacity,
                                         need_guard, need_desc, pref_addr,
-                                        direct_conn);
+                                        direct_conn, initiate_ipv6_extend);
   log_debug(LD_CIRC,
            "We found %d running nodes.",
             smartlist_len(sl));
diff --git a/src/feature/nodelist/node_select.h b/src/feature/nodelist/node_select.h
index 2e67f990f..29b6e6f2c 100644
--- a/src/feature/nodelist/node_select.h
+++ b/src/feature/nodelist/node_select.h
@@ -28,6 +28,8 @@ typedef enum router_crn_flags_t {
   /* On clients, only provide nodes with HSRend >= 2 protocol version which
    * is required for hidden service version >= 3. */
   CRN_RENDEZVOUS_V3 = 1<<9,
+  /* On clients, only provide nodes that can initiate IPv6 extends. */
+  CRN_INITIATE_IPV6_EXTEND = 1<<10,
 } router_crn_flags_t;
 
 /** Possible ways to weight routers when choosing one randomly.  See
diff --git a/src/feature/nodelist/routerlist.c b/src/feature/nodelist/routerlist.c
index e51125626..0d3d1bea3 100644
--- a/src/feature/nodelist/routerlist.c
+++ b/src/feature/nodelist/routerlist.c
@@ -512,13 +512,15 @@ routers_have_same_or_addrs(const routerinfo_t *r1, const routerinfo_t *r2)
 }
 
 /** Add every suitable node from our nodelist to <b>sl</b>, so that
- * we can pick a node for a circuit.
+ * we can pick a node for a circuit. See router_choose_random_node()
+ * for details.
  */
 void
 router_add_running_nodes_to_smartlist(smartlist_t *sl, int need_uptime,
                                       int need_capacity, int need_guard,
                                       int need_desc, int pref_addr,
-                                      int direct_conn)
+                                      int direct_conn,
+                                      bool initiate_ipv6_extend)
 {
   const int check_reach = !router_or_conn_should_skip_reachable_address_check(
                                                        get_options(),
@@ -545,7 +547,8 @@ router_add_running_nodes_to_smartlist(smartlist_t *sl, int need_uptime,
                                       FIREWALL_OR_CONNECTION,
                                       pref_addr))
       continue;
-
+    if (initiate_ipv6_extend && !node_supports_initiating_ipv6_extends(node))
+      continue;
     smartlist_add(sl, (void *)node);
   } SMARTLIST_FOREACH_END(node);
 }
diff --git a/src/feature/nodelist/routerlist.h b/src/feature/nodelist/routerlist.h
index 401ce5e35..1297bb4b6 100644
--- a/src/feature/nodelist/routerlist.h
+++ b/src/feature/nodelist/routerlist.h
@@ -61,7 +61,8 @@ int routers_have_same_or_addrs(const routerinfo_t *r1, const routerinfo_t *r2);
 void router_add_running_nodes_to_smartlist(smartlist_t *sl, int need_uptime,
                                            int need_capacity, int need_guard,
                                            int need_desc, int pref_addr,
-                                           int direct_conn);
+                                           int direct_conn,
+                                           bool initiate_ipv6_extend);
 
 const routerinfo_t *routerlist_find_my_routerinfo(void);
 uint32_t router_get_advertised_bandwidth(const routerinfo_t *router);





More information about the tor-commits mailing list