diff options
-rw-r--r-- | src/feature/client/transports.c | 1 | ||||
-rw-r--r-- | src/feature/control/control_getinfo.c | 1 | ||||
-rw-r--r-- | src/feature/dirclient/dirclient.c | 1 | ||||
-rw-r--r-- | src/feature/dirclient/dirclient_modes.c | 1 | ||||
-rw-r--r-- | src/feature/relay/include.am | 2 | ||||
-rw-r--r-- | src/feature/relay/relay_resolve_addr.c | 132 | ||||
-rw-r--r-- | src/feature/relay/relay_resolve_addr.h | 23 | ||||
-rw-r--r-- | src/feature/relay/router.c | 118 | ||||
-rw-r--r-- | src/feature/relay/router.h | 8 | ||||
-rw-r--r-- | src/test/test_config.c | 1 |
10 files changed, 167 insertions, 121 deletions
diff --git a/src/feature/client/transports.c b/src/feature/client/transports.c index 55069bb60a..b2a39c6787 100644 --- a/src/feature/client/transports.c +++ b/src/feature/client/transports.c @@ -97,6 +97,7 @@ #include "core/or/circuitbuild.h" #include "feature/client/transports.h" #include "feature/relay/router.h" +#include "feature/relay/relay_resolve_addr.h" /* 31851: split the server transport code out of the client module */ #include "feature/relay/transport_config.h" #include "app/config/statefile.h" diff --git a/src/feature/control/control_getinfo.c b/src/feature/control/control_getinfo.c index 5dcc4b170d..673920c9b7 100644 --- a/src/feature/control/control_getinfo.c +++ b/src/feature/control/control_getinfo.c @@ -44,6 +44,7 @@ #include "feature/nodelist/nodelist.h" #include "feature/nodelist/routerinfo.h" #include "feature/nodelist/routerlist.h" +#include "feature/relay/relay_resolve_addr.h" #include "feature/relay/router.h" #include "feature/relay/routermode.h" #include "feature/relay/selftest.h" diff --git a/src/feature/dirclient/dirclient.c b/src/feature/dirclient/dirclient.c index 2072dddadd..c80a6606a7 100644 --- a/src/feature/dirclient/dirclient.c +++ b/src/feature/dirclient/dirclient.c @@ -44,6 +44,7 @@ #include "feature/nodelist/routerinfo.h" #include "feature/nodelist/routerlist.h" #include "feature/nodelist/routerset.h" +#include "feature/relay/relay_resolve_addr.h" #include "feature/relay/routermode.h" #include "feature/relay/selftest.h" #include "feature/rend/rendcache.h" diff --git a/src/feature/dirclient/dirclient_modes.c b/src/feature/dirclient/dirclient_modes.c index 23fd1a2f6e..b385a6e86c 100644 --- a/src/feature/dirclient/dirclient_modes.c +++ b/src/feature/dirclient/dirclient_modes.c @@ -16,6 +16,7 @@ #include "feature/dirclient/dirclient_modes.h" #include "feature/dircache/dirserv.h" +#include "feature/relay/relay_resolve_addr.h" #include "feature/relay/router.h" #include "feature/relay/routermode.h" #include "feature/stats/predict_ports.h" diff --git a/src/feature/relay/include.am b/src/feature/relay/include.am index 654432c34b..2aa2985607 100644 --- a/src/feature/relay/include.am +++ b/src/feature/relay/include.am @@ -2,6 +2,7 @@ # Legacy shared relay code: migrate to the relay module over time LIBTOR_APP_A_SOURCES += \ src/feature/relay/onion_queue.c \ + src/feature/relay/relay_resolve_addr.c \ src/feature/relay/router.c # The Relay module. @@ -31,6 +32,7 @@ noinst_HEADERS += \ src/feature/relay/relay_handshake.h \ src/feature/relay/relay_periodic.h \ src/feature/relay/relay_sys.h \ + src/feature/relay/relay_resolve_addr.h \ src/feature/relay/router.h \ src/feature/relay/routerkeys.h \ src/feature/relay/routermode.h \ diff --git a/src/feature/relay/relay_resolve_addr.c b/src/feature/relay/relay_resolve_addr.c new file mode 100644 index 0000000000..7d83d870c7 --- /dev/null +++ b/src/feature/relay/relay_resolve_addr.c @@ -0,0 +1,132 @@ +/* Copyright (c) 2001-2020, The Tor Project, Inc. */ +/* See LICENSE for licensing information */ + +/** + * \file relay_resolve_addr.c + * \brief Implement relay resolving address mechanism. + **/ + +#include "core/or/or.h" + +#include "app/config/config.h" + +#include "core/mainloop/mainloop.h" + +#include "feature/control/control_events.h" +#include "feature/dircommon/dir_connection_st.h" +#include "feature/relay/relay_resolve_addr.h" +#include "feature/relay/router.h" +#include "feature/relay/routermode.h" + +/** The most recently guessed value of our IP address, based on directory + * headers. */ +static tor_addr_t last_guessed_ip = TOR_ADDR_NULL; + +/** We failed to resolve our address locally, but we'd like to build + * a descriptor and publish / test reachability. If we have a guess + * about our address based on directory headers, answer it and return + * 0; else return -1. */ +static int +router_guess_address_from_dir_headers(uint32_t *guess) +{ + if (!tor_addr_is_null(&last_guessed_ip)) { + *guess = tor_addr_to_ipv4h(&last_guessed_ip); + return 0; + } + return -1; +} + +/** A directory server <b>d_conn</b> told us our IP address is + * <b>suggestion</b>. + * If this address is different from the one we think we are now, and + * if our computer doesn't actually know its IP address, then switch. */ +void +router_new_address_suggestion(const char *suggestion, + const dir_connection_t *d_conn) +{ + tor_addr_t addr; + uint32_t cur = 0; /* Current IPv4 address. */ + const or_options_t *options = get_options(); + + /* first, learn what the IP address actually is */ + if (tor_addr_parse(&addr, suggestion) == -1) { + log_debug(LD_DIR, "Malformed X-Your-Address-Is header %s. Ignoring.", + escaped(suggestion)); + return; + } + + log_debug(LD_DIR, "Got X-Your-Address-Is: %s.", suggestion); + + if (!server_mode(options)) { + tor_addr_copy(&last_guessed_ip, &addr); + return; + } + + /* XXXX ipv6 */ + cur = get_last_resolved_addr(); + if (cur || + resolve_my_address(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; + } + if (tor_addr_is_internal(&addr, 0)) { + /* Don't believe anybody who says our IP is, say, 127.0.0.1. */ + return; + } + if (tor_addr_eq(&d_conn->base_.addr, &addr)) { + /* Don't believe anybody who says our IP is their IP. */ + log_debug(LD_DIR, "A directory server told us our IP address is %s, " + "but they are just reporting their own IP address. Ignoring.", + suggestion); + return; + } + + /* Okay. We can't resolve our own address, and X-Your-Address-Is is giving + * us an answer different from what we had the last time we managed to + * resolve it. */ + if (!tor_addr_eq(&last_guessed_ip, &addr)) { + control_event_server_status(LOG_NOTICE, + "EXTERNAL_ADDRESS ADDRESS=%s METHOD=DIRSERV", + suggestion); + log_addr_has_changed(LOG_NOTICE, &last_guessed_ip, &addr, + d_conn->base_.address); + ip_address_changed(0); + tor_addr_copy(&last_guessed_ip, &addr); /* router_rebuild_descriptor() + will fetch it */ + } +} + +/** Make a current best guess at our address, either because + * it's configured in torrc, or because we've learned it from + * dirserver headers. Place the answer in *<b>addr</b> and return + * 0 on success, else return -1 if we have no guess. + * + * If <b>cache_only</b> is true, just return any cached answers, and + * don't try to get any new answers. + */ +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(); + if (*addr) + return 0; + + /* Second, consider doing a resolve attempt right here. */ + if (!cache_only) { + if (resolve_my_address(LOG_INFO, options, addr, NULL, NULL) >= 0) { + log_info(LD_CONFIG,"Success: chose address '%s'.", fmt_addr32(*addr)); + return 0; + } + } + + /* Third, check the cached output from router_new_address_suggestion(). */ + if (router_guess_address_from_dir_headers(addr) >= 0) + return 0; + + /* We have no useful cached answers. Return failure. */ + return -1; +} diff --git a/src/feature/relay/relay_resolve_addr.h b/src/feature/relay/relay_resolve_addr.h new file mode 100644 index 0000000000..1ead2baf7a --- /dev/null +++ b/src/feature/relay/relay_resolve_addr.h @@ -0,0 +1,23 @@ +/* Copyright (c) 2020, The Tor Project, Inc. */ +/* See LICENSE for licensing information */ + +/** + * \file relay_resolve_addr.h + * \brief Header file for relay_resolve_addr.c. + **/ + +#ifndef TOR_RELAY_RESOLVE_ADDR_H +#define TOR_RELAY_RESOLVE_ADDR_H + +MOCK_DECL(int, router_pick_published_address, + (const or_options_t *options, uint32_t *addr, int cache_only)); + +void router_new_address_suggestion(const char *suggestion, + const dir_connection_t *d_conn); + +#ifdef RELAY_RESOLVE_ADDR_PRIVATE + +#endif /* RELAY_RESOLVE_ADDR_PRIVATE */ + +#endif /* TOR_RELAY_RESOLVE_ADDR_H */ + diff --git a/src/feature/relay/router.c b/src/feature/relay/router.c index 2858371af5..cbb49ede15 100644 --- a/src/feature/relay/router.c +++ b/src/feature/relay/router.c @@ -36,6 +36,7 @@ #include "feature/nodelist/torcert.h" #include "feature/relay/dns.h" #include "feature/relay/relay_config.h" +#include "feature/relay/relay_resolve_addr.h" #include "feature/relay/router.h" #include "feature/relay/routerkeys.h" #include "feature/relay/routermode.h" @@ -1763,41 +1764,6 @@ router_get_descriptor_gen_reason(void) return desc_gen_reason; } -static int router_guess_address_from_dir_headers(uint32_t *guess); - -/** Make a current best guess at our address, either because - * it's configured in torrc, or because we've learned it from - * dirserver headers. Place the answer in *<b>addr</b> and return - * 0 on success, else return -1 if we have no guess. - * - * If <b>cache_only</b> is true, just return any cached answers, and - * don't try to get any new answers. - */ -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(); - if (*addr) - return 0; - - /* Second, consider doing a resolve attempt right here. */ - if (!cache_only) { - if (resolve_my_address(LOG_INFO, options, addr, NULL, NULL) >= 0) { - log_info(LD_CONFIG,"Success: chose address '%s'.", fmt_addr32(*addr)); - return 0; - } - } - - /* Third, check the cached output from router_new_address_suggestion(). */ - if (router_guess_address_from_dir_headers(addr) >= 0) - return 0; - - /* We have no useful cached answers. Return failure. */ - return -1; -} - /* Like router_check_descriptor_address_consistency, but specifically for the * ORPort or DirPort. * listener_type is either CONN_TYPE_OR_LISTENER or CONN_TYPE_DIR_LISTENER. */ @@ -2523,7 +2489,7 @@ check_descriptor_bandwidth_changed(time_t now) /** Note at log level severity that our best guess of address has changed from * <b>prev</b> to <b>cur</b>. */ -static void +void log_addr_has_changed(int severity, const tor_addr_t *prev, const tor_addr_t *cur, @@ -2595,86 +2561,6 @@ check_descriptor_ipaddress_changed(time_t now) tor_free(hostname); } -/** The most recently guessed value of our IP address, based on directory - * headers. */ -static tor_addr_t last_guessed_ip = TOR_ADDR_NULL; - -/** A directory server <b>d_conn</b> told us our IP address is - * <b>suggestion</b>. - * If this address is different from the one we think we are now, and - * if our computer doesn't actually know its IP address, then switch. */ -void -router_new_address_suggestion(const char *suggestion, - const dir_connection_t *d_conn) -{ - tor_addr_t addr; - uint32_t cur = 0; /* Current IPv4 address. */ - const or_options_t *options = get_options(); - - /* first, learn what the IP address actually is */ - if (tor_addr_parse(&addr, suggestion) == -1) { - log_debug(LD_DIR, "Malformed X-Your-Address-Is header %s. Ignoring.", - escaped(suggestion)); - return; - } - - log_debug(LD_DIR, "Got X-Your-Address-Is: %s.", suggestion); - - if (!server_mode(options)) { - tor_addr_copy(&last_guessed_ip, &addr); - return; - } - - /* XXXX ipv6 */ - cur = get_last_resolved_addr(); - if (cur || - resolve_my_address(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; - } - if (tor_addr_is_internal(&addr, 0)) { - /* Don't believe anybody who says our IP is, say, 127.0.0.1. */ - return; - } - if (tor_addr_eq(&d_conn->base_.addr, &addr)) { - /* Don't believe anybody who says our IP is their IP. */ - log_debug(LD_DIR, "A directory server told us our IP address is %s, " - "but they are just reporting their own IP address. Ignoring.", - suggestion); - return; - } - - /* Okay. We can't resolve our own address, and X-Your-Address-Is is giving - * us an answer different from what we had the last time we managed to - * resolve it. */ - if (!tor_addr_eq(&last_guessed_ip, &addr)) { - control_event_server_status(LOG_NOTICE, - "EXTERNAL_ADDRESS ADDRESS=%s METHOD=DIRSERV", - suggestion); - log_addr_has_changed(LOG_NOTICE, &last_guessed_ip, &addr, - d_conn->base_.address); - ip_address_changed(0); - tor_addr_copy(&last_guessed_ip, &addr); /* router_rebuild_descriptor() - will fetch it */ - } -} - -/** We failed to resolve our address locally, but we'd like to build - * a descriptor and publish / test reachability. If we have a guess - * about our address based on directory headers, answer it and return - * 0; else return -1. */ -static int -router_guess_address_from_dir_headers(uint32_t *guess) -{ - if (!tor_addr_is_null(&last_guessed_ip)) { - *guess = tor_addr_to_ipv4h(&last_guessed_ip); - return 0; - } - return -1; -} - /** Set <b>platform</b> (max length <b>len</b>) to a NUL-terminated short * string describing the version of Tor and the operating system we're * currently running on. diff --git a/src/feature/relay/router.h b/src/feature/relay/router.h index 39c550dd25..50790a73dd 100644 --- a/src/feature/relay/router.h +++ b/src/feature/relay/router.h @@ -87,8 +87,6 @@ void mark_my_descriptor_dirty(const char *reason); void check_descriptor_bandwidth_changed(time_t now); void check_descriptor_ipaddress_changed(time_t now); int router_has_bandwidth_to_be_dirserver(const or_options_t *options); -void router_new_address_suggestion(const char *suggestion, - const dir_connection_t *d_conn); int router_compare_to_my_exit_policy(const tor_addr_t *addr, uint16_t port); MOCK_DECL(int, router_my_exit_policy_is_reject_star,(void)); MOCK_DECL(const routerinfo_t *, router_get_my_routerinfo, (void)); @@ -100,9 +98,6 @@ int router_digest_is_me(const char *digest); const uint8_t *router_get_my_id_digest(void); int router_extrainfo_digest_is_me(const char *digest); int router_is_me(const routerinfo_t *router); -MOCK_DECL(int,router_pick_published_address,(const or_options_t *options, - uint32_t *addr, - int cache_only)); int router_build_fresh_descriptor(routerinfo_t **r, extrainfo_t **e); int router_rebuild_descriptor(int force); char *router_dump_router_to_string(routerinfo_t *router, @@ -120,6 +115,9 @@ int extrainfo_dump_to_string(char **s, extrainfo_t *extrainfo, const char *routerinfo_err_to_string(int err); int routerinfo_err_is_transient(int err); +void log_addr_has_changed(int severity, const tor_addr_t *prev, + const tor_addr_t *cur, const char *source); + void router_reset_warnings(void); void router_free_all(void); diff --git a/src/test/test_config.c b/src/test/test_config.c index 9ccdbc72c0..2a29d026b4 100644 --- a/src/test/test_config.c +++ b/src/test/test_config.c @@ -42,6 +42,7 @@ #include "core/or/policies.h" #include "feature/rend/rendclient.h" #include "feature/rend/rendservice.h" +#include "feature/relay/relay_resolve_addr.h" #include "feature/relay/router.h" #include "feature/relay/routermode.h" #include "feature/nodelist/dirlist.h" |