diff options
-rw-r--r-- | doc/man/tor.1.txt | 6 | ||||
-rw-r--r-- | src/app/config/config.c | 1 | ||||
-rw-r--r-- | src/app/config/or_options_st.h | 4 | ||||
-rw-r--r-- | src/app/config/resolve_addr.c | 7 | ||||
-rw-r--r-- | src/feature/relay/relay_find_addr.c | 7 | ||||
-rw-r--r-- | src/test/test_config.c | 19 | ||||
-rw-r--r-- | src/test/test_relay.c | 2 |
7 files changed, 46 insertions, 0 deletions
diff --git a/doc/man/tor.1.txt b/doc/man/tor.1.txt index ca54fa125b..43fef69466 100644 --- a/doc/man/tor.1.txt +++ b/doc/man/tor.1.txt @@ -2138,6 +2138,12 @@ is non-zero): binds to. To bind to a different address, use the ORPort and OutboundBindAddress options. +[[AddressDisableIPv6]] **AddressDisableIPv6** **0**|**1**:: + By default, Tor will attempt to find the IPv6 of the relay if there is no + IPv4Only ORPort. If set, this options disable IPv6 auto discovery which + means no IPv6 address resolution, no IPv6 ORPorts, no IPv6 reachability + checks, and won't publish an IPv6 ORPort in its descriptor. (Default: 0) + [[AssumeReachable]] **AssumeReachable** **0**|**1**:: This option is used when bootstrapping a new Tor network. If set to 1, don't do self-reachability testing; just upload your server descriptor diff --git a/src/app/config/config.c b/src/app/config/config.c index 7d147ef456..9e7d1179ba 100644 --- a/src/app/config/config.c +++ b/src/app/config/config.c @@ -315,6 +315,7 @@ static const config_var_t option_vars_[] = { VAR("AccountingRule", STRING, AccountingRule_option, "max"), V(AccountingStart, STRING, NULL), V(Address, LINELIST, NULL), + V(AddressDisableIPv6, BOOL, "0"), OBSOLETE("AllowDotExit"), OBSOLETE("AllowInvalidNodes"), V(AllowNonRFC953Hostnames, BOOL, "0"), diff --git a/src/app/config/or_options_st.h b/src/app/config/or_options_st.h index 07126cc6ce..68be5711ce 100644 --- a/src/app/config/or_options_st.h +++ b/src/app/config/or_options_st.h @@ -75,6 +75,10 @@ struct or_options_t { * options is accepted as in IPv4 and IPv6. */ struct config_line_t *Address; + /** Boolean: If set, disable IPv6 address resolution, IPv6 ORPorts, IPv6 + * reachability checks, and publishing an IPv6 ORPort in its descriptor. */ + int AddressDisableIPv6; + char *PidFile; /**< Where to store PID of Tor process. */ struct routerset_t *ExitNodes; /**< Structure containing nicknames, digests, diff --git a/src/app/config/resolve_addr.c b/src/app/config/resolve_addr.c index ba1c854d77..d23e39b62d 100644 --- a/src/app/config/resolve_addr.c +++ b/src/app/config/resolve_addr.c @@ -632,6 +632,13 @@ find_my_address(const or_options_t *options, int family, int warn_severity, if (method_out) *method_out = NULL; if (hostname_out) *hostname_out = NULL; + /* If an IPv6 is requested, check if IPv6 address discovery is disabled and + * if so we always return a failure. It is done here so we don't populate + * the resolve cache or do any DNS resolution. */ + if (family == AF_INET6 && options->AddressDisableIPv6) { + return false; + } + /* * Step 1: Discover address by attempting 3 different methods consecutively. */ diff --git a/src/feature/relay/relay_find_addr.c b/src/feature/relay/relay_find_addr.c index 48f28b182a..43b958d563 100644 --- a/src/feature/relay/relay_find_addr.c +++ b/src/feature/relay/relay_find_addr.c @@ -105,6 +105,13 @@ relay_find_addr_to_publish, (const or_options_t *options, int family, tor_addr_make_unspec(addr_out); + /* If an IPv6 is requested, check if IPv6 address discovery is disabled on + * this instance. If so, we return a failure. It is done here so we don't + * query the suggested cache that might be populated with an IPv6. */ + if (family == AF_INET6 && options->AddressDisableIPv6) { + return false; + } + /* First, check our resolved address cache. It should contain the address * we've discovered from the periodic relay event. */ resolved_addr_get_last(family, addr_out); diff --git a/src/test/test_config.c b/src/test/test_config.c index 71b2cdf2f4..376200827d 100644 --- a/src/test/test_config.c +++ b/src/test/test_config.c @@ -1260,6 +1260,7 @@ get_interface_address6_failure(int severity, sa_family_t family, do { \ config_free_lines(options->Address); \ config_free_lines(options->ORPort_lines); \ + options->AddressDisableIPv6 = 0; \ options->ORPort_set = 0; \ tor_free(options->DirAuthorities); \ tor_free(hostname_out); \ @@ -1456,6 +1457,24 @@ test_config_find_my_address(void *arg) options_init(options); /* + * Case 0: + * AddressDisableIPv6 is set. + * + * Only run this if we are in the IPv6 test. + */ + if (p->family == AF_INET6) { + options->AddressDisableIPv6 = 1; + /* Set a valid IPv6. However, the discovery should still fail. */ + config_line_append(&options->Address, "Address", p->public_ip); + tor_addr_parse(&test_addr, p->public_ip); + + retval = find_my_address(options, p->family, LOG_NOTICE, &resolved_addr, + &method_used, &hostname_out); + VALIDATE_FOUND_ADDRESS(false, NULL, NULL); + CLEANUP_FOUND_ADDRESS; + } + + /* * Case 1: * 1. Address is a valid address. * diff --git a/src/test/test_relay.c b/src/test/test_relay.c index 60db98aec3..ee704ceb8c 100644 --- a/src/test/test_relay.c +++ b/src/test/test_relay.c @@ -302,6 +302,8 @@ test_find_addr_to_publish(void *arg) (void) arg; + memset(&options, 0, sizeof(options)); + /* Populate our resolved cache with a valid IPv4 and IPv6. */ family = tor_addr_parse(&ipv4_addr, "1.2.3.4"); tt_int_op(family, OP_EQ, AF_INET); |