LCOV - code coverage report
Current view: top level - app/config - resolve_addr.c (source / functions) Hit Total Coverage
Test: lcov.info Lines: 220 241 91.3 %
Date: 2021-11-24 03:28:48 Functions: 15 16 93.8 %

          Line data    Source code
       1             : /* Copyright (c) 2020-2021, The Tor Project, Inc. */
       2             : /* See LICENSE for licensing information */
       3             : 
       4             : /**
       5             :  * \file resolve_addr.c
       6             :  * \brief Implement resolving address functions
       7             :  **/
       8             : 
       9             : #define RESOLVE_ADDR_PRIVATE
      10             : 
      11             : #include "app/config/config.h"
      12             : #include "app/config/resolve_addr.h"
      13             : 
      14             : #include "core/mainloop/mainloop.h"
      15             : 
      16             : #include "feature/control/control_events.h"
      17             : #include "feature/dirauth/authmode.h"
      18             : 
      19             : #include "lib/encoding/confline.h"
      20             : #include "lib/net/gethostname.h"
      21             : #include "lib/net/resolve.h"
      22             : 
      23             : /** Maximum "Address" statement allowed in our configuration. */
      24             : #define MAX_CONFIG_ADDRESS 2
      25             : 
      26             : /** Ease our life. Arrays containing state per address family. These are to
      27             :  * add semantic to the code so we know what is accessed. */
      28             : #define IDX_NULL 0 /* Index to zeroed address object. */
      29             : #define IDX_IPV4 1 /* Index to AF_INET. */
      30             : #define IDX_IPV6 2 /* Index to AF_INET6. */
      31             : #define IDX_SIZE 3 /* How many indexes do we have. */
      32             : 
      33             : /** Function in our address function table return one of these code. */
      34             : typedef enum {
      35             :   /* The address has been found. */
      36             :   FN_RET_OK   = 0,
      37             :   /* The failure requirements were not met and thus it is recommended that the
      38             :    * caller stops the search. */
      39             :   FN_RET_BAIL = 1,
      40             :   /* The address was not found or failure is transient so the caller should go
      41             :    * to the next method. */
      42             :   FN_RET_NEXT = 2,
      43             : } fn_address_ret_t;
      44             : 
      45             : /** Last resolved addresses. */
      46             : static tor_addr_t last_resolved_addrs[] =
      47             :   { TOR_ADDR_NULL, TOR_ADDR_NULL, TOR_ADDR_NULL };
      48             : CTASSERT(ARRAY_LENGTH(last_resolved_addrs) == IDX_SIZE);
      49             : 
      50             : /** Last suggested addresses.
      51             :  *
      52             :  * These addresses come from a NETINFO cell from a trusted relay (currently
      53             :  * only authorities). We only use those in last resort. */
      54             : static tor_addr_t last_suggested_addrs[] =
      55             :   { TOR_ADDR_NULL, TOR_ADDR_NULL, TOR_ADDR_NULL };
      56             : CTASSERT(ARRAY_LENGTH(last_suggested_addrs) == IDX_SIZE);
      57             : 
      58             : /** True iff the address was found to be configured that is from the
      59             :  * configuration file either using Address or ORPort. */
      60             : static bool last_addrs_configured[] = { false, false, false };
      61             : CTASSERT(ARRAY_LENGTH(last_addrs_configured) == IDX_SIZE);
      62             : 
      63             : static inline int
      64         162 : af_to_idx(const int family)
      65             : {
      66         162 :   switch (family) {
      67             :   case AF_INET:
      68             :     return IDX_IPV4;
      69          29 :   case AF_INET6:
      70          29 :     return IDX_IPV6;
      71           0 :   default:
      72             :     /* It wouldn't be safe to just die here with an assert but we can heavily
      73             :      * scream with a bug. Return the index of the NULL address. */
      74           0 :     tor_assert_nonfatal_unreached();
      75           0 :     return IDX_NULL;
      76             :   }
      77             : }
      78             : 
      79             : /** Return string representation of the given method. */
      80             : const char *
      81          55 : resolved_addr_method_to_str(const resolved_addr_method_t method)
      82             : {
      83          55 :   switch (method) {
      84             :   case RESOLVED_ADDR_NONE:
      85             :     return "NONE";
      86          33 :   case RESOLVED_ADDR_CONFIGURED:
      87          33 :     return "CONFIGURED";
      88           4 :   case RESOLVED_ADDR_CONFIGURED_ORPORT:
      89           4 :     return "CONFIGURED_ORPORT";
      90           4 :   case RESOLVED_ADDR_GETHOSTNAME:
      91           4 :     return "GETHOSTNAME";
      92           8 :   case RESOLVED_ADDR_INTERFACE:
      93           8 :     return "INTERFACE";
      94           6 :   case RESOLVED_ADDR_RESOLVED:
      95           6 :     return "RESOLVED";
      96           0 :   default:
      97           0 :     tor_assert_nonfatal_unreached();
      98           0 :     return "???";
      99             :   }
     100             : }
     101             : 
     102             : /** Return true if the last address of family was configured or not. An
     103             :  * address is considered configured if it was found in the Address or ORPort
     104             :  * statement.
     105             :  *
     106             :  * This applies to the address returned by the function
     107             :  * resolved_addr_get_last() which is the cache of discovered addresses. */
     108             : bool
     109           0 : resolved_addr_is_configured(int family)
     110             : {
     111           0 :   return last_addrs_configured[af_to_idx(family)];
     112             : }
     113             : 
     114             : /** Copy the last suggested address of family into addr_out.
     115             :  *
     116             :  * If no last suggested address exists, the addr_out is a null address (use
     117             :  * tor_addr_is_null() to confirm). */
     118             : void
     119          12 : resolved_addr_get_suggested(int family, tor_addr_t *addr_out)
     120             : {
     121          12 :   tor_addr_copy(addr_out, &last_suggested_addrs[af_to_idx(family)]);
     122          12 : }
     123             : 
     124             : /** Set the last suggested address into our cache. This is called when we get
     125             :  * a new NETINFO cell from a trusted source. */
     126             : void
     127           4 : resolved_addr_set_suggested(const tor_addr_t *addr)
     128             : {
     129           4 :   if (BUG(tor_addr_family(addr) != AF_INET &&
     130             :           tor_addr_family(addr) != AF_INET6)) {
     131           0 :     return;
     132             :   }
     133             : 
     134             :   /* In case we don't have a configured address, log that we will be using the
     135             :    * one discovered from the dirauth. */
     136           4 :   const int idx = af_to_idx(tor_addr_family(addr));
     137           8 :   if (tor_addr_is_null(&last_resolved_addrs[idx]) &&
     138           4 :       !tor_addr_eq(&last_suggested_addrs[idx], addr)) {
     139           4 :     log_notice(LD_CONFIG, "External address seen and suggested by a "
     140             :                           "directory authority: %s", fmt_addr(addr));
     141             :   }
     142           4 :   tor_addr_copy(&last_suggested_addrs[idx], addr);
     143             : }
     144             : 
     145             : /** Copy the last resolved address of family into addr_out.
     146             :  *
     147             :  * If not last resolved address existed, the addr_out is a null address (use
     148             :  * tor_addr_is_null()). */
     149             : void
     150           8 : resolved_addr_get_last(int family, tor_addr_t *addr_out)
     151             : {
     152           8 :   tor_addr_copy(addr_out, &last_resolved_addrs[af_to_idx(family)]);
     153           8 : }
     154             : 
     155             : /** Reset the last resolved address of family.
     156             :  *
     157             :  * This makes it null address. */
     158             : void
     159           2 : resolved_addr_reset_last(int family)
     160             : {
     161           2 :   tor_addr_make_null(&last_resolved_addrs[af_to_idx(family)], family);
     162           2 : }
     163             : 
     164             : /** Errors returned by address_can_be_used() in order for the caller to know
     165             :  * why the address is denied or not. */
     166             : #define ERR_DEFAULT_DIRAUTH     -1 /* Using default authorities. */
     167             : #define ERR_ADDRESS_IS_INTERNAL -2 /* IP is internal. */
     168             : 
     169             : /** @brief Return true iff the given IP address can be used as a valid
     170             :  *         external resolved address.
     171             :  *
     172             :  * Two tests are done in this function:
     173             :  *    1) If the address if NOT internal, it can be used.
     174             :  *    2) If the address is internal and we have custom directory authorities
     175             :  *       configured then it can they be used. Important for testing networks.
     176             :  *
     177             :  * @param addr The IP address to validate.
     178             :  * @param options Global configuration options.
     179             :  * @param warn_severity Log level that should be used on error.
     180             :  * @param explicit_ip Was the IP address explicitly given.
     181             :  *
     182             :  * @return Return 0 if it can be used. Return error code ERR_* found at the
     183             :  *         top of the file.
     184             :  */
     185             : static int
     186         101 : address_can_be_used(const tor_addr_t *addr, const or_options_t *options,
     187             :                     int warn_severity, const bool explicit_ip)
     188             : {
     189         101 :   tor_assert(addr);
     190             : 
     191             :   /* Public address, this is fine. */
     192         101 :   if (!tor_addr_is_internal(addr, 0)) {
     193          91 :     goto allow;
     194             :   }
     195             : 
     196             :   /* We allow internal addresses to be used if the PublishServerDescriptor is
     197             :    * unset and AssumeReachable (or for IPv6) is set.
     198             :    *
     199             :    * This is to cover the case where a relay/bridge might be run behind a
     200             :    * firewall on a local network to users can reach the network through it
     201             :    * using Tor Browser for instance. */
     202          10 :   if (options->PublishServerDescriptor_ == NO_DIRINFO &&
     203           2 :       (options->AssumeReachable ||
     204           1 :        (tor_addr_family(addr) == AF_INET6 && options->AssumeReachableIPv6))) {
     205           2 :     goto allow;
     206             :   }
     207             : 
     208             :   /* We have a private IP address. This is also allowed if we set custom
     209             :    * directory authorities. */
     210           8 :   if (using_default_dir_authorities(options)) {
     211           6 :     log_fn(warn_severity, LD_CONFIG,
     212             :            "Address '%s' is a private IP address. Tor relays that use "
     213             :            "the default DirAuthorities must have public IP addresses.",
     214             :            fmt_addr(addr));
     215           6 :     return ERR_DEFAULT_DIRAUTH;
     216             :   }
     217             : 
     218           2 :   if (!explicit_ip) {
     219             :     /* Even with custom directory authorities, only an explicit internal
     220             :      * address is accepted. */
     221           0 :     log_fn(warn_severity, LD_CONFIG,
     222             :            "Address %s was resolved and thus not explicitly "
     223             :            "set. Even if DirAuthorities are custom, this is "
     224             :            "not allowed.", fmt_addr(addr));
     225           0 :     return ERR_ADDRESS_IS_INTERNAL;
     226             :   }
     227             : 
     228           2 :  allow:
     229             :   return 0;
     230             : }
     231             : 
     232             : /** @brief Get IP address from the given config line and for a specific address
     233             :  *         family.
     234             :  *
     235             :  * This can fail is more than two Address statement are found for the same
     236             :  * address family. It also fails if no statement is found.
     237             :  *
     238             :  * @param options Global configuration options.
     239             :  * @param warn_severity Log level that should be used on error.
     240             :  * @param family IP address family. Only AF_INET and AF_INET6 are supported.
     241             :  * @param method_out OUT: Method denoting how the address was found.
     242             :  *                   This is described in the control-spec.txt as
     243             :  *                   actions for "STATUS_SERVER".
     244             :  * @param hostname_out OUT: String containing the hostname gotten from the
     245             :  *                     Address value if any.
     246             :  * @param addr_out OUT: Tor address of the address found in the cline or
     247             :  *                 resolved from the cline.
     248             :  *
     249             :  * @return Return 0 on success that is an address has been found or resolved
     250             :  *         successfully. Return error code ERR_* found at the top of the file.
     251             :  */
     252             : static fn_address_ret_t
     253         106 : get_address_from_config(const or_options_t *options, int warn_severity,
     254             :                         int family, resolved_addr_method_t *method_out,
     255             :                         char **hostname_out, tor_addr_t *addr_out)
     256             : {
     257         106 :   int ret;
     258         106 :   bool explicit_ip = false, resolve_failure = false;
     259         106 :   int num_valid_addr = 0;
     260             : 
     261         106 :   tor_assert(options);
     262         106 :   tor_assert(addr_out);
     263         106 :   tor_assert(method_out);
     264         106 :   tor_assert(hostname_out);
     265             : 
     266             :   /* Set them to NULL for safety reasons. */
     267         106 :   *hostname_out = NULL;
     268         106 :   *method_out = RESOLVED_ADDR_NONE;
     269             : 
     270         106 :   log_debug(LD_CONFIG, "Attempting to get address from configuration");
     271             : 
     272         106 :   if (!options->Address) {
     273          14 :     log_info(LD_CONFIG, "No Address option found in configuration.");
     274             :     /* No Address statement, inform caller to try next method. */
     275          14 :     return FN_RET_NEXT;
     276             :   }
     277             : 
     278         194 :   for (const config_line_t *cfg = options->Address; cfg != NULL;
     279         102 :        cfg = cfg->next) {
     280         102 :     int af;
     281         102 :     tor_addr_t addr;
     282             : 
     283         102 :     af = tor_addr_parse(&addr, cfg->value);
     284         102 :     if (af == family) {
     285          87 :       tor_addr_copy(addr_out, &addr);
     286          87 :       *method_out = RESOLVED_ADDR_CONFIGURED;
     287          87 :       explicit_ip = true;
     288          87 :       num_valid_addr++;
     289          87 :       continue;
     290          15 :     } else if (af != -1) {
     291             :       /* Parsable address but just not the one from the family we want. Skip
     292             :        * it so we don't attempt a resolve. */
     293           4 :       continue;
     294             :     }
     295             : 
     296             :     /* Not an IP address. Considering this value a hostname and attempting to
     297             :      * do a DNS lookup. */
     298          11 :     if (!tor_addr_lookup(cfg->value, family, &addr)) {
     299           6 :       tor_addr_copy(addr_out, &addr);
     300           6 :       *method_out = RESOLVED_ADDR_RESOLVED;
     301           6 :       if (*hostname_out) {
     302           0 :         tor_free(*hostname_out);
     303             :       }
     304           6 :       *hostname_out = tor_strdup(cfg->value);
     305           6 :       explicit_ip = false;
     306           6 :       num_valid_addr++;
     307           6 :       continue;
     308             :     } else {
     309             :       /* Hostname that can't be resolved, this is a fatal error. */
     310           5 :       resolve_failure = true;
     311           5 :       log_fn(warn_severity, LD_CONFIG,
     312             :              "Could not resolve local Address '%s'. Failing.", cfg->value);
     313           5 :       continue;
     314             :     }
     315             :   }
     316             : 
     317          92 :   if (!num_valid_addr) {
     318           1 :     if (resolve_failure) {
     319             :       /* We found no address but we got a resolution failure. This means we
     320             :        * can know if the hostname given was v4 or v6 so we can't continue. */
     321             :       return FN_RET_BAIL;
     322             :     }
     323           0 :     log_info(LD_CONFIG,
     324             :              "No Address option found for family %s in configuration.",
     325             :              fmt_af_family(family));
     326             :     /* No Address statement for family so move on to try next method. */
     327           0 :     return FN_RET_NEXT;
     328             :   }
     329             : 
     330          91 :   if (num_valid_addr >= MAX_CONFIG_ADDRESS) {
     331             :     /* Too many Address for same family. This is a fatal error. */
     332           2 :     log_fn(warn_severity, LD_CONFIG,
     333             :            "Found %d Address statement of address family %s. "
     334             :            "Only one is allowed.", num_valid_addr, fmt_af_family(family));
     335           2 :     tor_free(*hostname_out);
     336           2 :     return FN_RET_BAIL;
     337             :   }
     338             : 
     339             :   /* Great, we found an address. */
     340          89 :   ret = address_can_be_used(addr_out, options, warn_severity, explicit_ip);
     341          89 :   if (ret != 0) {
     342             :     /* One of the requirement of this interface is if an internal Address is
     343             :      * used, custom authorities must be defined else it is a fatal error.
     344             :      * Furthermore, if the Address was resolved to an internal interface, we
     345             :      * stop immediately. */
     346           2 :     if (ret == ERR_ADDRESS_IS_INTERNAL) {
     347           0 :       static bool logged_once = false;
     348           0 :       if (!logged_once) {
     349           0 :         log_warn(LD_CONFIG, "Address set with an internal address. Tor will "
     350             :                             "not work unless custom directory authorities "
     351             :                             "are defined (AlternateDirAuthority). It is also "
     352             :                             "possible to use an internal address if "
     353             :                             "PublishServerDescriptor is set to 0 and "
     354             :                             "AssumeReachable(IPv6) to 1.");
     355           0 :         logged_once = true;
     356             :       }
     357             :     }
     358           2 :     tor_free(*hostname_out);
     359           2 :     return FN_RET_BAIL;
     360             :   }
     361             : 
     362             :   /* Address can be used. We are done. */
     363          87 :   log_info(LD_CONFIG, "Address found in configuration: %s",
     364             :            fmt_addr(addr_out));
     365          87 :   return FN_RET_OK;
     366             : }
     367             : 
     368             : /** @brief Get IP address from the local hostname by calling gethostbyname()
     369             :  *         and doing a DNS resolution on the hostname.
     370             :  *
     371             :  * @param options Global configuration options.
     372             :  * @param warn_severity Log level that should be used on error.
     373             :  * @param family IP address family. Only AF_INET and AF_INET6 are supported.
     374             :  * @param method_out OUT: Method denoting how the address was found.
     375             :  *                   This is described in the control-spec.txt as
     376             :  *                   actions for "STATUS_SERVER".
     377             :  * @param hostname_out OUT: String containing the local hostname.
     378             :  * @param addr_out OUT: Tor address resolved from the local hostname.
     379             :  *
     380             :  * @return Return 0 on success that is an address has been found and resolved
     381             :  *         successfully. Return error code ERR_* found at the top of the file.
     382             :  */
     383             : static fn_address_ret_t
     384           8 : get_address_from_hostname(const or_options_t *options, int warn_severity,
     385             :                           int family, resolved_addr_method_t *method_out,
     386             :                           char **hostname_out, tor_addr_t *addr_out)
     387             : {
     388           8 :   int ret;
     389           8 :   char hostname[256];
     390             : 
     391           8 :   tor_assert(addr_out);
     392           8 :   tor_assert(method_out);
     393             : 
     394             :   /* Set them to NULL for safety reasons. */
     395           8 :   *hostname_out = NULL;
     396           8 :   *method_out = RESOLVED_ADDR_NONE;
     397             : 
     398           8 :   log_debug(LD_CONFIG, "Attempting to get address from local hostname");
     399             : 
     400           8 :   if (tor_gethostname(hostname, sizeof(hostname)) < 0) {
     401           2 :     log_fn(warn_severity, LD_NET, "Error obtaining local hostname");
     402             :     /* Unable to obtain the local hostname is a fatal error. */
     403           2 :     return FN_RET_BAIL;
     404             :   }
     405           6 :   if (tor_addr_lookup(hostname, family, addr_out)) {
     406           2 :     log_fn(warn_severity, LD_NET,
     407             :            "Could not resolve local hostname '%s'. Failing.", hostname);
     408             :     /* Unable to resolve, inform caller to try next method. */
     409           2 :     return FN_RET_NEXT;
     410             :   }
     411             : 
     412           4 :   ret = address_can_be_used(addr_out, options, warn_severity, false);
     413           4 :   if (ret == ERR_DEFAULT_DIRAUTH) {
     414             :     /* Non custom authorities, inform caller to try next method. */
     415             :     return FN_RET_NEXT;
     416           2 :   } else if (ret == ERR_ADDRESS_IS_INTERNAL) {
     417             :     /* Internal address is a fatal error. */
     418             :     return FN_RET_BAIL;
     419             :   }
     420             : 
     421             :   /* addr_out contains the address of the local hostname. */
     422           2 :   *method_out = RESOLVED_ADDR_GETHOSTNAME;
     423           2 :   *hostname_out = tor_strdup(hostname);
     424             : 
     425             :   /* Found it! */
     426           2 :   log_info(LD_CONFIG, "Address found from local hostname: %s",
     427             :            fmt_addr(addr_out));
     428           2 :   return FN_RET_OK;
     429             : }
     430             : 
     431             : /** @brief Get IP address from a network interface.
     432             :  *
     433             :  * @param options Global configuration options.
     434             :  * @param warn_severity Log level that should be used on error.
     435             :  * @param family IP address family. Only AF_INET and AF_INET6 are supported.
     436             :  * @param method_out OUT: Always RESOLVED_ADDR_INTERFACE on success which
     437             :  *                   is detailed in the control-spec.txt as actions
     438             :  *                   for "STATUS_SERVER".
     439             :  * @param hostname_out OUT: String containing the local hostname. For this
     440             :  *                     function, it is always set to NULL.
     441             :  * @param addr_out OUT: Tor address found attached to the interface.
     442             :  *
     443             :  * @return Return 0 on success that is an address has been found. Return
     444             :  *         error code ERR_* found at the top of the file.
     445             :  */
     446             : static fn_address_ret_t
     447          12 : get_address_from_interface(const or_options_t *options, int warn_severity,
     448             :                            int family, resolved_addr_method_t *method_out,
     449             :                            char **hostname_out, tor_addr_t *addr_out)
     450             : {
     451          12 :   int ret;
     452             : 
     453          12 :   tor_assert(method_out);
     454          12 :   tor_assert(hostname_out);
     455          12 :   tor_assert(addr_out);
     456             : 
     457             :   /* Set them to NULL for safety reasons. */
     458          12 :   *method_out = RESOLVED_ADDR_NONE;
     459          12 :   *hostname_out = NULL;
     460             : 
     461          12 :   log_debug(LD_CONFIG, "Attempting to get address from network interface");
     462             : 
     463          12 :   if (get_interface_address6(warn_severity, family, addr_out) < 0) {
     464           8 :     log_fn(warn_severity, LD_CONFIG,
     465             :            "Could not get local interface IP address.");
     466             :     /* Unable to get IP from interface. Inform caller to try next method. */
     467           8 :     return FN_RET_NEXT;
     468             :   }
     469             : 
     470           4 :   ret = address_can_be_used(addr_out, options, warn_severity, false);
     471           4 :   if (ret < 0) {
     472             :     /* Unable to use address. Inform caller to try next method. */
     473             :     return FN_RET_NEXT;
     474             :   }
     475             : 
     476           4 :   *method_out = RESOLVED_ADDR_INTERFACE;
     477             : 
     478             :   /* Found it! */
     479           4 :   log_info(LD_CONFIG, "Address found from interface: %s", fmt_addr(addr_out));
     480           4 :   return FN_RET_OK;
     481             : }
     482             : 
     483             : /** @brief Get IP address from the ORPort (if any).
     484             :  *
     485             :  * @param options Global configuration options.
     486             :  * @param warn_severity Log level that should be used on error.
     487             :  * @param family IP address family. Only AF_INET and AF_INET6 are supported.
     488             :  * @param method_out OUT: Always RESOLVED_ADDR_CONFIGURED_ORPORT on success
     489             :  *                   which is detailed in the control-spec.txt as actions
     490             :  *                   for "STATUS_SERVER".
     491             :  * @param hostname_out OUT: String containing the ORPort hostname if any.
     492             :  * @param addr_out OUT: Tor address found if any.
     493             :  *
     494             :  * @return Return 0 on success that is an address has been found. Return
     495             :  *         error code ERR_* found at the top of the file.
     496             :  */
     497             : static fn_address_ret_t
     498          14 : get_address_from_orport(const or_options_t *options, int warn_severity,
     499             :                         int family, resolved_addr_method_t *method_out,
     500             :                         char **hostname_out, tor_addr_t *addr_out)
     501             : {
     502          14 :   int ret;
     503          14 :   const tor_addr_t *addr;
     504             : 
     505          14 :   tor_assert(method_out);
     506          14 :   tor_assert(hostname_out);
     507          14 :   tor_assert(addr_out);
     508             : 
     509             :   /* Set them to NULL for safety reasons. */
     510          14 :   *method_out = RESOLVED_ADDR_NONE;
     511          14 :   *hostname_out = NULL;
     512             : 
     513          14 :   log_debug(LD_CONFIG, "Attempting to get address from ORPort");
     514             : 
     515          14 :   if (!options->ORPort_set) {
     516          10 :     log_info(LD_CONFIG, "No ORPort found in configuration.");
     517             :     /* No ORPort statement, inform caller to try next method. */
     518          10 :     return FN_RET_NEXT;
     519             :   }
     520             : 
     521             :   /* Get ORPort for requested family. */
     522           4 :   addr = get_orport_addr(family);
     523           4 :   if (!addr) {
     524             :     /* No address configured for the ORPort. Ignore. */
     525             :     return FN_RET_NEXT;
     526             :   }
     527             : 
     528             :   /* We found the ORPort address. Just make sure it can be used. */
     529           4 :   ret = address_can_be_used(addr, options, warn_severity, true);
     530           4 :   if (ret < 0) {
     531             :     /* Unable to use address. Inform caller to try next method. */
     532             :     return FN_RET_NEXT;
     533             :   }
     534             : 
     535             :   /* Found it! */
     536           2 :   *method_out = RESOLVED_ADDR_CONFIGURED_ORPORT;
     537           2 :   tor_addr_copy(addr_out, addr);
     538             : 
     539           2 :   log_fn(warn_severity, LD_CONFIG, "Address found from ORPort: %s",
     540             :          fmt_addr(addr_out));
     541           2 :   return FN_RET_OK;
     542             : }
     543             : 
     544             : /** @brief Set the last resolved address cache using the given address.
     545             :  *
     546             :  * A log notice is emitted if the given address has changed from before. Not
     547             :  * emitted on first resolve.
     548             :  *
     549             :  * Control port event "STATUS_SERVER" is emitted with the new information if
     550             :  * it has changed.
     551             :  *
     552             :  * Finally, tor is notified that the IP address has changed.
     553             :  *
     554             :  * @param addr IP address to update the cache with.
     555             :  * @param method_used By which method did we resolved it (for logging and
     556             :  *                    control port).
     557             :  * @param hostname_used Which hostname was used. If none were used, it is
     558             :  *                      NULL. (for logging and control port).
     559             :  */
     560             : void
     561          97 : resolved_addr_set_last(const tor_addr_t *addr,
     562             :                        const resolved_addr_method_t method_used,
     563             :                        const char *hostname_used)
     564             : {
     565             :   /** Have we done a first resolve. This is used to control logging. */
     566          97 :   static bool have_resolved_once[] = { false, false, false };
     567          97 :   CTASSERT(ARRAY_LENGTH(have_resolved_once) == IDX_SIZE);
     568             : 
     569          97 :   bool *done_one_resolve;
     570          97 :   bool have_hostname = false;
     571          97 :   tor_addr_t *last_resolved;
     572             : 
     573          97 :   tor_assert(addr);
     574             : 
     575             :   /* Do we have an hostname. */
     576          97 :   have_hostname = (hostname_used != NULL);
     577             : 
     578          97 :   int idx = af_to_idx(tor_addr_family(addr));
     579          97 :   if (idx == IDX_NULL) {
     580             :     /* Not suppose to happen and if it does, af_to_idx() screams loudly. */
     581             :     return;
     582             :   }
     583             : 
     584             :   /* Get values from cache. */
     585          97 :   done_one_resolve = &have_resolved_once[idx];
     586          97 :   last_resolved = &last_resolved_addrs[idx];
     587             : 
     588             :   /* Same address last resolved. Ignore. */
     589          97 :   if (tor_addr_eq(last_resolved, addr)) {
     590             :     return;
     591             :   }
     592             : 
     593             :   /* Don't log notice if this is the first resolve we do. */
     594          37 :   if (*done_one_resolve) {
     595             :     /* Leave this as a notice, regardless of the requested severity,
     596             :      * at least until dynamic IP address support becomes bulletproof. */
     597          44 :     log_notice(LD_NET,
     598             :                "Your IP address seems to have changed to %s "
     599             :                "(METHOD=%s%s%s). Updating.",
     600             :                fmt_addr(addr),
     601             :                resolved_addr_method_to_str(method_used),
     602             :                have_hostname ? " HOSTNAME=" : "",
     603             :                have_hostname ? hostname_used : "");
     604          18 :     ip_address_changed(0);
     605             :   }
     606             : 
     607             :   /* Notify control port. */
     608         101 :   control_event_server_status(LOG_NOTICE,
     609             :                               "EXTERNAL_ADDRESS ADDRESS=%s METHOD=%s%s%s",
     610             :                               fmt_addr(addr),
     611             :                               resolved_addr_method_to_str(method_used),
     612             :                               have_hostname ? " HOSTNAME=" : "",
     613             :                               have_hostname ? hostname_used : "");
     614             :   /* Copy address to cache. */
     615          37 :   tor_addr_copy(last_resolved, addr);
     616          37 :   *done_one_resolve = true;
     617             : 
     618             :   /* Flag true if the address was configured. Else, indicate it was not. */
     619          37 :   last_addrs_configured[idx] = false;
     620          37 :   if (method_used == RESOLVED_ADDR_CONFIGURED ||
     621             :       method_used == RESOLVED_ADDR_CONFIGURED_ORPORT) {
     622          28 :     last_addrs_configured[idx] = true;
     623             :   }
     624             : }
     625             : 
     626             : /** Ease our lives. Typedef to the address discovery function signature. */
     627             : typedef fn_address_ret_t
     628             :   (*fn_address_t)(
     629             :      const or_options_t *options, int warn_severity, int family,
     630             :      resolved_addr_method_t *method_out, char **hostname_out,
     631             :      tor_addr_t *addr_out);
     632             : 
     633             : /** Address discovery function table. The order matters as in the first one is
     634             :  * executed first and so on. */
     635             : static const fn_address_t fn_address_table[] =
     636             : {
     637             :   /* These functions are in order for our find address algorithm. */
     638             :   get_address_from_config,
     639             :   get_address_from_orport,
     640             :   get_address_from_interface,
     641             :   get_address_from_hostname,
     642             : };
     643             : /** Length of address table as in how many functions. */
     644             : static const size_t fn_address_table_len =
     645             :   ARRAY_LENGTH(fn_address_table);
     646             : 
     647             : /* Address discover function table for authorities (bridge or directory).
     648             :  *
     649             :  * They only discover their address from either the configuration file or the
     650             :  * ORPort. They do not query the interface nor do any DNS resolution for
     651             :  * security reasons. */
     652             : static const fn_address_t fn_address_table_auth[] =
     653             : {
     654             :   /* These functions are in order for our find address algorithm. */
     655             :   get_address_from_config,
     656             :   get_address_from_orport,
     657             : };
     658             : /** Length of address table as in how many functions. */
     659             : static const size_t fn_address_table_auth_len =
     660             :   ARRAY_LENGTH(fn_address_table_auth);
     661             : 
     662             : /** @brief Attempt to find our IP address that can be used as our external
     663             :  *         reachable address.
     664             :  *
     665             :  *  The following describe the algorithm to find an address. Each have
     666             :  *  specific conditions so read carefully.
     667             :  *
     668             :  *  On success, true is returned and depending on how the address was found,
     669             :  *  the out parameters can have different values.
     670             :  *
     671             :  *  On error, false is returned and out parameters are set to NULL.
     672             :  *
     673             :  *  1. Look at the configuration Address option.
     674             : 
     675             :  *     If Address is a public address, True is returned and addr_out is set
     676             :  *     with it, the method_out is set to RESOLVED_ADDR_CONFIGURED and
     677             :  *     hostname_out is set to NULL.
     678             :  *
     679             :  *     If Address is an internal address but NO custom authorities are used,
     680             :  *     an error is returned.
     681             :  *
     682             :  *     If Address is a hostname, that is it can't be converted to an address,
     683             :  *     it is resolved. On success, addr_out is set with the address,
     684             :  *     method_out is set to RESOLVED_ADDR_RESOLVED and hostname_out is set
     685             :  *     to the resolved hostname. On failure to resolve, an error is returned.
     686             :  *
     687             :  *     If no given Address, fallback to the network interface (see section 2).
     688             :  *
     689             :  *  2. Look at the network interface.
     690             :  *
     691             :  *     Attempt to find the first public usable address from the list of
     692             :  *     network interfaces returned by the OS.
     693             :  *
     694             :  *     On failure, we attempt to look at the local hostname (3).
     695             :  *
     696             :  *     On success, addr_out is set with it, method_out is set to
     697             :  *     RESOLVED_ADDR_INTERFACE and hostname_out is set to NULL.
     698             :  *
     699             :  *  3. Look at the local hostname.
     700             :  *
     701             :  *     If the local hostname resolves to a non internal address, addr_out is
     702             :  *     set with it, method_out is set to RESOLVED_ADDR_GETHOSTNAME and
     703             :  *     hostname_out is set to the resolved hostname.
     704             :  *
     705             :  *     If a local hostname can NOT be found, an error is returned.
     706             :  *
     707             :  *     If the local hostname resolves to an internal address, an error is
     708             :  *     returned.
     709             :  *
     710             :  *     If the local hostname can NOT be resolved, an error is returned.
     711             :  *
     712             :  * @param options Global configuration options.
     713             :  * @param family IP address family. Only AF_INET and AF_INET6 are supported.
     714             :  * @param warn_severity Logging level.
     715             :  * @param addr_out OUT: Set with the IP address found if any.
     716             :  * @param method_out OUT: (optional) Method denoting how the address wa
     717             :  *                   found. This is described in the control-spec.txt as
     718             :  *                   actions for "STATUS_SERVER".
     719             :  * @param hostname_out OUT: String containing the hostname if any was used.
     720             :  *                     Only be set for RESOLVED and GETHOSTNAME methods.
     721             :  *                     Else it is set to NULL.
     722             :  *
     723             :  * @return True if the address was found for the given family. False if not or
     724             :  *         on errors.
     725             :  */
     726             : bool
     727         107 : find_my_address(const or_options_t *options, int family, int warn_severity,
     728             :                 tor_addr_t *addr_out, resolved_addr_method_t *method_out,
     729             :                 char **hostname_out)
     730             : {
     731         107 :   resolved_addr_method_t method_used = RESOLVED_ADDR_NONE;
     732         107 :   char *hostname_used = NULL;
     733         107 :   tor_addr_t my_addr;
     734         107 :   const fn_address_t *table = fn_address_table;
     735         107 :   size_t table_len = fn_address_table_len;
     736             : 
     737         107 :   tor_assert(options);
     738         107 :   tor_assert(addr_out);
     739             : 
     740             :   /* Set them to NULL for safety reasons. */
     741         107 :   tor_addr_make_unspec(addr_out);
     742         107 :   if (method_out) *method_out = RESOLVED_ADDR_NONE;
     743         107 :   if (hostname_out) *hostname_out = NULL;
     744             : 
     745             :   /* If an IPv6 is requested, check if IPv6 address discovery is disabled and
     746             :    * if so we always return a failure. It is done here so we don't populate
     747             :    * the resolve cache or do any DNS resolution. */
     748         107 :   if (family == AF_INET6 && options->AddressDisableIPv6) {
     749             :     return false;
     750             :   }
     751             : 
     752             :   /* For authorities (bridge and directory), we use a different table. */
     753         106 :   if (authdir_mode(options)) {
     754          71 :     table = fn_address_table_auth;
     755          71 :     table_len = fn_address_table_auth_len;
     756             :   }
     757             : 
     758             :   /*
     759             :    * Step 1: Discover address by calling methods from the function table.
     760             :    */
     761             : 
     762             :   /* Go over the function table. They are in order. */
     763         144 :   for (size_t idx = 0; idx < table_len; idx++) {
     764         140 :     fn_address_ret_t ret = table[idx](options, warn_severity, family,
     765             :                                       &method_used, &hostname_used, &my_addr);
     766         140 :     if (ret == FN_RET_BAIL) {
     767             :       return false;
     768         133 :     } else if (ret == FN_RET_OK) {
     769          95 :       goto found;
     770             :     }
     771          38 :     tor_assert(ret == FN_RET_NEXT);
     772             :   }
     773             : 
     774             :   /* We've exhausted our attempts. Failure. */
     775           4 :   log_fn(warn_severity, LD_CONFIG, "Unable to find our IP address.");
     776           4 :   return false;
     777             : 
     778          95 :  found:
     779             :   /*
     780             :    * Step 2: Update last resolved address cache and inform the control port.
     781             :    */
     782          95 :   resolved_addr_set_last(&my_addr, method_used, hostname_used);
     783             : 
     784          95 :   if (method_out) {
     785          25 :     *method_out = method_used;
     786             :   }
     787          95 :   if (hostname_out) {
     788          25 :     *hostname_out = hostname_used;
     789             :   } else {
     790          70 :     tor_free(hostname_used);
     791             :   }
     792             : 
     793          95 :   tor_addr_copy(addr_out, &my_addr);
     794          95 :   return true;
     795             : }
     796             : 
     797             : /** @brief: Return true iff the given addr is judged to be local to our
     798             :  * resolved address.
     799             :  *
     800             :  * This function is used to tell whether another address is 'remote' enough
     801             :  * that we can trust it when it tells us that we are reachable, or that we
     802             :  * have a certain address.
     803             :  *
     804             :  * The criterion to learn if the address is local are the following:
     805             :  *
     806             :  *    1. Internal address.
     807             :  *    2. If EnforceDistinctSubnets is set then it is never local.
     808             :  *    3. Network mask is compared. IPv4: /24 and IPv6 /48. This is different
     809             :  *       from the path selection that looks at /16 and /32 because we only
     810             :  *       want to learn here if the address is considered to come from the
     811             :  *       Internet basically.
     812             :  *
     813             :  * @param addr The address to test if local and also test against our resovled
     814             :  *             address.
     815             :  *
     816             :  * @return True iff address is considered local or else False.
     817             :  */
     818          35 : MOCK_IMPL(bool,
     819             : is_local_to_resolve_addr, (const tor_addr_t *addr))
     820             : {
     821          35 :   const int family = tor_addr_family(addr);
     822          70 :   const tor_addr_t *last_resolved_addr =
     823          35 :     &last_resolved_addrs[af_to_idx(family)];
     824             : 
     825             :   /* Internal address is always local. */
     826          35 :   if (tor_addr_is_internal(addr, 0)) {
     827             :     return true;
     828             :   }
     829             : 
     830             :   /* Address is not local if we don't enforce subnet distinction. */
     831           5 :   if (get_options()->EnforceDistinctSubnets == 0) {
     832             :     return false;
     833             :   }
     834             : 
     835           5 :   switch (family) {
     836           5 :   case AF_INET:
     837             :     /* It's possible that this next check will hit before the first time
     838             :      * find_my_address actually succeeds. For clients, it is likely that
     839             :      * find_my_address will never be called at all. In those cases,
     840             :      * last_resolved_addr_v4 will be 0, and so checking to see whether ip is
     841             :      * on the same /24 as last_resolved_addrs[AF_INET] will be the same as
     842             :      * checking whether it was on net 0, which is already done by
     843             :      * tor_addr_is_internal. */
     844           5 :     return tor_addr_compare_masked(addr, last_resolved_addr, 24,
     845           5 :                                    CMP_SEMANTIC) == 0;
     846           0 :   case AF_INET6:
     847             :     /* Look at /48 because it is typically the smallest network in the global
     848             :      * IPv6 routing tables, and it was previously the recommended per-customer
     849             :      * network block. (See [RFC 6177: IPv6 End Site Address Assignment].) */
     850           0 :     return tor_addr_compare_masked(addr, last_resolved_addr, 48,
     851           0 :                                    CMP_SEMANTIC) == 0;
     852             :     break;
     853             :   default:
     854             :     /* Unknown address type so not local. */
     855             :     return false;
     856             :   }
     857             : }
     858             : 
     859             : #ifdef TOR_UNIT_TESTS
     860             : 
     861             : void
     862           4 : resolve_addr_reset_suggested(int family)
     863             : {
     864           4 :   tor_addr_make_unspec(&last_suggested_addrs[af_to_idx(family)]);
     865           4 : }
     866             : 
     867             : #endif /* defined(TOR_UNIT_TESTS) */

Generated by: LCOV version 1.14