From 934ff535d69c36e76e6a7775735f57161d9b771c Mon Sep 17 00:00:00 2001 From: Jeroen Koekkoek Date: Thu, 3 Jan 2019 10:05:30 +0100 Subject: [PATCH] Cleanup socket functions a bit Signed-off-by: Jeroen Koekkoek --- src/os/include/os/os_socket.h | 31 +++---- src/os/src/os_socket.c | 147 +++++++--------------------------- src/os/tests/ifaddrs.c | 10 ++- 3 files changed, 50 insertions(+), 138 deletions(-) diff --git a/src/os/include/os/os_socket.h b/src/os/include/os/os_socket.h index cb59f93..c10b6eb 100644 --- a/src/os/include/os/os_socket.h +++ b/src/os/include/os/os_socket.h @@ -237,7 +237,23 @@ extern "C" { os_sockaddr_is_unspecified( const os_sockaddr *const sa) __nonnull_all__; - /* docced in implementation file */ + /** + * Check this address to see if it represents loopback. + * @return true if it does. false otherwise, or if unknown address type. + * @param thisSock A pointer to an os_sockaddr to be checked. + */ + OSAPI_EXPORT int + os_sockaddr_is_loopback( + _In_ const os_sockaddr *__restrict sa) __nonnull_all__; + + /** + * Checks two socket IP host addresses for be on the same subnet, considering the given subnetmask. + * It will not consider the possibility of IPv6 mapped IPv4 addresses or anything arcane like that. + * @param thisSock First address + * @param thatSock Second address. + * @param mask Subnetmask. + * @return true if equal, false otherwise. + */ OSAPI_EXPORT bool os_sockaddrSameSubnet(const os_sockaddr* thisSock, const os_sockaddr* thatSock, @@ -321,19 +337,6 @@ extern "C" { _Out_writes_z_(size) char *buf, _In_ size_t size); - /* docced in implementation file */ - OSAPI_EXPORT bool - os_sockaddrIsLoopback(const os_sockaddr* thisSock); - - /** - * Sets the address of the sockaddr to the special IN_ADDR_ANY value. - * @param sa the sockaddr to set the address for - * @pre sa is a valid sockaddr pointer - * @post Address of sa is set to the special IN_ADDR_ANY value - */ - OSAPI_EXPORT void - os_sockaddrSetInAddrAny(os_sockaddr* sa); - /** * @} */ diff --git a/src/os/src/os_socket.c b/src/os/src/os_socket.c index 71105ce..8461755 100644 --- a/src/os/src/os_socket.c +++ b/src/os/src/os_socket.c @@ -96,81 +96,44 @@ uint16_t os_sockaddr_get_port(const os_sockaddr *const sa) return port; } -static int os_sockaddr_compare( - const os_sockaddr *const sa1, - const os_sockaddr *const sa2) +int +os_sockaddr_is_unspecified( + _In_ const os_sockaddr *__restrict sa) { - int eq; - size_t sz; - - if ((eq = sa1->sa_family - sa2->sa_family) == 0) { - switch(sa1->sa_family) { -#if (OS_SOCKET_HAS_IPV6 == 1) - case AF_INET6: - { - os_sockaddr_in6 *sin61, *sin62; - sin61 = (os_sockaddr_in6 *)sa1; - sin62 = (os_sockaddr_in6 *)sa2; - sz = sizeof(sin61->sin6_addr); - eq = memcmp(&sin61->sin6_addr, &sin62->sin6_addr, sz); - } - break; -#endif /* OS_SOCKET_HAS_IPV6 */ -#ifdef __linux - case AF_PACKET: - { - struct sockaddr_ll *sll1, *sll2; - sll1 = (struct sockaddr_ll *)sa1; - sll2 = (struct sockaddr_ll *)sa2; - sz = sizeof(sll1->sll_addr); - eq = memcmp(sll1->sll_addr, sll2->sll_addr, sz); - } - break; -#endif /* __linux */ - default: - { - assert(sa1->sa_family == AF_INET); - os_sockaddr_in *sin1, *sin2; - sin1 = (os_sockaddr_in *)sa1; - sin2 = (os_sockaddr_in *)sa2; - sz = sizeof(sin1->sin_addr); - eq = memcmp(&sin1->sin_addr, &sin2->sin_addr, sz); - } - break; - } - } - - return eq; -} - -int os_sockaddr_is_unspecified(const os_sockaddr *const sa) -{ - int unspec = 0; - assert(sa != NULL); switch(sa->sa_family) { -#if (OS_SOCKET_HAS_IPV6 == 1) +#if OS_SOCKET_HAS_IPV6 case AF_INET6: - unspec = IN6_IS_ADDR_UNSPECIFIED(&((os_sockaddr_in6*)sa)->sin6_addr); - break; + return IN6_IS_ADDR_UNSPECIFIED(&((os_sockaddr_in6*)sa)->sin6_addr); #endif case AF_INET: - unspec = (((os_sockaddr_in *)sa)->sin_addr.s_addr == 0); - break; + return (((os_sockaddr_in *)sa)->sin_addr.s_addr == 0); } - return unspec; + return 0; +} + +int +os_sockaddr_is_loopback( + _In_ const os_sockaddr *__restrict sa) +{ + assert(sa != NULL); + + switch (sa->sa_family) { +#if OS_SOCKET_HAS_IPV6 + case AF_INET6: + return IN6_IS_ADDR_LOOPBACK( + ((const os_sockaddr_in6 *)sa)->sin6_addr); +#endif /* OS_SOCKET_HAS_IPV6 */ + case AF_INET: + return (((const os_sockaddr_in *)sa)->sin_addr.s_addr + == htonl(INADDR_LOOPBACK)); + } + + return 0; } -/** -* Checks two socket IP host addresses for be on the same subnet, considering the given subnetmask. -* It will not consider the possibility of IPv6 mapped IPv4 addresses or anything arcane like that. -* @param thisSock First address -* @param thatSock Second address. -* @param mask Subnetmask. -* @return true if equal, false otherwise. -*/ bool os_sockaddrSameSubnet(const os_sockaddr* thisSock, const os_sockaddr* thatSock, @@ -306,59 +269,3 @@ os_sockaddrtostr( return err; } - -/** -* Check this address to see if it represents loopback. -* @return true if it does. false otherwise, or if unknown address type. -* @param thisSock A pointer to an os_sockaddr to be checked. -*/ -bool -os_sockaddrIsLoopback(const os_sockaddr* thisSock) -{ - bool result = false; - -#if (OS_SOCKET_HAS_IPV6 == 1) - static os_sockaddr_storage linkLocalLoopback; - static os_sockaddr* linkLocalLoopbackPtr = NULL; - - if (linkLocalLoopbackPtr == NULL) - { - /* Initialise once (where 'once' implies some small integer) */ - os_sockaddrfromstr(AF_INET6, "fe80::1", (os_sockaddr*) &linkLocalLoopback); - linkLocalLoopbackPtr = (os_sockaddr*) &linkLocalLoopback; - } - - if (thisSock->sa_family == AF_INET6) - { - result = IN6_IS_ADDR_LOOPBACK(&((os_sockaddr_in6*)thisSock)->sin6_addr) || - os_sockaddr_compare(thisSock, linkLocalLoopbackPtr) == 0 ? true : false; - } - else -#endif - if (thisSock->sa_family == AF_INET) - { - result = (INADDR_LOOPBACK == ntohl(((os_sockaddr_in*)thisSock)->sin_addr.s_addr)) ? true : false; - } - - return result; -} - -void -os_sockaddrSetInAddrAny( - os_sockaddr* sa) -{ - assert(sa); -#if (OS_SOCKET_HAS_IPV6 == 1) - assert(sa->sa_family == AF_INET6 || sa->sa_family == AF_INET); - if (sa->sa_family == AF_INET6){ - ((os_sockaddr_in6*)sa)->sin6_addr = os_in6addr_any; - ((os_sockaddr_in6*)sa)->sin6_scope_id = 0; - } - else -#else - assert(sa->sa_family == AF_INET); -#endif - if (sa->sa_family == AF_INET){ - ((os_sockaddr_in*)sa)->sin_addr.s_addr = htonl(INADDR_ANY); - } -} diff --git a/src/os/tests/ifaddrs.c b/src/os/tests/ifaddrs.c index e978f29..f71c3b0 100644 --- a/src/os/tests/ifaddrs.c +++ b/src/os/tests/ifaddrs.c @@ -134,10 +134,12 @@ CU_Test(os_getifaddrs, ipv6) CU_ASSERT_EQUAL(ifa->addr->sa_family, AF_INET6); if (ifa->addr->sa_family == AF_INET6) { have_ipv6 = 1; - if (ifa->flags & IFF_LOOPBACK) { - CU_ASSERT(os_sockaddrIsLoopback(ifa->addr)); - } else { - CU_ASSERT(!os_sockaddrIsLoopback(ifa->addr)); + /* macOS assigns a link-local address to the loopback + interface, so the loopback address must be assigned to the + loopback interface, but the loopback interface can have + addresses other than the loopback address assigned. */ + if (os_sockaddr_is_loopback(ifa->addr)) { + CU_ASSERT(ifa->flags & IFF_LOOPBACK); } } }