Commit 3c0d3988 authored by Nick Mathewson's avatar Nick Mathewson 🤹
Browse files

Merge branch 'mr_274_squashed' into maint-0.4.5

parents af5250b1 f0304733
Loading
Loading
Loading
Loading

changes/ticket40254

0 → 100644
+4 −0
Original line number Diff line number Diff line
  o Minor bugfixes (relay, configuration):
    - Don't attempt to discover address (IPv4 or IPv6) if no ORPort for it can
      be found in the configuration. Fixes bug 40254; bugfix on 0.4.5.1-alpha.
+24 −0
Original line number Diff line number Diff line
@@ -99,6 +99,13 @@ relay_address_new_suggestion(const tor_addr_t *suggested_addr,
 *       populated by the NETINFO cell content or HTTP header from a
 *       directory.
 *
 * The AddressDisableIPv6 is checked here for IPv6 address discovery and if
 * set, false is returned and addr_out is UNSPEC.
 *
 * Before doing any discovery, the configuration is checked for an ORPort of
 * the given family. If none can be found, false is returned and addr_out is
 * UNSPEC.
 *
 * Return true on success and addr_out contains the address to use for the
 * given family. On failure to find the address, false is returned and
 * addr_out is set to an AF_UNSPEC address. */
@@ -118,6 +125,12 @@ relay_find_addr_to_publish, (const or_options_t *options, int family,
    return false;
  }

  /* There is no point on attempting an address discovery to publish if we
   * don't have an ORPort for this family. */
  if (!routerconf_find_or_port(options, family)) {
    return false;
  }

  /* First, check our resolved address cache. It should contain the address
   * we've discovered from the periodic relay event. */
  resolved_addr_get_last(family, addr_out);
@@ -131,6 +144,17 @@ relay_find_addr_to_publish, (const or_options_t *options, int family,
    if (find_my_address(options, family, LOG_INFO, addr_out, NULL, NULL)) {
      goto found;
    }
    /* No publishable address was found even though we have an ORPort thus
     * print a notice log so operator can notice. We'll do that every hour so
     * it is not too spammy but enough so operators address the issue. */
    static ratelim_t rlim = RATELIM_INIT(3600);
    log_fn_ratelim(&rlim, LOG_NOTICE, LD_CONFIG,
                   "Unable to find %s address for ORPort %u. "
                   "You might want to specify %sOnly to it or set an "
                   "explicit address or set Address.",
                   fmt_af_family(family),
                   routerconf_find_or_port(options, family),
                   fmt_af_family(family));
  }

  /* Third, consider address from our suggestion cache. */
+12 −27
Original line number Diff line number Diff line
@@ -2047,12 +2047,11 @@ MOCK_IMPL(STATIC int,
router_build_fresh_unsigned_routerinfo,(routerinfo_t **ri_out))
{
  routerinfo_t *ri = NULL;
  tor_addr_t ipv4_addr, ipv6_addr;
  tor_addr_t ipv4_addr;
  char platform[256];
  int hibernating = we_are_hibernating();
  const or_options_t *options = get_options();
  int result = TOR_ROUTERINFO_ERROR_INTERNAL_BUG;
  uint16_t ipv6_orport = 0;

  if (BUG(!ri_out)) {
    result = TOR_ROUTERINFO_ERROR_INTERNAL_BUG;
@@ -2064,10 +2063,6 @@ router_build_fresh_unsigned_routerinfo,(routerinfo_t **ri_out))
  bool have_v4 = relay_find_addr_to_publish(options, AF_INET,
                                            RELAY_FIND_ADDR_NO_FLAG,
                                            &ipv4_addr);
  bool have_v6 = relay_find_addr_to_publish(options, AF_INET6,
                                            RELAY_FIND_ADDR_NO_FLAG,
                                            &ipv6_addr);

  /* Tor requires a relay to have an IPv4 so bail if we can't find it. */
  if (!have_v4) {
    log_info(LD_CONFIG, "Don't know my address while generating descriptor. "
@@ -2079,24 +2074,21 @@ router_build_fresh_unsigned_routerinfo,(routerinfo_t **ri_out))
  /* Log a message if the address in the descriptor doesn't match the ORPort
   * and DirPort addresses configured by the operator. */
  router_check_descriptor_address_consistency(&ipv4_addr);
  router_check_descriptor_address_consistency(&ipv6_addr);

  ri = tor_malloc_zero(sizeof(routerinfo_t));
  tor_addr_copy(&ri->ipv4_addr, &ipv4_addr);
  ri->cache_info.routerlist_index = -1;
  ri->nickname = tor_strdup(options->Nickname);

  /* IPv4. */
  tor_addr_copy(&ri->ipv4_addr, &ipv4_addr);
  ri->ipv4_orport = routerconf_find_or_port(options, AF_INET);
  ri->ipv4_dirport = routerconf_find_dir_port(options, 0);

  /* IPv6. Do not publish an IPv6 if we don't have an ORPort that can be used
   * with the address. This is possible for instance if the ORPort is
   * IPv4Only. */
  ipv6_orport = routerconf_find_or_port(options, AF_INET6);
  if (have_v6 && ipv6_orport != 0) {
    tor_addr_copy(&ri->ipv6_addr, &ipv6_addr);
    ri->ipv6_orport = ipv6_orport;
  /* Optionally check for an IPv6. We still publish without one. */
  if (relay_find_addr_to_publish(options, AF_INET6, RELAY_FIND_ADDR_NO_FLAG,
                                 &ri->ipv6_addr)) {
    ri->ipv6_orport = routerconf_find_or_port(options, AF_INET6);
    router_check_descriptor_address_consistency(&ri->ipv6_addr);
  }

  ri->supports_tunnelled_dir_requests =
@@ -2679,18 +2671,11 @@ check_descriptor_ipaddress_changed(time_t now)
      previous = &my_ri->ipv6_addr;
    }

    /* Ignore returned value because we want to notice not only an address
     * change but also if an address is lost (current == UNSPEC). */
    bool found = find_my_address(get_options(), family, LOG_INFO, &current,
                                 &method, &hostname);
    if (!found) {
      /* Address was possibly not found because it is simply not configured or
       * discoverable. Fallback to our cache, which includes any suggestion
       * sent by a trusted directory server. */
      found = relay_find_addr_to_publish(get_options(), family,
                                         RELAY_FIND_ADDR_CACHE_ONLY,
    /* Attempt to discovery the publishable address for the family which will
     * actively attempt to discover the address if we are configured with a
     * port for the family. */
    relay_find_addr_to_publish(get_options(), family, RELAY_FIND_ADDR_NO_FLAG,
                               &current);
    }

    /* The "current" address might be UNSPEC meaning it was not discovered nor
     * found in our current cache. If we had an address before and we have
+24 −9
Original line number Diff line number Diff line
@@ -11,6 +11,7 @@
#include "feature/stats/bwhist.h"
#include "core/or/relay.h"
#include "lib/container/order.h"
#include "lib/encoding/confline.h"
/* For init/free stuff */
#include "core/or/scheduler.h"

@@ -23,6 +24,8 @@
#include "feature/relay/routermode.h"
#include "feature/dirclient/dir_server_st.h"

#define CONFIG_PRIVATE
#include "app/config/config.h"
#include "app/config/resolve_addr.h"

/* Test suite stuff */
@@ -298,11 +301,12 @@ test_find_addr_to_publish(void *arg)
  int family;
  bool ret;
  tor_addr_t ipv4_addr, ipv6_addr, cache_addr;
  or_options_t options;
  or_options_t *options;

  (void) arg;

  memset(&options, 0, sizeof(options));
  options = options_new();
  options_init(options);

  /* Populate our resolved cache with a valid IPv4 and IPv6. */
  family = tor_addr_parse(&ipv4_addr, "1.2.3.4");
@@ -317,13 +321,24 @@ test_find_addr_to_publish(void *arg)
  resolved_addr_get_last(AF_INET6, &cache_addr);
  tt_assert(tor_addr_eq(&ipv6_addr, &cache_addr));

  /* Setup ORPort config. */
  {
    int n, w, r;
    char *msg = NULL;

    config_line_append(&options->ORPort_lines, "ORPort", "9001");

    r = parse_ports(options, 0, &msg, &n, &w);
    tt_int_op(r, OP_EQ, 0);
  }

  /* 1. Address located in the resolved cache. */
  ret = relay_find_addr_to_publish(&options, AF_INET,
  ret = relay_find_addr_to_publish(options, AF_INET,
                                   RELAY_FIND_ADDR_CACHE_ONLY, &cache_addr);
  tt_assert(ret);
  tt_assert(tor_addr_eq(&ipv4_addr, &cache_addr));

  ret = relay_find_addr_to_publish(&options, AF_INET6,
  ret = relay_find_addr_to_publish(options, AF_INET6,
                                   RELAY_FIND_ADDR_CACHE_ONLY, &cache_addr);
  tt_assert(ret);
  tt_assert(tor_addr_eq(&ipv6_addr, &cache_addr));
@@ -334,13 +349,13 @@ test_find_addr_to_publish(void *arg)
   *    the find_my_address() code path because that is extensively tested in
   *    another unit tests. */
  resolved_addr_set_suggested(&ipv4_addr);
  ret = relay_find_addr_to_publish(&options, AF_INET,
  ret = relay_find_addr_to_publish(options, AF_INET,
                                   RELAY_FIND_ADDR_CACHE_ONLY, &cache_addr);
  tt_assert(ret);
  tt_assert(tor_addr_eq(&ipv4_addr, &cache_addr));

  resolved_addr_set_suggested(&ipv6_addr);
  ret = relay_find_addr_to_publish(&options, AF_INET6,
  ret = relay_find_addr_to_publish(options, AF_INET6,
                                   RELAY_FIND_ADDR_CACHE_ONLY, &cache_addr);
  tt_assert(ret);
  tt_assert(tor_addr_eq(&ipv6_addr, &cache_addr));
@@ -348,15 +363,15 @@ test_find_addr_to_publish(void *arg)
  resolve_addr_reset_suggested(AF_INET6);

  /* 3. No IP anywhere. */
  ret = relay_find_addr_to_publish(&options, AF_INET,
  ret = relay_find_addr_to_publish(options, AF_INET,
                                   RELAY_FIND_ADDR_CACHE_ONLY, &cache_addr);
  tt_assert(!ret);
  ret = relay_find_addr_to_publish(&options, AF_INET6,
  ret = relay_find_addr_to_publish(options, AF_INET6,
                                   RELAY_FIND_ADDR_CACHE_ONLY, &cache_addr);
  tt_assert(!ret);

 done:
  ;
  or_options_free(options);
}

struct testcase_t relay_tests[] = {