From 0c5166ac399e4d1c72d68926b1a6b72de09afef1 Mon Sep 17 00:00:00 2001 From: Benau Date: Mon, 19 Aug 2019 14:38:26 +0800 Subject: [PATCH] Add getaddrinfo_compat for workaround of an iOS 9 bug --- src/network/unix_ipv6.cpp | 73 +++++++++++++++++++++++++++++++++++---- src/network/unix_ipv6.hpp | 4 +++ 2 files changed, 70 insertions(+), 7 deletions(-) diff --git a/src/network/unix_ipv6.cpp b/src/network/unix_ipv6.cpp index a62372db5..e60ea70fc 100644 --- a/src/network/unix_ipv6.cpp +++ b/src/network/unix_ipv6.cpp @@ -15,6 +15,72 @@ // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +#ifdef WIN32 +#include "ws2tcpip.h" +#else +#include +#include +#include +#include +#include +#include +#endif + +// ---------------------------------------------------------------------------- +/** Workaround of a bug in iOS 9 where port number is not written. */ +extern "C" int getaddrinfo_compat(const char* hostname, + const char* servname, + const struct addrinfo* hints, + struct addrinfo** res) +{ +#ifdef IOS_STK + int err; + int numericPort; + + // If we're given a service name and it's a numeric string, + // set `numericPort` to that, otherwise it ends up as 0. + numericPort = servname != NULL ? atoi(servname) : 0; + + // Call `getaddrinfo` with our input parameters. + err = getaddrinfo(hostname, servname, hints, res); + + // Post-process the results of `getaddrinfo` to work around + if ((err == 0) && (numericPort != 0)) + { + for (const struct addrinfo* addr = *res; addr != NULL; + addr = addr->ai_next) + { + in_port_t* portPtr; + switch (addr->ai_family) + { + case AF_INET: + { + portPtr = &((struct sockaddr_in*)addr->ai_addr)->sin_port; + } + break; + case AF_INET6: + { + portPtr = &((struct sockaddr_in6*)addr->ai_addr)->sin6_port; + } + break; + default: + { + portPtr = NULL; + } + break; + } + if ((portPtr != NULL) && (*portPtr == 0)) + { + *portPtr = htons(numericPort); + } + } + } + return err; +#else + return getaddrinfo(hostname, servname, hints, res); +#endif +} + #ifndef ENABLE_IPV6 #include "network/unix_ipv6.hpp" // ---------------------------------------------------------------------------- @@ -37,13 +103,6 @@ std::string getIPV6ReadableFromMappedAddress(const ENetAddress* ea) #include "utils/log.hpp" #include "utils/types.hpp" -#include -#include -#include -#include -#include -#include - #include #include #include diff --git a/src/network/unix_ipv6.hpp b/src/network/unix_ipv6.hpp index 0203418ff..4903443b8 100644 --- a/src/network/unix_ipv6.hpp +++ b/src/network/unix_ipv6.hpp @@ -27,7 +27,11 @@ void unixInitialize(); void removeMappedAddress(const ENetAddress* ea); void getIPV6FromMappedAddress(const ENetAddress* ea, struct sockaddr_in6* in6); void getMappedFromIPV6(const struct sockaddr_in6* in6, ENetAddress* ea); +void addMappedAddress(const ENetAddress* ea, const struct sockaddr_in6* in6); +int getaddrinfo_compat(const char* hostname, const char* servname, + const struct addrinfo* hints, struct addrinfo** res); #ifdef __cplusplus } #endif std::string getIPV6ReadableFromMappedAddress(const ENetAddress* ea); +std::string getIPV6ReadableFromIn6(const struct sockaddr_in6* in);