commit 6888523d73bdb5822b78455fa2a864635bbe1f7f Author: rl1987 rl1987@sdf.lonestar.org Date: Mon Jan 5 22:12:46 2015 +0200
Moving the hacky part of get_interface_address6() into separate function. --- src/common/address.c | 83 +++++++++++++++++++++++++++++--------------------- 1 file changed, 49 insertions(+), 34 deletions(-)
diff --git a/src/common/address.c b/src/common/address.c index 3b4be1d..e3c2521 100644 --- a/src/common/address.c +++ b/src/common/address.c @@ -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.
tor-commits@lists.torproject.org