[tor-commits] [tor/master] relay: Publish IPv4 descriptor on guessed IPv6 reachability failure

dgoulet at torproject.org dgoulet at torproject.org
Fri Jul 24 17:04:52 UTC 2020


commit ad9806b5390f099a51ca8c8d34eff91e432da3f4
Author: David Goulet <dgoulet at torproject.org>
Date:   Fri Jul 24 09:11:16 2020 -0400

    relay: Publish IPv4 descriptor on guessed IPv6 reachability failure
    
    On an IPv6 reachability failure test, if the address was configured, don't
    publish the descriptor and log warn. If the address was auto discovered, still
    publish the descriptor.
    
    Closes #33247.
    
    Signed-off-by: David Goulet <dgoulet at torproject.org>
---
 src/feature/relay/relay_periodic.c | 35 +++++++++++++++++++++++++++--------
 src/feature/relay/router.c         | 30 +++++++++++++++++++++++++++++-
 src/feature/relay/router.h         |  2 ++
 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) {



More information about the tor-commits mailing list