diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/feature/relay/relay_periodic.c | 35 | ||||
-rw-r--r-- | src/feature/relay/router.c | 30 | ||||
-rw-r--r-- | src/feature/relay/router.h | 2 | ||||
-rw-r--r-- | src/feature/relay/selftest.c | 9 |
4 files changed, 66 insertions, 10 deletions
diff --git a/src/feature/relay/relay_periodic.c b/src/feature/relay/relay_periodic.c index cc346bc3fc..adff2c6a23 100644 --- a/src/feature/relay/relay_periodic.c +++ b/src/feature/relay/relay_periodic.c @@ -12,6 +12,8 @@ #include "orconfig.h" #include "core/or/or.h" +#include "app/config/resolve_addr.h" + #include "core/mainloop/periodic.h" #include "core/mainloop/cpuworker.h" // XXXX use a pubsub event. #include "core/mainloop/mainloop.h" @@ -218,14 +220,31 @@ reachability_warnings_callback(time_t now, const or_options_t *options) tor_asprintf(&where6, "[%s]:%d", address6, me->ipv6_orport); const char *opt_and = (!v4_ok && !v6_ok) ? "and" : ""; - log_warn(LD_CONFIG, - "Your server has not managed to confirm reachability for " - "its ORPort(s) at %s%s%s. Relays do not publish descriptors " - "until their ORPort and DirPort are reachable. Please check " - "your firewalls, ports, address, /etc/hosts file, etc.", - where4?where4:"", - opt_and, - where6?where6:""); + /* IPv4 reachability test worked but not the IPv6. We will _not_ + * publish the descriptor if our IPv6 was configured. We will if it + * was auto discovered. */ + if (v4_ok && !v6_ok && !resolved_addr_is_configured(AF_INET6)) { + static ratelim_t rlim = RATELIM_INIT(3600); + log_fn_ratelim(&rlim, LOG_NOTICE, LD_CONFIG, + "Auto-discovered IPv6 address %s has not been found " + "reachable. However, IPv4 address is reachable. " + "Publishing server descriptor without IPv6 address.", + where6 ? where6 : ""); + /* Indicate we want to publish even if reachability test failed. */ + mark_my_descriptor_if_omit_ipv6_changes("IPv4 is reachable. " + "IPv6 is not but was " + "auto-discovered", true); + } else { + log_warn(LD_CONFIG, + "Your server has not managed to confirm reachability for " + "its ORPort(s) at %s%s%s. Relays do not publish " + "descriptors until their ORPort and DirPort are " + "reachable. Please check your firewalls, ports, address, " + "/etc/hosts file, etc.", + where4?where4:"", + opt_and, + where6?where6:""); + } tor_free(where4); tor_free(where6); if (!v4_ok) { diff --git a/src/feature/relay/router.c b/src/feature/relay/router.c index 01d8bdcc87..48f53a263d 100644 --- a/src/feature/relay/router.c +++ b/src/feature/relay/router.c @@ -2442,6 +2442,34 @@ router_new_consensus_params(const networkstatus_t *ns) publish_even_when_ipv6_orport_unreachable = ar || ar6; } +/** Indicate if the IPv6 address should be omitted from the descriptor when + * publishing it. This can happen if the IPv4 is reachable but the + * auto-discovered IPv6 is not. We still publish the descriptor. + * + * Only relays should look at this and only for their descriptor. + * + * XXX: The real harder fix is to never put in the routerinfo_t a non + * reachable address and instead use the last resolved address cache to do + * reachability test or anything that has to do with what address tor thinks + * it has. */ +static bool omit_ipv6_on_publish = false; + +/** Mark our descriptor out of data iff the IPv6 omit status flag is flipped + * it changes from its previous value. + * + * This is used when our IPv6 port is found reachable or not. */ +void +mark_my_descriptor_if_omit_ipv6_changes(const char *reason, bool omit_ipv6) +{ + bool previous = omit_ipv6_on_publish; + omit_ipv6_on_publish = omit_ipv6; + + /* Only mark it dirty if the IPv6 omit flag was flipped. */ + if (previous != omit_ipv6) { + mark_my_descriptor_dirty(reason); + } +} + /** If our router descriptor ever goes this long without being regenerated * because something changed, we force an immediate regenerate-and-upload. */ #define FORCE_REGENERATE_DESCRIPTOR_INTERVAL (18*60*60) @@ -2847,7 +2875,7 @@ router_dump_router_to_string(routerinfo_t *router, } } - if (router->ipv6_orport && + if (!omit_ipv6_on_publish && router->ipv6_orport && tor_addr_family(&router->ipv6_addr) == AF_INET6) { char addr[TOR_ADDR_BUF_LEN]; const char *a; diff --git a/src/feature/relay/router.h b/src/feature/relay/router.h index c4e9af039f..89b4a479a4 100644 --- a/src/feature/relay/router.h +++ b/src/feature/relay/router.h @@ -84,6 +84,8 @@ void router_new_consensus_params(const networkstatus_t *); void router_upload_dir_desc_to_dirservers(int force); void mark_my_descriptor_dirty_if_too_old(time_t now); void mark_my_descriptor_dirty(const char *reason); +void mark_my_descriptor_if_omit_ipv6_changes(const char *reason, + bool omit_ipv6); 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); diff --git a/src/feature/relay/selftest.c b/src/feature/relay/selftest.c index d24748b297..13264d4a24 100644 --- a/src/feature/relay/selftest.c +++ b/src/feature/relay/selftest.c @@ -398,6 +398,7 @@ router_orport_found_reachable(int family) { const routerinfo_t *me = router_get_my_routerinfo(); const or_options_t *options = get_options(); + const char *reachable_reason = "ORPort found reachable"; bool *can_reach_ptr; if (family == AF_INET) { can_reach_ptr = &can_reach_or_port_ipv4; @@ -422,7 +423,13 @@ router_orport_found_reachable(int family) ready_to_publish(options) ? " Publishing server descriptor." : ""); - mark_my_descriptor_dirty("ORPort found reachable"); + /* Make sure our descriptor is marked to publish the IPv6 if it is now + * reachable. This can change at runtime. */ + if (family == AF_INET6) { + mark_my_descriptor_if_omit_ipv6_changes(reachable_reason, false); + } else { + mark_my_descriptor_dirty(reachable_reason); + } /* This is a significant enough change to upload immediately, * at least in a test network */ if (options->TestingTorNetwork == 1) { |