Commit 6888523d authored by rl1987's avatar rl1987 Committed by Nick Mathewson
Browse files

Moving the hacky part of get_interface_address6() into separate function.

parent 5c820def
Loading
Loading
Loading
Loading
+49 −34
Original line number Diff line number Diff line
@@ -1484,47 +1484,22 @@ tor_addr_is_multicast(const tor_addr_t *a)
  return 0;
}

/** Set *<b>addr</b> to the IP address (if any) of whatever interface
 * connects to the Internet.  This address should only be used in checking
 * whether our address has changed.  Return 0 on success, -1 on failure.
/** Attempt to retrieve IP address of current host by utilizing some
 * UDP socket trickery. Only look for address of given <b>family</b>.
 * Set result to *<b>addr</b>. Return 0 on success, -1 on failure.
 */
MOCK_IMPL(int,
get_interface_address6,(int severity, sa_family_t family, tor_addr_t *addr))
STATIC int
get_interface_address6_via_udp_socket_hack(int severity,
                                           sa_family_t family,
                                           tor_addr_t *addr)
{
  /* XXX really, this function should yield a smartlist of addresses. */
  smartlist_t *addrs;
  int sock=-1, r=-1;
  struct sockaddr_storage my_addr, target_addr;
  int sock=-1, r=-1;
  socklen_t addr_len;
  tor_assert(addr);

  /* Try to do this the smart way if possible. */
  if ((addrs = get_interface_addresses_raw(severity))) {
    int rv = -1;
    SMARTLIST_FOREACH_BEGIN(addrs, tor_addr_t *, a) {
      if (family != AF_UNSPEC && family != tor_addr_family(a))
        continue;
      if (tor_addr_is_loopback(a) ||
          tor_addr_is_multicast(a))
        continue;

      tor_addr_copy(addr, a);
      rv = 0;

      /* If we found a non-internal address, declare success.  Otherwise,
       * keep looking. */
      if (!tor_addr_is_internal(a, 0))
        break;
    } SMARTLIST_FOREACH_END(a);

    SMARTLIST_FOREACH(addrs, tor_addr_t *, a, tor_free(a));
    smartlist_free(addrs);
    return rv;
  }

  /* Okay, the smart way is out. */
  memset(addr, 0, sizeof(tor_addr_t));
  memset(&target_addr, 0, sizeof(target_addr));

  /* Don't worry: no packets are sent. We just need to use a real address
   * on the actual Internet. */
  if (family == AF_INET6) {
@@ -1546,6 +1521,7 @@ get_interface_address6,(int severity, sa_family_t family, tor_addr_t *addr))
  } else {
    return -1;
  }

  if (sock < 0) {
    int e = tor_socket_errno(-1);
    log_fn(severity, LD_NET, "unable to create socket: %s",
@@ -1574,6 +1550,45 @@ get_interface_address6,(int severity, sa_family_t family, tor_addr_t *addr))
  return r;
}

/** Set *<b>addr</b> to the IP address (if any) of whatever interface
 * connects to the Internet.  This address should only be used in checking
 * whether our address has changed.  Return 0 on success, -1 on failure.
 */
MOCK_IMPL(int,
get_interface_address6,(int severity, sa_family_t family, tor_addr_t *addr))
{
  /* XXX really, this function should yield a smartlist of addresses. */
  smartlist_t *addrs;
  tor_assert(addr);

  /* Try to do this the smart way if possible. */
  if ((addrs = get_interface_addresses_raw(severity))) {
    int rv = -1;
    SMARTLIST_FOREACH_BEGIN(addrs, tor_addr_t *, a) {
      if (family != AF_UNSPEC && family != tor_addr_family(a))
        continue;
      if (tor_addr_is_loopback(a) ||
          tor_addr_is_multicast(a))
        continue;

      tor_addr_copy(addr, a);
      rv = 0;

      /* If we found a non-internal address, declare success.  Otherwise,
       * keep looking. */
      if (!tor_addr_is_internal(a, 0))
        break;
    } SMARTLIST_FOREACH_END(a);

    SMARTLIST_FOREACH(addrs, tor_addr_t *, a, tor_free(a));
    smartlist_free(addrs);
    return rv;
  }

  /* Okay, the smart way is out. */
  return get_interface_address6_via_udp_socket_hack(severity,family,addr);
}

/* ======
 * IPv4 helpers
 * XXXX024 IPv6 deprecate some of these.