[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]

[tor-commits] [tor/master] relay: Launch dummy circuit only when descriptor build fails



commit bc5f26ff7006f50acd23f9eb1a99449612b95198
Author: David Goulet <dgoulet@xxxxxxxxxxxxxx>
Date:   Fri Sep 18 13:07:11 2020 -0400

    relay: Launch dummy circuit only when descriptor build fails
    
    First, this commit moves the launch_dummy_circuit_as_needed() function into
    relay_find_addr.c and renames it to relay_addr_learn_from_dirauth(). This is
    an attempt to centralize anything relate with address discovery in the right
    module.
    
    Second, when building a descriptor and we fail to discover our address,
    immediately launch a dummy circuit to an authority in an attempt to learn our
    descriptor.
    
    It is still only done every 20 minutes even though the descriptor build is
    done every minute. We ought to avoid load on the authority and if we can't
    learn in the first place our address from them, chances are more things are
    wrong.
    
    Related to #40071
    
    Signed-off-by: David Goulet <dgoulet@xxxxxxxxxxxxxx>
---
 src/feature/nodelist/routerlist.c   | 65 -----------------------------------
 src/feature/relay/relay_find_addr.c | 68 +++++++++++++++++++++++++++++++++++++
 src/feature/relay/relay_find_addr.h |  2 ++
 src/feature/relay/router.c          |  4 ++-
 4 files changed, 73 insertions(+), 66 deletions(-)

diff --git a/src/feature/nodelist/routerlist.c b/src/feature/nodelist/routerlist.c
index c1b02b586d..a1a348edb9 100644
--- a/src/feature/nodelist/routerlist.c
+++ b/src/feature/nodelist/routerlist.c
@@ -140,8 +140,6 @@ static int signed_desc_digest_is_recognized(signed_descriptor_t *desc);
 static const char *signed_descriptor_get_body_impl(
                                               const signed_descriptor_t *desc,
                                               int with_annotations);
-static void launch_dummy_circuit_as_needed(time_t now,
-                                   const or_options_t *options);
 
 /****************************************************************************/
 
@@ -2309,7 +2307,6 @@ update_all_descriptor_downloads(time_t now)
     return;
   update_router_descriptor_downloads(now);
   update_microdesc_downloads(now);
-  launch_dummy_circuit_as_needed(now, get_options());
 }
 
 /** Clear all our timeouts for fetching v3 directory stuff, and then
@@ -2763,68 +2760,6 @@ update_consensus_router_descriptor_downloads(time_t now, int is_vote,
   smartlist_free(no_longer_old);
 }
 
-/** How often should we launch a circuit to an authority to be sure of getting
- * a guess for our IP? */
-#define DUMMY_DOWNLOAD_INTERVAL (20*60)
-
-/** As needed, launch a dummy router descriptor fetch to see if our
- * address has changed. */
-static void
-launch_dummy_circuit_as_needed(time_t now, const or_options_t *options)
-{
-  static time_t last_dummy_circuit = 0;
-  bool have_addr;
-  tor_addr_t addr_out;
-
-  /* This dummy circuit only matter for relays. */
-  if (!server_mode(options)) {
-    return;
-  }
-
-  /* Lookup the address cache to learn if we have a good usable address. We
-   * still force relays to have an IPv4 so that alone is enough to learn if we
-   * need a lookup. In case we don't have one, we might want to attempt a
-   * dummy circuit to learn our address as a suggestion from an authority. */
-  have_addr = relay_find_addr_to_publish(options, AF_INET,
-                                         RELAY_FIND_ADDR_CACHE_ONLY,
-                                         &addr_out);
-
-  /* If we're a relay or bridge for which we were unable to discover our
-   * public address, we rely on learning our address from a directory
-   * authority from the NETINFO cell. */
-  if (!have_addr && last_dummy_circuit + DUMMY_DOWNLOAD_INTERVAL < now) {
-    last_dummy_circuit = now;
-
-    const routerstatus_t *rs = router_pick_trusteddirserver(V3_DIRINFO, 0);
-    if (BUG(!rs)) {
-      /* We should really always have trusted directories configured at this
-       * stage. They are loaded early either from default list or the one
-       * given in the configuration file. */
-      return;
-    }
-    const node_t *node = node_get_by_id(rs->identity_digest);
-    if (BUG(!node)) {
-      /* If there is a routerstatus_t, there is a node_t thus this should
-       * never fail. */
-      return;
-    }
-    extend_info_t *ei = extend_info_from_node(node, 1);
-    if (BUG(!ei)) {
-      return;
-    }
-
-    log_debug(LD_GENERAL, "Attempting dummy testing circuit to an authority "
-                          "in order to learn our address.");
-
-    /* Launch a one-hop testing circuit to a trusted authority so we can learn
-     * our address through the NETINFO cell. */
-    circuit_launch_by_extend_info(CIRCUIT_PURPOSE_TESTING, ei,
-                                  CIRCLAUNCH_IS_INTERNAL |
-                                  CIRCLAUNCH_ONEHOP_TUNNEL);
-    extend_info_free(ei);
-  }
-}
-
 /** Launch downloads for router status as needed. */
 void
 update_router_descriptor_downloads(time_t now)
diff --git a/src/feature/relay/relay_find_addr.c b/src/feature/relay/relay_find_addr.c
index 43b958d563..9c2c8b281c 100644
--- a/src/feature/relay/relay_find_addr.c
+++ b/src/feature/relay/relay_find_addr.c
@@ -12,10 +12,16 @@
 #include "app/config/resolve_addr.h"
 
 #include "core/mainloop/mainloop.h"
+#include "core/or/circuitlist.h"
+#include "core/or/circuituse.h"
+#include "core/or/extendinfo.h"
 
 #include "feature/control/control_events.h"
 #include "feature/dircommon/dir_connection_st.h"
 #include "feature/nodelist/dirlist.h"
+#include "feature/nodelist/node_select.h"
+#include "feature/nodelist/nodelist.h"
+#include "feature/nodelist/routerstatus_st.h"
 #include "feature/relay/relay_find_addr.h"
 #include "feature/relay/router.h"
 #include "feature/relay/routermode.h"
@@ -151,3 +157,65 @@ relay_has_address_set(int family)
   return relay_find_addr_to_publish(get_options(), family,
                                     RELAY_FIND_ADDR_CACHE_ONLY, &addr);
 }
+
+/** How often should we launch a circuit to an authority to be sure of getting
+ * a guess for our IP? */
+#define DUMMY_DOWNLOAD_INTERVAL (20*60)
+
+void
+relay_addr_learn_from_dirauth(void)
+{
+  static time_t last_dummy_circuit = 0;
+  const or_options_t *options = get_options();
+  time_t now = time(NULL);
+  bool have_addr;
+  tor_addr_t addr_out;
+
+  /* This dummy circuit only matter for relays. */
+  if (BUG(!server_mode(options))) {
+    return;
+  }
+
+  /* Lookup the address cache to learn if we have a good usable address. We
+   * still force relays to have an IPv4 so that alone is enough to learn if we
+   * need a lookup. In case we don't have one, we might want to attempt a
+   * dummy circuit to learn our address as a suggestion from an authority. */
+  have_addr = relay_find_addr_to_publish(options, AF_INET,
+                                         RELAY_FIND_ADDR_CACHE_ONLY,
+                                         &addr_out);
+
+  /* If we're a relay or bridge for which we were unable to discover our
+   * public address, we rely on learning our address from a directory
+   * authority from the NETINFO cell. */
+  if (!have_addr && last_dummy_circuit + DUMMY_DOWNLOAD_INTERVAL < now) {
+    last_dummy_circuit = now;
+
+    const routerstatus_t *rs = router_pick_trusteddirserver(V3_DIRINFO, 0);
+    if (BUG(!rs)) {
+      /* We should really always have trusted directories configured at this
+       * stage. They are loaded early either from default list or the one
+       * given in the configuration file. */
+      return;
+    }
+    const node_t *node = node_get_by_id(rs->identity_digest);
+    if (BUG(!node)) {
+      /* If there is a routerstatus_t, there is a node_t thus this should
+       * never fail. */
+      return;
+    }
+    extend_info_t *ei = extend_info_from_node(node, 1);
+    if (BUG(!ei)) {
+      return;
+    }
+
+    log_debug(LD_GENERAL, "Attempting dummy testing circuit to an authority "
+                          "in order to learn our address.");
+
+    /* Launch a one-hop testing circuit to a trusted authority so we can learn
+     * our address through the NETINFO cell. */
+    circuit_launch_by_extend_info(CIRCUIT_PURPOSE_TESTING, ei,
+                                  CIRCLAUNCH_IS_INTERNAL |
+                                  CIRCLAUNCH_ONEHOP_TUNNEL);
+    extend_info_free(ei);
+  }
+}
diff --git a/src/feature/relay/relay_find_addr.h b/src/feature/relay/relay_find_addr.h
index 3d30946b05..34890cd34e 100644
--- a/src/feature/relay/relay_find_addr.h
+++ b/src/feature/relay/relay_find_addr.h
@@ -24,6 +24,8 @@ MOCK_DECL(bool, relay_find_addr_to_publish,
 
 bool relay_has_address_set(int family);
 
+void relay_addr_learn_from_dirauth(void);
+
 #ifdef RELAY_FIND_ADDR_PRIVATE
 
 #endif /* RELAY_FIND_ADDR_PRIVATE */
diff --git a/src/feature/relay/router.c b/src/feature/relay/router.c
index 259c38f162..3aa9561f4f 100644
--- a/src/feature/relay/router.c
+++ b/src/feature/relay/router.c
@@ -2071,7 +2071,9 @@ router_build_fresh_unsigned_routerinfo,(routerinfo_t **ri_out))
 
   /* Tor requires a relay to have an IPv4 so bail if we can't find it. */
   if (!have_v4) {
-    log_warn(LD_CONFIG, "Don't know my address while generating descriptor");
+    log_info(LD_CONFIG, "Don't know my address while generating descriptor. "
+                        "Launching circuit to authority to learn it.");
+    relay_addr_learn_from_dirauth();
     result = TOR_ROUTERINFO_ERROR_NO_EXT_ADDR;
     goto err;
   }



_______________________________________________
tor-commits mailing list
tor-commits@xxxxxxxxxxxxxxxxxxxx
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits