Commit 374c1e97 authored by Nick Mathewson's avatar Nick Mathewson 👁
Browse files

Refactor tor_addr_t manipulation functions so that as few as possible look at...

Refactor tor_addr_t manipulation functions so that as few as possible look at the tor_addr_t representation.

svn:r17790
parent 616f6643
......@@ -62,7 +62,8 @@ tor_addr_to_sockaddr(const tor_addr_t *a,
struct sockaddr *sa_out,
socklen_t len)
{
if (a->family == AF_INET) {
sa_family_t family = tor_addr_family(a);
if (family == AF_INET) {
struct sockaddr_in *sin;
if (len < (int)sizeof(struct sockaddr_in))
return -1;
......@@ -71,7 +72,7 @@ tor_addr_to_sockaddr(const tor_addr_t *a,
sin->sin_port = htons(port);
sin->sin_addr.s_addr = tor_addr_to_ipv4n(a);
return sizeof(struct sockaddr_in);
} else if (a->family == AF_INET6) {
} else if (family == AF_INET6) {
struct sockaddr_in6 *sin6;
if (len < (int)sizeof(struct sockaddr_in6))
return -1;
......@@ -79,7 +80,7 @@ tor_addr_to_sockaddr(const tor_addr_t *a,
memset(sin6, 0, sizeof(struct sockaddr_in6));
sin6->sin6_family = AF_INET6;
sin6->sin6_port = htons(port);
memcpy(&sin6->sin6_addr, &a->addr.in6_addr, sizeof(struct in6_addr));
memcpy(&sin6->sin6_addr, tor_addr_to_in6(a), sizeof(struct in6_addr));
return sizeof(struct sockaddr_in6);
} else {
return -1;
......@@ -94,21 +95,18 @@ tor_addr_from_sockaddr(tor_addr_t *a, const struct sockaddr *sa,
{
tor_assert(a);
tor_assert(sa);
memset(a, 0, sizeof(tor_addr_t));
if (sa->sa_family == AF_INET) {
struct sockaddr_in *sin = (struct sockaddr_in *) sa;
a->family = AF_INET;
a->addr.in_addr.s_addr = sin->sin_addr.s_addr;
tor_addr_from_ipv4n(a, sin->sin_addr.s_addr);
if (port_out)
*port_out = ntohs(sin->sin_port);
} else if (sa->sa_family == AF_INET6) {
struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *) sa;
a->family = AF_INET6;
memcpy(&a->addr.in6_addr, &sin6->sin6_addr, sizeof(struct in6_addr));
tor_addr_from_in6(a, &sin6->sin6_addr);
if (port_out)
*port_out = ntohs(sin6->sin6_port);
} else {
a->family = AF_UNSPEC;
tor_addr_make_unspec(a);
return -1;
}
return 0;
......@@ -142,7 +140,6 @@ tor_addr_lookup(const char *name, uint16_t family, tor_addr_t *addr)
tor_assert(name);
tor_assert(addr);
tor_assert(family == AF_INET || family == AF_INET6 || family == AF_UNSPEC);
memset(addr, 0, sizeof(addr)); /* Clear the extraneous fields. */
if (!*name) {
/* Empty address is an error. */
return -1;
......@@ -150,14 +147,12 @@ tor_addr_lookup(const char *name, uint16_t family, tor_addr_t *addr)
/* It's an IPv4 IP. */
if (family == AF_INET6)
return -1;
addr->family = AF_INET;
memcpy(&addr->addr.in_addr, &iaddr, sizeof(struct in_addr));
tor_addr_from_in(addr, &iaddr);
return 0;
} else if (tor_inet_pton(AF_INET6, name, &iaddr6)) {
if (family == AF_INET)
return -1;
addr->family = AF_INET6;
memcpy(&addr->addr.in6_addr, &iaddr6, sizeof(struct in6_addr));
tor_addr_from_in6(addr, &iaddr6);
return 0;
} else {
#ifdef HAVE_GETADDRINFO
......@@ -188,16 +183,12 @@ tor_addr_lookup(const char *name, uint16_t family, tor_addr_t *addr)
if (!best)
best = res;
if (best->ai_family == AF_INET) {
addr->family = AF_INET;
memcpy(&addr->addr.in_addr,
&((struct sockaddr_in*)best->ai_addr)->sin_addr,
sizeof(struct in_addr));
tor_addr_from_in(addr,
&((struct sockaddr_in*)best->ai_addr)->sin_addr);
result = 0;
} else if (best->ai_family == AF_INET6) {
addr->family = AF_INET6;
memcpy(&addr->addr.in6_addr,
&((struct sockaddr_in6*)best->ai_addr)->sin6_addr,
sizeof(struct in6_addr));
tor_addr_from_in6(addr,
&((struct sockaddr_in6*)best->ai_addr)->sin6_addr);
result = 0;
}
freeaddrinfo(res);
......@@ -231,11 +222,10 @@ tor_addr_lookup(const char *name, uint16_t family, tor_addr_t *addr)
#endif
#endif /* endif HAVE_GETHOSTBYNAME_R_6_ARG. */
if (ent) {
addr->family = ent->h_addrtype;
if (ent->h_addrtype == AF_INET) {
memcpy(&addr->addr.in_addr, ent->h_addr, sizeof(struct in_addr));
tor_addr_from_in(addr, (struct in_addr*) ent->h_addr);
} else if (ent->h_addrtype == AF_INET6) {
memcpy(&addr->addr.in6_addr, ent->h_addr, sizeof(struct in6_addr));
tor_addr_from_in(addr, (struct in6_addr*) ent->h_addr);
} else {
tor_assert(0); /* gethostbyname() returned a bizarre addrtype */
}
......@@ -383,9 +373,7 @@ tor_addr_parse_reverse_lookup_name(tor_addr_t *result, const char *address,
|((inaddr.s_addr & 0xff000000ul) >> 24));
if (result) {
memset(result, 0, sizeof(tor_addr_t));
result->family = AF_INET;
result->addr.in_addr.s_addr = inaddr.s_addr;
tor_addr_from_in(result, &inaddr);
}
return 1;
}
......@@ -421,8 +409,7 @@ tor_addr_parse_reverse_lookup_name(tor_addr_t *result, const char *address,
return -1;
if (result) {
result->family = AF_INET6;
memcpy(&result->addr.in6_addr, &in6, sizeof(in6));
tor_addr_from_in6(result, &in6);
}
return 1;
}
......@@ -462,10 +449,11 @@ tor_addr_to_reverse_lookup_name(char *out, size_t outlen,
} else if (addr->family == AF_INET6) {
int i;
char *cp = out;
const uint8_t *bytes = tor_addr_to_in6_addr8(addr);
if (outlen < REVERSE_LOOKUP_NAME_BUF_LEN)
return -1;
for (i = 15; i >= 0; --i) {
uint8_t byte = addr->addr.in6_addr.s6_addr[i];
uint8_t byte = bytes[i];
*cp++ = "0123456789abcdef"[byte & 0x0f];
*cp++ = '.';
*cp++ = "0123456789abcdef"[byte >> 4];
......@@ -506,6 +494,9 @@ tor_addr_parse_mask_ports(const char *s, tor_addr_t *addr_out,
char *base = NULL, *address, *mask = NULL, *port = NULL, *rbracket = NULL;
char *endptr;
int any_flag=0, v4map=0;
sa_family_t family;
struct in6_addr in6_tmp;
struct in_addr in_tmp;
tor_assert(s);
tor_assert(addr_out);
......@@ -552,12 +543,14 @@ tor_addr_parse_mask_ports(const char *s, tor_addr_t *addr_out,
memset(addr_out, 0, sizeof(tor_addr_t));
if (!strcmp(address, "*")) {
addr_out->family = AF_INET; /* AF_UNSPEC ???? XXXX_IP6 */
family = AF_INET; /* AF_UNSPEC ???? XXXX_IP6 */
any_flag = 1;
} else if (tor_inet_pton(AF_INET6, address, &addr_out->addr.in6_addr) > 0) {
addr_out->family = AF_INET6;
} else if (tor_inet_pton(AF_INET, address, &addr_out->addr.in_addr) > 0) {
addr_out->family = AF_INET;
} else if (tor_inet_pton(AF_INET6, address, &in6_tmp) > 0) {
family = AF_INET6;
tor_addr_from_in6(addr_out, &in6_tmp);
} else if (tor_inet_pton(AF_INET, address, &in_tmp) > 0) {
family = AF_INET;
tor_addr_from_in(addr_out, &in_tmp);
} else {
log_warn(LD_GENERAL, "Malformed IP %s in address pattern; rejecting.",
escaped(address));
......@@ -591,7 +584,7 @@ tor_addr_parse_mask_ports(const char *s, tor_addr_t *addr_out,
bits = (int) strtol(mask, &endptr, 10);
if (!*endptr) { /* strtol converted everything, so it was an integer */
if ((bits<0 || bits>128) ||
((tor_addr_family(addr_out) == AF_INET) && bits > 32)) {
(family == AF_INET && bits > 32)) {
log_warn(LD_GENERAL,
"Bad number of mask bits (%d) on address range; rejecting.",
bits);
......@@ -613,7 +606,7 @@ tor_addr_parse_mask_ports(const char *s, tor_addr_t *addr_out,
goto err;
}
}
if (tor_addr_family(addr_out) == AF_INET6 && v4map) {
if (family == AF_INET6 && v4map) {
if (bits > 32 && bits < 96) { /* Crazy */
log_warn(LD_GENERAL,
"Bad mask bits %i for V4-mapped V6 address; rejecting.",
......@@ -829,8 +822,8 @@ tor_addr_compare_masked(const tor_addr_t *addr1, const tor_addr_t *addr2,
case AF_UNSPEC:
return 0; /* All unspecified addresses are equal */
case AF_INET: {
uint32_t a1 = ntohl(addr1->addr.in_addr.s_addr);
uint32_t a2 = ntohl(addr2->addr.in_addr.s_addr);
uint32_t a1 = tor_addr_to_ipv4h(addr1);
uint32_t a2 = tor_addr_to_ipv4h(addr2);
if (mbits <= 0)
return 0;
if (mbits > 32)
......@@ -841,8 +834,8 @@ tor_addr_compare_masked(const tor_addr_t *addr1, const tor_addr_t *addr2,
return r;
}
case AF_INET6: {
const uint8_t *a1 = addr1->addr.in6_addr.s6_addr;
const uint8_t *a2 = addr2->addr.in6_addr.s6_addr;
const uint8_t *a1 = tor_addr_to_in6_addr8(addr1);
const uint8_t *a2 = tor_addr_to_in6_addr8(addr2);
const int bytes = mbits >> 3;
const int leftover_bits = mbits & 7;
if (bytes && (r = memcmp(a1, a2, bytes))) {
......@@ -958,14 +951,18 @@ tor_addr_from_str(tor_addr_t *addr, const char *src)
{
char *tmp = NULL; /* Holds substring if we got a dotted quad. */
int result;
struct in_addr in_tmp;
struct in6_addr in6_tmp;
tor_assert(addr && src);
if (src[0] == '[' && src[1])
src = tmp = tor_strndup(src+1, strlen(src)-2);
if (tor_inet_pton(AF_INET6, src, &addr->addr.in6_addr) > 0) {
result = addr->family = AF_INET6;
} else if (tor_inet_pton(AF_INET, src, &addr->addr.in_addr) > 0) {
result = addr->family = AF_INET;
if (tor_inet_pton(AF_INET6, src, &in6_tmp) > 0) {
result = AF_INET6;
tor_addr_from_in6(addr, &in6_tmp);
} else if (tor_inet_pton(AF_INET, src, &in_tmp) > 0) {
result = AF_INET;
tor_addr_from_in(addr, &in_tmp);
} else {
result = -1;
}
......
......@@ -157,6 +157,8 @@ void tor_addr_from_ipv4n(tor_addr_t *dest, uint32_t v4addr);
#define tor_addr_from_ipv4h(dest, v4addr) \
tor_addr_from_ipv4n((dest), htonl(v4addr))
void tor_addr_from_ipv6_bytes(tor_addr_t *dest, const char *bytes);
#define tor_addr_from_in(dest, in) \
tor_addr_from_ipv4n((dest), (in)->s_addr);
void tor_addr_from_in6(tor_addr_t *dest, const struct in6_addr *in6);
int tor_addr_is_null(const tor_addr_t *addr);
int tor_addr_is_loopback(const tor_addr_t *addr);
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment