commit b8042c9d9a44eaf78c5580a1b0a3d15a90f125ce Author: David Goulet dgoulet@torproject.org Date: Thu Jun 18 16:07:22 2020 -0400
addr: Make resolve_my_address_v4() use find_my_address()
In order to transition smoothly, maek resolve_my_address_v4() call the new fancy find_my_address() with AF_INET.
Next commits should remove the use of resolve_my_address_v4() accross the code to use find_my_address().
This commit is so the unit tests would be more easily fixed and port to the new find_my_address() internals.
Part of #33233.
Signed-off-by: David Goulet dgoulet@torproject.org --- src/app/config/resolve_addr.c | 198 ++---------------------------------------- src/test/test_config.c | 126 ++++++++++++--------------- 2 files changed, 60 insertions(+), 264 deletions(-)
diff --git a/src/app/config/resolve_addr.c b/src/app/config/resolve_addr.c index 5cabb5889..9a7fbde16 100644 --- a/src/app/config/resolve_addr.c +++ b/src/app/config/resolve_addr.c @@ -579,200 +579,14 @@ resolve_my_address_v4(int warn_severity, const or_options_t *options, uint32_t *addr_out, const char **method_out, char **hostname_out) { - struct in_addr in; - uint32_t addr; /* host order */ - char hostname[256]; - const char *method_used; - const char *hostname_used; - int explicit_ip=1; - int explicit_hostname=1; - int from_interface=0; - char *addr_string = NULL; - int notice_severity = warn_severity <= LOG_NOTICE ? - LOG_NOTICE : warn_severity; - - tor_addr_t myaddr; - tor_assert(addr_out); - - /* - * Step one: Fill in 'hostname' to be our best guess. - */ - - if (options->Address) { - /* Only 1 Address is supported even though this is a list. */ - strlcpy(hostname, options->Address->value, sizeof(hostname)); - log_debug(LD_CONFIG, "Trying configured Address '%s' as local hostname", - hostname); - } else { /* then we need to guess our address */ - explicit_ip = 0; /* it's implicit */ - explicit_hostname = 0; /* it's implicit */ - - if (tor_gethostname(hostname, sizeof(hostname)) < 0) { - log_fn(warn_severity, LD_NET,"Error obtaining local hostname"); - return -1; - } - log_debug(LD_CONFIG, "Guessed local host name as '%s'", hostname); - } - - /* - * Step two: Now that we know 'hostname', parse it or resolve it. If - * it doesn't parse or resolve, look at the interface address. Set 'addr' - * to be our (host-order) 32-bit answer. - */ - - if (tor_inet_aton(hostname, &in) == 0) { - /* then we have to resolve it */ - log_debug(LD_CONFIG, "Local hostname '%s' is DNS address. " - "Trying to resolve to IP address.", hostname); - explicit_ip = 0; - if (tor_lookup_hostname(hostname, &addr)) { /* failed to resolve */ - uint32_t interface_ip; /* host order */ - - if (explicit_hostname) { - log_fn(warn_severity, LD_CONFIG, - "Could not resolve local Address '%s'. Failing.", hostname); - return -1; - } - log_fn(notice_severity, LD_CONFIG, - "Could not resolve guessed local hostname '%s'. " - "Trying something else.", hostname); - if (get_interface_address(warn_severity, &interface_ip)) { - log_fn(warn_severity, LD_CONFIG, - "Could not get local interface IP address. Failing."); - return -1; - } - from_interface = 1; - addr = interface_ip; - log_fn(notice_severity, LD_CONFIG, "Learned IP address '%s' for " - "local interface. Using that.", fmt_addr32(addr)); - strlcpy(hostname, "<guessed from interfaces>", sizeof(hostname)); - } else { /* resolved hostname into addr */ - tor_addr_from_ipv4h(&myaddr, addr); - - if (!explicit_hostname && - tor_addr_is_internal(&myaddr, 0)) { - tor_addr_t interface_ip; - - log_fn(notice_severity, LD_CONFIG, "Guessed local hostname '%s' " - "resolves to a private IP address (%s). Trying something " - "else.", hostname, fmt_addr32(addr)); - - if (get_interface_address6(warn_severity, AF_INET, &interface_ip)<0) { - log_fn(warn_severity, LD_CONFIG, - "Could not get local interface IP address. Too bad."); - } else if (tor_addr_is_internal(&interface_ip, 0)) { - log_fn(notice_severity, LD_CONFIG, - "Interface IP address '%s' is a private address too. " - "Ignoring.", fmt_addr(&interface_ip)); - } else { - from_interface = 1; - addr = tor_addr_to_ipv4h(&interface_ip); - log_fn(notice_severity, LD_CONFIG, - "Learned IP address '%s' for local interface." - " Using that.", fmt_addr32(addr)); - strlcpy(hostname, "<guessed from interfaces>", sizeof(hostname)); - } - } - } - } else { - log_debug(LD_CONFIG, "Local hostname '%s' is already IP address, " - "skipping DNS resolution", hostname); - addr = ntohl(in.s_addr); /* set addr so that addr_string is not - * illformed */ - } - - /* - * Step three: Check whether 'addr' is an internal IP address, and error - * out if it is and we don't want that. - */ - - tor_addr_from_ipv4h(&myaddr,addr); - - addr_string = tor_dup_ip(addr); - if (addr_string && tor_addr_is_internal(&myaddr, 0)) { - /* make sure we're ok with publishing an internal IP */ - if (using_default_dir_authorities(options)) { - /* if they are using the default authorities, disallow internal IPs - * always. For IPv6 ORPorts, this check is done in - * router_get_advertised_ipv6_or_ap(). See #33681. */ - log_fn(warn_severity, LD_CONFIG, - "Address '%s' resolves to private IP address '%s'. " - "Tor servers that use the default DirAuthorities must have " - "public IP addresses.", hostname, addr_string); - tor_free(addr_string); - return -1; - } - if (!explicit_ip) { - /* even if they've set their own authorities, require an explicit IP if - * they're using an internal address. */ - log_fn(warn_severity, LD_CONFIG, "Address '%s' resolves to private " - "IP address '%s'. Please set the Address config option to be " - "the IP address you want to use.", hostname, addr_string); - tor_free(addr_string); - return -1; - } - } - - /* - * Step four: We have a winner! 'addr' is our answer for sure, and - * 'addr_string' is its string form. Fill out the various fields to - * say how we decided it. - */ - - log_debug(LD_CONFIG, "Resolved Address to '%s'.", addr_string); - - if (explicit_ip) { - method_used = "CONFIGURED"; - hostname_used = NULL; - } else if (explicit_hostname) { - method_used = "RESOLVED"; - hostname_used = hostname; - } else if (from_interface) { - method_used = "INTERFACE"; - hostname_used = NULL; - } else { - method_used = "GETHOSTNAME"; - hostname_used = hostname; - } - - *addr_out = addr; - if (method_out) - *method_out = method_used; - if (hostname_out) - *hostname_out = hostname_used ? tor_strdup(hostname_used) : NULL; - - /* - * Step five: Check if the answer has changed since last time (or if - * there was no last time), and if so call various functions to keep - * us up-to-date. - */ - - if (last_resolved_addr_v4 && last_resolved_addr_v4 != *addr_out) { - /* Leave this as a notice, regardless of the requested severity, - * at least until dynamic IP address support becomes bulletproof. */ - log_notice(LD_NET, - "Your IP address seems to have changed to %s " - "(METHOD=%s%s%s). Updating.", - addr_string, method_used, - hostname_used ? " HOSTNAME=" : "", - hostname_used ? hostname_used : ""); - ip_address_changed(0); - } - - if (last_resolved_addr_v4 != *addr_out) { - control_event_server_status(LOG_NOTICE, - "EXTERNAL_ADDRESS ADDRESS=%s METHOD=%s%s%s", - addr_string, method_used, - hostname_used ? " HOSTNAME=" : "", - hostname_used ? hostname_used : ""); + tor_addr_t my_addr; + bool ret = find_my_address(options, AF_INET, warn_severity, &my_addr, + method_out, hostname_out); + if (!ret) { + return -1; } - last_resolved_addr_v4 = *addr_out; - - /* - * And finally, clean up and return success. - */
- tor_free(addr_string); + *addr_out = tor_addr_to_ipv4h(&my_addr); return 0; }
diff --git a/src/test/test_config.c b/src/test/test_config.c index 87104113b..a6b02713f 100644 --- a/src/test/test_config.c +++ b/src/test/test_config.c @@ -990,52 +990,55 @@ test_config_fix_my_family(void *arg)
static int n_hostname_01010101 = 0;
-/** This mock function is meant to replace tor_lookup_hostname(). +/** This mock function is meant to replace tor_addr_lookup(). * It answers with 1.1.1.1 as IP adddress that resulted from lookup. * This function increments <b>n_hostname_01010101</b> counter by one * every time it is called. */ static int -tor_lookup_hostname_01010101(const char *name, uint32_t *addr) +tor_addr_lookup_01010101(const char *name, uint16_t family, tor_addr_t *addr) { n_hostname_01010101++;
- if (name && addr) { - *addr = ntohl(0x01010101); + if (family == AF_INET) { + if (name && addr) { + tor_addr_from_ipv4h(addr, 0x01010101); + } } - return 0; }
static int n_hostname_localhost = 0;
-/** This mock function is meant to replace tor_lookup_hostname(). +/** This mock function is meant to replace tor_addr_lookup(). * It answers with 127.0.0.1 as IP adddress that resulted from lookup. * This function increments <b>n_hostname_localhost</b> counter by one * every time it is called. */ static int -tor_lookup_hostname_localhost(const char *name, uint32_t *addr) +tor_addr_lookup_localhost(const char *name, uint16_t family, tor_addr_t *addr) { n_hostname_localhost++;
- if (name && addr) { - *addr = 0x7f000001; + if (family == AF_INET) { + if (name && addr) { + tor_addr_from_ipv4h(addr, 0x7f000001); + } } - return 0; }
static int n_hostname_failure = 0;
-/** This mock function is meant to replace tor_lookup_hostname(). +/** This mock function is meant to replace tor_addr_lookup(). * It pretends to fail by returning -1 to caller. Also, this function * increments <b>n_hostname_failure</b> every time it is called. */ static int -tor_lookup_hostname_failure(const char *name, uint32_t *addr) +tor_addr_lookup_failure(const char *name, uint16_t family, tor_addr_t *addr) { (void)name; + (void)family; (void)addr;
n_hostname_failure++; @@ -1097,29 +1100,29 @@ tor_gethostname_failure(char *name, size_t namelen) return -1; }
-static int n_get_interface_address = 0; +static int n_get_interface_address6 = 0; +static sa_family_t last_address6_family;
/** This mock function is meant to replace get_interface_address(). * It answers with address 8.8.8.8. This function increments * <b>n_get_interface_address</b> by one every time it is called. */ static int -get_interface_address_08080808(int severity, uint32_t *addr) +get_interface_address6_08080808(int severity, sa_family_t family, + tor_addr_t *addr) { (void)severity;
- n_get_interface_address++; + n_get_interface_address6++;
- if (addr) { - *addr = ntohl(0x08080808); + if (family == AF_INET) { + if (addr) { + tor_addr_from_ipv4h(addr, 0x08080808); + } } - return 0; }
-static int n_get_interface_address6 = 0; -static sa_family_t last_address6_family; - /** This mock function is meant to replace get_interface_address6(). * It answers with IP address 9.9.9.9 iff both of the following are true: * - <b>family</b> is AF_INET @@ -1145,25 +1148,6 @@ get_interface_address6_replacement(int severity, sa_family_t family, return 0; }
-static int n_get_interface_address_failure = 0; - -/** - * This mock function is meant to replace get_interface_address(). - * It pretends to fail getting interface address by returning -1. - * <b>n_get_interface_address_failure</b> is incremented by one - * every time this function is called. - */ -static int -get_interface_address_failure(int severity, uint32_t *addr) -{ - (void)severity; - (void)addr; - - n_get_interface_address_failure++; - - return -1; -} - static int n_get_interface_address6_failure = 0;
/** @@ -1200,8 +1184,6 @@ test_config_resolve_my_address_v4(void *arg) int prev_n_gethostname_replacement; int prev_n_gethostname_failure; int prev_n_gethostname_localhost; - int prev_n_get_interface_address; - int prev_n_get_interface_address_failure; int prev_n_get_interface_address6; int prev_n_get_interface_address6_failure;
@@ -1225,18 +1207,18 @@ test_config_resolve_my_address_v4(void *arg) tt_want(retval == 0); tt_want_str_op(method_used,OP_EQ,"CONFIGURED"); tt_want(hostname_out == NULL); - tt_assert(resolved_addr == 0x80348069); + tt_u64_op(resolved_addr, OP_EQ, 0x80348069);
config_free_lines(options->Address);
/* * CASE 2: * If options->Address is a valid DNS address, we want resolve_my_address_v4() - * function to ask tor_lookup_hostname() for help with resolving it + * function to ask tor_addr_lookup() for help with resolving it * and return the address that was resolved (in host order). */
- MOCK(tor_lookup_hostname,tor_lookup_hostname_01010101); + MOCK(tor_addr_lookup, tor_addr_lookup_01010101);
strlcpy(buf, "Address www.torproject.org\n", sizeof(buf)); config_get_lines(buf, &(options->Address), 0); @@ -1250,9 +1232,9 @@ test_config_resolve_my_address_v4(void *arg) tt_want(n_hostname_01010101 == prev_n_hostname_01010101 + 1); tt_want_str_op(method_used,OP_EQ,"RESOLVED"); tt_want_str_op(hostname_out,OP_EQ,"www.torproject.org"); - tt_assert(resolved_addr == 0x01010101); + tt_u64_op(resolved_addr, OP_EQ, 0x01010101);
- UNMOCK(tor_lookup_hostname); + UNMOCK(tor_addr_lookup);
config_free_lines(options->Address); tor_free(hostname_out); @@ -1261,14 +1243,14 @@ test_config_resolve_my_address_v4(void *arg) * CASE 3: * Given that options->Address is NULL, we want resolve_my_address_v4() * to try and use tor_gethostname() to get hostname AND use - * tor_lookup_hostname() to get IP address. + * tor_addr_lookup() to get IP address. */
resolved_addr = 0; options->Address = NULL;
MOCK(tor_gethostname,tor_gethostname_replacement); - MOCK(tor_lookup_hostname,tor_lookup_hostname_01010101); + MOCK(tor_addr_lookup,tor_addr_lookup_01010101);
prev_n_gethostname_replacement = n_gethostname_replacement; prev_n_hostname_01010101 = n_hostname_01010101; @@ -1284,7 +1266,7 @@ test_config_resolve_my_address_v4(void *arg) tt_assert(resolved_addr == 0x01010101);
UNMOCK(tor_gethostname); - UNMOCK(tor_lookup_hostname); + UNMOCK(tor_addr_lookup);
tor_free(hostname_out);
@@ -1313,7 +1295,7 @@ test_config_resolve_my_address_v4(void *arg) * cannot be resolved. */
- MOCK(tor_lookup_hostname,tor_lookup_hostname_failure); + MOCK(tor_addr_lookup,tor_addr_lookup_failure);
prev_n_hostname_failure = n_hostname_failure;
@@ -1326,7 +1308,7 @@ test_config_resolve_my_address_v4(void *arg) tt_want(n_hostname_failure == prev_n_hostname_failure + 1); tt_int_op(retval, OP_EQ, -1);
- UNMOCK(tor_lookup_hostname); + UNMOCK(tor_addr_lookup);
config_free_lines(options->Address); options->Address = NULL; @@ -1359,20 +1341,20 @@ test_config_resolve_my_address_v4(void *arg) */
MOCK(tor_gethostname,tor_gethostname_replacement); - MOCK(tor_lookup_hostname,tor_lookup_hostname_failure); - MOCK(get_interface_address,get_interface_address_08080808); + MOCK(tor_addr_lookup,tor_addr_lookup_failure); + MOCK(get_interface_address6, get_interface_address6_08080808);
prev_n_gethostname_replacement = n_gethostname_replacement; - prev_n_get_interface_address = n_get_interface_address; + prev_n_get_interface_address6 = n_get_interface_address6;
retval = resolve_my_address_v4(LOG_NOTICE,options,&resolved_addr, - &method_used,&hostname_out); + &method_used,&hostname_out);
tt_want(retval == 0); tt_want_int_op(n_gethostname_replacement, OP_EQ, prev_n_gethostname_replacement + 1); - tt_want_int_op(n_get_interface_address, OP_EQ, - prev_n_get_interface_address + 1); + tt_want_int_op(n_get_interface_address6, OP_EQ, + prev_n_get_interface_address6 + 1); tt_want_str_op(method_used,OP_EQ,"INTERFACE"); tt_want(hostname_out == NULL); tt_assert(resolved_addr == 0x08080808); @@ -1387,16 +1369,16 @@ test_config_resolve_my_address_v4(void *arg) * get_interface_address() fails. */
- MOCK(get_interface_address,get_interface_address_failure); + MOCK(get_interface_address6, get_interface_address6_failure);
- prev_n_get_interface_address_failure = n_get_interface_address_failure; + prev_n_get_interface_address6_failure = n_get_interface_address6_failure; prev_n_gethostname_replacement = n_gethostname_replacement;
retval = resolve_my_address_v4(LOG_NOTICE,options,&resolved_addr, &method_used,&hostname_out);
- tt_want(n_get_interface_address_failure == - prev_n_get_interface_address_failure + 1); + tt_want(n_get_interface_address6_failure == + prev_n_get_interface_address6_failure + 1); tt_want(n_gethostname_replacement == prev_n_gethostname_replacement + 1); tt_int_op(retval, OP_EQ, -1); @@ -1406,14 +1388,14 @@ test_config_resolve_my_address_v4(void *arg)
/* * CASE 9: - * Given that options->Address is NULL AND tor_lookup_hostname() + * Given that options->Address is NULL AND tor_addr_lookup() * fails AND hostname returned by gethostname() resolves * to local IP address, we want resolve_my_address_v4() function to * call get_interface_address6(.,AF_INET,.) and return IP address * the latter function has found. */
- MOCK(tor_lookup_hostname,tor_lookup_hostname_failure); + MOCK(tor_addr_lookup,tor_addr_lookup_failure); MOCK(tor_gethostname,tor_gethostname_replacement); MOCK(get_interface_address6,get_interface_address6_replacement);
@@ -1432,7 +1414,7 @@ test_config_resolve_my_address_v4(void *arg) tt_want_str_op(method_used,OP_EQ,"INTERFACE"); tt_assert(resolved_addr == 0x09090909);
- UNMOCK(tor_lookup_hostname); + UNMOCK(tor_addr_lookup); UNMOCK(tor_gethostname); UNMOCK(get_interface_address6);
@@ -1444,11 +1426,11 @@ test_config_resolve_my_address_v4(void *arg) * 1. options->Address is not NULL * 2. ... but it cannot be converted to struct in_addr by * tor_inet_aton() - * 3. ... and tor_lookup_hostname() fails to resolve the + * 3. ... and tor_addr_lookup() fails to resolve the * options->Address */
- MOCK(tor_lookup_hostname,tor_lookup_hostname_failure); + MOCK(tor_addr_lookup, tor_addr_lookup_failure);
prev_n_hostname_failure = n_hostname_failure;
@@ -1462,7 +1444,7 @@ test_config_resolve_my_address_v4(void *arg) tt_int_op(retval, OP_EQ, -1);
UNMOCK(tor_gethostname); - UNMOCK(tor_lookup_hostname); + UNMOCK(tor_addr_lookup);
tor_free(hostname_out);
@@ -1474,7 +1456,7 @@ test_config_resolve_my_address_v4(void *arg) * if running on. * 3. Hostname from previous step cannot be converted to * address by using tor_inet_aton() function. - * 4. However, tor_lookup_hostname() succeeds in resolving the + * 4. However, tor_addr_lookup() succeeds in resolving the * hostname from step 2. * 5. Unfortunately, tor_addr_is_internal() deems this address * to be internal. @@ -1489,7 +1471,7 @@ test_config_resolve_my_address_v4(void *arg) options->Address = NULL;
MOCK(tor_gethostname,tor_gethostname_replacement); - MOCK(tor_lookup_hostname,tor_lookup_hostname_localhost); + MOCK(tor_addr_lookup,tor_addr_lookup_localhost); MOCK(get_interface_address6,get_interface_address6_replacement);
prev_n_gethostname_replacement = n_gethostname_replacement; @@ -1533,7 +1515,7 @@ test_config_resolve_my_address_v4(void *arg) tt_int_op(retval, OP_EQ, -1);
UNMOCK(tor_gethostname); - UNMOCK(tor_lookup_hostname); + UNMOCK(tor_addr_lookup); UNMOCK(get_interface_address6);
/* CASE 12: @@ -1570,7 +1552,7 @@ test_config_resolve_my_address_v4(void *arg) tor_free(hostname_out);
UNMOCK(tor_gethostname); - UNMOCK(tor_lookup_hostname); + UNMOCK(tor_addr_lookup); UNMOCK(get_interface_address); UNMOCK(get_interface_address6); UNMOCK(tor_gethostname);