[tor-commits] [tor/master] config: New file resolve_addr.{c|h}

nickm at torproject.org nickm at torproject.org
Thu May 7 12:31:37 UTC 2020


commit a25f16707296b0a25c09c09cc31387b9ef799fae
Author: David Goulet <dgoulet at torproject.org>
Date:   Tue May 5 13:42:52 2020 -0400

    config: New file resolve_addr.{c|h}
    
    Move a series of function from config.c into that new file which is related to
    address resolving.
    
    Part of #33789
    
    Signed-off-by: David Goulet <dgoulet at torproject.org>
---
 scripts/maint/practracker/exceptions.txt |   2 +-
 src/app/config/config.c                  | 289 -----------------------------
 src/app/config/config.h                  |   6 -
 src/app/config/include.am                |   2 +
 src/app/config/resolve_addr.c            | 308 +++++++++++++++++++++++++++++++
 src/app/config/resolve_addr.h            |  28 +++
 src/core/mainloop/connection.c           |   1 +
 src/core/or/channeltls.c                 |   1 +
 src/core/stA1RajU                        |   0
 src/core/stiysZND                        | Bin 0 -> 19083264 bytes
 src/feature/dirauth/dirauth_config.c     |   1 +
 src/feature/dirauth/dirvote.c            |   1 +
 src/feature/dircache/dircache.c          |   1 +
 src/feature/nodelist/dirlist.c           |   1 +
 src/feature/relay/relay_resolve_addr.c   |   1 +
 src/feature/relay/router.c               |   1 +
 src/test/test_channeltls.c               |   1 +
 src/test/test_config.c                   |   1 +
 18 files changed, 349 insertions(+), 296 deletions(-)

diff --git a/scripts/maint/practracker/exceptions.txt b/scripts/maint/practracker/exceptions.txt
index 8f718deff..fc9a05c84 100644
--- a/scripts/maint/practracker/exceptions.txt
+++ b/scripts/maint/practracker/exceptions.txt
@@ -36,7 +36,6 @@
 problem file-size /src/app/config/config.c 7525
 problem include-count /src/app/config/config.c 80
 problem function-size /src/app/config/config.c:options_act() 381
-problem function-size /src/app/config/config.c:resolve_my_address() 191
 problem function-size /src/app/config/config.c:options_validate_cb() 794
 problem function-size /src/app/config/config.c:options_init_from_torrc() 192
 problem function-size /src/app/config/config.c:options_init_from_string() 103
@@ -47,6 +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 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/config.c b/src/app/config/config.c
index 0ae650eb0..7ed373c54 100644
--- a/src/app/config/config.c
+++ b/src/app/config/config.c
@@ -2722,23 +2722,6 @@ list_enabled_modules(void)
   // test variants in test_parseconf.sh to no useful purpose.
 }
 
-/** Last value actually set by resolve_my_address. */
-static uint32_t last_resolved_addr = 0;
-
-/** Accessor for last_resolved_addr from outside this file. */
-uint32_t
-get_last_resolved_addr(void)
-{
-  return last_resolved_addr;
-}
-
-/** Reset last_resolved_addr from outside this file. */
-void
-reset_last_resolved_addr(void)
-{
-  last_resolved_addr = 0;
-}
-
 /* Return true if <b>options</b> is using the default authorities, and false
  * if any authority-related option has been overridden. */
 int
@@ -2747,278 +2730,6 @@ using_default_dir_authorities(const or_options_t *options)
   return (!options->DirAuthorities && !options->AlternateDirAuthority);
 }
 
-/**
- * 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 <b>options-\>Address</b> to get our
- * non-local IP address.
- *
- * If <b>options-\>Address</b> represents a non-local IP address,
- * consider it ours.
- *
- * If <b>options-\>Address</b> is a DNS name that resolves to
- * a non-local IP address, consider this IP address ours.
- *
- * If <b>options-\>Address</b> 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 <b>options-\>Address</b> cannot be resolved.
- *   - <b>options-\>Address</b> 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 *<b>addr_out</b>.
- *   - If <b>method_out</b> is non-NULL, set *<b>method_out</b> to a static
- *     string describing how we arrived at our answer.
- *      - "CONFIGURED" - parsed from IP address string in
- *        <b>options-\>Address</b>
- *      - "RESOLVED" - resolved from DNS name in <b>options-\>Address</b>
- *      - "GETHOSTNAME" - resolved from a local hostname.
- *      - "INTERFACE" - retrieved from a network interface.
- *   - If <b>hostname_out</b> is non-NULL, and we resolved a hostname to
- *     get our address, set *<b>hostname_out</b> to a newly allocated string
- *     holding that hostname. (If we didn't get our address by resolving a
- *     hostname, set *<b>hostname_out</b> to NULL.)
- *
- * 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)
-{
-  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;
-  const char *address = options->Address;
-  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 (address && *address) {
-    strlcpy(hostname, address, sizeof(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);
-  }
-
-  /*
-   * 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 */
-    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, "<guessed from interfaces>", 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, "<guessed from interfaces>", sizeof(hostname));
-        }
-      }
-    }
-  } else {
-    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 (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 && last_resolved_addr != *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 != *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;
-
-  /*
-   * And finally, clean up and return success.
-   */
-
-  tor_free(addr_string);
-  return 0;
-}
-
-/** Return true iff <b>addr</b> 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))
-{
-  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);
-
-    /* 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.
-     */
-    if ((last_resolved_addr & (uint32_t)0xffffff00ul)
-        == (ip & (uint32_t)0xffffff00ul))
-      return 1;
-  }
-  return 0;
-}
-
 /** Return a new empty or_options_t.  Used for testing. */
 or_options_t *
 options_new(void)
diff --git a/src/app/config/config.h b/src/app/config/config.h
index 460b5ef0e..17caa0e3f 100644
--- a/src/app/config/config.h
+++ b/src/app/config/config.h
@@ -55,12 +55,6 @@ typedef enum setopt_err_t {
 setopt_err_t options_trial_assign(struct config_line_t *list, unsigned flags,
                                   char **msg);
 
-uint32_t get_last_resolved_addr(void);
-void reset_last_resolved_addr(void);
-int resolve_my_address(int warn_severity, const or_options_t *options,
-                       uint32_t *addr_out,
-                       const char **method_out, char **hostname_out);
-MOCK_DECL(int, is_local_addr, (const tor_addr_t *addr));
 void options_init(or_options_t *options);
 
 #define OPTIONS_DUMP_MINIMAL 1
diff --git a/src/app/config/include.am b/src/app/config/include.am
index 5d625efec..14320a6b1 100644
--- a/src/app/config/include.am
+++ b/src/app/config/include.am
@@ -3,6 +3,7 @@
 LIBTOR_APP_A_SOURCES += 			\
 	src/app/config/config.c			\
 	src/app/config/quiet_level.c		\
+	src/app/config/resolve_addr.c		\
 	src/app/config/statefile.c
 
 # ADD_C_FILE: INSERT HEADERS HERE.
@@ -11,6 +12,7 @@ noinst_HEADERS +=					\
 	src/app/config/or_options_st.h			\
 	src/app/config/or_state_st.h			\
 	src/app/config/quiet_level.h			\
+	src/app/config/resolve_addr.h			\
 	src/app/config/statefile.h			\
 	src/app/config/tor_cmdline_mode.h
 
diff --git a/src/app/config/resolve_addr.c b/src/app/config/resolve_addr.c
new file mode 100644
index 000000000..b551615c0
--- /dev/null
+++ b/src/app/config/resolve_addr.c
@@ -0,0 +1,308 @@
+/* Copyright (c) 2020, The Tor Project, Inc. */
+/* See LICENSE for licensing information */
+
+/**
+ * \file resolve_addr.c
+ * \brief Implement resolving address functions
+ **/
+
+#define RESOLVE_ADDR_PRIVATE
+
+#include "app/config/config.h"
+#include "app/config/resolve_addr.h"
+
+#include "core/mainloop/mainloop.h"
+
+#include "feature/control/control_events.h"
+
+#include "lib/net/gethostname.h"
+#include "lib/net/resolve.h"
+
+/** Last value actually set by resolve_my_address. */
+static uint32_t last_resolved_addr = 0;
+
+/** Accessor for last_resolved_addr from outside this file. */
+uint32_t
+get_last_resolved_addr(void)
+{
+  return last_resolved_addr;
+}
+
+/** Reset last_resolved_addr from outside this file. */
+void
+reset_last_resolved_addr(void)
+{
+  last_resolved_addr = 0;
+}
+
+/**
+ * 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 <b>options-\>Address</b> to get our
+ * non-local IP address.
+ *
+ * If <b>options-\>Address</b> represents a non-local IP address,
+ * consider it ours.
+ *
+ * If <b>options-\>Address</b> is a DNS name that resolves to
+ * a non-local IP address, consider this IP address ours.
+ *
+ * If <b>options-\>Address</b> 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 <b>options-\>Address</b> cannot be resolved.
+ *   - <b>options-\>Address</b> 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 *<b>addr_out</b>.
+ *   - If <b>method_out</b> is non-NULL, set *<b>method_out</b> to a static
+ *     string describing how we arrived at our answer.
+ *      - "CONFIGURED" - parsed from IP address string in
+ *        <b>options-\>Address</b>
+ *      - "RESOLVED" - resolved from DNS name in <b>options-\>Address</b>
+ *      - "GETHOSTNAME" - resolved from a local hostname.
+ *      - "INTERFACE" - retrieved from a network interface.
+ *   - If <b>hostname_out</b> is non-NULL, and we resolved a hostname to
+ *     get our address, set *<b>hostname_out</b> to a newly allocated string
+ *     holding that hostname. (If we didn't get our address by resolving a
+ *     hostname, set *<b>hostname_out</b> to NULL.)
+ *
+ * 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)
+{
+  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;
+  const char *address = options->Address;
+  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 (address && *address) {
+    strlcpy(hostname, address, sizeof(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);
+  }
+
+  /*
+   * 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 */
+    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, "<guessed from interfaces>", 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, "<guessed from interfaces>", sizeof(hostname));
+        }
+      }
+    }
+  } else {
+    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 (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 && last_resolved_addr != *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 != *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;
+
+  /*
+   * And finally, clean up and return success.
+   */
+
+  tor_free(addr_string);
+  return 0;
+}
+
+/** Return true iff <b>addr</b> 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))
+{
+  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);
+
+    /* 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.
+     */
+    if ((last_resolved_addr & (uint32_t)0xffffff00ul)
+        == (ip & (uint32_t)0xffffff00ul))
+      return 1;
+  }
+  return 0;
+}
diff --git a/src/app/config/resolve_addr.h b/src/app/config/resolve_addr.h
new file mode 100644
index 000000000..374754640
--- /dev/null
+++ b/src/app/config/resolve_addr.h
@@ -0,0 +1,28 @@
+/* Copyright (c) 2020, The Tor Project, Inc. */
+/* See LICENSE for licensing information */
+
+/**
+ * \file resolve_addr.h
+ * \brief Header file for resolve_addr.c.
+ **/
+
+#ifndef TOR_CONFIG_RESOLVE_ADDR_H
+#define TOR_CONFIG_RESOLVE_ADDR_H
+
+#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);
+
+uint32_t get_last_resolved_addr(void);
+void reset_last_resolved_addr(void);
+
+MOCK_DECL(int, is_local_addr, (const tor_addr_t *addr));
+
+#ifdef RESOLVE_ADDR_PRIVATE
+
+#endif /* RESOLVE_ADDR_PRIVATE */
+
+#endif /* TOR_CONFIG_RESOLVE_ADDR_H */
+
diff --git a/src/core/mainloop/connection.c b/src/core/mainloop/connection.c
index db59e6b28..a8417e46d 100644
--- a/src/core/mainloop/connection.c
+++ b/src/core/mainloop/connection.c
@@ -67,6 +67,7 @@
  */
 #define CHANNEL_OBJECT_PRIVATE
 #include "app/config/config.h"
+#include "app/config/resolve_addr.h"
 #include "core/mainloop/connection.h"
 #include "core/mainloop/mainloop.h"
 #include "core/mainloop/netstatus.h"
diff --git a/src/core/or/channeltls.c b/src/core/or/channeltls.c
index 484727268..59cec5ead 100644
--- a/src/core/or/channeltls.c
+++ b/src/core/or/channeltls.c
@@ -45,6 +45,7 @@
 #include "core/or/circuitmux_ewma.h"
 #include "core/or/command.h"
 #include "app/config/config.h"
+#include "app/config/resolve_addr.h"
 #include "core/mainloop/connection.h"
 #include "core/or/connection_or.h"
 #include "feature/relay/relay_handshake.h"
diff --git a/src/core/stA1RajU b/src/core/stA1RajU
new file mode 100644
index 000000000..e69de29bb
diff --git a/src/core/stiysZND b/src/core/stiysZND
new file mode 100644
index 000000000..faa365b76
Binary files /dev/null and b/src/core/stiysZND differ
diff --git a/src/feature/dirauth/dirauth_config.c b/src/feature/dirauth/dirauth_config.c
index 38d2a8bc5..a0b6de7ec 100644
--- a/src/feature/dirauth/dirauth_config.c
+++ b/src/feature/dirauth/dirauth_config.c
@@ -20,6 +20,7 @@
 /* Required for dirinfo_type_t in or_options_t */
 #include "core/or/or.h"
 #include "app/config/config.h"
+#include "app/config/resolve_addr.h"
 
 #include "feature/dirauth/voting_schedule.h"
 #include "feature/stats/rephist.h"
diff --git a/src/feature/dirauth/dirvote.c b/src/feature/dirauth/dirvote.c
index 7eb2b720a..6bf30d083 100644
--- a/src/feature/dirauth/dirvote.c
+++ b/src/feature/dirauth/dirvote.c
@@ -6,6 +6,7 @@
 #define DIRVOTE_PRIVATE
 #include "core/or/or.h"
 #include "app/config/config.h"
+#include "app/config/resolve_addr.h"
 #include "core/or/policies.h"
 #include "core/or/protover.h"
 #include "core/or/tor_version_st.h"
diff --git a/src/feature/dircache/dircache.c b/src/feature/dircache/dircache.c
index 4f7f20920..ca127720f 100644
--- a/src/feature/dircache/dircache.c
+++ b/src/feature/dircache/dircache.c
@@ -13,6 +13,7 @@
 #include "core/or/or.h"
 
 #include "app/config/config.h"
+#include "app/config/resolve_addr.h"
 #include "core/mainloop/connection.h"
 #include "core/or/relay.h"
 #include "feature/dirauth/dirvote.h"
diff --git a/src/feature/nodelist/dirlist.c b/src/feature/nodelist/dirlist.c
index ad3af0a14..d7069bb0e 100644
--- a/src/feature/nodelist/dirlist.c
+++ b/src/feature/nodelist/dirlist.c
@@ -27,6 +27,7 @@
 #include "core/or/or.h"
 
 #include "app/config/config.h"
+#include "app/config/resolve_addr.h"
 #include "core/or/policies.h"
 #include "feature/control/control_events.h"
 #include "feature/dirauth/authmode.h"
diff --git a/src/feature/relay/relay_resolve_addr.c b/src/feature/relay/relay_resolve_addr.c
index 7d83d870c..c929219d4 100644
--- a/src/feature/relay/relay_resolve_addr.c
+++ b/src/feature/relay/relay_resolve_addr.c
@@ -9,6 +9,7 @@
 #include "core/or/or.h"
 
 #include "app/config/config.h"
+#include "app/config/resolve_addr.h"
 
 #include "core/mainloop/mainloop.h"
 
diff --git a/src/feature/relay/router.c b/src/feature/relay/router.c
index cbb49ede1..e20e7709e 100644
--- a/src/feature/relay/router.c
+++ b/src/feature/relay/router.c
@@ -8,6 +8,7 @@
 
 #include "core/or/or.h"
 #include "app/config/config.h"
+#include "app/config/resolve_addr.h"
 #include "app/config/statefile.h"
 #include "app/main/main.h"
 #include "core/mainloop/connection.h"
diff --git a/src/test/test_channeltls.c b/src/test/test_channeltls.c
index 94ce56f2b..f4f5cb447 100644
--- a/src/test/test_channeltls.c
+++ b/src/test/test_channeltls.c
@@ -14,6 +14,7 @@
 #include "core/mainloop/connection.h"
 #include "core/or/connection_or.h"
 #include "app/config/config.h"
+#include "app/config/resolve_addr.h"
 /* For init/free stuff */
 #include "core/or/scheduler.h"
 #include "lib/tls/tortls.h"
diff --git a/src/test/test_config.c b/src/test/test_config.c
index 2a29d026b..5e57aab52 100644
--- a/src/test/test_config.c
+++ b/src/test/test_config.c
@@ -18,6 +18,7 @@
 #include "core/or/circuitmux_ewma.h"
 #include "core/or/circuitbuild.h"
 #include "app/config/config.h"
+#include "app/config/resolve_addr.h"
 #include "feature/relay/relay_config.h"
 #include "feature/relay/transport_config.h"
 #include "lib/confmgt/confmgt.h"





More information about the tor-commits mailing list