From: David Kalnischkies Date: Thu, 3 Nov 2022 22:53:30 +0000 (+0100) Subject: Simplify IPv6 compare functions to unconfuse gcc compiler X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=c0f616e;p=thirdparty%2Ftvheadend.git Simplify IPv6 compare functions to unconfuse gcc compiler 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. --- 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) :