addr: Prioritize interface lookup over local hostname

The find_my_address() function now prioritize the local interface over the
local hostname when guessing the IP address.

See proposal 312, section 3.2.1, general case:
https://gitweb.torproject.org/torspec.git/tree/proposals/312-relay-auto-ipv6-addr.txt#n359

The entire unit tests had to be refactored to make this possible. Instead of
hot patching it, it has been rewritten to cover all possible cases and the
test interface has been changed to accomodate both IPv4 and IPv6 in order for
them to be tested identically.

Closes #33238

Signed-off-by: David Goulet <dgoulet@torproject.org>
This commit is contained in:
David Goulet 2020-07-02 09:44:49 -04:00 committed by Nick Mathewson
parent 9b560ea714
commit 45afb31e1c
3 changed files with 283 additions and 713 deletions

5
changes/ticket33238 Normal file
View File

@ -0,0 +1,5 @@
o Minor feature (address discovery):
- If no Address statements are found, relays now prioritize guessing their
address by looking at the local interface instead of the local hostname.
If the interface address can't be found, the local hostname is used.
Closes ticket 33238.

View File

@ -445,8 +445,8 @@ static fn_address_ret_t
{ {
/* These functions are in order for our find address algorithm. */ /* These functions are in order for our find address algorithm. */
get_address_from_config, get_address_from_config,
get_address_from_hostname,
get_address_from_interface, get_address_from_interface,
get_address_from_hostname,
}; };
/** Length of address table as in how many functions. */ /** Length of address table as in how many functions. */
static const size_t fn_address_table_len = ARRAY_LENGTH(fn_address_table); static const size_t fn_address_table_len = ARRAY_LENGTH(fn_address_table);
@ -478,7 +478,17 @@ static const size_t fn_address_table_len = ARRAY_LENGTH(fn_address_table);
* *
* If no given Address, fallback to the local hostname (see section 2). * If no given Address, fallback to the local hostname (see section 2).
* *
* 2. Look at the local hostname. * 2. Look at the network interface.
*
* Attempt to find the first public usable address from the list of
* network interface returned by the OS.
*
* On failure, we attempt to look at the local hostname (3).
*
* On success, addr_out is set with it, method_out is set to "INTERFACE"
* and hostname_out is set to NULL.
*
* 3. Look at the local hostname.
* *
* If the local hostname resolves to a non internal address, addr_out is * If the local hostname resolves to a non internal address, addr_out is
* set with it, method_out is set to "GETHOSTNAME" and hostname_out is set * set with it, method_out is set to "GETHOSTNAME" and hostname_out is set
@ -489,20 +499,7 @@ static const size_t fn_address_table_len = ARRAY_LENGTH(fn_address_table);
* If the local hostname resolves to an internal address, an error is * If the local hostname resolves to an internal address, an error is
* returned. * returned.
* *
* If the local hostname can NOT be resolved, fallback to the network * If the local hostname can NOT be resolved, an error is returned.
* interface (see section 3).
*
* 3. Look at the network interface.
*
* Attempt to find the first public usable address from the list of
* network interface returned by the OS.
*
* On failure, an error is returned. This error indicates that all
* attempts have failed and thus the address for the given family can not
* be found.
*
* On success, addr_out is set with it, method_out is set to "INTERFACE"
* and hostname_out is set to NULL.
* *
* @param options Global configuration options. * @param options Global configuration options.
* @param family IP address family. Only AF_INET and AF_INET6 are supported. * @param family IP address family. Only AF_INET and AF_INET6 are supported.

File diff suppressed because it is too large Load Diff