mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2024-11-27 22:03:31 +01:00
Add family argument to get_interface_addresses_raw (and subfunctions).
This commit is contained in:
parent
cdbb04be10
commit
44497e9ebc
5
changes/feature17950
Normal file
5
changes/feature17950
Normal file
@ -0,0 +1,5 @@
|
||||
o Minor features:
|
||||
- Add a family argument to get_interface_addresses_raw() and
|
||||
subfunctions to make network interface address interogation more
|
||||
efficient. Now Tor can specifically ask for IPv4, IPv6 or both
|
||||
types of interfaces from the operating system. Resolves ticket 17950.
|
@ -1274,7 +1274,7 @@ typedef ULONG (WINAPI *GetAdaptersAddresses_fn_t)(
|
||||
* into smartlist of <b>tor_addr_t</b> structures.
|
||||
*/
|
||||
STATIC smartlist_t *
|
||||
ifaddrs_to_smartlist(const struct ifaddrs *ifa)
|
||||
ifaddrs_to_smartlist(const struct ifaddrs *ifa, sa_family_t family)
|
||||
{
|
||||
smartlist_t *result = smartlist_new();
|
||||
const struct ifaddrs *i;
|
||||
@ -1285,8 +1285,7 @@ ifaddrs_to_smartlist(const struct ifaddrs *ifa)
|
||||
continue;
|
||||
if (!i->ifa_addr)
|
||||
continue;
|
||||
if (i->ifa_addr->sa_family != AF_INET &&
|
||||
i->ifa_addr->sa_family != AF_INET6)
|
||||
if (family != AF_UNSPEC && i->ifa_addr->sa_family != family)
|
||||
continue;
|
||||
if (tor_addr_from_sockaddr(&tmp, i->ifa_addr, NULL) < 0)
|
||||
continue;
|
||||
@ -1301,7 +1300,7 @@ ifaddrs_to_smartlist(const struct ifaddrs *ifa)
|
||||
* <b>tor_addr_t</b> structures.
|
||||
*/
|
||||
STATIC smartlist_t *
|
||||
get_interface_addresses_ifaddrs(int severity)
|
||||
get_interface_addresses_ifaddrs(int severity, sa_family_t family)
|
||||
{
|
||||
|
||||
/* Most free Unixy systems provide getifaddrs, which gives us a linked list
|
||||
@ -1314,7 +1313,7 @@ get_interface_addresses_ifaddrs(int severity)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
result = ifaddrs_to_smartlist(ifa);
|
||||
result = ifaddrs_to_smartlist(ifa, family);
|
||||
|
||||
freeifaddrs(ifa);
|
||||
|
||||
@ -1356,7 +1355,7 @@ ip_adapter_addresses_to_smartlist(const IP_ADAPTER_ADDRESSES *addresses)
|
||||
* <b>tor_addr_t</b> structures.
|
||||
*/
|
||||
STATIC smartlist_t *
|
||||
get_interface_addresses_win32(int severity)
|
||||
get_interface_addresses_win32(int severity, sa_family_t family)
|
||||
{
|
||||
|
||||
/* Windows XP began to provide GetAdaptersAddresses. Windows 2000 had a
|
||||
@ -1390,7 +1389,7 @@ get_interface_addresses_win32(int severity)
|
||||
/* Guess how much space we need. */
|
||||
size = 15*1024;
|
||||
addresses = tor_malloc(size);
|
||||
res = fn(AF_UNSPEC, FLAGS, NULL, addresses, &size);
|
||||
res = fn(family, FLAGS, NULL, addresses, &size);
|
||||
if (res == ERROR_BUFFER_OVERFLOW) {
|
||||
/* we didn't guess that we needed enough space; try again */
|
||||
tor_free(addresses);
|
||||
@ -1464,7 +1463,7 @@ ifreq_to_smartlist(char *buf, size_t buflen)
|
||||
* <b>tor_addr_t</b> structures.
|
||||
*/
|
||||
STATIC smartlist_t *
|
||||
get_interface_addresses_ioctl(int severity)
|
||||
get_interface_addresses_ioctl(int severity, sa_family_t family)
|
||||
{
|
||||
/* Some older unixy systems make us use ioctl(SIOCGIFCONF) */
|
||||
struct ifconf ifc;
|
||||
@ -1473,7 +1472,14 @@ get_interface_addresses_ioctl(int severity)
|
||||
|
||||
/* This interface, AFAICT, only supports AF_INET addresses,
|
||||
* except on AIX. For Solaris, we could use SIOCGLIFCONF. */
|
||||
fd = socket(AF_INET, SOCK_DGRAM, 0);
|
||||
|
||||
/* FIXME: for now, we bail out if family is not AF_INET since
|
||||
* ioctl() technique supports non-IPv4 interface addresses on
|
||||
* a small number of niche systems only. */
|
||||
if (family != AF_INET)
|
||||
return NULL;
|
||||
|
||||
fd = socket(family, SOCK_DGRAM, 0);
|
||||
if (fd < 0) {
|
||||
tor_log(severity, LD_NET, "socket failed: %s", strerror(errno));
|
||||
goto done;
|
||||
@ -1508,21 +1514,23 @@ get_interface_addresses_ioctl(int severity)
|
||||
/** Try to ask our network interfaces what addresses they are bound to.
|
||||
* Return a new smartlist of tor_addr_t on success, and NULL on failure.
|
||||
* (An empty smartlist indicates that we successfully learned that we have no
|
||||
* addresses.) Log failure messages at <b>severity</b>. */
|
||||
* addresses.) Log failure messages at <b>severity</b>. Only return the
|
||||
* interface addresses of requested <b>family</b> and ignore the addresses
|
||||
* of other address families. */
|
||||
MOCK_IMPL(smartlist_t *,
|
||||
get_interface_addresses_raw,(int severity))
|
||||
get_interface_addresses_raw,(int severity, sa_family_t family))
|
||||
{
|
||||
smartlist_t *result = NULL;
|
||||
#if defined(HAVE_IFADDRS_TO_SMARTLIST)
|
||||
if ((result = get_interface_addresses_ifaddrs(severity)))
|
||||
if ((result = get_interface_addresses_ifaddrs(severity, family)))
|
||||
return result;
|
||||
#endif
|
||||
#if defined(HAVE_IP_ADAPTER_TO_SMARTLIST)
|
||||
if ((result = get_interface_addresses_win32(severity)))
|
||||
if ((result = get_interface_addresses_win32(severity, family)))
|
||||
return result;
|
||||
#endif
|
||||
#if defined(HAVE_IFCONF_TO_SMARTLIST)
|
||||
if ((result = get_interface_addresses_ioctl(severity)))
|
||||
if ((result = get_interface_addresses_ioctl(severity, family)))
|
||||
return result;
|
||||
#endif
|
||||
(void) severity;
|
||||
@ -1686,15 +1694,9 @@ MOCK_IMPL(smartlist_t *,get_interface_address6_list,(int severity,
|
||||
tor_addr_t addr;
|
||||
|
||||
/* Try to do this the smart way if possible. */
|
||||
if ((addrs = get_interface_addresses_raw(severity))) {
|
||||
if ((addrs = get_interface_addresses_raw(severity, family))) {
|
||||
SMARTLIST_FOREACH_BEGIN(addrs, tor_addr_t *, a)
|
||||
{
|
||||
if (family != AF_UNSPEC && family != tor_addr_family(a)) {
|
||||
SMARTLIST_DEL_CURRENT(addrs, a);
|
||||
tor_free(a);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (tor_addr_is_loopback(a) ||
|
||||
tor_addr_is_multicast(a)) {
|
||||
SMARTLIST_DEL_CURRENT(addrs, a);
|
||||
|
@ -311,26 +311,31 @@ get_interface_address_list(int severity, int include_internal)
|
||||
tor_addr_port_t *tor_addr_port_new(const tor_addr_t *addr, uint16_t port);
|
||||
|
||||
#ifdef ADDRESS_PRIVATE
|
||||
MOCK_DECL(smartlist_t *,get_interface_addresses_raw,(int severity));
|
||||
MOCK_DECL(smartlist_t *,get_interface_addresses_raw,(int severity,
|
||||
sa_family_t family));
|
||||
MOCK_DECL(int,get_interface_address6_via_udp_socket_hack,(int severity,
|
||||
sa_family_t family,
|
||||
tor_addr_t *addr));
|
||||
|
||||
#ifdef HAVE_IFADDRS_TO_SMARTLIST
|
||||
STATIC smartlist_t *ifaddrs_to_smartlist(const struct ifaddrs *ifa);
|
||||
STATIC smartlist_t *get_interface_addresses_ifaddrs(int severity);
|
||||
STATIC smartlist_t *ifaddrs_to_smartlist(const struct ifaddrs *ifa,
|
||||
sa_family_t family);
|
||||
STATIC smartlist_t *get_interface_addresses_ifaddrs(int severity,
|
||||
sa_family_t family);
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_IP_ADAPTER_TO_SMARTLIST
|
||||
STATIC smartlist_t *ip_adapter_addresses_to_smartlist(
|
||||
const IP_ADAPTER_ADDRESSES *addresses);
|
||||
STATIC smartlist_t *get_interface_addresses_win32(int severity);
|
||||
STATIC smartlist_t *get_interface_addresses_win32(int severity,
|
||||
sa_family_t family);
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_IFCONF_TO_SMARTLIST
|
||||
STATIC smartlist_t *ifreq_to_smartlist(char *ifr,
|
||||
size_t buflen);
|
||||
STATIC smartlist_t *get_interface_addresses_ioctl(int severity);
|
||||
STATIC smartlist_t *get_interface_addresses_ioctl(int severity,
|
||||
sa_family_t family);
|
||||
#endif
|
||||
|
||||
#endif // ADDRESS_PRIVATE
|
||||
|
@ -220,7 +220,7 @@ test_address_ifaddrs_to_smartlist(void *arg)
|
||||
ifa_ipv6->ifa_dstaddr = NULL;
|
||||
ifa_ipv6->ifa_data = NULL;
|
||||
|
||||
smartlist = ifaddrs_to_smartlist(ifa);
|
||||
smartlist = ifaddrs_to_smartlist(ifa, AF_UNSPEC);
|
||||
|
||||
tt_assert(smartlist);
|
||||
tt_assert(smartlist_len(smartlist) == 3);
|
||||
@ -281,7 +281,7 @@ test_address_get_if_addrs_ifaddrs(void *arg)
|
||||
|
||||
(void)arg;
|
||||
|
||||
results = get_interface_addresses_ifaddrs(LOG_ERR);
|
||||
results = get_interface_addresses_ifaddrs(LOG_ERR, AF_UNSPEC);
|
||||
|
||||
tt_assert(results);
|
||||
/* Some FreeBSD jails don't have localhost IP address. Instead, they only
|
||||
@ -314,7 +314,7 @@ test_address_get_if_addrs_win32(void *arg)
|
||||
|
||||
(void)arg;
|
||||
|
||||
results = get_interface_addresses_win32(LOG_ERR);
|
||||
results = get_interface_addresses_win32(LOG_ERR, AF_UNSPEC);
|
||||
|
||||
tt_int_op(smartlist_len(results),>=,1);
|
||||
tt_assert(smartlist_contains_localhost_tor_addr(results));
|
||||
@ -511,7 +511,7 @@ test_address_get_if_addrs_ioctl(void *arg)
|
||||
|
||||
(void)arg;
|
||||
|
||||
result = get_interface_addresses_ioctl(LOG_ERR);
|
||||
result = get_interface_addresses_ioctl(LOG_ERR, AF_INET);
|
||||
|
||||
/* On an IPv6-only system, this will fail and return NULL
|
||||
tt_assert(result);
|
||||
@ -845,9 +845,10 @@ test_address_get_if_addrs6_list_no_internal(void *arg)
|
||||
static int called_get_interface_addresses_raw = 0;
|
||||
|
||||
static smartlist_t *
|
||||
mock_get_interface_addresses_raw_fail(int severity)
|
||||
mock_get_interface_addresses_raw_fail(int severity, sa_family_t family)
|
||||
{
|
||||
(void)severity;
|
||||
(void)family;
|
||||
|
||||
called_get_interface_addresses_raw++;
|
||||
return smartlist_new();
|
||||
|
Loading…
Reference in New Issue
Block a user