From c0f616e56bc4df70978a060b72f8c6a7ca487d3f Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Thu, 3 Nov 2022 23:53:30 +0100 Subject: [PATCH] Simplify IPv6 compare functions to unconfuse gcc compiler MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit In file included from src/tcp.c:32: In function ‘ip_check_is_any_v6’, inlined from ‘ip_check_is_any’ at src/tcp.h:110:46, inlined from ‘ip_check_is_local_address’ at src/tcp.c:89:17: src/tcp.h:105:57: warning: array subscript 1 is outside array bounds of ‘const struct sockaddr_storage[0]’ [-Warray-bounds] 105 | { return ((uint64_t *)IP_AS_V6(address, addr).s6_addr)[0] == ((uint64_t *)(&in6addr_any.s6_addr))[0] && | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~ src/tcp.h: In function ‘ip_check_is_local_address’: src/tcp.h:108:19: note: at offset 8 into object ‘address’ of size 8 108 | static inline int ip_check_is_any(const struct sockaddr_storage *address) | ^~~~~~~~~~~~~~~ And more for the other half of the function and its three-times more or less copy-paste instances. sockaddr_storage is not an array, but what we actually do here is access s6_addr – which is an array of uint8_t. Accessing the 16 uint8_t as 2 uint64_t apparently works, but not doing it results in hopefully simpler to understand code for both humans and compilers alike. --- src/tcp.h | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/tcp.h b/src/tcp.h index ea210600b..726dfaeba 100644 --- a/src/tcp.h +++ b/src/tcp.h @@ -68,8 +68,7 @@ static inline int ip_check_equal_v4 static inline int ip_check_equal_v6 (const struct sockaddr_storage *a, const struct sockaddr_storage *b) - { return ((uint64_t *)IP_AS_V6(a, addr).s6_addr)[0] == ((uint64_t *)IP_AS_V6(b, addr).s6_addr)[0] && - ((uint64_t *)IP_AS_V6(a, addr).s6_addr)[1] == ((uint64_t *)IP_AS_V6(b, addr).s6_addr)[1]; } + { return memcmp(IP_AS_V6(a, addr).s6_addr, IP_AS_V6(b, addr).s6_addr, sizeof(IP_AS_V6(a, addr).s6_addr)) == 0; } static inline int ip_check_equal (const struct sockaddr_storage *a, const struct sockaddr_storage *b) @@ -86,10 +85,12 @@ static inline int ip_check_in_network_v4(const struct sockaddr_storage *network, static inline int ip_check_in_network_v6(const struct sockaddr_storage *network, const struct sockaddr_storage *mask, const struct sockaddr_storage *address) - { return (((uint64_t *)IP_AS_V6(address, addr).s6_addr)[0] & ((uint64_t *)IP_AS_V6(mask, addr).s6_addr)[0]) == - (((uint64_t *)IP_AS_V6(network, addr).s6_addr)[0] & ((uint64_t *)IP_AS_V6(mask, addr).s6_addr)[0]) && - (((uint64_t *)IP_AS_V6(address, addr).s6_addr)[0] & ((uint64_t *)IP_AS_V6(mask, addr).s6_addr)[1]) == - (((uint64_t *)IP_AS_V6(network, addr).s6_addr)[1] & ((uint64_t *)IP_AS_V6(mask, addr).s6_addr)[1]); } + { + for (short i = 0; i < sizeof(IP_AS_V6(address, addr).s6_addr); ++i) + if (((IP_AS_V6(address, addr).s6_addr)[i] & (IP_AS_V6(mask, addr).s6_addr)[i]) != ((IP_AS_V6(network, addr).s6_addr)[i] & (IP_AS_V6(mask, addr).s6_addr)[i])) + return 0; + return 1; + } static inline int ip_check_in_network(const struct sockaddr_storage *network, const struct sockaddr_storage *mask, @@ -101,8 +102,7 @@ static inline int ip_check_is_any_v4(const struct sockaddr_storage *address) { return IP_AS_V4(address, addr).s_addr == INADDR_ANY; } static inline int ip_check_is_any_v6(const struct sockaddr_storage *address) - { return ((uint64_t *)IP_AS_V6(address, addr).s6_addr)[0] == ((uint64_t *)(&in6addr_any.s6_addr))[0] && - ((uint64_t *)IP_AS_V6(address, addr).s6_addr)[1] == ((uint64_t *)(&in6addr_any.s6_addr))[1]; } + { return memcmp(IP_AS_V6(address, addr).s6_addr, in6addr_any.s6_addr, sizeof(in6addr_any.s6_addr)) == 0; } static inline int ip_check_is_any(const struct sockaddr_storage *address) { return address->ss_family == AF_INET ? ip_check_is_any_v4(address) : -- 2.47.2