[tor-commits] [tor/master] Add new option ClientAutoIPv6ORPort to switch between IPv4 and IPv6 OR ports

nickm at torproject.org nickm at torproject.org
Sun Dec 2 01:32:25 UTC 2018


commit 822cb93cab59e9735e2efda70bc88c47cc92c498
Author: Neel Chauhan <neel at neelc.org>
Date:   Wed Sep 26 19:14:33 2018 -0400

    Add new option ClientAutoIPv6ORPort to switch between IPv4 and IPv6 OR ports
---
 changes/ticket27490            |  6 ++++++
 doc/tor.1.txt                  |  6 ++++++
 src/app/config/config.c        |  1 +
 src/app/config/or_options_st.h |  3 +++
 src/core/mainloop/connection.c |  5 +++++
 src/core/or/policies.c         | 15 ++++++++++++++-
 src/feature/client/bridges.c   |  3 ++-
 7 files changed, 37 insertions(+), 2 deletions(-)

diff --git a/changes/ticket27490 b/changes/ticket27490
new file mode 100644
index 000000000..523477dfe
--- /dev/null
+++ b/changes/ticket27490
@@ -0,0 +1,6 @@
+  o Minor features (ipv6):
+    - We add an option ClientAutoIPv6ORPort which makes clients randomly
+      prefer a node's IPv4 or IPv6 ORPort. The random preference is set
+      every time a node is loaded from a new consensus or bridge config.
+      Closes ticket 27490. Patch by Neel Chauhan.
+
diff --git a/doc/tor.1.txt b/doc/tor.1.txt
index 406372433..bd4dbbcbd 100644
--- a/doc/tor.1.txt
+++ b/doc/tor.1.txt
@@ -1748,6 +1748,12 @@ The following options are useful only for clients (that is, if
     other clients prefer IPv4. Other things may influence the choice. This
     option breaks a tie to the favor of IPv6. (Default: auto)
 
+[[ClientAutoIPv6ORPort]] **ClientAutoIPv6ORPort** **0**|**1**::
+    If this option is set to 1, Tor clients randomly prefer a node's IPv4 or
+    IPv6 ORPort. The random preference is set every time a node is loaded
+    from a new consensus or bridge config. When this option is set to 1,
+    **ClientPreferIPv6ORPort** is ignored. (Default: 0)
+
 [[PathsNeededToBuildCircuits]] **PathsNeededToBuildCircuits** __NUM__::
     Tor clients don't build circuits for user traffic until they know
     about enough of the network so that they could potentially construct
diff --git a/src/app/config/config.c b/src/app/config/config.c
index 01b48e3c5..6a510c56d 100644
--- a/src/app/config/config.c
+++ b/src/app/config/config.c
@@ -332,6 +332,7 @@ static config_var_t option_vars_[] = {
   V(ClientOnly,                  BOOL,     "0"),
   V(ClientPreferIPv6ORPort,      AUTOBOOL, "auto"),
   V(ClientPreferIPv6DirPort,     AUTOBOOL, "auto"),
+  V(ClientAutoIPv6ORPort,        BOOL,     "0"),
   V(ClientRejectInternalAddresses, BOOL,   "1"),
   V(ClientTransportPlugin,       LINELIST, NULL),
   V(ClientUseIPv6,               BOOL,     "0"),
diff --git a/src/app/config/or_options_st.h b/src/app/config/or_options_st.h
index 3524b99b5..ff3d30d7e 100644
--- a/src/app/config/or_options_st.h
+++ b/src/app/config/or_options_st.h
@@ -666,6 +666,9 @@ struct or_options_t {
    * accessing this value directly.  */
   int ClientPreferIPv6DirPort;
 
+  /** If true, prefer an IPv4 or IPv6 OR port at random. */
+  int ClientAutoIPv6ORPort;
+
   /** The length of time that we think a consensus should be fresh. */
   int V3AuthVotingInterval;
   /** The length of time we think it will take to distribute votes. */
diff --git a/src/core/mainloop/connection.c b/src/core/mainloop/connection.c
index 4231bec01..9f8169082 100644
--- a/src/core/mainloop/connection.c
+++ b/src/core/mainloop/connection.c
@@ -2069,6 +2069,11 @@ connection_connect_log_client_use_ip_version(const connection_t *conn)
     return;
   }
 
+  if (fascist_firewall_use_ipv6(options)) {
+    log_info(LD_NET, "Our outgoing connection is using IPv%d.",
+             tor_addr_family(&real_addr) == AF_INET6 ? 6 : 4);
+  }
+
   /* Check if we couldn't satisfy an address family preference */
   if ((!pref_ipv6 && tor_addr_family(&real_addr) == AF_INET6)
       || (pref_ipv6 && tor_addr_family(&real_addr) == AF_INET)) {
diff --git a/src/core/or/policies.c b/src/core/or/policies.c
index 3443a1710..e51a49cf6 100644
--- a/src/core/or/policies.c
+++ b/src/core/or/policies.c
@@ -28,6 +28,7 @@
 #include "feature/nodelist/routerparse.h"
 #include "feature/stats/geoip.h"
 #include "ht.h"
+#include "lib/crypt_ops/crypto_rand.h"
 #include "lib/encoding/confline.h"
 
 #include "core/or/addr_policy_st.h"
@@ -487,6 +488,15 @@ fascist_firewall_prefer_ipv6_impl(const or_options_t *options)
   return -1;
 }
 
+/* Choose whether we prefer IPv4 or IPv6 by randomly choosing an address
+ * family. Return 0 for IPv4, and 1 for IPv6. */
+static int
+fascist_firewall_rand_prefer_ipv6_addr(void)
+{
+  /* TODO: Check for failures, and infer our preference based on this. */
+  return crypto_rand_int(2);
+}
+
 /** Do we prefer to connect to IPv6 ORPorts?
  * Use node_ipv6_or_preferred() whenever possible: it supports bridge client
  * per-node IPv6 preferences.
@@ -501,7 +511,10 @@ fascist_firewall_prefer_ipv6_orport(const or_options_t *options)
   }
 
   /* We can use both IPv4 and IPv6 - which do we prefer? */
-  if (options->ClientPreferIPv6ORPort == 1) {
+  if (options->ClientAutoIPv6ORPort == 1) {
+    /* If ClientAutoIPv6ORPort is 1, we prefer IPv4 or IPv6 at random. */
+    return fascist_firewall_rand_prefer_ipv6_addr();
+  } else if (options->ClientPreferIPv6ORPort == 1) {
     return 1;
   }
 
diff --git a/src/feature/client/bridges.c b/src/feature/client/bridges.c
index e8afb5a92..e3ed28841 100644
--- a/src/feature/client/bridges.c
+++ b/src/feature/client/bridges.c
@@ -844,7 +844,8 @@ rewrite_node_address_for_bridge(const bridge_info_t *bridge, node_t *node)
       }
     }
 
-    if (options->ClientPreferIPv6ORPort == -1) {
+    if (options->ClientPreferIPv6ORPort == -1 ||
+        options->ClientAutoIPv6ORPort == 0) {
       /* Mark which address to use based on which bridge_t we got. */
       node->ipv6_preferred = (tor_addr_family(&bridge->addr) == AF_INET6 &&
                               !tor_addr_is_null(&node->ri->ipv6_addr));





More information about the tor-commits mailing list