diff --git a/ChangeLog b/ChangeLog index 10adb2f744..8447f6c522 100644 --- a/ChangeLog +++ b/ChangeLog @@ -8,6 +8,8 @@ Changes in version 0.2.0.5-alpha - 2007-??-?? o Major bugfixes (compilation): - Try to fix win32 compilation again: Improve checking for ipv6 types. + - Try to fix MSVC compilation: build correctly on platforms that + do not define s6_addr16 or s6_addr32. - Fix compile on platforms without getaddrinfo: bug found by Li-Hui Zhou. diff --git a/src/common/compat.h b/src/common/compat.h index 9e3069d1fb..647e64c4b7 100644 --- a/src/common/compat.h +++ b/src/common/compat.h @@ -298,6 +298,16 @@ struct in6_addr typedef uint16_t sa_family_t; #endif +#ifndef _MSC_VER +/* Apparently, MSVC doesn't define s6_addr16 or s6_addr32. How dumb. */ +/* XXXX020 detect with autoconf. */ +#define S6_ADDR16(x) ((x).s6_addr16) +#define S6_ADDR32(x) ((x).s6_addr32) +#else +#define S6_ADDR16(x) ((uint16_t*)((char*)&(x).s6_addr)) +#define S6_ADDR32(x) ((uint32_t*)((char*)&(x).s6_addr)) +#endif + /* XXXX020 detect sockaddr_in6 correctly on ms_windows; this is also a hack. */ #if !defined(HAVE_STRUCT_SOCKADDR_IN6) && !defined(MS_WINDOWS) struct sockaddr_in6 { @@ -367,6 +377,9 @@ IN_PORT(const tor_addr_t *a) return a->sa6.sin6_port; } +#define IN6_ADDRESS16(x) S6_ADDR16(*IN6_ADDRESS(x)) +#define IN6_ADDRESS32(x) S6_ADDR32(*IN6_ADDRESS(x)) + #define INET_NTOA_BUF_LEN 16 /* 255.255.255.255 */ #define TOR_ADDR_BUF_LEN 46 /* ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255 */ diff --git a/src/common/util.c b/src/common/util.c index 006eeb68d6..81ba00b2bf 100644 --- a/src/common/util.c +++ b/src/common/util.c @@ -1876,15 +1876,15 @@ tor_addr_is_internal(const tor_addr_t *addr, int for_listening) } else if (v_family == AF_INET6) { if (tor_addr_is_v4(addr)) { /* v4-mapped */ v_family = AF_INET; - iph4 = ntohl(IN6_ADDRESS(addr)->s6_addr32[3]); + iph4 = ntohl(IN6_ADDRESS32(addr)[3]); } } if (v_family == AF_INET6) { - iph6[0] = ntohl(IN6_ADDRESS(addr)->s6_addr32[0]); - iph6[1] = ntohl(IN6_ADDRESS(addr)->s6_addr32[1]); - iph6[2] = ntohl(IN6_ADDRESS(addr)->s6_addr32[2]); - iph6[3] = ntohl(IN6_ADDRESS(addr)->s6_addr32[3]); + iph6[0] = ntohl(IN6_ADDRESS32(addr)[0]); + iph6[1] = ntohl(IN6_ADDRESS32(addr)[1]); + iph6[2] = ntohl(IN6_ADDRESS32(addr)[2]); + iph6[3] = ntohl(IN6_ADDRESS32(addr)[3]); if (for_listening && !iph6[0] && !iph6[1] && !iph6[2] && !iph6[3]) /* :: */ return 0; @@ -2396,9 +2396,9 @@ tor_addr_is_v4(const tor_addr_t *addr) return 1; if (IN_FAMILY(addr) == AF_INET6) { /* First two don't need to be ordered */ - if ((IN6_ADDRESS(addr)->s6_addr32[0] == 0) && - (IN6_ADDRESS(addr)->s6_addr32[1] == 0) && - (ntohl(IN6_ADDRESS(addr)->s6_addr32[2]) == 0x0000ffffu)) + if ((IN6_ADDRESS32(addr)[0] == 0) && + (IN6_ADDRESS32(addr)[1] == 0) && + (ntohl(IN6_ADDRESS32(addr)[2]) == 0x0000ffffu)) return 1; } @@ -2415,10 +2415,10 @@ tor_addr_is_null(const tor_addr_t *addr) switch (IN_FAMILY(addr)) { case AF_INET6: - return (!IN6_ADDRESS(addr)->s6_addr32[0] && - !IN6_ADDRESS(addr)->s6_addr32[1] && - !IN6_ADDRESS(addr)->s6_addr32[2] && - !IN6_ADDRESS(addr)->s6_addr32[3]); + return (!IN6_ADDRESS32(addr)[0] && + !IN6_ADDRESS32(addr)[1] && + !IN6_ADDRESS32(addr)[2] && + !IN6_ADDRESS32(addr)[3]); case AF_INET: return (!IN4_ADDRESS(addr)->s_addr); default: @@ -2540,8 +2540,8 @@ tor_addr_compare_masked(const tor_addr_t *addr1, const tor_addr_t *addr2, return 1; return 0; } else if (v_family[0] == AF_INET6) { /* Real IPv6 */ - const uint32_t *a1 = IN6_ADDRESS(addr1)->s6_addr32; - const uint32_t *a2 = IN6_ADDRESS(addr2)->s6_addr32; + const uint32_t *a1 = IN6_ADDRESS32(addr1); + const uint32_t *a2 = IN6_ADDRESS32(addr2); for (idx = 0; idx < 4; ++idx) { uint32_t masked_a = ntohl(a1[idx]); uint32_t masked_b = ntohl(a2[idx]); @@ -2633,7 +2633,7 @@ get_interface_address6(int severity, sa_family_t family, tor_addr_t *addr) sock = tor_open_socket(PF_INET6,SOCK_DGRAM,IPPROTO_UDP); my_addr_len = sizeof(struct sockaddr_in6); sin6->sin6_family = AF_INET6; - sin6->sin6_addr.s6_addr16[0] = htons(0x2002); /* 2002:: */ + S6_ADDR16(sin6->sin6_addr)[0] = htons(0x2002); /* 2002:: */ } else if (family == AF_INET) { struct sockaddr_in *sin = (struct sockaddr_in*)&target_addr; sock = tor_open_socket(PF_INET,SOCK_DGRAM,IPPROTO_UDP); diff --git a/src/or/test.c b/src/or/test.c index 2df0785f03..fbec7e87c1 100644 --- a/src/or/test.c +++ b/src/or/test.c @@ -1069,10 +1069,10 @@ _test_eq_ip6(struct in6_addr *a, struct in6_addr *b, const char *e1, * conventions of the other test macros. */ #define test_addr_parse_check(ip1, ip2, ip3, ip4, mm, pt1, pt2) STMT_BEGIN \ test_assert(r>=0); \ - test_eq(htonl(ip1), IN6_ADDRESS(&t1)->s6_addr32[0]); \ - test_eq(htonl(ip2), IN6_ADDRESS(&t1)->s6_addr32[1]); \ - test_eq(htonl(ip3), IN6_ADDRESS(&t1)->s6_addr32[2]); \ - test_eq(htonl(ip4), IN6_ADDRESS(&t1)->s6_addr32[3]); \ + test_eq(htonl(ip1), IN6_ADDRESS32(&t1)[0]); \ + test_eq(htonl(ip2), IN6_ADDRESS32(&t1)[1]); \ + test_eq(htonl(ip3), IN6_ADDRESS32(&t1)[2]); \ + test_eq(htonl(ip4), IN6_ADDRESS32(&t1)[3]); \ test_eq(mask, mm); \ test_eq(port1, pt1); \ test_eq(port2, pt2); \