From 47f9edde699ad687884b6222b557c10dee2592c9 Mon Sep 17 00:00:00 2001 From: David Goulet Date: Mon, 15 Jun 2020 15:02:08 -0400 Subject: [PATCH 01/14] config: Change Address to be a LINELIST With prop312, we want to support IPv4 and IPv6 thus multiple Address statement (up to 2) will be accepted. For this, "Address" option becomes a LINELIST so we can properly process the IPv4 or/and IPv6. Part of #33233 Signed-off-by: David Goulet --- src/app/config/config.c | 4 ++-- src/app/config/or_options_st.h | 5 ++++- src/app/config/resolve_addr.c | 7 ++++--- src/app/main/main.c | 3 +-- src/feature/relay/relay_config.c | 2 +- src/test/test_config.c | 35 ++++++++++++++++---------------- 6 files changed, 30 insertions(+), 26 deletions(-) diff --git a/src/app/config/config.c b/src/app/config/config.c index 71f8c18ca2..286cd9304a 100644 --- a/src/app/config/config.c +++ b/src/app/config/config.c @@ -313,7 +313,7 @@ static const config_var_t option_vars_[] = { V(AccountingMax, MEMUNIT, "0 bytes"), VAR("AccountingRule", STRING, AccountingRule_option, "max"), V(AccountingStart, STRING, NULL), - V(Address, STRING, NULL), + V(Address, LINELIST, NULL), OBSOLETE("AllowDotExit"), OBSOLETE("AllowInvalidNodes"), V(AllowNonRFC953Hostnames, BOOL, "0"), @@ -4028,7 +4028,7 @@ options_check_transition_cb(const void *old_, if (! CFG_EQ_INT(old, new_val, opt)) \ BAD_CHANGE_TO(opt," with Sandbox active") - SB_NOCHANGE_STR(Address); + SB_NOCHANGE_LINELIST(Address); SB_NOCHANGE_STR(ServerDNSResolvConfFile); SB_NOCHANGE_STR(DirPortFrontPage); SB_NOCHANGE_STR(CookieAuthFile); diff --git a/src/app/config/or_options_st.h b/src/app/config/or_options_st.h index bf58205f89..2f375f5d9b 100644 --- a/src/app/config/or_options_st.h +++ b/src/app/config/or_options_st.h @@ -71,7 +71,10 @@ struct or_options_t { int CacheDirectoryGroupReadable; /**< Boolean: Is the CacheDirectory g+r? */ char *Nickname; /**< OR only: nickname of this onion router. */ - char *Address; /**< OR only: configured address for this onion router. */ + /** OR only: configured address for this onion router. Up to two times this + * options is accepted as in IPv4 and IPv6. */ + struct config_line_t *Address; + 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 9d1a8e0260..5723a00fa7 100644 --- a/src/app/config/resolve_addr.c +++ b/src/app/config/resolve_addr.c @@ -15,6 +15,7 @@ #include "feature/control/control_events.h" +#include "lib/encoding/confline.h" #include "lib/net/gethostname.h" #include "lib/net/resolve.h" @@ -97,7 +98,6 @@ resolve_my_address(int warn_severity, const or_options_t *options, int explicit_hostname=1; int from_interface=0; char *addr_string = NULL; - const char *address = options->Address; int notice_severity = warn_severity <= LOG_NOTICE ? LOG_NOTICE : warn_severity; @@ -108,8 +108,9 @@ resolve_my_address(int warn_severity, const or_options_t *options, * Step one: Fill in 'hostname' to be our best guess. */ - if (address && *address) { - strlcpy(hostname, address, sizeof(hostname)); + 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 */ diff --git a/src/app/main/main.c b/src/app/main/main.c index dc39611f98..32c34ea821 100644 --- a/src/app/main/main.c +++ b/src/app/main/main.c @@ -795,8 +795,7 @@ do_dump_config(void) static void init_addrinfo(void) { - if (! server_mode(get_options()) || - (get_options()->Address && strlen(get_options()->Address) > 0)) { + if (! server_mode(get_options()) || get_options()->Address) { /* We don't need to seed our own hostname, because we won't be calling * resolve_my_address on it. */ diff --git a/src/feature/relay/relay_config.c b/src/feature/relay/relay_config.c index fac6a2f577..7b43b57423 100644 --- a/src/feature/relay/relay_config.c +++ b/src/feature/relay/relay_config.c @@ -1029,7 +1029,7 @@ options_transition_affects_descriptor(const or_options_t *old_options, YES_IF_CHANGED_STRING(DataDirectory); YES_IF_CHANGED_STRING(Nickname); - YES_IF_CHANGED_STRING(Address); + YES_IF_CHANGED_LINELIST(Address); YES_IF_CHANGED_LINELIST(ExitPolicy); YES_IF_CHANGED_BOOL(ExitRelay); YES_IF_CHANGED_BOOL(ExitPolicyRejectPrivate); diff --git a/src/test/test_config.c b/src/test/test_config.c index 095eb24c49..2b44505329 100644 --- a/src/test/test_config.c +++ b/src/test/test_config.c @@ -1190,6 +1190,7 @@ test_config_resolve_my_address(void *arg) { or_options_t *options; uint32_t resolved_addr; + char buf[1024]; const char *method_used; char *hostname_out = NULL; int retval; @@ -1215,8 +1216,8 @@ test_config_resolve_my_address(void *arg) * If options->Address is a valid IPv4 address string, we want * the corresponding address to be parsed and returned. */ - - options->Address = tor_strdup("128.52.128.105"); + strlcpy(buf, "Address 128.52.128.105\n", sizeof(buf)); + config_get_lines(buf, &(options->Address), 0); retval = resolve_my_address(LOG_NOTICE,options,&resolved_addr, &method_used,&hostname_out); @@ -1226,7 +1227,7 @@ test_config_resolve_my_address(void *arg) tt_want(hostname_out == NULL); tt_assert(resolved_addr == 0x80348069); - tor_free(options->Address); + config_free_lines(options->Address); /* * CASE 2: @@ -1237,8 +1238,8 @@ test_config_resolve_my_address(void *arg) MOCK(tor_lookup_hostname,tor_lookup_hostname_01010101); - tor_free(options->Address); - options->Address = tor_strdup("www.torproject.org"); + strlcpy(buf, "Address www.torproject.org\n", sizeof(buf)); + config_get_lines(buf, &(options->Address), 0); prev_n_hostname_01010101 = n_hostname_01010101; @@ -1253,7 +1254,7 @@ test_config_resolve_my_address(void *arg) UNMOCK(tor_lookup_hostname); - tor_free(options->Address); + config_free_lines(options->Address); tor_free(hostname_out); /* @@ -1264,7 +1265,6 @@ test_config_resolve_my_address(void *arg) */ resolved_addr = 0; - tor_free(options->Address); options->Address = NULL; MOCK(tor_gethostname,tor_gethostname_replacement); @@ -1295,8 +1295,8 @@ test_config_resolve_my_address(void *arg) */ resolved_addr = 0; - tor_free(options->Address); - options->Address = tor_strdup("127.0.0.1"); + strlcpy(buf, "Address 127.0.0.1\n", sizeof(buf)); + config_get_lines(buf, &(options->Address), 0); retval = resolve_my_address(LOG_NOTICE,options,&resolved_addr, &method_used,&hostname_out); @@ -1304,7 +1304,7 @@ test_config_resolve_my_address(void *arg) tt_want(resolved_addr == 0); tt_int_op(retval, OP_EQ, -1); - tor_free(options->Address); + config_free_lines(options->Address); tor_free(hostname_out); /* @@ -1317,8 +1317,8 @@ test_config_resolve_my_address(void *arg) prev_n_hostname_failure = n_hostname_failure; - tor_free(options->Address); - options->Address = tor_strdup("www.tor-project.org"); + strlcpy(buf, "Address www.tor-project.org\n", sizeof(buf)); + config_get_lines(buf, &(options->Address), 0); retval = resolve_my_address(LOG_NOTICE,options,&resolved_addr, &method_used,&hostname_out); @@ -1328,7 +1328,8 @@ test_config_resolve_my_address(void *arg) UNMOCK(tor_lookup_hostname); - tor_free(options->Address); + config_free_lines(options->Address); + options->Address = NULL; tor_free(hostname_out); /* @@ -1451,8 +1452,8 @@ test_config_resolve_my_address(void *arg) prev_n_hostname_failure = n_hostname_failure; - tor_free(options->Address); - options->Address = tor_strdup("some_hostname"); + strlcpy(buf, "Address some_hostname\n", sizeof(buf)); + config_get_lines(buf, &(options->Address), 0); retval = resolve_my_address(LOG_NOTICE, options, &resolved_addr, &method_used,&hostname_out); @@ -1484,7 +1485,7 @@ test_config_resolve_my_address(void *arg) * and address from step 6. */ - tor_free(options->Address); + config_free_lines(options->Address); options->Address = NULL; MOCK(tor_gethostname,tor_gethostname_replacement); @@ -1563,7 +1564,7 @@ test_config_resolve_my_address(void *arg) UNMOCK(tor_gethostname); done: - tor_free(options->Address); + config_free_lines(options->Address); tor_free(options->DirAuthorities); or_options_free(options); tor_free(hostname_out); From 6da8c0b4fa9243158c860035c27d2d9bba17a832 Mon Sep 17 00:00:00 2001 From: David Goulet Date: Mon, 15 Jun 2020 15:27:32 -0400 Subject: [PATCH 02/14] addr: Rename resolve_my_address to be v4 specific Part of #33233 Signed-off-by: David Goulet --- scripts/maint/practracker/exceptions.txt | 2 +- src/app/config/resolve_addr.c | 6 +-- src/app/config/resolve_addr.h | 6 +-- src/feature/dirauth/dirauth_config.c | 2 +- src/feature/dirauth/dirvote.c | 2 +- src/feature/nodelist/dirlist.c | 4 +- src/feature/relay/relay_find_addr.c | 4 +- src/feature/relay/router.c | 2 +- src/test/test_config.c | 52 ++++++++++++------------ 9 files changed, 40 insertions(+), 40 deletions(-) diff --git a/scripts/maint/practracker/exceptions.txt b/scripts/maint/practracker/exceptions.txt index 154f43ee1f..a5b3ca7242 100644 --- a/scripts/maint/practracker/exceptions.txt +++ b/scripts/maint/practracker/exceptions.txt @@ -46,7 +46,7 @@ problem function-size /src/app/config/config.c:parse_dir_authority_line() 150 problem function-size /src/app/config/config.c:parse_dir_fallback_line() 101 problem function-size /src/app/config/config.c:port_parse_config() 435 problem function-size /src/app/config/config.c:parse_ports() 132 -problem function-size /src/app/config/resolve_addr.c:resolve_my_address() 191 +problem function-size /src/app/config/resolve_addr.c:resolve_my_address_v4() 197 problem file-size /src/app/config/or_options_st.h 1050 problem include-count /src/app/main/main.c 68 problem function-size /src/app/main/main.c:dumpstats() 102 diff --git a/src/app/config/resolve_addr.c b/src/app/config/resolve_addr.c index 5723a00fa7..fe375848d7 100644 --- a/src/app/config/resolve_addr.c +++ b/src/app/config/resolve_addr.c @@ -85,9 +85,9 @@ reset_last_resolved_addr(void) * XXXX ipv6 */ int -resolve_my_address(int warn_severity, const or_options_t *options, - uint32_t *addr_out, - const char **method_out, char **hostname_out) +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 */ diff --git a/src/app/config/resolve_addr.h b/src/app/config/resolve_addr.h index 3747546402..2c8143df5b 100644 --- a/src/app/config/resolve_addr.h +++ b/src/app/config/resolve_addr.h @@ -11,9 +11,9 @@ #include "app/config/or_options_st.h" -int resolve_my_address(int warn_severity, const or_options_t *options, - uint32_t *addr_out, - const char **method_out, char **hostname_out); +int resolve_my_address_v4(int warn_severity, const or_options_t *options, + uint32_t *addr_out, + const char **method_out, char **hostname_out); uint32_t get_last_resolved_addr(void); void reset_last_resolved_addr(void); diff --git a/src/feature/dirauth/dirauth_config.c b/src/feature/dirauth/dirauth_config.c index a0b6de7eca..888b8e7d94 100644 --- a/src/feature/dirauth/dirauth_config.c +++ b/src/feature/dirauth/dirauth_config.c @@ -78,7 +78,7 @@ options_validate_dirauth_mode(const or_options_t *old_options, /* confirm that our address isn't broken, so we can complain now */ uint32_t tmp; - if (resolve_my_address(LOG_WARN, options, &tmp, NULL, NULL) < 0) + if (resolve_my_address_v4(LOG_WARN, options, &tmp, NULL, NULL) < 0) REJECT("Failed to resolve/guess local address. See logs for details."); if (!options->ContactInfo && !options->TestingTorNetwork) diff --git a/src/feature/dirauth/dirvote.c b/src/feature/dirauth/dirvote.c index 79651563b4..3030955fd1 100644 --- a/src/feature/dirauth/dirvote.c +++ b/src/feature/dirauth/dirvote.c @@ -4492,7 +4492,7 @@ dirserv_generate_networkstatus_vote_obj(crypto_pk_t *private_key, log_err(LD_BUG, "Error computing identity key digest"); return NULL; } - if (resolve_my_address(LOG_WARN, options, &addr, NULL, &hostname)<0) { + if (resolve_my_address_v4(LOG_WARN, options, &addr, NULL, &hostname)<0) { log_warn(LD_NET, "Couldn't resolve my hostname"); return NULL; } diff --git a/src/feature/nodelist/dirlist.c b/src/feature/nodelist/dirlist.c index 33d1bfc4d0..4481daba6f 100644 --- a/src/feature/nodelist/dirlist.c +++ b/src/feature/nodelist/dirlist.c @@ -349,8 +349,8 @@ trusted_dir_server_new(const char *nickname, const char *address, dir_server_t *result; if (!address) { /* The address is us; we should guess. */ - if (resolve_my_address(LOG_WARN, get_options(), - &a, NULL, &hostname) < 0) { + if (resolve_my_address_v4(LOG_WARN, get_options(), + &a, NULL, &hostname) < 0) { log_warn(LD_CONFIG, "Couldn't find a suitable address when adding ourself as a " "trusted directory server."); diff --git a/src/feature/relay/relay_find_addr.c b/src/feature/relay/relay_find_addr.c index 86cd799d42..561ef1507a 100644 --- a/src/feature/relay/relay_find_addr.c +++ b/src/feature/relay/relay_find_addr.c @@ -66,7 +66,7 @@ router_new_address_suggestion(const char *suggestion, /* XXXX ipv6 */ cur = get_last_resolved_addr(); if (cur || - resolve_my_address(LOG_INFO, options, &cur, NULL, NULL) >= 0) { + resolve_my_address_v4(LOG_INFO, options, &cur, NULL, NULL) >= 0) { /* We're all set -- we already know our address. Great. */ tor_addr_from_ipv4h(&last_guessed_ip, cur); /* store it in case we need it later */ @@ -118,7 +118,7 @@ router_pick_published_address, (const or_options_t *options, uint32_t *addr, /* Second, consider doing a resolve attempt right here. */ if (!cache_only) { - if (resolve_my_address(LOG_INFO, options, addr, NULL, NULL) >= 0) { + if (resolve_my_address_v4(LOG_INFO, options, addr, NULL, NULL) >= 0) { log_info(LD_CONFIG,"Success: chose address '%s'.", fmt_addr32(*addr)); return 0; } diff --git a/src/feature/relay/router.c b/src/feature/relay/router.c index 6914946729..4d5ed3a3e1 100644 --- a/src/feature/relay/router.c +++ b/src/feature/relay/router.c @@ -2552,7 +2552,7 @@ check_descriptor_ipaddress_changed(time_t now) /* XXXX ipv6 */ prev = my_ri->addr; - if (resolve_my_address(LOG_INFO, options, &cur, &method, &hostname) < 0) { + if (resolve_my_address_v4(LOG_INFO, options, &cur, &method, &hostname) < 0) { log_info(LD_CONFIG,"options->Address didn't resolve into an IP."); return; } diff --git a/src/test/test_config.c b/src/test/test_config.c index 2b44505329..87104113bc 100644 --- a/src/test/test_config.c +++ b/src/test/test_config.c @@ -1186,7 +1186,7 @@ get_interface_address6_failure(int severity, sa_family_t family, } static void -test_config_resolve_my_address(void *arg) +test_config_resolve_my_address_v4(void *arg) { or_options_t *options; uint32_t resolved_addr; @@ -1219,7 +1219,7 @@ test_config_resolve_my_address(void *arg) strlcpy(buf, "Address 128.52.128.105\n", sizeof(buf)); config_get_lines(buf, &(options->Address), 0); - retval = resolve_my_address(LOG_NOTICE,options,&resolved_addr, + retval = resolve_my_address_v4(LOG_NOTICE,options,&resolved_addr, &method_used,&hostname_out); tt_want(retval == 0); @@ -1231,7 +1231,7 @@ test_config_resolve_my_address(void *arg) /* * CASE 2: - * If options->Address is a valid DNS address, we want resolve_my_address() + * 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 * and return the address that was resolved (in host order). */ @@ -1243,7 +1243,7 @@ test_config_resolve_my_address(void *arg) prev_n_hostname_01010101 = n_hostname_01010101; - retval = resolve_my_address(LOG_NOTICE,options,&resolved_addr, + retval = resolve_my_address_v4(LOG_NOTICE,options,&resolved_addr, &method_used,&hostname_out); tt_want(retval == 0); @@ -1259,7 +1259,7 @@ test_config_resolve_my_address(void *arg) /* * CASE 3: - * Given that options->Address is NULL, we want resolve_my_address() + * 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. */ @@ -1273,7 +1273,7 @@ test_config_resolve_my_address(void *arg) prev_n_gethostname_replacement = n_gethostname_replacement; prev_n_hostname_01010101 = n_hostname_01010101; - retval = resolve_my_address(LOG_NOTICE,options,&resolved_addr, + retval = resolve_my_address_v4(LOG_NOTICE,options,&resolved_addr, &method_used,&hostname_out); tt_want(retval == 0); @@ -1291,14 +1291,14 @@ test_config_resolve_my_address(void *arg) /* * CASE 4: * Given that options->Address is a local host address, we want - * resolve_my_address() function to fail. + * resolve_my_address_v4() function to fail. */ resolved_addr = 0; strlcpy(buf, "Address 127.0.0.1\n", sizeof(buf)); config_get_lines(buf, &(options->Address), 0); - retval = resolve_my_address(LOG_NOTICE,options,&resolved_addr, + retval = resolve_my_address_v4(LOG_NOTICE,options,&resolved_addr, &method_used,&hostname_out); tt_want(resolved_addr == 0); @@ -1309,7 +1309,7 @@ test_config_resolve_my_address(void *arg) /* * CASE 5: - * We want resolve_my_address() to fail if DNS address in options->Address + * We want resolve_my_address_v4() to fail if DNS address in options->Address * cannot be resolved. */ @@ -1320,7 +1320,7 @@ test_config_resolve_my_address(void *arg) strlcpy(buf, "Address www.tor-project.org\n", sizeof(buf)); config_get_lines(buf, &(options->Address), 0); - retval = resolve_my_address(LOG_NOTICE,options,&resolved_addr, + retval = resolve_my_address_v4(LOG_NOTICE,options,&resolved_addr, &method_used,&hostname_out); tt_want(n_hostname_failure == prev_n_hostname_failure + 1); @@ -1335,14 +1335,14 @@ test_config_resolve_my_address(void *arg) /* * CASE 6: * If options->Address is NULL AND gettting local hostname fails, we want - * resolve_my_address() to fail as well. + * resolve_my_address_v4() to fail as well. */ MOCK(tor_gethostname,tor_gethostname_failure); prev_n_gethostname_failure = n_gethostname_failure; - retval = resolve_my_address(LOG_NOTICE,options,&resolved_addr, + retval = resolve_my_address_v4(LOG_NOTICE,options,&resolved_addr, &method_used,&hostname_out); tt_want(n_gethostname_failure == prev_n_gethostname_failure + 1); @@ -1353,7 +1353,7 @@ test_config_resolve_my_address(void *arg) /* * CASE 7: - * We want resolve_my_address() to try and get network interface address via + * We want resolve_my_address_v4() to try and get network interface address via * get_interface_address() if hostname returned by tor_gethostname() cannot be * resolved into IP address. */ @@ -1365,7 +1365,7 @@ test_config_resolve_my_address(void *arg) prev_n_gethostname_replacement = n_gethostname_replacement; prev_n_get_interface_address = n_get_interface_address; - retval = resolve_my_address(LOG_NOTICE,options,&resolved_addr, + retval = resolve_my_address_v4(LOG_NOTICE,options,&resolved_addr, &method_used,&hostname_out); tt_want(retval == 0); @@ -1383,7 +1383,7 @@ test_config_resolve_my_address(void *arg) /* * CASE 8: * Suppose options->Address is NULL AND hostname returned by tor_gethostname() - * is unresolvable. We want resolve_my_address to fail if + * is unresolvable. We want resolve_my_address_v4 to fail if * get_interface_address() fails. */ @@ -1392,7 +1392,7 @@ test_config_resolve_my_address(void *arg) prev_n_get_interface_address_failure = n_get_interface_address_failure; prev_n_gethostname_replacement = n_gethostname_replacement; - retval = resolve_my_address(LOG_NOTICE,options,&resolved_addr, + retval = resolve_my_address_v4(LOG_NOTICE,options,&resolved_addr, &method_used,&hostname_out); tt_want(n_get_interface_address_failure == @@ -1408,7 +1408,7 @@ test_config_resolve_my_address(void *arg) * CASE 9: * Given that options->Address is NULL AND tor_lookup_hostname() * fails AND hostname returned by gethostname() resolves - * to local IP address, we want resolve_my_address() function to + * 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. */ @@ -1421,7 +1421,7 @@ test_config_resolve_my_address(void *arg) prev_n_hostname_failure = n_hostname_failure; prev_n_get_interface_address6 = n_get_interface_address6; - retval = resolve_my_address(LOG_NOTICE,options,&resolved_addr, + retval = resolve_my_address_v4(LOG_NOTICE,options,&resolved_addr, &method_used,&hostname_out); tt_want(last_address6_family == AF_INET); @@ -1439,7 +1439,7 @@ test_config_resolve_my_address(void *arg) tor_free(hostname_out); /* - * CASE 10: We want resolve_my_address() to fail if all of the following + * CASE 10: We want resolve_my_address_v4() to fail if all of the following * are true: * 1. options->Address is not NULL * 2. ... but it cannot be converted to struct in_addr by @@ -1455,7 +1455,7 @@ test_config_resolve_my_address(void *arg) strlcpy(buf, "Address some_hostname\n", sizeof(buf)); config_get_lines(buf, &(options->Address), 0); - retval = resolve_my_address(LOG_NOTICE, options, &resolved_addr, + retval = resolve_my_address_v4(LOG_NOTICE, options, &resolved_addr, &method_used,&hostname_out); tt_want(n_hostname_failure == prev_n_hostname_failure + 1); @@ -1496,7 +1496,7 @@ test_config_resolve_my_address(void *arg) prev_n_hostname_localhost = n_hostname_localhost; prev_n_get_interface_address6 = n_get_interface_address6; - retval = resolve_my_address(LOG_DEBUG, options, &resolved_addr, + retval = resolve_my_address_v4(LOG_DEBUG, options, &resolved_addr, &method_used,&hostname_out); tt_want(n_gethostname_replacement == prev_n_gethostname_replacement + 1); @@ -1512,7 +1512,7 @@ test_config_resolve_my_address(void *arg) * 1-5 as above. * 6. get_interface_address6() fails. * - * In this subcase, we want resolve_my_address() to fail. + * In this subcase, we want resolve_my_address_v4() to fail. */ UNMOCK(get_interface_address6); @@ -1522,7 +1522,7 @@ test_config_resolve_my_address(void *arg) prev_n_hostname_localhost = n_hostname_localhost; prev_n_get_interface_address6_failure = n_get_interface_address6_failure; - retval = resolve_my_address(LOG_DEBUG, options, &resolved_addr, + retval = resolve_my_address_v4(LOG_DEBUG, options, &resolved_addr, &method_used,&hostname_out); tt_want(n_gethostname_replacement == prev_n_gethostname_replacement + 1); @@ -1544,7 +1544,7 @@ test_config_resolve_my_address(void *arg) * 4. into IPv4 address that tor_addr_is_inernal() considers to be * internal. * - * In this case, we want resolve_my_address() to fail. + * In this case, we want resolve_my_address_v4() to fail. */ tor_free(options->Address); @@ -1555,7 +1555,7 @@ test_config_resolve_my_address(void *arg) prev_n_gethostname_localhost = n_gethostname_localhost; - retval = resolve_my_address(LOG_DEBUG, options, &resolved_addr, + retval = resolve_my_address_v4(LOG_DEBUG, options, &resolved_addr, &method_used,&hostname_out); tt_want(n_gethostname_localhost == prev_n_gethostname_localhost + 1); @@ -6257,7 +6257,7 @@ struct testcase_t config_tests[] = { CONFIG_TEST(adding_dir_servers, TT_FORK), CONFIG_TEST(default_dir_servers, TT_FORK), CONFIG_TEST(default_fallback_dirs, 0), - CONFIG_TEST(resolve_my_address, TT_FORK), + CONFIG_TEST(resolve_my_address_v4, TT_FORK), CONFIG_TEST(addressmap, 0), CONFIG_TEST(parse_bridge_line, 0), CONFIG_TEST(parse_transport_options_line, 0), From d08d7e1535fe7b47319e67ca31d4b8f64fdea465 Mon Sep 17 00:00:00 2001 From: David Goulet Date: Mon, 15 Jun 2020 15:31:34 -0400 Subject: [PATCH 03/14] addr: Rename last_resolved_addr to be v4 specific Part of #33233 Signed-off-by: David Goulet --- src/app/config/resolve_addr.c | 28 ++++++++++++++-------------- src/app/config/resolve_addr.h | 4 ++-- src/core/mainloop/connection.c | 2 +- src/feature/relay/relay_find_addr.c | 4 ++-- 4 files changed, 19 insertions(+), 19 deletions(-) diff --git a/src/app/config/resolve_addr.c b/src/app/config/resolve_addr.c index fe375848d7..6b66a71009 100644 --- a/src/app/config/resolve_addr.c +++ b/src/app/config/resolve_addr.c @@ -20,20 +20,20 @@ #include "lib/net/resolve.h" /** Last value actually set by resolve_my_address. */ -static uint32_t last_resolved_addr = 0; +static uint32_t last_resolved_addr_v4 = 0; -/** Accessor for last_resolved_addr from outside this file. */ +/** Accessor for last_resolved_addr_v4 from outside this file. */ uint32_t -get_last_resolved_addr(void) +get_last_resolved_addr_v4(void) { - return last_resolved_addr; + return last_resolved_addr_v4; } -/** Reset last_resolved_addr from outside this file. */ +/** Reset last_resolved_addr_v4 from outside this file. */ void -reset_last_resolved_addr(void) +reset_last_resolved_addr_v4(void) { - last_resolved_addr = 0; + last_resolved_addr_v4 = 0; } /** @@ -257,7 +257,7 @@ resolve_my_address_v4(int warn_severity, const or_options_t *options, * us up-to-date. */ - if (last_resolved_addr && last_resolved_addr != *addr_out) { + 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, @@ -269,14 +269,14 @@ resolve_my_address_v4(int warn_severity, const or_options_t *options, ip_address_changed(0); } - if (last_resolved_addr != *addr_out) { + 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 : ""); } - last_resolved_addr = *addr_out; + last_resolved_addr_v4 = *addr_out; /* * And finally, clean up and return success. @@ -303,11 +303,11 @@ is_local_addr, (const tor_addr_t *addr)) /* It's possible that this next check will hit before the first time * resolve_my_address actually succeeds. (For clients, it is likely that * resolve_my_address will never be called at all). In those cases, - * last_resolved_addr will be 0, and so checking to see whether ip is on - * the same /24 as last_resolved_addr will be the same as checking whether - * it was on net 0, which is already done by tor_addr_is_internal. + * last_resolved_addr_v4 will be 0, and so checking to see whether ip is + * on the same /24 as last_resolved_addr_v4 will be the same as checking + * whether it was on net 0, which is already done by tor_addr_is_internal. */ - if ((last_resolved_addr & (uint32_t)0xffffff00ul) + if ((last_resolved_addr_v4 & (uint32_t)0xffffff00ul) == (ip & (uint32_t)0xffffff00ul)) return 1; } diff --git a/src/app/config/resolve_addr.h b/src/app/config/resolve_addr.h index 2c8143df5b..6c94fe06ba 100644 --- a/src/app/config/resolve_addr.h +++ b/src/app/config/resolve_addr.h @@ -15,8 +15,8 @@ int resolve_my_address_v4(int warn_severity, const or_options_t *options, uint32_t *addr_out, const char **method_out, char **hostname_out); -uint32_t get_last_resolved_addr(void); -void reset_last_resolved_addr(void); +uint32_t get_last_resolved_addr_v4(void); +void reset_last_resolved_addr_v4(void); MOCK_DECL(int, is_local_addr, (const tor_addr_t *addr)); diff --git a/src/core/mainloop/connection.c b/src/core/mainloop/connection.c index a8417e46d9..9fff71ee0a 100644 --- a/src/core/mainloop/connection.c +++ b/src/core/mainloop/connection.c @@ -4870,7 +4870,7 @@ client_check_address_changed(tor_socket_t sock) smartlist_clear(outgoing_addrs); smartlist_add(outgoing_addrs, tor_memdup(&out_addr, sizeof(tor_addr_t))); /* We'll need to resolve ourselves again. */ - reset_last_resolved_addr(); + reset_last_resolved_addr_v4(); /* Okay, now change our keys. */ ip_address_changed(1); } diff --git a/src/feature/relay/relay_find_addr.c b/src/feature/relay/relay_find_addr.c index 561ef1507a..cc08914f6b 100644 --- a/src/feature/relay/relay_find_addr.c +++ b/src/feature/relay/relay_find_addr.c @@ -64,7 +64,7 @@ router_new_address_suggestion(const char *suggestion, } /* XXXX ipv6 */ - cur = get_last_resolved_addr(); + cur = get_last_resolved_addr_v4(); if (cur || resolve_my_address_v4(LOG_INFO, options, &cur, NULL, NULL) >= 0) { /* We're all set -- we already know our address. Great. */ @@ -112,7 +112,7 @@ router_pick_published_address, (const or_options_t *options, uint32_t *addr, int cache_only)) { /* First, check the cached output from resolve_my_address(). */ - *addr = get_last_resolved_addr(); + *addr = get_last_resolved_addr_v4(); if (*addr) return 0; From 9e85056de9ffe4858e2a07a5fd5e5fd4d144e688 Mon Sep 17 00:00:00 2001 From: David Goulet Date: Thu, 18 Jun 2020 13:39:20 -0400 Subject: [PATCH 04/14] addr: New find_my_address() to support multiple address families resolve_my_address() was beyond repair in terms of refactoring. Way too complex and doing too many things. This commit implements find_my_address() which in theory does the same as resolve_my_address() but in a more clean, concise and modern way using the tor_addr_t interface and for multiple address family. The caller needs to pass the address family (IPv4 or IPv6) which this interface supports. For both, a last resolved cache is used as well. Implements #33233 Signed-off-by: David Goulet --- src/app/config/resolve_addr.c | 490 ++++++++++++++++++++++++++++++++++ src/app/config/resolve_addr.h | 4 + 2 files changed, 494 insertions(+) diff --git a/src/app/config/resolve_addr.c b/src/app/config/resolve_addr.c index 6b66a71009..5cabb5889f 100644 --- a/src/app/config/resolve_addr.c +++ b/src/app/config/resolve_addr.c @@ -19,6 +19,31 @@ #include "lib/net/gethostname.h" #include "lib/net/resolve.h" +/** Maximum "Address" statement allowed in our configuration. */ +#define MAX_CONFIG_ADDRESS 2 + +/** Errors use when finding our IP address. Some are transient and some are + * persistent, just attach semantic to the values. They are all negative so + * one can do a catch all. */ + +#define ERR_FAIL_RESOLVE -1 /* Hostname resolution failed. */ +#define ERR_GET_HOSTNAME -2 /* Unable to get local hostname. */ +#define ERR_NO_OPT_ADDRESS -3 /* No Address in config. */ +#define ERR_TOO_MANY_ADDRESS -4 /* Too many Address for one family. */ +#define ERR_GET_INTERFACE -5 /* Unable to query network interface. */ +#define ERR_UNUSABLE_ADDRESS -6 /* Unusable address. It is internal. */ +#define ERR_DEFAULT_DIRAUTH -7 /* Using default authorities. */ +#define ERR_ADDRESS_IS_INTERNAL -8 /* IP is internal. */ + +/** Ease our life. Arrays containing state per address family. These are to + * add semantic to the code so we know what is accessed. */ +#define IDX_IPV4 0 /* Index to AF_INET. */ +#define IDX_IPV6 1 /* Index to AF_INET6. */ +#define IDX_SIZE 2 /* How many indexes do we have. */ + +/** Last resolved addresses. */ +static tor_addr_t last_resolved_addrs[IDX_SIZE]; + /** Last value actually set by resolve_my_address. */ static uint32_t last_resolved_addr_v4 = 0; @@ -36,6 +61,471 @@ reset_last_resolved_addr_v4(void) last_resolved_addr_v4 = 0; } +/** @brief Return true iff the given IP address can be used as a valid + * external resolved address. + * + * Two tests are done in this function: + * 1) If the address if NOT internal, it can be used. + * 2) If the address is internal and we have custom directory authorities + * configured then it can they be used. Important for testing networks. + * + * @param addr The IP address to validate. + * @param options Global configuration options. + * @param warn_severity Log level that should be used on error. + * @param explicit_ip Was the IP address explicitly given. + * + * @return Return 0 if it can be used. Return error code ERR_* found at the + * top of the file. + */ +static int +address_can_be_used(const tor_addr_t *addr, const or_options_t *options, + int warn_severity, const bool explicit_ip) +{ + tor_assert(addr); + + /* Public address, this is fine. */ + if (!tor_addr_is_internal(addr, 0)) { + goto allow; + } + + /* We have a private IP address. It is allowed only if we set custom + * directory authorities. */ + if (using_default_dir_authorities(options)) { + log_fn(warn_severity, LD_CONFIG, + "Address '%s' is a private IP address. Tor relays that use " + "the default DirAuthorities must have public IP addresses.", + fmt_addr(addr)); + return ERR_DEFAULT_DIRAUTH; + } + + if (!explicit_ip) { + /* Even with custom directory authorities, only an explicit internal + * address is accepted. */ + log_fn(warn_severity, LD_CONFIG, + "Address %s was resolved and thus not explicitly " + "set. Even if DirAuthorities are custom, this is " + "not allowed.", fmt_addr(addr)); + return ERR_ADDRESS_IS_INTERNAL; + } + + allow: + return 0; +} + +/** @brief Get IP address from the given config line and for a specific address + * family. + * + * This can fail is more than two Address statement are found for the same + * address family. It also fails if no statement is found. + * + * On failure, no out parameters should be used or considered valid. + * + * @param options Global configuration options. + * @param warn_severity Log level that should be used on error. + * @param family IP address family. Only AF_INET and AF_INET6 are supported. + * @param method_out OUT: String denoting by which method the address was + * found. This is described in the control-spec.txt as + * actions for "STATUS_SERVER". + * @param hostname_out OUT: String containing the hostname gotten from the + * Address value if any. + * @param addr_out OUT: Tor address of the address found in the cline or + * resolved from the cline. + * + * @return Return 0 on success that is an address has been found or resolved + * successfully. Return error code ERR_* found at the top of the file. + */ +static int +get_address_from_config(const or_options_t *options, int warn_severity, + int family, const char **method_out, + char **hostname_out, tor_addr_t *addr_out) +{ + bool explicit_ip = false; + int num_valid_addr = 0; + + tor_assert(options); + tor_assert(addr_out); + tor_assert(method_out); + tor_assert(hostname_out); + + log_debug(LD_CONFIG, "Attempting to get address from configuration"); + + if (!options->Address) { + log_info(LD_CONFIG, "No Address option found in configuration."); + return ERR_NO_OPT_ADDRESS; + } + + for (const config_line_t *cfg = options->Address; cfg != NULL; + cfg = cfg->next) { + int af; + tor_addr_t addr; + + af = tor_addr_parse(&addr, cfg->value); + if (af == family) { + tor_addr_copy(addr_out, &addr); + *method_out = "CONFIGURED"; + explicit_ip = true; + num_valid_addr++; + continue; + } + + /* Not an IP address. Considering this value a hostname and attempting to + * do a DNS lookup. */ + if (!tor_addr_lookup(cfg->value, family, &addr)) { + tor_addr_copy(addr_out, &addr); + *method_out = "RESOLVED"; + *hostname_out = tor_strdup(cfg->value); + explicit_ip = false; + num_valid_addr++; + continue; + } else { + /* If we have hostname we are unable to resolve, it is an persistent + * error and thus we stop right away. */ + log_fn(warn_severity, LD_CONFIG, + "Could not resolve local Address '%s'. Failing.", cfg->value); + return ERR_FAIL_RESOLVE; + } + } + + if (!num_valid_addr) { + log_fn(warn_severity, LD_CONFIG, + "No Address option found for family %s in configuration.", + fmt_af_family(family)); + return ERR_NO_OPT_ADDRESS; + } + + if (num_valid_addr >= MAX_CONFIG_ADDRESS) { + log_fn(warn_severity, LD_CONFIG, + "Found %d Address statement of address family %s. " + "Only one is allowed.", num_valid_addr, fmt_af_family(family)); + return ERR_TOO_MANY_ADDRESS; + } + + /* Great, we found an address. */ + return address_can_be_used(addr_out, options, warn_severity, explicit_ip); +} + +/** @brief Get IP address from the local hostname by calling gethostbyname() + * and doing a DNS resolution on the hostname. + * + * On failure, no out parameters should be used or considered valid. + * + * @param options Global configuration options. + * @param warn_severity Log level that should be used on error. + * @param family IP address family. Only AF_INET and AF_INET6 are supported. + * @param method_out OUT: String denoting by which method the address was + * found. This is described in the control-spec.txt as + * actions for "STATUS_SERVER". + * @param hostname_out OUT: String containing the local hostname. + * @param addr_out OUT: Tor address resolved from the local hostname. + * + * @return Return 0 on success that is an address has been found and resolved + * successfully. Return error code ERR_* found at the top of the file. + */ +static int +get_address_from_hostname(const or_options_t *options, int warn_severity, + int family, const char **method_out, + char **hostname_out, tor_addr_t *addr_out) +{ + int ret; + char hostname[256]; + + tor_assert(addr_out); + tor_assert(method_out); + + log_debug(LD_CONFIG, "Attempting to get address from local hostname"); + + if (tor_gethostname(hostname, sizeof(hostname)) < 0) { + log_fn(warn_severity, LD_NET, "Error obtaining local hostname"); + return ERR_GET_HOSTNAME; + } + if (tor_addr_lookup(hostname, family, addr_out)) { + log_fn(warn_severity, LD_NET, + "Could not resolve local hostname '%s'. Failing.", hostname); + return ERR_FAIL_RESOLVE; + } + + ret = address_can_be_used(addr_out, options, warn_severity, false); + if (ret < 0) { + return ret; + } + + /* addr_out contains the address of the local hostname. */ + *method_out = "GETHOSTNAME"; + *hostname_out = tor_strdup(hostname); + + return 0; +} + +/** @brief Get IP address from a network interface. + * + * On failure, no out parameters should be used or considered valid. + * + * @param options Global configuration options. + * @param warn_severity Log level that should be used on error. + * @param family IP address family. Only AF_INET and AF_INET6 are supported. + * @param method_out OUT: Always "INTERFACE" on success which is detailed in + * the control-spec.txt as actions for "STATUS_SERVER". + * @param addr_out OUT: Tor address found attached to the interface. + * + * @return Return 0 on success that is an address has been found. Return + * error code ERR_* found at the top of the file. + */ +static int +get_address_from_interface(const or_options_t *options, int warn_severity, + int family, const char **method_out, + tor_addr_t *addr_out) +{ + int ret; + + tor_assert(method_out); + tor_assert(addr_out); + + log_debug(LD_CONFIG, "Attempting to get address from network interface"); + + if (get_interface_address6(warn_severity, family, addr_out) < 0) { + log_fn(warn_severity, LD_CONFIG, + "Could not get local interface IP address."); + return ERR_GET_INTERFACE; + } + + ret = address_can_be_used(addr_out, options, warn_severity, false); + if (ret < 0) { + return ret; + } + + *method_out = "INTERFACE"; + + return 0; +} + +/** @brief Update the last resolved address cache using the given address. + * + * A log notice is emitted if the given address has changed from before. Not + * emitted on first resolve. + * + * Control port event "STATUS_SERVER" is emitted with the new information if + * it has changed. + * + * Finally, tor is notified that the IP address has changed. + * + * @param addr IP address to update the cache with. + * @param method_used By which method did we resolved it (for logging and + * control port). + * @param hostname_used Which hostname was used. If none were used, it is an + * empty string. (for logging and control port). + */ +static void +update_resolved_cache(const tor_addr_t *addr, const char *method_used, + const char *hostname_used) +{ + /** Have we done a first resolve. This is used to control logging. */ + static bool have_resolved_once[IDX_SIZE] = { false, false }; + bool *done_one_resolve; + bool have_hostname = false; + tor_addr_t *last_resolved; + + tor_assert(addr); + tor_assert(method_used); + tor_assert(hostname_used); + + /* Do we have an hostname. */ + have_hostname = strlen(hostname_used) > 0; + + switch (tor_addr_family(addr)) { + case AF_INET: + done_one_resolve = &have_resolved_once[IDX_IPV4]; + last_resolved = &last_resolved_addrs[IDX_IPV4]; + break; + case AF_INET6: + done_one_resolve = &have_resolved_once[IDX_IPV6]; + last_resolved = &last_resolved_addrs[IDX_IPV6]; + break; + default: + tor_assert_nonfatal_unreached(); + return; + } + + /* Same address last resolved. Ignore. */ + if (tor_addr_eq(last_resolved, addr)) { + return; + } + + /* Don't log notice if this is the first resolve we do. */ + if (*done_one_resolve) { + /* 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.", + fmt_addr(addr), method_used, + have_hostname ? " HOSTNAME=" : "", + have_hostname ? hostname_used : ""); + ip_address_changed(0); + } + + /* Notify control port. */ + control_event_server_status(LOG_NOTICE, + "EXTERNAL_ADDRESS ADDRESS=%s METHOD=%s%s%s", + fmt_addr(addr), method_used, + have_hostname ? " HOSTNAME=" : "", + have_hostname ? hostname_used : ""); + /* Copy address to cache. */ + tor_addr_copy(last_resolved, addr); + *done_one_resolve = true; +} + +/** @brief Attempt to find our IP address that can be used as our external + * reachable address. + * + * The following describe the algorithm to find an address. Each have + * specific conditions so read carefully. + * + * On success, true is returned and depending on how the address was found, + * the out parameters can have different values. + * + * On error, false is returned and all out parameters are untouched. + * + * 1. Look at the configuration Address option. + + * If Address is a public address, True is returned and addr_out is set + * with it, the method_out is set to "CONFIGURED" and hostname_out is set + * to NULL. + * + * If Address is an internal address but NO custom authorities are used, + * an error is returned. + * + * If Address is a hostname, that is it can't be converted to an address, + * it is resolved. On success, addr_out is set with the address, + * method_out is set to "RESOLVED" and hostname_out is set to the resolved + * hostname. On failure to resolve, an error is returned. + * + * If no given Address, fallback to the local hostname (see section 2). + * + * 2. Look at the local hostname. + * + * 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 + * to the resolved hostname. + * + * If a local hostname can NOT be found, an error is returned. + * + * If the local hostname resolves to an internal address, an error is + * returned. + * + * If the local hostname can NOT be resolved, fallback to the network + * 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 family IP address family. Only AF_INET and AF_INET6 are supported. + * @param warn_severity Logging level. + * @param addr_out OUT: Set with the IP address found if any. + * @param method_out OUT: (optional) String denoting by which method the + * address was found. This is described in the + * control-spec.txt as actions for "STATUS_SERVER". + * @param hostname_out OUT: String containing the hostname if any was used. + * Only be set for "RESOLVED" and "GETHOSTNAME" methods. + * Else it is set to NULL. + * + * @return True if the address was found for the given family. False if not or + * on errors. + */ +bool +find_my_address(const or_options_t *options, int family, int warn_severity, + tor_addr_t *addr_out, const char **method_out, + char **hostname_out) +{ + int ret; + const char *method_used; + char *hostname_used = tor_strdup(""); + tor_addr_t my_addr; + + tor_assert(options); + tor_assert(addr_out); + + /* + * Step 1: Discover address by attempting 3 different methods consecutively. + */ + + /* Attempt #1: Get address from configuration. */ + ret = get_address_from_config(options, warn_severity, family, &method_used, + &hostname_used, &my_addr); + if (ret == 0) { + log_fn(warn_severity, LD_CONFIG, "Address found in configuration: %s", + fmt_addr(&my_addr)); + } else { + /* Unable to resolve an Address statement is a failure. Also, using + * default dirauth error means that the configured address is internal + * which is only accepted if custom authorities are used. */ + if (ret == ERR_FAIL_RESOLVE || ret == ERR_DEFAULT_DIRAUTH) { + return false; + } + + /* Attempt #2: Get local hostname and resolve it. */ + ret = get_address_from_hostname(options, warn_severity, family, + &method_used, &hostname_used, &my_addr); + if (ret == 0) { + log_fn(warn_severity, LD_CONFIG, "Address found from local hostname: " + "%s", fmt_addr(&my_addr)); + } else if (ret < 0) { + /* Unable to get the hostname results in a failure. If the address is + * internal, we stop right away. */ + if (ret == ERR_GET_HOSTNAME || ret == ERR_ADDRESS_IS_INTERNAL) { + return false; + } + + /* Attempt #3: Get address from interface. */ + ret = get_address_from_interface(options, warn_severity, family, + &method_used, &my_addr); + if (ret == 0) { + log_fn(warn_severity, LD_CONFIG, "Address found from interface: %s", + fmt_addr(&my_addr)); + } else { + /* We've exhausted our attempts. Failure. */ + log_fn(warn_severity, LD_CONFIG, "Unable to find our IP address."); + return false; + } + } + } + tor_assert(method_used); + + /* From here, my_addr is a valid IP address of "family" and can be used as + * our external IP address. */ + + /* + * Step 2: Update last resolved address cache and inform the control port. + */ + update_resolved_cache(&my_addr, method_used, hostname_used); + + if (method_out) { + *method_out = method_used; + } + if (hostname_out) { + *hostname_out = NULL; + if (strlen(hostname_used) > 0) { + *hostname_out = hostname_used; + } else { + tor_free(hostname_used); + } + } else { + tor_free(hostname_used); + } + + tor_addr_copy(addr_out, &my_addr); + return true; +} + /** * Attempt getting our non-local (as judged by tor_addr_is_internal() * function) IP address using following techniques, listed in diff --git a/src/app/config/resolve_addr.h b/src/app/config/resolve_addr.h index 6c94fe06ba..2cd27d1700 100644 --- a/src/app/config/resolve_addr.h +++ b/src/app/config/resolve_addr.h @@ -15,6 +15,10 @@ int resolve_my_address_v4(int warn_severity, const or_options_t *options, uint32_t *addr_out, const char **method_out, char **hostname_out); +bool find_my_address(const or_options_t *options, int family, + int warn_severity, tor_addr_t *addr_out, + const char **method_out, char **hostname_out); + uint32_t get_last_resolved_addr_v4(void); void reset_last_resolved_addr_v4(void); From b8042c9d9a44eaf78c5580a1b0a3d15a90f125ce Mon Sep 17 00:00:00 2001 From: David Goulet Date: Thu, 18 Jun 2020 16:07:22 -0400 Subject: [PATCH 05/14] 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 --- 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 5cabb5889f..9a7fbde160 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); + 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; } - /* - * 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, "", 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, "", 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 : ""); - } - 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 87104113bc..a6b02713f9 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 n_hostname_01010101 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 n_hostname_localhost 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 n_hostname_failure 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 * n_get_interface_address 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: * - family 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. - * n_get_interface_address_failure 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); From 7795dd7ef6fa01202b91d20a0ac82eda1456cef8 Mon Sep 17 00:00:00 2001 From: David Goulet Date: Tue, 23 Jun 2020 10:06:19 -0400 Subject: [PATCH 06/14] addr: Refactor last resolved address cache accessors Series of things done in this commit: 1. Rename the functions to better reflect the namespace of the file. 2. Make both reset and get function to operate on the last_resolved_addrs cache that is per family. 3. Make the get function to take a tor_addr_t. 4. Change all callsite to use the new convention. Part of #33233 Signed-off-by: David Goulet --- src/app/config/resolve_addr.c | 19 ++++++++++++------- src/app/config/resolve_addr.h | 4 ++-- src/core/mainloop/connection.c | 2 +- src/feature/relay/relay_find_addr.c | 26 +++++++++++++++++++------- 4 files changed, 34 insertions(+), 17 deletions(-) diff --git a/src/app/config/resolve_addr.c b/src/app/config/resolve_addr.c index 9a7fbde160..1e861217de 100644 --- a/src/app/config/resolve_addr.c +++ b/src/app/config/resolve_addr.c @@ -47,18 +47,23 @@ static tor_addr_t last_resolved_addrs[IDX_SIZE]; /** Last value actually set by resolve_my_address. */ static uint32_t last_resolved_addr_v4 = 0; -/** Accessor for last_resolved_addr_v4 from outside this file. */ -uint32_t -get_last_resolved_addr_v4(void) +/** Copy the last resolved address of family into addr_out. + * + * If not last resolved address existed, the addr_out is a null address (use + * tor_addr_is_null()). */ +void +resolved_addr_get_last(int family, tor_addr_t *addr_out) { - return last_resolved_addr_v4; + tor_addr_copy(addr_out, &last_resolved_addrs[family]); } -/** Reset last_resolved_addr_v4 from outside this file. */ +/** Reset the last resolved address of family. + * + * This makes it null address. */ void -reset_last_resolved_addr_v4(void) +resolved_addr_reset_last(int family) { - last_resolved_addr_v4 = 0; + tor_addr_make_null(&last_resolved_addrs[family], family); } /** @brief Return true iff the given IP address can be used as a valid diff --git a/src/app/config/resolve_addr.h b/src/app/config/resolve_addr.h index 2cd27d1700..17e9402033 100644 --- a/src/app/config/resolve_addr.h +++ b/src/app/config/resolve_addr.h @@ -19,8 +19,8 @@ bool find_my_address(const or_options_t *options, int family, int warn_severity, tor_addr_t *addr_out, const char **method_out, char **hostname_out); -uint32_t get_last_resolved_addr_v4(void); -void reset_last_resolved_addr_v4(void); +void resolved_addr_get_last(int family, tor_addr_t *addr_out); +void resolved_addr_reset_last(int family); MOCK_DECL(int, is_local_addr, (const tor_addr_t *addr)); diff --git a/src/core/mainloop/connection.c b/src/core/mainloop/connection.c index 9fff71ee0a..3ebe18cd33 100644 --- a/src/core/mainloop/connection.c +++ b/src/core/mainloop/connection.c @@ -4870,7 +4870,7 @@ client_check_address_changed(tor_socket_t sock) smartlist_clear(outgoing_addrs); smartlist_add(outgoing_addrs, tor_memdup(&out_addr, sizeof(tor_addr_t))); /* We'll need to resolve ourselves again. */ - reset_last_resolved_addr_v4(); + resolved_addr_reset_last(AF_INET); /* Okay, now change our keys. */ ip_address_changed(1); } diff --git a/src/feature/relay/relay_find_addr.c b/src/feature/relay/relay_find_addr.c index cc08914f6b..70cb77d4bf 100644 --- a/src/feature/relay/relay_find_addr.c +++ b/src/feature/relay/relay_find_addr.c @@ -45,7 +45,7 @@ void router_new_address_suggestion(const char *suggestion, const dir_connection_t *d_conn) { - tor_addr_t addr; + tor_addr_t addr, last_resolved_addr; uint32_t cur = 0; /* Current IPv4 address. */ const or_options_t *options = get_options(); @@ -64,14 +64,22 @@ router_new_address_suggestion(const char *suggestion, } /* XXXX ipv6 */ - cur = get_last_resolved_addr_v4(); - if (cur || - resolve_my_address_v4(LOG_INFO, options, &cur, NULL, NULL) >= 0) { + resolved_addr_get_last(AF_INET, &last_resolved_addr); + if (!tor_addr_is_null(&last_resolved_addr)) { + /* Lets use this one. */ + tor_addr_copy(&last_guessed_ip, &last_resolved_addr); + return; + } + + /* Attempt to find our address. */ + if (resolve_my_address_v4(LOG_INFO, options, &cur, NULL, NULL) >= 0) { /* We're all set -- we already know our address. Great. */ tor_addr_from_ipv4h(&last_guessed_ip, cur); /* store it in case we need it later */ return; } + + /* Consider the suggestion from the directory. */ if (tor_addr_is_internal(&addr, 0)) { /* Don't believe anybody who says our IP is, say, 127.0.0.1. */ return; @@ -111,10 +119,14 @@ MOCK_IMPL(int, router_pick_published_address, (const or_options_t *options, uint32_t *addr, int cache_only)) { - /* First, check the cached output from resolve_my_address(). */ - *addr = get_last_resolved_addr_v4(); - if (*addr) + tor_addr_t last_resolved_addr; + + /* First, check the cached output from resolve_my_address_v4(). */ + resolved_addr_get_last(AF_INET, &last_resolved_addr); + if (!tor_addr_is_null(&last_resolved_addr)) { + *addr = tor_addr_to_ipv4h(&last_resolved_addr); return 0; + } /* Second, consider doing a resolve attempt right here. */ if (!cache_only) { From 2f3b4e38888116f434297fb45ac093acd2d01e55 Mon Sep 17 00:00:00 2001 From: David Goulet Date: Tue, 23 Jun 2020 10:43:39 -0400 Subject: [PATCH 07/14] addr: Refactor is_local_addr() to support IPv6 Series of changes: 1. Rename function to reflect the namespace of the file. 2. Use the new last resolved cache instead of the unused last_resolved_addr_v4 (which is also removed in this commit). 3. Make the entire code base use the new resolved_addr_is_local() function. You will notice that this function uses /24 to differentiate subnets where the rest of tor uses /16 (including documentation of EnforceDistinctSubnets). Ticket #40009 has been opened for that. But that the moment, the function keeps looking at /24. Part of #33233 Signed-off-by: David Goulet --- src/app/config/resolve_addr.c | 56 ++++++++++++++++++++------------- src/app/config/resolve_addr.h | 2 +- src/core/or/channeltls.c | 6 ++-- src/feature/dircache/dircache.c | 2 +- src/test/test_channeltls.c | 32 +++++++++---------- 5 files changed, 56 insertions(+), 42 deletions(-) diff --git a/src/app/config/resolve_addr.c b/src/app/config/resolve_addr.c index 1e861217de..c73519f148 100644 --- a/src/app/config/resolve_addr.c +++ b/src/app/config/resolve_addr.c @@ -44,9 +44,6 @@ /** Last resolved addresses. */ static tor_addr_t last_resolved_addrs[IDX_SIZE]; -/** Last value actually set by resolve_my_address. */ -static uint32_t last_resolved_addr_v4 = 0; - /** Copy the last resolved address of family into addr_out. * * If not last resolved address existed, the addr_out is a null address (use @@ -598,27 +595,44 @@ resolve_my_address_v4(int warn_severity, const or_options_t *options, /** Return true iff addr is judged to be on the same network as us, or * on a private network. */ -MOCK_IMPL(int, -is_local_addr, (const tor_addr_t *addr)) +MOCK_IMPL(bool, +resolved_addr_is_local, (const tor_addr_t *addr)) { - if (tor_addr_is_internal(addr, 0)) - return 1; - /* Check whether ip is on the same /24 as we are. */ - if (get_options()->EnforceDistinctSubnets == 0) - return 0; - if (tor_addr_family(addr) == AF_INET) { - uint32_t ip = tor_addr_to_ipv4h(addr); + const int family = tor_addr_family(addr); + const tor_addr_t *last_resolved_addr = &last_resolved_addrs[family]; + + /* Internal address is always local. */ + if (tor_addr_is_internal(addr, 0)) { + return true; + } + + /* Address is not local if we don't enforce subnet distinction. */ + if (get_options()->EnforceDistinctSubnets == 0) { + return false; + } + + switch (family) { + case AF_INET: + /* XXX: Why is this /24 and not /16 which the rest of tor does? Unknown + * reasons at the moment highlighted in ticket #40009. Because of that, we + * can't use addrs_in_same_network_family(). */ /* It's possible that this next check will hit before the first time - * resolve_my_address actually succeeds. (For clients, it is likely that - * resolve_my_address will never be called at all). In those cases, + * resolve_my_address_v4 actually succeeds. For clients, it is likely that + * resolve_my_address_v4 will never be called at all. In those cases, * last_resolved_addr_v4 will be 0, and so checking to see whether ip is - * on the same /24 as last_resolved_addr_v4 will be the same as checking - * whether it was on net 0, which is already done by tor_addr_is_internal. - */ - if ((last_resolved_addr_v4 & (uint32_t)0xffffff00ul) - == (ip & (uint32_t)0xffffff00ul)) - return 1; + * on the same /24 as last_resolved_addrs[AF_INET] will be the same as + * checking whether it was on net 0, which is already done by + * tor_addr_is_internal. */ + return tor_addr_compare_masked(addr, last_resolved_addr, 24, + CMP_SEMANTIC) == 0; + case AF_INET6: + /* Look at the /32 like addrs_in_same_network_family() does. */ + return tor_addr_compare_masked(addr, last_resolved_addr, 32, + CMP_SEMANTIC) == 0; + break; + default: + /* Unknown address type so not local. */ + return false; } - return 0; } diff --git a/src/app/config/resolve_addr.h b/src/app/config/resolve_addr.h index 17e9402033..f435ab29a4 100644 --- a/src/app/config/resolve_addr.h +++ b/src/app/config/resolve_addr.h @@ -22,7 +22,7 @@ bool find_my_address(const or_options_t *options, int family, void resolved_addr_get_last(int family, tor_addr_t *addr_out); void resolved_addr_reset_last(int family); -MOCK_DECL(int, is_local_addr, (const tor_addr_t *addr)); +MOCK_DECL(bool, resolved_addr_is_local, (const tor_addr_t *addr)); #ifdef RESOLVE_ADDR_PRIVATE diff --git a/src/core/or/channeltls.c b/src/core/or/channeltls.c index 395fbf3455..3e7f25ae48 100644 --- a/src/core/or/channeltls.c +++ b/src/core/or/channeltls.c @@ -203,7 +203,7 @@ channel_tls_connect(const tor_addr_t *addr, uint16_t port, tlschan, (chan->global_identifier)); - if (is_local_addr(addr)) { + if (resolved_addr_is_local(addr)) { log_debug(LD_CHANNEL, "Marking new outgoing channel %"PRIu64 " at %p as local", (chan->global_identifier), chan); @@ -340,7 +340,7 @@ channel_tls_handle_incoming(or_connection_t *orconn) tlschan->conn = orconn; orconn->chan = tlschan; - if (is_local_addr(&(TO_CONN(orconn)->addr))) { + if (resolved_addr_is_local(&(TO_CONN(orconn)->addr))) { log_debug(LD_CHANNEL, "Marking new incoming channel %"PRIu64 " at %p as local", (chan->global_identifier), chan); @@ -1353,7 +1353,7 @@ channel_tls_update_marks(or_connection_t *conn) chan = TLS_CHAN_TO_BASE(conn->chan); - if (is_local_addr(&(TO_CONN(conn)->addr))) { + if (resolved_addr_is_local(&(TO_CONN(conn)->addr))) { if (!channel_is_local(chan)) { log_debug(LD_CHANNEL, "Marking channel %"PRIu64 " at %p as local", diff --git a/src/feature/dircache/dircache.c b/src/feature/dircache/dircache.c index ca127720f2..44dc462051 100644 --- a/src/feature/dircache/dircache.c +++ b/src/feature/dircache/dircache.c @@ -142,7 +142,7 @@ write_http_response_header_impl(dir_connection_t *conn, ssize_t length, if (type) { buf_add_printf(buf, "Content-Type: %s\r\n", type); } - if (!is_local_addr(&conn->base_.addr)) { + if (!resolved_addr_is_local(&conn->base_.addr)) { /* Don't report the source address for a nearby/private connection. * Otherwise we tend to mis-report in cases where incoming ports are * being forwarded to a Tor server running behind the firewall. */ diff --git a/src/test/test_channeltls.c b/src/test/test_channeltls.c index f4f5cb447e..8018000331 100644 --- a/src/test/test_channeltls.c +++ b/src/test/test_channeltls.c @@ -38,13 +38,13 @@ static or_connection_t * tlschan_connection_or_connect_mock( const char *digest, const ed25519_public_key_t *ed_id, channel_tls_t *tlschan); -static int tlschan_is_local_addr_mock(const tor_addr_t *addr); +static bool tlschan_resolved_addr_is_local_mock(const tor_addr_t *addr); /* Fake close method */ static void tlschan_fake_close_method(channel_t *chan); /* Flags controlling behavior of channeltls unit test mocks */ -static int tlschan_local = 0; +static bool tlschan_local = false; static const buf_t * tlschan_buf_datalen_mock_target = NULL; static size_t tlschan_buf_datalen_mock_size = 0; @@ -67,9 +67,9 @@ test_channeltls_create(void *arg) test_addr.addr.in_addr.s_addr = htonl(0x01020304); /* For this test we always want the address to be treated as non-local */ - tlschan_local = 0; - /* Install is_local_addr() mock */ - MOCK(is_local_addr, tlschan_is_local_addr_mock); + tlschan_local = false; + /* Install resolved_addr_is_local() mock */ + MOCK(resolved_addr_is_local, tlschan_resolved_addr_is_local_mock); /* Install mock for connection_or_connect() */ MOCK(connection_or_connect, tlschan_connection_or_connect_mock); @@ -92,7 +92,7 @@ test_channeltls_create(void *arg) } UNMOCK(connection_or_connect); - UNMOCK(is_local_addr); + UNMOCK(resolved_addr_is_local); return; } @@ -116,9 +116,9 @@ test_channeltls_num_bytes_queued(void *arg) test_addr.addr.in_addr.s_addr = htonl(0x01020304); /* For this test we always want the address to be treated as non-local */ - tlschan_local = 0; - /* Install is_local_addr() mock */ - MOCK(is_local_addr, tlschan_is_local_addr_mock); + tlschan_local = false; + /* Install resolved_addr_is_local() mock */ + MOCK(resolved_addr_is_local, tlschan_resolved_addr_is_local_mock); /* Install mock for connection_or_connect() */ MOCK(connection_or_connect, tlschan_connection_or_connect_mock); @@ -178,7 +178,7 @@ test_channeltls_num_bytes_queued(void *arg) } UNMOCK(connection_or_connect); - UNMOCK(is_local_addr); + UNMOCK(resolved_addr_is_local); return; } @@ -201,9 +201,9 @@ test_channeltls_overhead_estimate(void *arg) test_addr.addr.in_addr.s_addr = htonl(0x01020304); /* For this test we always want the address to be treated as non-local */ - tlschan_local = 0; - /* Install is_local_addr() mock */ - MOCK(is_local_addr, tlschan_is_local_addr_mock); + tlschan_local = false; + /* Install resolved_addr_is_local() mock */ + MOCK(resolved_addr_is_local, tlschan_resolved_addr_is_local_mock); /* Install mock for connection_or_connect() */ MOCK(connection_or_connect, tlschan_connection_or_connect_mock); @@ -252,7 +252,7 @@ test_channeltls_overhead_estimate(void *arg) } UNMOCK(connection_or_connect); - UNMOCK(is_local_addr); + UNMOCK(resolved_addr_is_local); return; } @@ -321,8 +321,8 @@ tlschan_fake_close_method(channel_t *chan) return; } -static int -tlschan_is_local_addr_mock(const tor_addr_t *addr) +static bool +tlschan_resolved_addr_is_local_mock(const tor_addr_t *addr) { tt_ptr_op(addr, OP_NE, NULL); From b76325190b3fb2d01fb0c9f0d2ffe76a284d1766 Mon Sep 17 00:00:00 2001 From: David Goulet Date: Tue, 23 Jun 2020 11:19:50 -0400 Subject: [PATCH 08/14] addr: Remove resolve_my_address_v4() Replace it by find_my_address() everywhere. This changes many parts of the code that uses it to use a tor_addr_t instead of a plain uint32_t for IPv4. Many changes to the unit test to also use the new interface. Part #33233 Signed-off-by: David Goulet --- src/app/config/resolve_addr.c | 68 +------------- src/app/config/resolve_addr.h | 4 - src/feature/dirauth/dirauth_config.c | 4 +- src/feature/dirauth/dirvote.c | 8 +- src/feature/nodelist/dirlist.c | 10 +- src/feature/relay/relay_find_addr.c | 17 ++-- src/feature/relay/router.c | 5 +- src/test/test_config.c | 136 +++++++++++++++------------ 8 files changed, 100 insertions(+), 152 deletions(-) diff --git a/src/app/config/resolve_addr.c b/src/app/config/resolve_addr.c index c73519f148..56548e6e70 100644 --- a/src/app/config/resolve_addr.c +++ b/src/app/config/resolve_addr.c @@ -528,70 +528,6 @@ find_my_address(const or_options_t *options, int family, int warn_severity, return true; } -/** - * Attempt getting our non-local (as judged by tor_addr_is_internal() - * function) IP address using following techniques, listed in - * order from best (most desirable, try first) to worst (least - * desirable, try if everything else fails). - * - * First, attempt using options-\>Address to get our - * non-local IP address. - * - * If options-\>Address represents a non-local IP address, - * consider it ours. - * - * If options-\>Address is a DNS name that resolves to - * a non-local IP address, consider this IP address ours. - * - * If options-\>Address is NULL, fall back to getting local - * hostname and using it in above-described ways to try and - * get our IP address. - * - * In case local hostname cannot be resolved to a non-local IP - * address, try getting an IP address of network interface - * in hopes it will be non-local one. - * - * Fail if one or more of the following is true: - * - DNS name in options-\>Address cannot be resolved. - * - options-\>Address is a local host address. - * - Attempt at getting local hostname fails. - * - Attempt at getting network interface address fails. - * - * Return 0 if all is well, or -1 if we can't find a suitable - * public IP address. - * - * If we are returning 0: - * - Put our public IP address (in host order) into *addr_out. - * - If method_out is non-NULL, set *method_out to a static - * string describing how we arrived at our answer. - * - "CONFIGURED" - parsed from IP address string in - * options-\>Address - * - "RESOLVED" - resolved from DNS name in options-\>Address - * - "GETHOSTNAME" - resolved from a local hostname. - * - "INTERFACE" - retrieved from a network interface. - * - If hostname_out is non-NULL, and we resolved a hostname to - * get our address, set *hostname_out to a newly allocated string - * holding that hostname. (If we didn't get our address by resolving a - * hostname, set *hostname_out to NULL.) - * - * XXXX ipv6 - */ -int -resolve_my_address_v4(int warn_severity, const or_options_t *options, - uint32_t *addr_out, - const char **method_out, char **hostname_out) -{ - 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; - } - - *addr_out = tor_addr_to_ipv4h(&my_addr); - return 0; -} - /** Return true iff addr is judged to be on the same network as us, or * on a private network. */ @@ -618,8 +554,8 @@ resolved_addr_is_local, (const tor_addr_t *addr)) * can't use addrs_in_same_network_family(). */ /* It's possible that this next check will hit before the first time - * resolve_my_address_v4 actually succeeds. For clients, it is likely that - * resolve_my_address_v4 will never be called at all. In those cases, + * find_my_address actually succeeds. For clients, it is likely that + * find_my_address will never be called at all. In those cases, * last_resolved_addr_v4 will be 0, and so checking to see whether ip is * on the same /24 as last_resolved_addrs[AF_INET] will be the same as * checking whether it was on net 0, which is already done by diff --git a/src/app/config/resolve_addr.h b/src/app/config/resolve_addr.h index f435ab29a4..ff732561c6 100644 --- a/src/app/config/resolve_addr.h +++ b/src/app/config/resolve_addr.h @@ -11,10 +11,6 @@ #include "app/config/or_options_st.h" -int resolve_my_address_v4(int warn_severity, const or_options_t *options, - uint32_t *addr_out, - const char **method_out, char **hostname_out); - bool find_my_address(const or_options_t *options, int family, int warn_severity, tor_addr_t *addr_out, const char **method_out, char **hostname_out); diff --git a/src/feature/dirauth/dirauth_config.c b/src/feature/dirauth/dirauth_config.c index 888b8e7d94..1ffd33e5f1 100644 --- a/src/feature/dirauth/dirauth_config.c +++ b/src/feature/dirauth/dirauth_config.c @@ -77,8 +77,8 @@ options_validate_dirauth_mode(const or_options_t *old_options, return 0; /* confirm that our address isn't broken, so we can complain now */ - uint32_t tmp; - if (resolve_my_address_v4(LOG_WARN, options, &tmp, NULL, NULL) < 0) + tor_addr_t tmp; + if (!find_my_address(options, AF_INET, LOG_WARN, &tmp, NULL, NULL)) REJECT("Failed to resolve/guess local address. See logs for details."); if (!options->ContactInfo && !options->TestingTorNetwork) diff --git a/src/feature/dirauth/dirvote.c b/src/feature/dirauth/dirvote.c index 3030955fd1..5fda842246 100644 --- a/src/feature/dirauth/dirvote.c +++ b/src/feature/dirauth/dirvote.c @@ -4463,7 +4463,7 @@ dirserv_generate_networkstatus_vote_obj(crypto_pk_t *private_key, const or_options_t *options = get_options(); const dirauth_options_t *d_options = dirauth_get_options(); networkstatus_t *v3_out = NULL; - uint32_t addr; + tor_addr_t addr; char *hostname = NULL, *client_versions = NULL, *server_versions = NULL; const char *contact; smartlist_t *routers, *routerstatuses; @@ -4492,13 +4492,13 @@ dirserv_generate_networkstatus_vote_obj(crypto_pk_t *private_key, log_err(LD_BUG, "Error computing identity key digest"); return NULL; } - if (resolve_my_address_v4(LOG_WARN, options, &addr, NULL, &hostname)<0) { + if (!find_my_address(options, AF_INET, LOG_WARN, &addr, NULL, &hostname)) { log_warn(LD_NET, "Couldn't resolve my hostname"); return NULL; } if (!hostname || !strchr(hostname, '.')) { tor_free(hostname); - hostname = tor_dup_ip(addr); + hostname = tor_addr_to_str_dup(&addr); } if (!hostname) { @@ -4722,7 +4722,7 @@ dirserv_generate_networkstatus_vote_obj(crypto_pk_t *private_key, memcpy(voter->identity_digest, identity_digest, DIGEST_LEN); voter->sigs = smartlist_new(); voter->address = hostname; - voter->addr = addr; + voter->addr = tor_addr_to_ipv4h(&addr); voter->dir_port = router_get_advertised_dir_port(options, 0); voter->or_port = router_get_advertised_or_port(options); voter->contact = tor_strdup(contact); diff --git a/src/feature/nodelist/dirlist.c b/src/feature/nodelist/dirlist.c index 4481daba6f..f49d991f9b 100644 --- a/src/feature/nodelist/dirlist.c +++ b/src/feature/nodelist/dirlist.c @@ -343,25 +343,25 @@ trusted_dir_server_new(const char *nickname, const char *address, const char *digest, const char *v3_auth_digest, dirinfo_type_t type, double weight) { - uint32_t a; tor_addr_t addr; char *hostname=NULL; dir_server_t *result; if (!address) { /* The address is us; we should guess. */ - if (resolve_my_address_v4(LOG_WARN, get_options(), - &a, NULL, &hostname) < 0) { + if (!find_my_address(get_options(), AF_INET, LOG_WARN, &addr, + NULL, &hostname)) { log_warn(LD_CONFIG, "Couldn't find a suitable address when adding ourself as a " "trusted directory server."); return NULL; } if (!hostname) - hostname = tor_dup_ip(a); + hostname = tor_addr_to_str_dup(&addr); if (!hostname) return NULL; } else { + uint32_t a; if (tor_lookup_hostname(address, &a)) { log_warn(LD_CONFIG, "Unable to lookup address for directory server at '%s'", @@ -369,8 +369,8 @@ trusted_dir_server_new(const char *nickname, const char *address, return NULL; } hostname = tor_strdup(address); + tor_addr_from_ipv4h(&addr, a); } - tor_addr_from_ipv4h(&addr, a); result = dir_server_new(1, nickname, &addr, hostname, dir_port, or_port, diff --git a/src/feature/relay/relay_find_addr.c b/src/feature/relay/relay_find_addr.c index 70cb77d4bf..a51457ddbb 100644 --- a/src/feature/relay/relay_find_addr.c +++ b/src/feature/relay/relay_find_addr.c @@ -45,8 +45,7 @@ void router_new_address_suggestion(const char *suggestion, const dir_connection_t *d_conn) { - tor_addr_t addr, last_resolved_addr; - uint32_t cur = 0; /* Current IPv4 address. */ + tor_addr_t addr, my_addr, last_resolved_addr; const or_options_t *options = get_options(); /* first, learn what the IP address actually is */ @@ -72,10 +71,10 @@ router_new_address_suggestion(const char *suggestion, } /* Attempt to find our address. */ - if (resolve_my_address_v4(LOG_INFO, options, &cur, NULL, NULL) >= 0) { + if (find_my_address(options, AF_INET, LOG_INFO, &my_addr, NULL, NULL)) { /* We're all set -- we already know our address. Great. */ - tor_addr_from_ipv4h(&last_guessed_ip, cur); /* store it in case we - need it later */ + tor_addr_copy(&last_guessed_ip, &my_addr); /* store it in case we + need it later */ return; } @@ -121,7 +120,7 @@ router_pick_published_address, (const or_options_t *options, uint32_t *addr, { tor_addr_t last_resolved_addr; - /* First, check the cached output from resolve_my_address_v4(). */ + /* First, check the cached output from find_my_address(). */ resolved_addr_get_last(AF_INET, &last_resolved_addr); if (!tor_addr_is_null(&last_resolved_addr)) { *addr = tor_addr_to_ipv4h(&last_resolved_addr); @@ -130,8 +129,10 @@ router_pick_published_address, (const or_options_t *options, uint32_t *addr, /* Second, consider doing a resolve attempt right here. */ if (!cache_only) { - if (resolve_my_address_v4(LOG_INFO, options, addr, NULL, NULL) >= 0) { - log_info(LD_CONFIG,"Success: chose address '%s'.", fmt_addr32(*addr)); + tor_addr_t my_addr; + if (find_my_address(options, AF_INET, LOG_INFO, &my_addr, NULL, NULL)) { + log_info(LD_CONFIG,"Success: chose address '%s'.", fmt_addr(&my_addr)); + *addr = tor_addr_to_ipv4h(&my_addr); return 0; } } diff --git a/src/feature/relay/router.c b/src/feature/relay/router.c index 4d5ed3a3e1..fd62a3073a 100644 --- a/src/feature/relay/router.c +++ b/src/feature/relay/router.c @@ -2540,6 +2540,7 @@ void check_descriptor_ipaddress_changed(time_t now) { uint32_t prev, cur; + tor_addr_t addr; const or_options_t *options = get_options(); const char *method = NULL; char *hostname = NULL; @@ -2552,10 +2553,12 @@ check_descriptor_ipaddress_changed(time_t now) /* XXXX ipv6 */ prev = my_ri->addr; - if (resolve_my_address_v4(LOG_INFO, options, &cur, &method, &hostname) < 0) { + if (!find_my_address(options, AF_INET, LOG_INFO, &addr, &method, + &hostname)) { log_info(LD_CONFIG,"options->Address didn't resolve into an IP."); return; } + cur = tor_addr_to_ipv4h(&addr); if (prev != cur) { char *source; diff --git a/src/test/test_config.c b/src/test/test_config.c index a6b02713f9..b082a4989a 100644 --- a/src/test/test_config.c +++ b/src/test/test_config.c @@ -1170,14 +1170,14 @@ get_interface_address6_failure(int severity, sa_family_t family, } static void -test_config_resolve_my_address_v4(void *arg) +test_config_find_my_address(void *arg) { or_options_t *options; - uint32_t resolved_addr; + tor_addr_t resolved_addr, test_addr; char buf[1024]; const char *method_used; char *hostname_out = NULL; - int retval; + bool retval; int prev_n_hostname_01010101; int prev_n_hostname_localhost; int prev_n_hostname_failure; @@ -1200,20 +1200,21 @@ test_config_resolve_my_address_v4(void *arg) */ strlcpy(buf, "Address 128.52.128.105\n", sizeof(buf)); config_get_lines(buf, &(options->Address), 0); + tor_addr_parse(&test_addr, "128.52.128.105"); - retval = resolve_my_address_v4(LOG_NOTICE,options,&resolved_addr, - &method_used,&hostname_out); + retval = find_my_address(options, AF_INET, LOG_NOTICE, &resolved_addr, + &method_used, &hostname_out); - tt_want(retval == 0); + tt_want(retval == true); tt_want_str_op(method_used,OP_EQ,"CONFIGURED"); tt_want(hostname_out == NULL); - tt_u64_op(resolved_addr, OP_EQ, 0x80348069); + tt_int_op(tor_addr_eq(&resolved_addr, &test_addr), OP_EQ, 1); config_free_lines(options->Address); /* * CASE 2: - * If options->Address is a valid DNS address, we want resolve_my_address_v4() + * If options->Address is a valid DNS address, we want find_my_address() * function to ask tor_addr_lookup() for help with resolving it * and return the address that was resolved (in host order). */ @@ -1222,17 +1223,18 @@ test_config_resolve_my_address_v4(void *arg) strlcpy(buf, "Address www.torproject.org\n", sizeof(buf)); config_get_lines(buf, &(options->Address), 0); + tor_addr_parse(&test_addr, "1.1.1.1"); prev_n_hostname_01010101 = n_hostname_01010101; - retval = resolve_my_address_v4(LOG_NOTICE,options,&resolved_addr, - &method_used,&hostname_out); + retval = find_my_address(options, AF_INET, LOG_NOTICE, &resolved_addr, + &method_used, &hostname_out); - tt_want(retval == 0); + tt_want(retval == true); 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_u64_op(resolved_addr, OP_EQ, 0x01010101); + tt_int_op(tor_addr_eq(&resolved_addr, &test_addr), OP_EQ, 1); UNMOCK(tor_addr_lookup); @@ -1241,13 +1243,14 @@ test_config_resolve_my_address_v4(void *arg) /* * CASE 3: - * Given that options->Address is NULL, we want resolve_my_address_v4() + * Given that options->Address is NULL, we want find_my_address() * to try and use tor_gethostname() to get hostname AND use * tor_addr_lookup() to get IP address. */ - resolved_addr = 0; + tor_addr_make_unspec(&resolved_addr); options->Address = NULL; + tor_addr_parse(&test_addr, "1.1.1.1"); MOCK(tor_gethostname,tor_gethostname_replacement); MOCK(tor_addr_lookup,tor_addr_lookup_01010101); @@ -1255,15 +1258,15 @@ test_config_resolve_my_address_v4(void *arg) prev_n_gethostname_replacement = n_gethostname_replacement; prev_n_hostname_01010101 = n_hostname_01010101; - retval = resolve_my_address_v4(LOG_NOTICE,options,&resolved_addr, - &method_used,&hostname_out); + retval = find_my_address(options, AF_INET, LOG_NOTICE, &resolved_addr, + &method_used, &hostname_out); - tt_want(retval == 0); + tt_want(retval == true); tt_want(n_gethostname_replacement == prev_n_gethostname_replacement + 1); tt_want(n_hostname_01010101 == prev_n_hostname_01010101 + 1); tt_want_str_op(method_used,OP_EQ,"GETHOSTNAME"); tt_want_str_op(hostname_out,OP_EQ,"onionrouter!"); - tt_assert(resolved_addr == 0x01010101); + tt_int_op(tor_addr_eq(&resolved_addr, &test_addr), OP_EQ, 1); UNMOCK(tor_gethostname); UNMOCK(tor_addr_lookup); @@ -1273,25 +1276,26 @@ test_config_resolve_my_address_v4(void *arg) /* * CASE 4: * Given that options->Address is a local host address, we want - * resolve_my_address_v4() function to fail. + * find_my_address() function to fail. */ - resolved_addr = 0; + tor_addr_make_unspec(&resolved_addr); strlcpy(buf, "Address 127.0.0.1\n", sizeof(buf)); config_get_lines(buf, &(options->Address), 0); + tor_addr_parse(&test_addr, "127.0.0.1"); - retval = resolve_my_address_v4(LOG_NOTICE,options,&resolved_addr, - &method_used,&hostname_out); + retval = find_my_address(options, AF_INET, LOG_NOTICE, &resolved_addr, + &method_used, &hostname_out); - tt_want(resolved_addr == 0); - tt_int_op(retval, OP_EQ, -1); + tt_want(tor_addr_is_null(&resolved_addr) == 1); + tt_want(retval == false); config_free_lines(options->Address); tor_free(hostname_out); /* * CASE 5: - * We want resolve_my_address_v4() to fail if DNS address in options->Address + * We want find_my_address() to fail if DNS address in options->Address * cannot be resolved. */ @@ -1302,11 +1306,12 @@ test_config_resolve_my_address_v4(void *arg) strlcpy(buf, "Address www.tor-project.org\n", sizeof(buf)); config_get_lines(buf, &(options->Address), 0); - retval = resolve_my_address_v4(LOG_NOTICE,options,&resolved_addr, - &method_used,&hostname_out); + retval = find_my_address(options, AF_INET, LOG_NOTICE, &resolved_addr, + &method_used, &hostname_out); tt_want(n_hostname_failure == prev_n_hostname_failure + 1); - tt_int_op(retval, OP_EQ, -1); + tt_want(tor_addr_is_null(&resolved_addr) == 1); + tt_want(retval == false); UNMOCK(tor_addr_lookup); @@ -1317,25 +1322,26 @@ test_config_resolve_my_address_v4(void *arg) /* * CASE 6: * If options->Address is NULL AND gettting local hostname fails, we want - * resolve_my_address_v4() to fail as well. + * find_my_address() to fail as well. */ MOCK(tor_gethostname,tor_gethostname_failure); prev_n_gethostname_failure = n_gethostname_failure; - retval = resolve_my_address_v4(LOG_NOTICE,options,&resolved_addr, - &method_used,&hostname_out); + retval = find_my_address(options, AF_INET, LOG_NOTICE, &resolved_addr, + &method_used, &hostname_out); tt_want(n_gethostname_failure == prev_n_gethostname_failure + 1); - tt_int_op(retval, OP_EQ, -1); + tt_want(tor_addr_is_null(&resolved_addr) == 1); + tt_want(retval == false); UNMOCK(tor_gethostname); tor_free(hostname_out); /* * CASE 7: - * We want resolve_my_address_v4() to try and get network interface address via + * We want find_my_address() to try and get network interface address via * get_interface_address() if hostname returned by tor_gethostname() cannot be * resolved into IP address. */ @@ -1344,20 +1350,22 @@ test_config_resolve_my_address_v4(void *arg) MOCK(tor_addr_lookup,tor_addr_lookup_failure); MOCK(get_interface_address6, get_interface_address6_08080808); + tor_addr_parse(&test_addr, "8.8.8.8"); + prev_n_gethostname_replacement = n_gethostname_replacement; prev_n_get_interface_address6 = n_get_interface_address6; - retval = resolve_my_address_v4(LOG_NOTICE,options,&resolved_addr, - &method_used,&hostname_out); + retval = find_my_address(options, AF_INET, LOG_NOTICE, &resolved_addr, + &method_used, &hostname_out); - tt_want(retval == 0); + tt_want(retval == true); tt_want_int_op(n_gethostname_replacement, OP_EQ, prev_n_gethostname_replacement + 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); + tt_int_op(tor_addr_eq(&resolved_addr, &test_addr), OP_EQ, 1); UNMOCK(get_interface_address); tor_free(hostname_out); @@ -1365,7 +1373,7 @@ test_config_resolve_my_address_v4(void *arg) /* * CASE 8: * Suppose options->Address is NULL AND hostname returned by tor_gethostname() - * is unresolvable. We want resolve_my_address_v4 to fail if + * is unresolvable. We want find_my_address to fail if * get_interface_address() fails. */ @@ -1374,14 +1382,14 @@ test_config_resolve_my_address_v4(void *arg) 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); + retval = find_my_address(options, AF_INET, LOG_NOTICE, &resolved_addr, + &method_used, &hostname_out); 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); + tt_want(retval == false); UNMOCK(get_interface_address); tor_free(hostname_out); @@ -1390,7 +1398,7 @@ test_config_resolve_my_address_v4(void *arg) * CASE 9: * 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 + * to local IP address, we want find_my_address() function to * call get_interface_address6(.,AF_INET,.) and return IP address * the latter function has found. */ @@ -1399,20 +1407,22 @@ test_config_resolve_my_address_v4(void *arg) MOCK(tor_gethostname,tor_gethostname_replacement); MOCK(get_interface_address6,get_interface_address6_replacement); + tor_addr_parse(&test_addr, "9.9.9.9"); + prev_n_gethostname_replacement = n_gethostname_replacement; prev_n_hostname_failure = n_hostname_failure; prev_n_get_interface_address6 = n_get_interface_address6; - retval = resolve_my_address_v4(LOG_NOTICE,options,&resolved_addr, - &method_used,&hostname_out); + retval = find_my_address(options, AF_INET, LOG_NOTICE, &resolved_addr, + &method_used, &hostname_out); tt_want(last_address6_family == AF_INET); tt_want(n_get_interface_address6 == prev_n_get_interface_address6 + 1); tt_want(n_hostname_failure == prev_n_hostname_failure + 1); tt_want(n_gethostname_replacement == prev_n_gethostname_replacement + 1); - tt_want(retval == 0); + tt_want(retval == true); tt_want_str_op(method_used,OP_EQ,"INTERFACE"); - tt_assert(resolved_addr == 0x09090909); + tt_int_op(tor_addr_eq(&resolved_addr, &test_addr), OP_EQ, 1); UNMOCK(tor_addr_lookup); UNMOCK(tor_gethostname); @@ -1421,7 +1431,7 @@ test_config_resolve_my_address_v4(void *arg) tor_free(hostname_out); /* - * CASE 10: We want resolve_my_address_v4() to fail if all of the following + * CASE 10: We want find_my_address() to fail if all of the following * are true: * 1. options->Address is not NULL * 2. ... but it cannot be converted to struct in_addr by @@ -1437,11 +1447,11 @@ test_config_resolve_my_address_v4(void *arg) strlcpy(buf, "Address some_hostname\n", sizeof(buf)); config_get_lines(buf, &(options->Address), 0); - retval = resolve_my_address_v4(LOG_NOTICE, options, &resolved_addr, - &method_used,&hostname_out); + retval = find_my_address(options, AF_INET, LOG_NOTICE, &resolved_addr, + &method_used, &hostname_out); tt_want(n_hostname_failure == prev_n_hostname_failure + 1); - tt_int_op(retval, OP_EQ, -1); + tt_want(retval == false); UNMOCK(tor_gethostname); UNMOCK(tor_addr_lookup); @@ -1469,6 +1479,7 @@ test_config_resolve_my_address_v4(void *arg) config_free_lines(options->Address); options->Address = NULL; + tor_addr_parse(&test_addr, "9.9.9.9"); MOCK(tor_gethostname,tor_gethostname_replacement); MOCK(tor_addr_lookup,tor_addr_lookup_localhost); @@ -1478,8 +1489,8 @@ test_config_resolve_my_address_v4(void *arg) prev_n_hostname_localhost = n_hostname_localhost; prev_n_get_interface_address6 = n_get_interface_address6; - retval = resolve_my_address_v4(LOG_DEBUG, options, &resolved_addr, - &method_used,&hostname_out); + retval = find_my_address(options, AF_INET, LOG_NOTICE, &resolved_addr, + &method_used, &hostname_out); tt_want(n_gethostname_replacement == prev_n_gethostname_replacement + 1); tt_want(n_hostname_localhost == prev_n_hostname_localhost + 1); @@ -1487,14 +1498,15 @@ test_config_resolve_my_address_v4(void *arg) tt_str_op(method_used,OP_EQ,"INTERFACE"); tt_ptr_op(hostname_out, OP_EQ, NULL); - tt_int_op(retval, OP_EQ, 0); + tt_want(retval == true); + tt_int_op(tor_addr_eq(&resolved_addr, &test_addr), OP_EQ, 1); /* * CASE 11b: * 1-5 as above. * 6. get_interface_address6() fails. * - * In this subcase, we want resolve_my_address_v4() to fail. + * In this subcase, we want find_my_address() to fail. */ UNMOCK(get_interface_address6); @@ -1504,15 +1516,15 @@ test_config_resolve_my_address_v4(void *arg) prev_n_hostname_localhost = n_hostname_localhost; prev_n_get_interface_address6_failure = n_get_interface_address6_failure; - retval = resolve_my_address_v4(LOG_DEBUG, options, &resolved_addr, - &method_used,&hostname_out); + retval = find_my_address(options, AF_INET, LOG_DEBUG, &resolved_addr, + &method_used, &hostname_out); tt_want(n_gethostname_replacement == prev_n_gethostname_replacement + 1); tt_want(n_hostname_localhost == prev_n_hostname_localhost + 1); tt_want(n_get_interface_address6_failure == prev_n_get_interface_address6_failure + 1); - tt_int_op(retval, OP_EQ, -1); + tt_want(retval == false); UNMOCK(tor_gethostname); UNMOCK(tor_addr_lookup); @@ -1526,7 +1538,7 @@ test_config_resolve_my_address_v4(void *arg) * 4. into IPv4 address that tor_addr_is_inernal() considers to be * internal. * - * In this case, we want resolve_my_address_v4() to fail. + * In this case, we want find_my_address() to fail. */ tor_free(options->Address); @@ -1537,11 +1549,11 @@ test_config_resolve_my_address_v4(void *arg) prev_n_gethostname_localhost = n_gethostname_localhost; - retval = resolve_my_address_v4(LOG_DEBUG, options, &resolved_addr, - &method_used,&hostname_out); + retval = find_my_address(options, AF_INET, LOG_DEBUG, &resolved_addr, + &method_used, &hostname_out); tt_want(n_gethostname_localhost == prev_n_gethostname_localhost + 1); - tt_int_op(retval, OP_EQ, -1); + tt_want(retval == false); UNMOCK(tor_gethostname); @@ -6239,7 +6251,7 @@ struct testcase_t config_tests[] = { CONFIG_TEST(adding_dir_servers, TT_FORK), CONFIG_TEST(default_dir_servers, TT_FORK), CONFIG_TEST(default_fallback_dirs, 0), - CONFIG_TEST(resolve_my_address_v4, TT_FORK), + CONFIG_TEST(find_my_address, TT_FORK), CONFIG_TEST(addressmap, 0), CONFIG_TEST(parse_bridge_line, 0), CONFIG_TEST(parse_transport_options_line, 0), From 901a2507e6b16e2eb07566825de274be0aecfd9e Mon Sep 17 00:00:00 2001 From: David Goulet Date: Tue, 23 Jun 2020 11:22:32 -0400 Subject: [PATCH 09/14] changes: Add changes file for ticket #33233 Signed-off-by: David Goulet --- changes/ticket33233 | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 changes/ticket33233 diff --git a/changes/ticket33233 b/changes/ticket33233 new file mode 100644 index 0000000000..977286c323 --- /dev/null +++ b/changes/ticket33233 @@ -0,0 +1,4 @@ + o Major feature (IPv6, relay): + - The torrc option Address now supports IPv6. By doing so, we've also + unified the interface to find our address to support IPv4, IPv6 and + hostname. Closes ticket 33233; From 5f62ae25774aece55cb8aa9ebd61316608a0560d Mon Sep 17 00:00:00 2001 From: David Goulet Date: Wed, 24 Jun 2020 08:04:31 -0400 Subject: [PATCH 10/14] test: Modernize find_my_address() unit test Signed-off-by: David Goulet --- src/test/test_config.c | 28 +++++++++++----------------- 1 file changed, 11 insertions(+), 17 deletions(-) diff --git a/src/test/test_config.c b/src/test/test_config.c index b082a4989a..7b7c9c6216 100644 --- a/src/test/test_config.c +++ b/src/test/test_config.c @@ -1174,7 +1174,6 @@ test_config_find_my_address(void *arg) { or_options_t *options; tor_addr_t resolved_addr, test_addr; - char buf[1024]; const char *method_used; char *hostname_out = NULL; bool retval; @@ -1198,8 +1197,7 @@ test_config_find_my_address(void *arg) * If options->Address is a valid IPv4 address string, we want * the corresponding address to be parsed and returned. */ - strlcpy(buf, "Address 128.52.128.105\n", sizeof(buf)); - config_get_lines(buf, &(options->Address), 0); + config_line_append(&options->Address, "Address", "128.52.128.105"); tor_addr_parse(&test_addr, "128.52.128.105"); retval = find_my_address(options, AF_INET, LOG_NOTICE, &resolved_addr, @@ -1208,7 +1206,7 @@ test_config_find_my_address(void *arg) tt_want(retval == true); tt_want_str_op(method_used,OP_EQ,"CONFIGURED"); tt_want(hostname_out == NULL); - tt_int_op(tor_addr_eq(&resolved_addr, &test_addr), OP_EQ, 1); + tt_assert(tor_addr_eq(&resolved_addr, &test_addr)); config_free_lines(options->Address); @@ -1221,8 +1219,7 @@ test_config_find_my_address(void *arg) MOCK(tor_addr_lookup, tor_addr_lookup_01010101); - strlcpy(buf, "Address www.torproject.org\n", sizeof(buf)); - config_get_lines(buf, &(options->Address), 0); + config_line_append(&options->Address, "Address", "www.torproject.org"); tor_addr_parse(&test_addr, "1.1.1.1"); prev_n_hostname_01010101 = n_hostname_01010101; @@ -1234,7 +1231,7 @@ test_config_find_my_address(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_int_op(tor_addr_eq(&resolved_addr, &test_addr), OP_EQ, 1); + tt_assert(tor_addr_eq(&resolved_addr, &test_addr)); UNMOCK(tor_addr_lookup); @@ -1266,7 +1263,7 @@ test_config_find_my_address(void *arg) tt_want(n_hostname_01010101 == prev_n_hostname_01010101 + 1); tt_want_str_op(method_used,OP_EQ,"GETHOSTNAME"); tt_want_str_op(hostname_out,OP_EQ,"onionrouter!"); - tt_int_op(tor_addr_eq(&resolved_addr, &test_addr), OP_EQ, 1); + tt_assert(tor_addr_eq(&resolved_addr, &test_addr)); UNMOCK(tor_gethostname); UNMOCK(tor_addr_lookup); @@ -1280,8 +1277,7 @@ test_config_find_my_address(void *arg) */ tor_addr_make_unspec(&resolved_addr); - strlcpy(buf, "Address 127.0.0.1\n", sizeof(buf)); - config_get_lines(buf, &(options->Address), 0); + config_line_append(&options->Address, "Address", "127.0.0.1"); tor_addr_parse(&test_addr, "127.0.0.1"); retval = find_my_address(options, AF_INET, LOG_NOTICE, &resolved_addr, @@ -1303,8 +1299,7 @@ test_config_find_my_address(void *arg) prev_n_hostname_failure = n_hostname_failure; - strlcpy(buf, "Address www.tor-project.org\n", sizeof(buf)); - config_get_lines(buf, &(options->Address), 0); + config_line_append(&options->Address, "Address", "www.tor-project.org"); retval = find_my_address(options, AF_INET, LOG_NOTICE, &resolved_addr, &method_used, &hostname_out); @@ -1365,7 +1360,7 @@ test_config_find_my_address(void *arg) prev_n_get_interface_address6 + 1); tt_want_str_op(method_used,OP_EQ,"INTERFACE"); tt_want(hostname_out == NULL); - tt_int_op(tor_addr_eq(&resolved_addr, &test_addr), OP_EQ, 1); + tt_assert(tor_addr_eq(&resolved_addr, &test_addr)); UNMOCK(get_interface_address); tor_free(hostname_out); @@ -1422,7 +1417,7 @@ test_config_find_my_address(void *arg) tt_want(n_gethostname_replacement == prev_n_gethostname_replacement + 1); tt_want(retval == true); tt_want_str_op(method_used,OP_EQ,"INTERFACE"); - tt_int_op(tor_addr_eq(&resolved_addr, &test_addr), OP_EQ, 1); + tt_assert(tor_addr_eq(&resolved_addr, &test_addr)); UNMOCK(tor_addr_lookup); UNMOCK(tor_gethostname); @@ -1444,8 +1439,7 @@ test_config_find_my_address(void *arg) prev_n_hostname_failure = n_hostname_failure; - strlcpy(buf, "Address some_hostname\n", sizeof(buf)); - config_get_lines(buf, &(options->Address), 0); + config_line_append(&options->Address, "Address", "some_hostname"); retval = find_my_address(options, AF_INET, LOG_NOTICE, &resolved_addr, &method_used, &hostname_out); @@ -1499,7 +1493,7 @@ test_config_find_my_address(void *arg) tt_str_op(method_used,OP_EQ,"INTERFACE"); tt_ptr_op(hostname_out, OP_EQ, NULL); tt_want(retval == true); - tt_int_op(tor_addr_eq(&resolved_addr, &test_addr), OP_EQ, 1); + tt_assert(tor_addr_eq(&resolved_addr, &test_addr)); /* * CASE 11b: From 5895aafe7ed86bded4c5a597113a616db7c0a44f Mon Sep 17 00:00:00 2001 From: David Goulet Date: Wed, 24 Jun 2020 08:27:24 -0400 Subject: [PATCH 11/14] addr: Safeguard last resolved address index access The last resolved address cache uses an index that is mapped to an address family (AF_INET and AF_INET6). This commit adds a conversion function from af to index and change the code to use that all the time only. In the process, this commit fixes a bug that the last resolved address accessors were using the af value insted of the index. Spotted by nickm during review Signed-off-by: David Goulet --- src/app/config/resolve_addr.c | 47 ++++++++++++++++++++++------------- 1 file changed, 30 insertions(+), 17 deletions(-) diff --git a/src/app/config/resolve_addr.c b/src/app/config/resolve_addr.c index 56548e6e70..de39f9df97 100644 --- a/src/app/config/resolve_addr.c +++ b/src/app/config/resolve_addr.c @@ -37,13 +37,30 @@ /** Ease our life. Arrays containing state per address family. These are to * add semantic to the code so we know what is accessed. */ -#define IDX_IPV4 0 /* Index to AF_INET. */ -#define IDX_IPV6 1 /* Index to AF_INET6. */ -#define IDX_SIZE 2 /* How many indexes do we have. */ +#define IDX_NULL 0 /* Index to zeroed address object. */ +#define IDX_IPV4 1 /* Index to AF_INET. */ +#define IDX_IPV6 2 /* Index to AF_INET6. */ +#define IDX_SIZE 3 /* How many indexes do we have. */ /** Last resolved addresses. */ static tor_addr_t last_resolved_addrs[IDX_SIZE]; +static inline int +af_to_idx(const int family) +{ + switch (family) { + case AF_INET: + return IDX_IPV4; + case AF_INET6: + return IDX_IPV6; + default: + /* It wouldn't be safe to just die here with an assert but we can heavily + * scream with a bug. Return the index of the NULL address. */ + tor_assert_nonfatal_unreached(); + return IDX_NULL; + } +} + /** Copy the last resolved address of family into addr_out. * * If not last resolved address existed, the addr_out is a null address (use @@ -51,7 +68,7 @@ static tor_addr_t last_resolved_addrs[IDX_SIZE]; void resolved_addr_get_last(int family, tor_addr_t *addr_out) { - tor_addr_copy(addr_out, &last_resolved_addrs[family]); + tor_addr_copy(addr_out, &last_resolved_addrs[af_to_idx(family)]); } /** Reset the last resolved address of family. @@ -60,7 +77,7 @@ resolved_addr_get_last(int family, tor_addr_t *addr_out) void resolved_addr_reset_last(int family) { - tor_addr_make_null(&last_resolved_addrs[family], family); + tor_addr_make_null(&last_resolved_addrs[af_to_idx(family)], family); } /** @brief Return true iff the given IP address can be used as a valid @@ -321,7 +338,7 @@ update_resolved_cache(const tor_addr_t *addr, const char *method_used, const char *hostname_used) { /** Have we done a first resolve. This is used to control logging. */ - static bool have_resolved_once[IDX_SIZE] = { false, false }; + static bool have_resolved_once[IDX_SIZE] = { false, false, false }; bool *done_one_resolve; bool have_hostname = false; tor_addr_t *last_resolved; @@ -333,20 +350,16 @@ update_resolved_cache(const tor_addr_t *addr, const char *method_used, /* Do we have an hostname. */ have_hostname = strlen(hostname_used) > 0; - switch (tor_addr_family(addr)) { - case AF_INET: - done_one_resolve = &have_resolved_once[IDX_IPV4]; - last_resolved = &last_resolved_addrs[IDX_IPV4]; - break; - case AF_INET6: - done_one_resolve = &have_resolved_once[IDX_IPV6]; - last_resolved = &last_resolved_addrs[IDX_IPV6]; - break; - default: - tor_assert_nonfatal_unreached(); + int idx = af_to_idx(tor_addr_family(addr)); + if (idx == IDX_NULL) { + /* Not suppose to happen and if it does, af_to_idx() screams loudly. */ return; } + /* Get values from cache. */ + done_one_resolve = &have_resolved_once[idx]; + last_resolved = &last_resolved_addrs[idx]; + /* Same address last resolved. Ignore. */ if (tor_addr_eq(last_resolved, addr)) { return; From 25a451bac748fd01498d3b851d4f1a5e556eaf32 Mon Sep 17 00:00:00 2001 From: David Goulet Date: Wed, 24 Jun 2020 08:53:52 -0400 Subject: [PATCH 12/14] addr: Set out parameters to NULL in resolve_addr.c By doing this, a memory leak was found with "hostname_used" that could have been overwritten by another function. This commit changes that by making it a NULL string instead. Found by nickm's review. Signed-off-by: David Goulet --- src/app/config/resolve_addr.c | 36 ++++++++++++++++++++--------------- 1 file changed, 21 insertions(+), 15 deletions(-) diff --git a/src/app/config/resolve_addr.c b/src/app/config/resolve_addr.c index de39f9df97..dada4dabf9 100644 --- a/src/app/config/resolve_addr.c +++ b/src/app/config/resolve_addr.c @@ -137,8 +137,6 @@ address_can_be_used(const tor_addr_t *addr, const or_options_t *options, * This can fail is more than two Address statement are found for the same * address family. It also fails if no statement is found. * - * On failure, no out parameters should be used or considered valid. - * * @param options Global configuration options. * @param warn_severity Log level that should be used on error. * @param family IP address family. Only AF_INET and AF_INET6 are supported. @@ -166,6 +164,10 @@ get_address_from_config(const or_options_t *options, int warn_severity, tor_assert(method_out); tor_assert(hostname_out); + /* Set them to NULL for safety reasons. */ + *hostname_out = NULL; + *method_out = NULL; + log_debug(LD_CONFIG, "Attempting to get address from configuration"); if (!options->Address) { @@ -226,8 +228,6 @@ get_address_from_config(const or_options_t *options, int warn_severity, /** @brief Get IP address from the local hostname by calling gethostbyname() * and doing a DNS resolution on the hostname. * - * On failure, no out parameters should be used or considered valid. - * * @param options Global configuration options. * @param warn_severity Log level that should be used on error. * @param family IP address family. Only AF_INET and AF_INET6 are supported. @@ -251,6 +251,10 @@ get_address_from_hostname(const or_options_t *options, int warn_severity, tor_assert(addr_out); tor_assert(method_out); + /* Set them to NULL for safety reasons. */ + *hostname_out = NULL; + *method_out = NULL; + log_debug(LD_CONFIG, "Attempting to get address from local hostname"); if (tor_gethostname(hostname, sizeof(hostname)) < 0) { @@ -276,8 +280,6 @@ get_address_from_hostname(const or_options_t *options, int warn_severity, } /** @brief Get IP address from a network interface. - * - * On failure, no out parameters should be used or considered valid. * * @param options Global configuration options. * @param warn_severity Log level that should be used on error. @@ -299,6 +301,9 @@ get_address_from_interface(const or_options_t *options, int warn_severity, tor_assert(method_out); tor_assert(addr_out); + /* Set them to NULL for safety reasons. */ + *method_out = NULL; + log_debug(LD_CONFIG, "Attempting to get address from network interface"); if (get_interface_address6(warn_severity, family, addr_out) < 0) { @@ -330,8 +335,8 @@ get_address_from_interface(const or_options_t *options, int warn_severity, * @param addr IP address to update the cache with. * @param method_used By which method did we resolved it (for logging and * control port). - * @param hostname_used Which hostname was used. If none were used, it is an - * empty string. (for logging and control port). + * @param hostname_used Which hostname was used. If none were used, it is + * NULL. (for logging and control port). */ static void update_resolved_cache(const tor_addr_t *addr, const char *method_used, @@ -345,10 +350,9 @@ update_resolved_cache(const tor_addr_t *addr, const char *method_used, tor_assert(addr); tor_assert(method_used); - tor_assert(hostname_used); /* Do we have an hostname. */ - have_hostname = strlen(hostname_used) > 0; + have_hostname = (hostname_used != NULL); int idx = af_to_idx(tor_addr_family(addr)); if (idx == IDX_NULL) { @@ -398,7 +402,7 @@ update_resolved_cache(const tor_addr_t *addr, const char *method_used, * On success, true is returned and depending on how the address was found, * the out parameters can have different values. * - * On error, false is returned and all out parameters are untouched. + * On error, false is returned and out parameters are set to NULL. * * 1. Look at the configuration Address option. @@ -463,12 +467,16 @@ find_my_address(const or_options_t *options, int family, int warn_severity, { int ret; const char *method_used; - char *hostname_used = tor_strdup(""); + char *hostname_used = NULL; tor_addr_t my_addr; tor_assert(options); tor_assert(addr_out); + /* Set them to NULL for safety reasons. */ + if (method_out) *method_out = NULL; + if (hostname_out) *hostname_out = NULL; + /* * Step 1: Discover address by attempting 3 different methods consecutively. */ @@ -528,10 +536,8 @@ find_my_address(const or_options_t *options, int family, int warn_severity, } if (hostname_out) { *hostname_out = NULL; - if (strlen(hostname_used) > 0) { + if (hostname_used) { *hostname_out = hostname_used; - } else { - tor_free(hostname_used); } } else { tor_free(hostname_used); From 59f5c3d26337ba82be2a7cb2af02ba77e02c1b87 Mon Sep 17 00:00:00 2001 From: David Goulet Date: Wed, 24 Jun 2020 10:35:27 -0400 Subject: [PATCH 13/14] addr: Refactor find_my_address() to simplify it Instead of a complex if/else block, use a table of functions that have the same interface and each of them attempt to find the address one after the other. Pointed out by nickm's during review. Signed-off-by: David Goulet --- src/app/config/resolve_addr.c | 177 +++++++++++++++++++--------------- 1 file changed, 99 insertions(+), 78 deletions(-) diff --git a/src/app/config/resolve_addr.c b/src/app/config/resolve_addr.c index dada4dabf9..cd19402f94 100644 --- a/src/app/config/resolve_addr.c +++ b/src/app/config/resolve_addr.c @@ -22,19 +22,6 @@ /** Maximum "Address" statement allowed in our configuration. */ #define MAX_CONFIG_ADDRESS 2 -/** Errors use when finding our IP address. Some are transient and some are - * persistent, just attach semantic to the values. They are all negative so - * one can do a catch all. */ - -#define ERR_FAIL_RESOLVE -1 /* Hostname resolution failed. */ -#define ERR_GET_HOSTNAME -2 /* Unable to get local hostname. */ -#define ERR_NO_OPT_ADDRESS -3 /* No Address in config. */ -#define ERR_TOO_MANY_ADDRESS -4 /* Too many Address for one family. */ -#define ERR_GET_INTERFACE -5 /* Unable to query network interface. */ -#define ERR_UNUSABLE_ADDRESS -6 /* Unusable address. It is internal. */ -#define ERR_DEFAULT_DIRAUTH -7 /* Using default authorities. */ -#define ERR_ADDRESS_IS_INTERNAL -8 /* IP is internal. */ - /** Ease our life. Arrays containing state per address family. These are to * add semantic to the code so we know what is accessed. */ #define IDX_NULL 0 /* Index to zeroed address object. */ @@ -42,6 +29,18 @@ #define IDX_IPV6 2 /* Index to AF_INET6. */ #define IDX_SIZE 3 /* How many indexes do we have. */ +/** Function in our address function table return one of these code. */ +typedef enum { + /* The address has been found. */ + FN_RET_OK = 0, + /* The failure requirements were not met and thus it is recommended that the + * caller stops the search. */ + FN_RET_BAIL = 1, + /* The address was not found or failure is transient so the caller should go + * to the next method. */ + FN_RET_NEXT = 2, +} fn_address_ret_t; + /** Last resolved addresses. */ static tor_addr_t last_resolved_addrs[IDX_SIZE]; @@ -80,6 +79,11 @@ resolved_addr_reset_last(int family) tor_addr_make_null(&last_resolved_addrs[af_to_idx(family)], family); } +/** Errors returned by address_can_be_used() in order for the caller to know + * why the address is denied or not. */ +#define ERR_DEFAULT_DIRAUTH -1 /* Using default authorities. */ +#define ERR_ADDRESS_IS_INTERNAL -2 /* IP is internal. */ + /** @brief Return true iff the given IP address can be used as a valid * external resolved address. * @@ -151,11 +155,12 @@ address_can_be_used(const tor_addr_t *addr, const or_options_t *options, * @return Return 0 on success that is an address has been found or resolved * successfully. Return error code ERR_* found at the top of the file. */ -static int +static fn_address_ret_t get_address_from_config(const or_options_t *options, int warn_severity, int family, const char **method_out, char **hostname_out, tor_addr_t *addr_out) { + int ret; bool explicit_ip = false; int num_valid_addr = 0; @@ -172,7 +177,8 @@ get_address_from_config(const or_options_t *options, int warn_severity, if (!options->Address) { log_info(LD_CONFIG, "No Address option found in configuration."); - return ERR_NO_OPT_ADDRESS; + /* No Address statement, inform caller to try next method. */ + return FN_RET_NEXT; } for (const config_line_t *cfg = options->Address; cfg != NULL; @@ -199,11 +205,10 @@ get_address_from_config(const or_options_t *options, int warn_severity, num_valid_addr++; continue; } else { - /* If we have hostname we are unable to resolve, it is an persistent - * error and thus we stop right away. */ + /* Hostname that can't be resolved, this is a fatal error. */ log_fn(warn_severity, LD_CONFIG, "Could not resolve local Address '%s'. Failing.", cfg->value); - return ERR_FAIL_RESOLVE; + return FN_RET_BAIL; } } @@ -211,18 +216,32 @@ get_address_from_config(const or_options_t *options, int warn_severity, log_fn(warn_severity, LD_CONFIG, "No Address option found for family %s in configuration.", fmt_af_family(family)); - return ERR_NO_OPT_ADDRESS; + /* No Address statement for family, inform caller to try next method. */ + return FN_RET_NEXT; } if (num_valid_addr >= MAX_CONFIG_ADDRESS) { + /* Too many Address for same family. This is a fatal error. */ log_fn(warn_severity, LD_CONFIG, "Found %d Address statement of address family %s. " "Only one is allowed.", num_valid_addr, fmt_af_family(family)); - return ERR_TOO_MANY_ADDRESS; + return FN_RET_BAIL; } /* Great, we found an address. */ - return address_can_be_used(addr_out, options, warn_severity, explicit_ip); + ret = address_can_be_used(addr_out, options, warn_severity, explicit_ip); + if (ret != 0) { + /* One of the requirement of this interface is if an internal Address is + * used, custom authorities must be defined else it is a fatal error. + * Furthermore, if the Address was resolved to an internal interface, we + * stop immediately. */ + return FN_RET_BAIL; + } + + /* Address can be used. We are done. */ + log_fn(warn_severity, LD_CONFIG, "Address found in configuration: %s", + fmt_addr(addr_out)); + return FN_RET_OK; } /** @brief Get IP address from the local hostname by calling gethostbyname() @@ -240,7 +259,7 @@ get_address_from_config(const or_options_t *options, int warn_severity, * @return Return 0 on success that is an address has been found and resolved * successfully. Return error code ERR_* found at the top of the file. */ -static int +static fn_address_ret_t get_address_from_hostname(const or_options_t *options, int warn_severity, int family, const char **method_out, char **hostname_out, tor_addr_t *addr_out) @@ -259,24 +278,33 @@ get_address_from_hostname(const or_options_t *options, int warn_severity, if (tor_gethostname(hostname, sizeof(hostname)) < 0) { log_fn(warn_severity, LD_NET, "Error obtaining local hostname"); - return ERR_GET_HOSTNAME; + /* Unable to obtain the local hostname is a fatal error. */ + return FN_RET_BAIL; } if (tor_addr_lookup(hostname, family, addr_out)) { log_fn(warn_severity, LD_NET, "Could not resolve local hostname '%s'. Failing.", hostname); - return ERR_FAIL_RESOLVE; + /* Unable to resolve, inform caller to try next method. */ + return FN_RET_NEXT; } ret = address_can_be_used(addr_out, options, warn_severity, false); - if (ret < 0) { - return ret; + if (ret == ERR_DEFAULT_DIRAUTH) { + /* Non custom authorities, inform caller to try next method. */ + return FN_RET_NEXT; + } else if (ret == ERR_ADDRESS_IS_INTERNAL) { + /* Internal address is a fatal error. */ + return FN_RET_BAIL; } /* addr_out contains the address of the local hostname. */ *method_out = "GETHOSTNAME"; *hostname_out = tor_strdup(hostname); - return 0; + /* Found it! */ + log_fn(warn_severity, LD_CONFIG, "Address found from local hostname: %s", + fmt_addr(addr_out)); + return FN_RET_OK; } /** @brief Get IP address from a network interface. @@ -286,40 +314,49 @@ get_address_from_hostname(const or_options_t *options, int warn_severity, * @param family IP address family. Only AF_INET and AF_INET6 are supported. * @param method_out OUT: Always "INTERFACE" on success which is detailed in * the control-spec.txt as actions for "STATUS_SERVER". + * @param hostname_out OUT: String containing the local hostname. For this + * function, it is always set to NULL. * @param addr_out OUT: Tor address found attached to the interface. * * @return Return 0 on success that is an address has been found. Return * error code ERR_* found at the top of the file. */ -static int +static fn_address_ret_t get_address_from_interface(const or_options_t *options, int warn_severity, int family, const char **method_out, - tor_addr_t *addr_out) + char **hostname_out, tor_addr_t *addr_out) { int ret; tor_assert(method_out); + tor_assert(hostname_out); tor_assert(addr_out); /* Set them to NULL for safety reasons. */ *method_out = NULL; + *hostname_out = NULL; log_debug(LD_CONFIG, "Attempting to get address from network interface"); if (get_interface_address6(warn_severity, family, addr_out) < 0) { log_fn(warn_severity, LD_CONFIG, "Could not get local interface IP address."); - return ERR_GET_INTERFACE; + /* Unable to get IP from interface. Inform caller to try next method. */ + return FN_RET_NEXT; } ret = address_can_be_used(addr_out, options, warn_severity, false); if (ret < 0) { - return ret; + /* Unable to use address. Inform caller to try next method. */ + return FN_RET_NEXT; } *method_out = "INTERFACE"; - return 0; + /* Found it! */ + log_fn(warn_severity, LD_CONFIG, "Address found from interface: %s", + fmt_addr(addr_out)); + return FN_RET_OK; } /** @brief Update the last resolved address cache using the given address. @@ -393,6 +430,21 @@ update_resolved_cache(const tor_addr_t *addr, const char *method_used, *done_one_resolve = true; } +/** Address discovery function table. The order matters as in the first one is + * executed first and so on. */ +static fn_address_ret_t + (*fn_address_table[])( + const or_options_t *options, int warn_severity, int family, + const char **method_out, char **hostname_out, tor_addr_t *addr_out) = +{ + /* These functions are in order for our find address algorithm. */ + get_address_from_config, + get_address_from_hostname, + get_address_from_interface, +}; +/** Length of address table as in how many functions. */ +static const size_t fn_address_table_len = ARRAY_LENGTH(fn_address_table); + /** @brief Attempt to find our IP address that can be used as our external * reachable address. * @@ -465,8 +517,7 @@ find_my_address(const or_options_t *options, int family, int warn_severity, tor_addr_t *addr_out, const char **method_out, char **hostname_out) { - int ret; - const char *method_used; + const char *method_used = NULL; char *hostname_used = NULL; tor_addr_t my_addr; @@ -481,51 +532,24 @@ find_my_address(const or_options_t *options, int family, int warn_severity, * Step 1: Discover address by attempting 3 different methods consecutively. */ - /* Attempt #1: Get address from configuration. */ - ret = get_address_from_config(options, warn_severity, family, &method_used, - &hostname_used, &my_addr); - if (ret == 0) { - log_fn(warn_severity, LD_CONFIG, "Address found in configuration: %s", - fmt_addr(&my_addr)); - } else { - /* Unable to resolve an Address statement is a failure. Also, using - * default dirauth error means that the configured address is internal - * which is only accepted if custom authorities are used. */ - if (ret == ERR_FAIL_RESOLVE || ret == ERR_DEFAULT_DIRAUTH) { + /* Go over the function table. They are in order. */ + for (size_t idx = 0; idx < fn_address_table_len; idx++) { + fn_address_ret_t ret = fn_address_table[idx](options, warn_severity, + family, &method_used, + &hostname_used, &my_addr); + if (ret == FN_RET_BAIL) { return false; + } else if (ret == FN_RET_OK) { + goto found; } - - /* Attempt #2: Get local hostname and resolve it. */ - ret = get_address_from_hostname(options, warn_severity, family, - &method_used, &hostname_used, &my_addr); - if (ret == 0) { - log_fn(warn_severity, LD_CONFIG, "Address found from local hostname: " - "%s", fmt_addr(&my_addr)); - } else if (ret < 0) { - /* Unable to get the hostname results in a failure. If the address is - * internal, we stop right away. */ - if (ret == ERR_GET_HOSTNAME || ret == ERR_ADDRESS_IS_INTERNAL) { - return false; - } - - /* Attempt #3: Get address from interface. */ - ret = get_address_from_interface(options, warn_severity, family, - &method_used, &my_addr); - if (ret == 0) { - log_fn(warn_severity, LD_CONFIG, "Address found from interface: %s", - fmt_addr(&my_addr)); - } else { - /* We've exhausted our attempts. Failure. */ - log_fn(warn_severity, LD_CONFIG, "Unable to find our IP address."); - return false; - } - } + tor_assert(ret == FN_RET_NEXT); } - tor_assert(method_used); - /* From here, my_addr is a valid IP address of "family" and can be used as - * our external IP address. */ + /* We've exhausted our attempts. Failure. */ + log_fn(warn_severity, LD_CONFIG, "Unable to find our IP address."); + return false; + found: /* * Step 2: Update last resolved address cache and inform the control port. */ @@ -535,10 +559,7 @@ find_my_address(const or_options_t *options, int family, int warn_severity, *method_out = method_used; } if (hostname_out) { - *hostname_out = NULL; - if (hostname_used) { - *hostname_out = hostname_used; - } + *hostname_out = hostname_used; } else { tor_free(hostname_used); } From 29a35d262c4b60535050748df78325c78060c535 Mon Sep 17 00:00:00 2001 From: David Goulet Date: Wed, 24 Jun 2020 10:42:00 -0400 Subject: [PATCH 14/14] addr: Rename resolved_addr_is_local() Better function name. Signed-off-by: David Goulet --- src/app/config/resolve_addr.c | 2 +- src/app/config/resolve_addr.h | 2 +- src/core/or/channeltls.c | 6 +++--- src/feature/dircache/dircache.c | 2 +- src/test/test_channeltls.c | 18 +++++++++--------- 5 files changed, 15 insertions(+), 15 deletions(-) diff --git a/src/app/config/resolve_addr.c b/src/app/config/resolve_addr.c index cd19402f94..15a94cb82e 100644 --- a/src/app/config/resolve_addr.c +++ b/src/app/config/resolve_addr.c @@ -572,7 +572,7 @@ find_my_address(const or_options_t *options, int family, int warn_severity, * on a private network. */ MOCK_IMPL(bool, -resolved_addr_is_local, (const tor_addr_t *addr)) +is_local_to_resolve_addr, (const tor_addr_t *addr)) { const int family = tor_addr_family(addr); const tor_addr_t *last_resolved_addr = &last_resolved_addrs[family]; diff --git a/src/app/config/resolve_addr.h b/src/app/config/resolve_addr.h index ff732561c6..54f55ba36c 100644 --- a/src/app/config/resolve_addr.h +++ b/src/app/config/resolve_addr.h @@ -18,7 +18,7 @@ bool find_my_address(const or_options_t *options, int family, void resolved_addr_get_last(int family, tor_addr_t *addr_out); void resolved_addr_reset_last(int family); -MOCK_DECL(bool, resolved_addr_is_local, (const tor_addr_t *addr)); +MOCK_DECL(bool, is_local_to_resolve_addr, (const tor_addr_t *addr)); #ifdef RESOLVE_ADDR_PRIVATE diff --git a/src/core/or/channeltls.c b/src/core/or/channeltls.c index 3e7f25ae48..f9937ce880 100644 --- a/src/core/or/channeltls.c +++ b/src/core/or/channeltls.c @@ -203,7 +203,7 @@ channel_tls_connect(const tor_addr_t *addr, uint16_t port, tlschan, (chan->global_identifier)); - if (resolved_addr_is_local(addr)) { + if (is_local_to_resolve_addr(addr)) { log_debug(LD_CHANNEL, "Marking new outgoing channel %"PRIu64 " at %p as local", (chan->global_identifier), chan); @@ -340,7 +340,7 @@ channel_tls_handle_incoming(or_connection_t *orconn) tlschan->conn = orconn; orconn->chan = tlschan; - if (resolved_addr_is_local(&(TO_CONN(orconn)->addr))) { + if (is_local_to_resolve_addr(&(TO_CONN(orconn)->addr))) { log_debug(LD_CHANNEL, "Marking new incoming channel %"PRIu64 " at %p as local", (chan->global_identifier), chan); @@ -1353,7 +1353,7 @@ channel_tls_update_marks(or_connection_t *conn) chan = TLS_CHAN_TO_BASE(conn->chan); - if (resolved_addr_is_local(&(TO_CONN(conn)->addr))) { + if (is_local_to_resolve_addr(&(TO_CONN(conn)->addr))) { if (!channel_is_local(chan)) { log_debug(LD_CHANNEL, "Marking channel %"PRIu64 " at %p as local", diff --git a/src/feature/dircache/dircache.c b/src/feature/dircache/dircache.c index 44dc462051..691c100974 100644 --- a/src/feature/dircache/dircache.c +++ b/src/feature/dircache/dircache.c @@ -142,7 +142,7 @@ write_http_response_header_impl(dir_connection_t *conn, ssize_t length, if (type) { buf_add_printf(buf, "Content-Type: %s\r\n", type); } - if (!resolved_addr_is_local(&conn->base_.addr)) { + if (!is_local_to_resolve_addr(&conn->base_.addr)) { /* Don't report the source address for a nearby/private connection. * Otherwise we tend to mis-report in cases where incoming ports are * being forwarded to a Tor server running behind the firewall. */ diff --git a/src/test/test_channeltls.c b/src/test/test_channeltls.c index 8018000331..f682c57acf 100644 --- a/src/test/test_channeltls.c +++ b/src/test/test_channeltls.c @@ -68,8 +68,8 @@ test_channeltls_create(void *arg) /* For this test we always want the address to be treated as non-local */ tlschan_local = false; - /* Install resolved_addr_is_local() mock */ - MOCK(resolved_addr_is_local, tlschan_resolved_addr_is_local_mock); + /* Install is_local_to_resolve_addr() mock */ + MOCK(is_local_to_resolve_addr, tlschan_resolved_addr_is_local_mock); /* Install mock for connection_or_connect() */ MOCK(connection_or_connect, tlschan_connection_or_connect_mock); @@ -92,7 +92,7 @@ test_channeltls_create(void *arg) } UNMOCK(connection_or_connect); - UNMOCK(resolved_addr_is_local); + UNMOCK(is_local_to_resolve_addr); return; } @@ -117,8 +117,8 @@ test_channeltls_num_bytes_queued(void *arg) /* For this test we always want the address to be treated as non-local */ tlschan_local = false; - /* Install resolved_addr_is_local() mock */ - MOCK(resolved_addr_is_local, tlschan_resolved_addr_is_local_mock); + /* Install is_local_to_resolve_addr() mock */ + MOCK(is_local_to_resolve_addr, tlschan_resolved_addr_is_local_mock); /* Install mock for connection_or_connect() */ MOCK(connection_or_connect, tlschan_connection_or_connect_mock); @@ -178,7 +178,7 @@ test_channeltls_num_bytes_queued(void *arg) } UNMOCK(connection_or_connect); - UNMOCK(resolved_addr_is_local); + UNMOCK(is_local_to_resolve_addr); return; } @@ -202,8 +202,8 @@ test_channeltls_overhead_estimate(void *arg) /* For this test we always want the address to be treated as non-local */ tlschan_local = false; - /* Install resolved_addr_is_local() mock */ - MOCK(resolved_addr_is_local, tlschan_resolved_addr_is_local_mock); + /* Install is_local_to_resolve_addr() mock */ + MOCK(is_local_to_resolve_addr, tlschan_resolved_addr_is_local_mock); /* Install mock for connection_or_connect() */ MOCK(connection_or_connect, tlschan_connection_or_connect_mock); @@ -252,7 +252,7 @@ test_channeltls_overhead_estimate(void *arg) } UNMOCK(connection_or_connect); - UNMOCK(resolved_addr_is_local); + UNMOCK(is_local_to_resolve_addr); return; }