aboutsummaryrefslogtreecommitdiff
path: root/src/common/address.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/common/address.c')
-rw-r--r--src/common/address.c81
1 files changed, 54 insertions, 27 deletions
diff --git a/src/common/address.c b/src/common/address.c
index 794345a138..5074c1ccf0 100644
--- a/src/common/address.c
+++ b/src/common/address.c
@@ -1,6 +1,6 @@
/* Copyright (c) 2003-2004, Roger Dingledine
* Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
- * Copyright (c) 2007-2016, The Tor Project, Inc. */
+ * Copyright (c) 2007-2017, The Tor Project, Inc. */
/* See LICENSE for licensing information */
/**
@@ -33,7 +33,7 @@
#include <process.h>
#include <windows.h>
#include <iphlpapi.h>
-#endif
+#endif /* defined(_WIN32) */
#include "compat.h"
#include "util.h"
@@ -159,6 +159,8 @@ tor_addr_from_sockaddr(tor_addr_t *a, const struct sockaddr *sa,
tor_assert(a);
tor_assert(sa);
+ /* This memset is redundant; leaving it in to avoid any future accidents,
+ however. */
memset(a, 0, sizeof(*a));
if (sa->sa_family == AF_INET) {
@@ -196,7 +198,7 @@ tor_sockaddr_to_str(const struct sockaddr *sa)
tor_asprintf(&result, "unix:%s", s_un->sun_path);
return result;
}
-#endif
+#endif /* defined(HAVE_SYS_UN_H) */
if (sa->sa_family == AF_UNSPEC)
return tor_strdup("unspec");
@@ -235,8 +237,8 @@ tor_addr_make_null(tor_addr_t *a, sa_family_t family)
*
* Return 0 on success, -1 on failure; 1 on transient failure.
*/
-int
-tor_addr_lookup(const char *name, uint16_t family, tor_addr_t *addr)
+MOCK_IMPL(int,
+tor_addr_lookup,(const char *name, uint16_t family, tor_addr_t *addr))
{
/* Perhaps eventually this should be replaced by a tor_getaddrinfo or
* something.
@@ -303,7 +305,7 @@ tor_addr_lookup(const char *name, uint16_t family, tor_addr_t *addr)
return result;
}
return (err == EAI_AGAIN) ? 1 : -1;
-#else
+#else /* !(defined(HAVE_GETADDRINFO)) */
struct hostent *ent;
int err;
#ifdef HAVE_GETHOSTBYNAME_R_6_ARG
@@ -328,7 +330,7 @@ tor_addr_lookup(const char *name, uint16_t family, tor_addr_t *addr)
#else
err = h_errno;
#endif
-#endif /* endif HAVE_GETHOSTBYNAME_R_6_ARG. */
+#endif /* defined(HAVE_GETHOSTBYNAME_R_6_ARG) || ... */
if (ent) {
if (ent->h_addrtype == AF_INET) {
tor_addr_from_in(addr, (struct in_addr*) ent->h_addr);
@@ -344,7 +346,7 @@ tor_addr_lookup(const char *name, uint16_t family, tor_addr_t *addr)
#else
return (err == TRY_AGAIN) ? 1 : -1;
#endif
-#endif
+#endif /* defined(HAVE_GETADDRINFO) */
}
}
@@ -562,8 +564,8 @@ tor_addr_parse_PTR_name(tor_addr_t *result, const char *address,
/** Convert <b>addr</b> to an in-addr.arpa name or a .ip6.arpa name,
* and store the result in the <b>outlen</b>-byte buffer at
- * <b>out</b>. Return the number of chars written to <b>out</b>, not
- * including the trailing \0, on success. Returns -1 on failure. */
+ * <b>out</b>. Returns a non-negative integer on success.
+ * Returns -1 on failure. */
int
tor_addr_to_PTR_name(char *out, size_t outlen,
const tor_addr_t *addr)
@@ -905,8 +907,8 @@ tor_addr_is_loopback(const tor_addr_t *addr)
return (tor_addr_to_ipv4h(addr) & 0xff000000) == 0x7f000000;
case AF_UNSPEC:
return 0;
- default:
/* LCOV_EXCL_START */
+ default:
tor_fragile_assert();
return 0;
/* LCOV_EXCL_STOP */
@@ -1029,8 +1031,10 @@ tor_addr_copy_tight(tor_addr_t *dest, const tor_addr_t *src)
memcpy(dest->addr.in6_addr.s6_addr, src->addr.in6_addr.s6_addr, 16);
case AF_UNSPEC:
break;
+ // LCOV_EXCL_START
default:
- tor_fragile_assert(); // LCOV_EXCL_LINE
+ tor_fragile_assert();
+ // LCOV_EXCL_STOP
}
}
@@ -1121,7 +1125,7 @@ tor_addr_compare_masked(const tor_addr_t *addr1, const tor_addr_t *addr2,
case AF_UNIX:
/* HACKHACKHACKHACKHACK:
* tor_addr_t doesn't contain a copy of sun_path, so it's not
- * possible to comapre this at all.
+ * possible to compare this at all.
*
* Since the only time we currently actually should be comparing
* 2 AF_UNIX addresses is when dealing with ISO_CLIENTADDR (which
@@ -1136,8 +1140,8 @@ tor_addr_compare_masked(const tor_addr_t *addr1, const tor_addr_t *addr2,
return 0;
else
return 1;
- default:
/* LCOV_EXCL_START */
+ default:
tor_fragile_assert();
return 0;
/* LCOV_EXCL_STOP */
@@ -1195,8 +1199,8 @@ tor_addr_hash(const tor_addr_t *addr)
return siphash24g(unspec_hash_input, sizeof(unspec_hash_input));
case AF_INET6:
return siphash24g(&addr->addr.in6_addr.s6_addr, 16);
- default:
/* LCOV_EXCL_START */
+ default:
tor_fragile_assert();
return 0;
/* LCOV_EXCL_STOP */
@@ -1432,7 +1436,7 @@ get_interface_addresses_ifaddrs(int severity, sa_family_t family)
return result;
}
-#endif
+#endif /* defined(HAVE_IFADDRS_TO_SMARTLIST) */
#ifdef HAVE_IP_ADAPTER_TO_SMARTLIST
@@ -1526,7 +1530,7 @@ get_interface_addresses_win32(int severity, sa_family_t family)
return result;
}
-#endif
+#endif /* defined(HAVE_IP_ADAPTER_TO_SMARTLIST) */
#ifdef HAVE_IFCONF_TO_SMARTLIST
@@ -1539,6 +1543,18 @@ get_interface_addresses_win32(int severity, sa_family_t family)
#define _SIZEOF_ADDR_IFREQ sizeof
#endif
+/* Free ifc->ifc_buf safely. */
+static void
+ifconf_free_ifc_buf(struct ifconf *ifc)
+{
+ /* On macOS, tor_free() takes the address of ifc.ifc_buf, which leads to
+ * undefined behaviour, because pointer-to-pointers are expected to be
+ * aligned at 8-bytes, but the ifconf structure is packed. So we use
+ * raw_free() instead. */
+ raw_free(ifc->ifc_buf);
+ ifc->ifc_buf = NULL;
+}
+
/** Convert <b>*buf</b>, an ifreq structure array of size <b>buflen</b>,
* into smartlist of <b>tor_addr_t</b> structures.
*/
@@ -1625,10 +1641,10 @@ get_interface_addresses_ioctl(int severity, sa_family_t family)
done:
if (fd >= 0)
close(fd);
- tor_free(ifc.ifc_buf);
+ ifconf_free_ifc_buf(&ifc);
return result;
}
-#endif
+#endif /* defined(HAVE_IFCONF_TO_SMARTLIST) */
/** 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.
@@ -1783,14 +1799,14 @@ get_interface_address6,(int severity, sa_family_t family, tor_addr_t *addr))
break;
} SMARTLIST_FOREACH_END(a);
- free_interface_address6_list(addrs);
+ interface_address6_list_free(addrs);
return rv;
}
/** Free a smartlist of IP addresses returned by get_interface_address6_list.
*/
void
-free_interface_address6_list(smartlist_t *addrs)
+interface_address6_list_free_(smartlist_t *addrs)
{
if (addrs != NULL) {
SMARTLIST_FOREACH(addrs, tor_addr_t *, a, tor_free(a));
@@ -1805,11 +1821,12 @@ free_interface_address6_list(smartlist_t *addrs)
* An empty smartlist means that there are no addresses of the selected type
* matching these criteria.
* Returns NULL on failure.
- * Use free_interface_address6_list to free the returned list.
+ * Use interface_address6_list_free to free the returned list.
*/
-MOCK_IMPL(smartlist_t *,get_interface_address6_list,(int severity,
- sa_family_t family,
- int include_internal))
+MOCK_IMPL(smartlist_t *,
+get_interface_address6_list,(int severity,
+ sa_family_t family,
+ int include_internal))
{
smartlist_t *addrs;
tor_addr_t addr;
@@ -2077,7 +2094,8 @@ parse_port_range(const char *port, uint16_t *port_min_out,
/** Given an IPv4 in_addr struct *<b>in</b> (in network order, as usual),
* write it as a string into the <b>buf_len</b>-byte buffer in
- * <b>buf</b>.
+ * <b>buf</b>. Returns a non-negative integer on success.
+ * Returns -1 on failure.
*/
int
tor_inet_ntoa(const struct in_addr *in, char *buf, size_t buf_len)
@@ -2128,7 +2146,8 @@ get_interface_address,(int severity, uint32_t *addr))
}
/** Return true if we can tell that <b>name</b> is a canonical name for the
- * loopback address. */
+ * loopback address. Return true also for *.local hostnames, which are
+ * multicast DNS names for hosts on the local network. */
int
tor_addr_hostname_is_local(const char *name)
{
@@ -2149,3 +2168,11 @@ tor_addr_port_new(const tor_addr_t *addr, uint16_t port)
return ap;
}
+/** Return true iff <a>a</b> and <b>b</b> are the same address and port */
+int
+tor_addr_port_eq(const tor_addr_port_t *a,
+ const tor_addr_port_t *b)
+{
+ return tor_addr_eq(&a->addr, &b->addr) && a->port == b->port;
+}
+