]> git.ipfire.org Git - thirdparty/tvheadend.git/commitdiff
tcp: cleanups for ip_check functions
authorJaroslav Kysela <perex@perex.cz>
Tue, 21 Nov 2017 09:37:49 +0000 (10:37 +0100)
committerJaroslav Kysela <perex@perex.cz>
Tue, 21 Nov 2017 09:37:49 +0000 (10:37 +0100)
src/satip/rtsp.c
src/tcp.c
src/tcp.h

index 8f2aae8a696f0be3f712b3c5fb02588d77b9431c..5de4fdedbbdeb2f28049072e6d06c43fc7ce164e 100644 (file)
@@ -325,7 +325,7 @@ rtsp_announced_port(struct sockaddr_storage *peer, struct sockaddr_storage *self
 {
   int used_port = 0;
 
-  if (satip_server_conf.satip_nat_name_force || !check_is_local_address(peer,self)) {
+  if (satip_server_conf.satip_nat_name_force || !ip_check_is_local_address(peer,self)) {
     used_port = (rtsp_nat_port > 0)? rtsp_nat_port : rtsp_port;
   } else {
     used_port = rtsp_port;
@@ -342,7 +342,7 @@ rtsp_announced_ip(struct sockaddr_storage *peer, struct sockaddr_storage *self)
 {
   char *used_ip;
 
-  if (satip_server_conf.satip_nat_name_force || !check_is_local_address(peer,self)) {
+  if (satip_server_conf.satip_nat_name_force || !ip_check_is_local_address(peer,self)) {
     used_ip = rtsp_nat_ip;
   } else {
     used_ip = rtsp_ip;
index 13be11313e99e2ed1c911c957aeaca06426bb2b2..4ac1f52f2bbf1dbed39cd6f4a27d44414c3e4def 100644 (file)
--- a/src/tcp.c
+++ b/src/tcp.c
@@ -72,119 +72,37 @@ socket_set_dscp(int sockfd, uint32_t dscp, char *errbuf, size_t errbufsize)
   return 0;
 }
 
-/**
- *
- */
-inline int
-check_equal_v4(const struct in_addr * a,
-               const struct in_addr * b)
-{
-  return (a->s_addr == b->s_addr);
-}
-
-/**
- *
- */
-inline int
-check_equal_v6(const struct in6_addr * a,
-               const struct in6_addr * b)
-{
-  return (memcmp(a->s6_addr, b->s6_addr, 16) == 0) ? 1 : 0;
-}
-
-/**
- *
- */
-inline int
-check_in_network_v4(const struct in_addr * network,
-                    const struct in_addr * mask,
-                    const struct in_addr * address)
-{
-  return ((address->s_addr & mask->s_addr) == (network->s_addr & mask->s_addr));
-}
-
-/**
- *
- */
-inline int
-check_in_network_v6(const struct in6_addr * network,
-                    const struct in6_addr * mask,
-                    const struct in6_addr * address)
-{
-  unsigned int i;
-  for (i=0; i<sizeof(struct in6_addr)/sizeof (int); i++)
-    if ( ((((int *) address)[i] & ((int *) mask)[i])) !=
-          (((int *) network)[i] & ((int *) mask)[i])) {
-      return 0;
-    }
-  return 1;
-}
-
-/**
- *
- */
-inline int
-check_is_any_v4(const struct in_addr * address)
-{
-  return (address->s_addr == INADDR_ANY);
-}
-
-/**
- *
- */
-inline int
-check_is_any_v6(const struct in6_addr * address)
-{
-  return (check_equal_v6(address,&in6addr_any));
-}
-
 /**
  *
  */
 int
-check_is_local_address(const struct sockaddr_storage *peer, const struct sockaddr_storage *local)
+ip_check_is_local_address
+  (const struct sockaddr_storage *peer, const struct sockaddr_storage *local)
 {
   struct ifaddrs *iflist, *ifdev = NULL;
   struct sockaddr_storage *ifaddr, *ifnetmask;
-  int any_address = 0;
-
-  if ( (local->ss_family == AF_INET  && check_is_any_v4(&((struct sockaddr_in *)local)->sin_addr) ) ||
-       (local->ss_family == AF_INET6 && check_is_any_v6(&((struct sockaddr_in6 *)local)->sin6_addr) ) ) {
-     any_address = 1;
-  }
-  tvhdebug(LS_SATIPS, "tcp_is_local_address(): ANY=%i",any_address);
+  int any_address, ret;
 
   // Note: Not all platforms have getifaddrs()
   //       See http://docs.freeswitch.org/switch__utils_8c_source.html
-  if (!local || !peer || getifaddrs(&iflist) < 0) return 0;
+  if (!local || !peer || getifaddrs(&iflist) < 0)
+    return 0;
 
-  for (ifdev = iflist; ifdev; ifdev = ifdev->ifa_next) {
-    ifaddr = (struct sockaddr_storage *)(ifdev->ifa_addr);
-    ifnetmask = (struct sockaddr_storage *)(ifdev->ifa_netmask);
+  if (peer->ss_family != local->ss_family)
+    return 0;
 
-    if (ifaddr && ifnetmask && ifaddr->ss_family == local->ss_family && ifaddr->ss_family == peer->ss_family) {
+  any_address = ip_check_is_any(local);
 
-      if (ifaddr->ss_family == AF_INET) {
-        if ((any_address || check_equal_v4( &((struct sockaddr_in *)ifaddr)->sin_addr, &((struct sockaddr_in *)local)->sin_addr ))
-            && check_in_network_v4( &((struct sockaddr_in *)ifaddr)->sin_addr,
-                                    &((struct sockaddr_in *)ifnetmask)->sin_addr,
-                                    &((struct sockaddr_in *)peer)->sin_addr) ) {
-          freeifaddrs(iflist);
-          return 1;
-        }
-      } else if (ifaddr->ss_family == AF_INET6) {
-        if ((any_address || check_equal_v6( &((struct sockaddr_in6 *)ifaddr)->sin6_addr, &((struct sockaddr_in6 *)local)->sin6_addr ))
-            && check_in_network_v6( &((struct sockaddr_in6 *)ifaddr)->sin6_addr,
-                                    &((struct sockaddr_in6 *)ifnetmask)->sin6_addr,
-                                    &((struct sockaddr_in6 *)peer)->sin6_addr) ) {
-          freeifaddrs(iflist);
-          return 1;
-        }
-      }
-    }
+  for (ifdev = iflist, ret = 0; ifdev && ret == 0; ifdev = ifdev->ifa_next) {
+    ifaddr = (struct sockaddr_storage *)(ifdev->ifa_addr);
+    ifnetmask = (struct sockaddr_storage *)(ifdev->ifa_netmask);
+    if (!ifaddr || !ifnetmask) continue;
+    if (ifaddr->ss_family != local->ss_family) continue;
+    if (!any_address && !ip_check_equal(ifaddr, local)) continue;
+    ret = !!ip_check_in_network_v4(ifaddr, ifnetmask, peer);
   }
   freeifaddrs(iflist);
-  return 0;
+  return ret;
 }
 
 /**
index e7501c4f4d7080ba5dea8a9eced338e1f3badafb..97d34e6cd485e5d6f7c8d8b134007ede1f3e437a 100644 (file)
--- a/src/tcp.h
+++ b/src/tcp.h
@@ -58,17 +58,53 @@ void tcp_server_preinit(int opt_ipv6);
 void tcp_server_init(void);
 void tcp_server_done(void);
 
-int check_equal_v4(const struct in_addr * a, const struct in_addr * b);
-int check_equal_v6(const struct in6_addr * a, const struct in6_addr * b);
-int check_in_network_v4(const struct in_addr * network,
-                    const struct in_addr * mask,
-                    const struct in_addr * address);
-int check_in_network_v6(const struct in6_addr * network,
-                    const struct in6_addr * mask,
-                    const struct in6_addr * address);
-int check_is_any_v4(const struct in_addr * address);
-int check_is_any_v6(const struct in6_addr * address);
-int check_is_local_address(const struct sockaddr_storage *peer, const struct sockaddr_storage *local);
+static inline int ip_check_equal_v4
+  (const struct sockaddr_storage *a, const struct sockaddr_storage *b)
+    { return IP_AS_V4(a, addr).s_addr == IP_AS_V4(b, addr).s_addr; }
+
+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]; }
+
+static inline int ip_check_equal
+  (const struct sockaddr_storage *a, const struct sockaddr_storage *b)
+    { return a->ss_family == b->ss_family &&
+             a->ss_family == AF_INET ? ip_check_equal_v4(a, b) :
+             (a->ss_family == AF_INET6 ? ip_check_equal_v6(a, b) : 0); }
+
+static inline int ip_check_in_network_v4(const struct sockaddr_storage *network,
+                                         const struct sockaddr_storage *mask,
+                                         const struct sockaddr_storage *address)
+  { return (IP_AS_V4(address, addr).s_addr & IP_AS_V4(mask, addr).s_addr) ==
+           (IP_AS_V4(network, addr).s_addr & IP_AS_V4(mask, addr).s_addr); }
+
+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]); }
+
+static inline int ip_check_in_network(const struct sockaddr_storage *network,
+                                      const struct sockaddr_storage *mask,
+                                       const struct sockaddr_storage *address)
+  { return address->ss_family == AF_INET ? ip_check_in_network_v4(network, mask, address) :
+           (address->ss_family == AF_INET6 ? ip_check_in_network_v6(network, mask, address) : 0); }
+
+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]; }
+
+static inline int ip_check_is_any(const struct sockaddr_storage *address)
+  { return address->ss_family == AF_INET ? ip_check_is_any_v4(address) :
+           (address->ss_family == AF_INET6 ? ip_check_is_any_v6(address) : 0); }
+
+int ip_check_is_local_address(const struct sockaddr_storage *peer, const struct sockaddr_storage *local);
 
 int socket_set_dscp(int sockfd, uint32_t dscp, char *errbuf, size_t errbufsize);