Add new option ClientAutoIPv6ORPort to switch between IPv4 and IPv6 OR ports

This commit is contained in:
Neel Chauhan 2018-09-26 19:14:33 -04:00 committed by Nick Mathewson
parent c82163dff4
commit 822cb93cab
7 changed files with 37 additions and 2 deletions

6
changes/ticket27490 Normal file
View File

@ -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.

View File

@ -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 other clients prefer IPv4. Other things may influence the choice. This
option breaks a tie to the favor of IPv6. (Default: auto) 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__:: [[PathsNeededToBuildCircuits]] **PathsNeededToBuildCircuits** __NUM__::
Tor clients don't build circuits for user traffic until they know Tor clients don't build circuits for user traffic until they know
about enough of the network so that they could potentially construct about enough of the network so that they could potentially construct

View File

@ -332,6 +332,7 @@ static config_var_t option_vars_[] = {
V(ClientOnly, BOOL, "0"), V(ClientOnly, BOOL, "0"),
V(ClientPreferIPv6ORPort, AUTOBOOL, "auto"), V(ClientPreferIPv6ORPort, AUTOBOOL, "auto"),
V(ClientPreferIPv6DirPort, AUTOBOOL, "auto"), V(ClientPreferIPv6DirPort, AUTOBOOL, "auto"),
V(ClientAutoIPv6ORPort, BOOL, "0"),
V(ClientRejectInternalAddresses, BOOL, "1"), V(ClientRejectInternalAddresses, BOOL, "1"),
V(ClientTransportPlugin, LINELIST, NULL), V(ClientTransportPlugin, LINELIST, NULL),
V(ClientUseIPv6, BOOL, "0"), V(ClientUseIPv6, BOOL, "0"),

View File

@ -666,6 +666,9 @@ struct or_options_t {
* accessing this value directly. */ * accessing this value directly. */
int ClientPreferIPv6DirPort; 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. */ /** The length of time that we think a consensus should be fresh. */
int V3AuthVotingInterval; int V3AuthVotingInterval;
/** The length of time we think it will take to distribute votes. */ /** The length of time we think it will take to distribute votes. */

View File

@ -2069,6 +2069,11 @@ connection_connect_log_client_use_ip_version(const connection_t *conn)
return; 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 */ /* Check if we couldn't satisfy an address family preference */
if ((!pref_ipv6 && tor_addr_family(&real_addr) == AF_INET6) if ((!pref_ipv6 && tor_addr_family(&real_addr) == AF_INET6)
|| (pref_ipv6 && tor_addr_family(&real_addr) == AF_INET)) { || (pref_ipv6 && tor_addr_family(&real_addr) == AF_INET)) {

View File

@ -28,6 +28,7 @@
#include "feature/nodelist/routerparse.h" #include "feature/nodelist/routerparse.h"
#include "feature/stats/geoip.h" #include "feature/stats/geoip.h"
#include "ht.h" #include "ht.h"
#include "lib/crypt_ops/crypto_rand.h"
#include "lib/encoding/confline.h" #include "lib/encoding/confline.h"
#include "core/or/addr_policy_st.h" #include "core/or/addr_policy_st.h"
@ -487,6 +488,15 @@ fascist_firewall_prefer_ipv6_impl(const or_options_t *options)
return -1; 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? /** Do we prefer to connect to IPv6 ORPorts?
* Use node_ipv6_or_preferred() whenever possible: it supports bridge client * Use node_ipv6_or_preferred() whenever possible: it supports bridge client
* per-node IPv6 preferences. * 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? */ /* 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; return 1;
} }

View File

@ -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. */ /* Mark which address to use based on which bridge_t we got. */
node->ipv6_preferred = (tor_addr_family(&bridge->addr) == AF_INET6 && node->ipv6_preferred = (tor_addr_family(&bridge->addr) == AF_INET6 &&
!tor_addr_is_null(&node->ri->ipv6_addr)); !tor_addr_is_null(&node->ri->ipv6_addr));