]> git.ipfire.org Git - thirdparty/tvheadend.git/commitdiff
Simplify IPv6 compare functions to unconfuse gcc compiler
authorDavid Kalnischkies <david@kalnischkies.de>
Thu, 3 Nov 2022 22:53:30 +0000 (23:53 +0100)
committerFlole998 <Flole998@users.noreply.github.com>
Mon, 21 Nov 2022 01:33:44 +0000 (02:33 +0100)
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

index ea210600bd6cb803454072ba863176913e335ba2..726dfaeba31ed136797967d02a9ff68e0600742e 100644 (file)
--- 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) :