Commit 2d33d192 authored by teor (Tim Wilson-Brown)'s avatar teor (Tim Wilson-Brown)
Browse files

Add ClientUseIPv4 and ClientPreferIPv6DirPort torrc options

ClientUseIPv4 0 tells tor to avoid IPv4 client connections.
ClientPreferIPv6DirPort 1 tells tor to prefer IPv6 directory connections.

Refactor policy for IPv4/IPv6 preferences.

Fix a bug where node->ipv6_preferred could become stale if
ClientPreferIPv6ORPort was changed after the consensus was loaded.

Update documentation, existing code, add unit tests.
parent 4460feaf
Loading
Loading
Loading
Loading

changes/feature17840

0 → 100644
+9 −0
Original line number Diff line number Diff line
  o Minor feature (IPv6):
    - Add ClientUseIPv4, which is set to 1 by default. If set to 0, tor
      avoids using IPv4 for client OR and directory connections.
    - Add ClientPreferIPv6DirPort, which is set to 0 by default. If set
      to 1, tor prefers IPv6 directory addresses.
    - Try harder to fulfil IP version restrictions ClientUseIPv4 0 and
      ClientUseIPv6 0; and the preferences ClientPreferIPv6ORPort and
      ClientPreferIPv6DirPort.
      Closes ticket 17840; patch by "teor".
+26 −7
Original line number Diff line number Diff line
@@ -367,6 +367,7 @@ GENERAL OPTIONS
    authorities.
    By default, the directory authorities are also FallbackDirs. Specifying a
    FallbackDir replaces Tor's default hard-coded FallbackDirs (if any).
    (See the **DirAuthority** entry for an explanation of each flag.)

[[UseDefaultFallbackDirs]] **UseDefaultFallbackDirs** **0**|**1**::
    Use Tor's default hard-coded FallbackDirs (if any). (When a
@@ -390,6 +391,10 @@ GENERAL OPTIONS
    if an "ipv6=__address__:__orport__" flag is present, then the directory
    authority is listening for IPv6 connections on the indicated IPv6 address
    and OR Port. +
 +
    Tor will contact the authority at __address__:__port__ (the DirPort) to
    download directory documents. If an IPv6 address is supplied, Tor will
    also download directory documents at the IPv6 address on the DirPort. +
 +
    If no **DirAuthority** line is given, Tor will use the default directory
    authorities. NOTE: this option is intended for setting up a private Tor
@@ -1483,17 +1488,31 @@ The following options are useful only for clients (that is, if
    If no defaults are available there, these options default to 20, .80,
    .60, and 100, respectively.

[[ClientUseIPv4]] **ClientUseIPv4** **0**|**1**::
    If this option is set to 0, Tor will avoid connecting to directory servers
    and entry nodes over IPv4. Note that clients with an IPv4
    address in a **Bridge**, proxy, or pluggable transport line will try
    connecting over IPv4 even if **ClientUseIPv4** is set to 0. (Default: 1)

[[ClientUseIPv6]] **ClientUseIPv6** **0**|**1**::
    If this option is set to 1, Tor might connect to entry nodes over
    IPv6. Note that clients configured with an IPv6 address in a
    **Bridge** line will try connecting over IPv6 even if
    **ClientUseIPv6** is set to 0. (Default: 0)
    If this option is set to 1, Tor might connect to directory servers or
    entry nodes over IPv6. Note that clients configured with an IPv6 address
    in a **Bridge**, proxy, or pluggable transport line will try connecting
    over IPv6 even if **ClientUseIPv6** is set to 0. (Default: 0)

[[ClientPreferIPv6DirPort]] **ClientPreferIPv6DirPort** **0**|**1**::
    If this option is set to 1, Tor prefers a directory port with an IPv6
    address over one with IPv4, for direct connections, if a given directory
    server has both. (Tor also prefers an IPv6 DirPort if IPv4Client is set to
    0.) Other things may influence the choice. This option breaks a tie to the
    favor of IPv6. (Default: 0)

[[ClientPreferIPv6ORPort]] **ClientPreferIPv6ORPort** **0**|**1**::
    If this option is set to 1, Tor prefers an OR port with an IPv6
    address over one with IPv4 if a given entry node has both. Other
    things may influence the choice. This option breaks a tie to the
    favor of IPv6. (Default: 0)
    address over one with IPv4 if a given entry node has both. (Tor also
    prefers an IPv6 ORPort if IPv4Client is set to 0.) Other things may
    influence the choice. This option breaks a tie to the favor of IPv6.
    (Default: 0)

[[PathsNeededToBuildCircuits]] **PathsNeededToBuildCircuits** __NUM__::
    Tor clients don't build circuits for user traffic until they know
+6 −8
Original line number Diff line number Diff line
@@ -2161,14 +2161,12 @@ choose_good_entry_server(uint8_t purpose, cpath_build_state_t *state)
     * family. */
    nodelist_add_node_and_family(excluded, node);
  }
  if (firewall_is_fascist_or()) {
  /* Exclude all ORs that we can't reach through our firewall */
  smartlist_t *nodes = nodelist_get_list();
  SMARTLIST_FOREACH(nodes, const node_t *, node, {
      if (!fascist_firewall_allows_node(node))
    if (!fascist_firewall_allows_node(node, FIREWALL_OR_CONNECTION, 0))
      smartlist_add(excluded, (void*)node);
  });
  }
  /* and exclude current entry guards and their families,
   * unless we're in a test network, and excluding guards
   * would exclude all nodes (i.e. we're in an incredibly small tor network,
+48 −3
Original line number Diff line number Diff line
@@ -191,9 +191,11 @@ static config_var_t option_vars_[] = {
  V(ClientDNSRejectInternalAddresses, BOOL,"1"),
  V(ClientOnly,                  BOOL,     "0"),
  V(ClientPreferIPv6ORPort,      BOOL,     "0"),
  V(ClientPreferIPv6DirPort,     BOOL,     "0"),
  V(ClientRejectInternalAddresses, BOOL,   "1"),
  V(ClientTransportPlugin,       LINELIST, NULL),
  V(ClientUseIPv6,               BOOL,     "0"),
  V(ClientUseIPv4,               BOOL,     "1"),
  V(ConsensusParams,             STRING,   NULL),
  V(ConnLimit,                   UINT,     "1000"),
  V(ConnDirectionStatistics,     BOOL,     "0"),
@@ -3071,6 +3073,9 @@ options_validate(or_options_t *old_options, or_options_t *options,
    }
  }

  /* Terminate Reachable*Addresses with reject *, but check if it has an
   * IPv6 entry on the way through */
  int reachable_knows_ipv6 = 0;
  for (i=0; i<3; i++) {
    config_line_t **linep =
      (i==0) ? &options->ReachableAddresses :
@@ -3080,7 +3085,19 @@ options_validate(or_options_t *old_options, or_options_t *options,
      continue;
    /* We need to end with a reject *:*, not an implicit accept *:* */
    for (;;) {
      if (!strcmp((*linep)->value, "reject *:*")) /* already there */
      /* Check if the policy has an IPv6 entry, or uses IPv4-specific
       * policies (and therefore we assume it's aware of IPv6). */
      if (!strcmpstart((*linep)->value, "accept6") ||
          !strcmpstart((*linep)->value, "reject6") ||
          !strstr((*linep)->value, "*6") ||
          strchr((*linep)->value, '[') ||
          !strcmpstart((*linep)->value, "accept4") ||
          !strcmpstart((*linep)->value, "reject4") ||
          !strstr((*linep)->value, "*4"))
        reachable_knows_ipv6 = 1;
       /* already has a reject all */
      if (!strcmp((*linep)->value, "reject *:*") ||
          !strcmp((*linep)->value, "reject *"))
        break;
      linep = &((*linep)->next);
      if (!*linep) {
@@ -3095,13 +3112,41 @@ options_validate(or_options_t *old_options, or_options_t *options,
    }
  }

  if ((options->ReachableAddresses ||
  if (options->ClientUseIPv6 &&
      (options->ReachableAddresses ||
       options->ReachableORAddresses ||
       options->ReachableDirAddresses) &&
      !reachable_knows_ipv6)
    log_warn(LD_CONFIG, "You have set ClientUseIPv6 1 and at least one of "
             "ReachableAddresses, ReachableORAddresses, or "
             "ReachableDirAddresses, but without any IPv6-specific rules. "
             "Tor won't connect to any IPv6 addresses, unless a rule accepts "
             "them. (Use 'accept6 *:*' or 'reject6 *:*' as the last rule to "
             "disable this warning.)");

  if ((options->ReachableAddresses ||
       options->ReachableORAddresses ||
       options->ReachableDirAddresses ||
       options->ClientUseIPv4 == 0) &&
      server_mode(options))
    REJECT("Servers must be able to freely connect to the rest "
           "of the Internet, so they must not set Reachable*Addresses "
           "or FascistFirewall.");
           "or FascistFirewall or FirewallPorts or ClientUseIPv4 0.");

  /* We check if Reachable*Addresses blocks all addresses in
   * parse_reachable_addresses(). */
  if (options->ClientUseIPv4 == 0 && options->ClientUseIPv6 == 0)
    REJECT("Tor cannot connect to the Internet if ClientUseIPv4 is 0 and "
           "ClientUseIPv6 is 0. Please set at least one of these options "
           "to 1.");

  if (options->ClientUseIPv6 == 0 && options->ClientPreferIPv6ORPort == 1)
    log_warn(LD_CONFIG, "ClientPreferIPv6ORPort 1 is ignored unless "
             "ClientUseIPv6 is also 1.");

  if (options->ClientUseIPv6 == 0 && options->ClientPreferIPv6DirPort == 1)
    log_warn(LD_CONFIG, "ClientPreferIPv6DirPort 1 is ignored unless "
             "ClientUseIPv6 is also 1.");

  if (options->UseBridges &&
      server_mode(options))
+2 −0
Original line number Diff line number Diff line
@@ -37,6 +37,7 @@
#include "ext_orport.h"
#include "geoip.h"
#include "main.h"
#include "nodelist.h"
#include "policies.h"
#include "reasons.h"
#include "relay.h"
@@ -44,6 +45,7 @@
#include "rendcommon.h"
#include "rephist.h"
#include "router.h"
#include "routerlist.h"
#include "transports.h"
#include "routerparse.h"
#include "transports.h"
Loading