From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Dominika Liberda <ja@sdomi.pl>
Date: Sun, 2 Jul 2023 06:13:05 +0200
Subject: [PATCH] Remove IPv6 support

---
 CMakeLists.txt                              |   2 +-
 lib/enet/unix.c                             |   5 +-
 src/network/network_config.cpp              |  24 +-
 src/network/network_console.cpp             |   1 +
 src/network/protocols/connect_to_server.cpp |  22 +-
 src/network/protocols/server_lobby.cpp      |  17 +-
 src/network/servers_manager.cpp             |   8 +-
 src/network/socket_address.cpp              |  57 +--
 src/network/stk_host.cpp                    |   4 +-
 src/network/stk_ipv6.cpp                    | 514 --------------------
 10 files changed, 27 insertions(+), 627 deletions(-)
 delete mode 100644 src/network/stk_ipv6.cpp

diff --git a/CMakeLists.txt b/CMakeLists.txt
index 98dd5dcaef4547717f92440b269216b8994a29f0..c71db3253748c169eedb855cc0374c051eea95e4 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -30,7 +30,7 @@ option(CHECK_ASSETS "Check if assets are installed in ../stk-assets" ON)
 option(USE_SYSTEM_ANGELSCRIPT "Use system angelscript instead of built-in angelscript. If you enable this option, make sure to use a compatible version." OFF)
 option(USE_SYSTEM_ENET "Use system ENet instead of the built-in version, when available." ON)
 CMAKE_DEPENDENT_OPTION(USE_IPV6 "Allow create or connect to game server with IPv6 address, system enet will not be used." ON
-  "NOT USE_SWITCH" OFF)
+  "NOT USE_SWITCH;NOT MINERVA" OFF)
 option(USE_SYSTEM_WIIUSE "Use system WiiUse instead of the built-in version, when available." OFF)
 option(USE_SQLITE3 "Use sqlite to manage server stats and ban list." ON)
 
diff --git a/lib/enet/unix.c b/lib/enet/unix.c
index c10a3d99d998abac64b2c4dce17c45728cabaf12..1cadc204a9a167e02f9f8d445ec42f524a1fd815 100644
--- a/lib/enet/unix.c
+++ b/lib/enet/unix.c
@@ -64,7 +64,10 @@ typedef int socklen_t;
 static enet_uint32 timeBase = 0;
 
 // Global variable handled by STK
-extern int isIPv6Socket(void);
+//extern int isIPv6Socket(void);
+int isIPv6Socket(void) {
+	return 0;
+}
 
 int
 enet_initialize (void)
diff --git a/src/network/network_config.cpp b/src/network/network_config.cpp
index 6d3f676cfb85de47403b944af43e76fa1f70d769..088bebd0a661170806d0d6cbf4f8a72ced612b4e 100644
--- a/src/network/network_config.cpp
+++ b/src/network/network_config.cpp
@@ -103,31 +103,19 @@ void NetworkConfig::initSystemIP()
         return;
     }
     ENetAddress eaddr = {};
-    setIPv6Socket(0);
+    //setIPv6Socket(0);
     auto ipv4 = std::unique_ptr<Network>(new Network(1, 1, 0, 0, &eaddr));
-    setIPv6Socket(1);
+    //setIPv6Socket(1);
     auto ipv6 = std::unique_ptr<Network>(new Network(1, 1, 0, 0, &eaddr));
-    setIPv6Socket(0);
+    //setIPv6Socket(0);
     if (ipv4 && ipv4->getENetHost())
         m_system_ipv4 = true;
-    if (ipv6 && ipv6->getENetHost())
-        m_system_ipv6 = true;
+    //if (ipv6 && ipv6->getENetHost())
+    //    m_system_ipv6 = true;
     // If any 1 of them is missing set default network setting accordingly
-    if (!m_system_ipv4)
-    {
-        Log::warn("NetworkConfig", "System doesn't support IPv4");
-        if (m_system_ipv6)
-        {
-            UserConfigParams::m_ipv6_lan = true;
-            ServerConfig::m_ipv6_connection = true;
-        }
-    }
-    else if (!m_system_ipv6)
-    {
-        Log::warn("NetworkConfig", "System doesn't support IPv6");
+
         UserConfigParams::m_ipv6_lan = false;
         ServerConfig::m_ipv6_connection = false;
-    }
     enet_deinitialize();
 }   // initSystemIP
 
diff --git a/src/network/network_console.cpp b/src/network/network_console.cpp
index 502ed5fcdffc27b167e14770a47254d7a5e18a20..2fe7e3282c6f48a61763c1e3a4b2b5a2d059fd92 100644
--- a/src/network/network_console.cpp
+++ b/src/network/network_console.cpp
@@ -26,6 +26,7 @@
 #include "utils/time.hpp"
 #include "utils/vs.hpp"
 #include "main_loop.hpp"
+#include <sys/select.h>
 
 #include <iostream>
 #include <limits>
diff --git a/src/network/protocols/connect_to_server.cpp b/src/network/protocols/connect_to_server.cpp
index 598273c2a7094b2928828dfa2d10fbee678909b5..d3a4bc2952adc491f7e9393490db866f5b44d0b6 100644
--- a/src/network/protocols/connect_to_server.cpp
+++ b/src/network/protocols/connect_to_server.cpp
@@ -115,13 +115,6 @@ void ConnectToServer::setup()
         m_state = GOT_SERVER_ADDRESS;
         // For graphical client server the IPv6 socket is handled by server
         // process
-        if (!STKHost::get()->isClientServer())
-        {
-            if (m_server->useIPV6Connection())
-                setIPv6Socket(1);
-            else
-                setIPv6Socket(0);
-        }
     }
     else
         m_state = SET_PUBLIC_ADDRESS;
@@ -243,19 +236,6 @@ void ConnectToServer::asynchronousUpdate()
             // the IPv4 address to NAT64 one in GOT_SERVER_ADDRESS
             bool ipv6_socket = m_server->useIPV6Connection() ||
                 NetworkConfig::get()->getIPType() == NetworkConfig::IP_V6_NAT64;
-            if (STKHost::get()->getNetwork()->isIPv6Socket() != ipv6_socket)
-            {
-                // Free the bound socket first
-                delete STKHost::get()->getNetwork();
-                setIPv6Socket(ipv6_socket ? 1 : 0);
-                ENetAddress addr = {};
-                addr.port = NetworkConfig::get()->getClientPort();
-                auto new_network = new Network(/*peer_count*/1,
-                    /*channel_limit*/EVENT_CHANNEL_COUNT,
-                    /*max_in_bandwidth*/0, /*max_out_bandwidth*/0, &addr,
-                    true/*change_port_if_bound*/);
-                STKHost::get()->replaceNetwork(new_network);
-            }
 
             if (m_server->supportsEncryption())
             {
@@ -416,7 +396,7 @@ int ConnectToServer::interceptCallback(ENetHost* host, ENetEvent* event)
 #if defined(ENABLE_IPV6) || defined(__SWITCH__)
         if (enet_ip_not_equal(host->receivedAddress.host, m_server_address.host) ||
 #else
-        if (host->receivedAddress.host != m_server_address.host ||
+        if (host->receivedAddress.host.p0 != m_server_address.host.p0 ||
 #endif
             host->receivedAddress.port != m_server_address.port)
         {
diff --git a/src/network/protocols/server_lobby.cpp b/src/network/protocols/server_lobby.cpp
index 2f05fbacb4026054e1dd3f9b9ede35faa529c796..535094cf6aba847259501675ec8303e62faa3156 100644
--- a/src/network/protocols/server_lobby.cpp
+++ b/src/network/protocols/server_lobby.cpp
@@ -120,7 +120,7 @@ static void upperIPv6SQL(sqlite3_context* context, int argc,
         sqlite3_result_int64(context, 0);
         return;
     }
-    sqlite3_result_int64(context, upperIPv6(ipv6));
+    //sqlite3_result_int64(context, upperIPv6(ipv6));
 }
 
 // ----------------------------------------------------------------------------
@@ -140,7 +140,7 @@ void insideIPv6CIDRSQL(sqlite3_context* context, int argc,
         sqlite3_result_int(context, 0);
         return;
     }
-    sqlite3_result_int(context, insideIPv6CIDR(ipv6_cidr, ipv6_in));
+    //sqlite3_result_int(context, insideIPv6CIDR(ipv6_cidr, ipv6_in));
 }   // insideIPv6CIDRSQL
 
 // ----------------------------------------------------------------------------
@@ -307,10 +307,7 @@ void ServerLobby::initDatabase()
             // Return zero to let caller return SQLITE_BUSY immediately
             return 0;
         }, NULL);
-    sqlite3_create_function(m_db, "insideIPv6CIDR", 2, SQLITE_UTF8, NULL,
-        &insideIPv6CIDRSQL, NULL, NULL);
-    sqlite3_create_function(m_db, "upperIPv6", 1, SQLITE_UTF8, NULL,
-        &upperIPv6SQL, NULL, NULL);
+    
     checkTableExists(ServerConfig::m_ip_ban_table, m_ip_ban_table_exists);
     checkTableExists(ServerConfig::m_ipv6_ban_table, m_ipv6_ban_table_exists);
     checkTableExists(ServerConfig::m_online_id_ban_table,
@@ -1035,13 +1032,7 @@ void ServerLobby::pollDatabase()
                         continue;
 
                     char* ipv6_cidr = data[0];
-                    if (insideIPv6CIDR(ipv6_cidr, ipv6.c_str()) == 1)
-                    {
-                        Log::info("ServerLobby",
-                            "Kick %s, reason: %s, description: %s",
-                            ipv6.c_str(), data[1], data[2]);
-                        p->kick();
-                    }
+                    
                 }
                 return 0;
             }, &peers, NULL);
diff --git a/src/network/servers_manager.cpp b/src/network/servers_manager.cpp
index 4187a319f7ae6535ef21b7dc9b1d6f3e546ef13d..8326ade484ad8d4e7cbf862884474ae6d105605f 100644
--- a/src/network/servers_manager.cpp
+++ b/src/network/servers_manager.cpp
@@ -225,13 +225,11 @@ std::shared_ptr<ServerList> ServersManager::getLANRefreshRequest() const
                 return;
 
             ENetAddress addr = {};
-            setIPv6Socket(UserConfigParams::m_ipv6_lan ? 1 : 0);
-            NetworkConfig::get()->setIPType(UserConfigParams::m_ipv6_lan ?
-                NetworkConfig::IP_DUAL_STACK : NetworkConfig::IP_V4);
+            //setIPv6Socket(UserConfigParams::m_ipv6_lan ? 1 : 0);
+            NetworkConfig::get()->setIPType(NetworkConfig::IP_V4);
             Network *broadcast = new Network(1, 1, 0, 0, &addr);
             if (!broadcast->getENetHost())
             {
-                setIPv6Socket(0);
                 m_success = true;
                 delete broadcast;
                 server_list->m_list_updated = true;
@@ -309,7 +307,7 @@ std::shared_ptr<ServerList> ServersManager::getLANRefreshRequest() const
                     //all_servers.[name] = servers_now.back();
                 }   // if received_data
             }    // while still waiting
-            setIPv6Socket(0);
+         
             delete broadcast;
             m_success = true;
             for (auto& i : servers_now)
diff --git a/src/network/socket_address.cpp b/src/network/socket_address.cpp
index affd7e81cabf71df4a3df6b9e99d8a3c188fbfd3..1fb7a6bebedc48d042f80481a11b24762088b106 100644
--- a/src/network/socket_address.cpp
+++ b/src/network/socket_address.cpp
@@ -104,7 +104,7 @@ SocketAddress::SocketAddress(const ENetAddress& ea)
 #ifdef __SWITCH__
     setIP(htonl(ea.host.p0));
 #else
-    setIP(htonl(ea.host));
+    setIP(htonl(ea.host.p0));
 #endif
     setPort(ea.port);
 #endif
@@ -190,7 +190,7 @@ void SocketAddress::init(const std::string& str, uint16_t port_number,
     hints.ai_family = family;
     hints.ai_socktype = SOCK_STREAM;
 
-    int status = getaddrinfo_compat(addr_str.c_str(), port_str.c_str(), &hints,
+    int status = getaddrinfo(addr_str.c_str(), port_str.c_str(), &hints,
         &res);
     if (status != 0)
     {
@@ -235,15 +235,6 @@ void SocketAddress::init(const std::string& str, uint16_t port_number,
             found = true;
             break;
         case AF_INET6:
-            if (ipv4_mapped ||
-                !isIPv4MappedAddress((const struct sockaddr_in6*)addr->ai_addr))
-            {
-                // OSX and iOS can return AF_INET6 with ::ffff:x.y.z.w for server
-                // with A record, skip them and make it only get real AAAA record
-                m_family = AF_INET6;
-                memcpy(m_sockaddr.data(), addr->ai_addr, sizeof(sockaddr_in6));
-                found = true;
-            }
             break;
         default:
             break;
@@ -259,14 +250,7 @@ void SocketAddress::init(const std::string& str, uint16_t port_number,
  *  address too. */
 uint32_t SocketAddress::getIP() const
 {
-    if (m_family == AF_INET6)
-    {
-        sockaddr_in6* in6 = (sockaddr_in6*)m_sockaddr.data();
-        if (isIPv4MappedAddress(in6))
-            return ntohl(((in_addr*)(in6->sin6_addr.s6_addr + 12))->s_addr);
-        return 0;
-    }
-    else if (m_family == AF_INET)
+	if (m_family == AF_INET)
     {
         sockaddr_in* in = (sockaddr_in*)m_sockaddr.data();
         return ntohl(in->sin_addr.s_addr);
@@ -369,11 +353,6 @@ bool SocketAddress::isPublicAddressLocalhost() const
             memcpy(&addr, p->ifa_addr, sizeof(sockaddr_in6));
             sockaddr_in6* my_in6 = (sockaddr_in6*)m_sockaddr.data();
             addr.sin6_port = my_in6->sin6_port;
-            if (sameIPV6(my_in6, &addr))
-            {
-                is_local_host = true;
-                break;
-            }
         }
     }
     freeifaddrs(addresses);
@@ -433,11 +412,6 @@ bool SocketAddress::isPublicAddressLocalhost() const
                 memcpy(&addr, unicast->Address.lpSockaddr, sizeof(sockaddr_in6));
                 sockaddr_in6* my_in6 = (sockaddr_in6*)m_sockaddr.data();
                 addr.sin6_port = my_in6->sin6_port;
-                if (sameIPV6(my_in6, &addr))
-                {
-                    is_local_host = true;
-                    break;
-                }
             }
         }
     }
@@ -538,12 +512,7 @@ bool SocketAddress::operator==(const SocketAddress& other) const
         return in_a->sin_addr.s_addr == in_b->sin_addr.s_addr &&
             in_a->sin_port == in_b->sin_port;
     }
-    else if (m_family == AF_INET6 && other.m_family == AF_INET6)
-    {
-        sockaddr_in6* in6_a = (sockaddr_in6*)m_sockaddr.data();
-        sockaddr_in6* in6_b = (sockaddr_in6*)(other.m_sockaddr.data());
-        return sameIPV6(in6_a, in6_b);
-    }
+    
     return false;
 }   // operator==
 
@@ -558,12 +527,6 @@ bool SocketAddress::operator!=(const SocketAddress& other) const
         return in_a->sin_addr.s_addr != in_b->sin_addr.s_addr ||
             in_a->sin_port != in_b->sin_port;
     }
-    else if (m_family == AF_INET6 && other.m_family == AF_INET6)
-    {
-        sockaddr_in6* in6_a = (sockaddr_in6*)m_sockaddr.data();
-        sockaddr_in6* in6_b = (sockaddr_in6*)(other.m_sockaddr.data());
-        return !sameIPV6(in6_a, in6_b);
-    }
     return true;
 }   // operator!=
 
@@ -580,16 +543,6 @@ std::string SocketAddress::toString(bool show_port) const
         if (show_port)
             result += ":" + StringUtils::toString(getPort());
     }
-    else
-    {
-        result = getIPV6ReadableFromIn6((sockaddr_in6*)m_sockaddr.data());
-        if (show_port)
-        {
-            result.insert (0, 1, '[');
-            result += "]";
-            result += ":" + StringUtils::toString(getPort());
-        }
-    }
     return result;
 }   // toString
 
@@ -769,7 +722,7 @@ ENetAddress SocketAddress::toENetAddress() const
             ((ip & 0x000000ff) << 24);
     }
 #else
-    ea.host = ((ip & 0xff000000) >> 24) +
+    ea.host.p0 = ((ip & 0xff000000) >> 24) +
         ((ip & 0x00ff0000) >> 8) + ((ip & 0x0000ff00) << 8) +
         ((ip & 0x000000ff) << 24);
 #endif
diff --git a/src/network/stk_host.cpp b/src/network/stk_host.cpp
index 9cfec4adc3ec2240ecfce6b5a149363e82548d48..961e5ff79725cf66cd60ea42263427fa99b381d9 100644
--- a/src/network/stk_host.cpp
+++ b/src/network/stk_host.cpp
@@ -265,7 +265,7 @@ STKHost::STKHost(bool server)
     ENetAddress addr = {};
     if (server)
     {
-        setIPv6Socket(ServerConfig::m_ipv6_connection ? 1 : 0);
+        
 #ifdef ENABLE_IPV6
         if (NetworkConfig::get()->getIPType() == NetworkConfig::IP_V4 &&
             ServerConfig::m_ipv6_connection)
@@ -1012,7 +1012,7 @@ void STKHost::mainLoop(ProcessType pt)
                 (enet_ip_not_equal(ea_peer_now.host, ea.host) &&
                 ea_peer_now.port != ea.port))
 #else
-                (ea_peer_now.host != ea.host && ea_peer_now.port != ea.port))
+                (ea_peer_now.host.p0 != ea.host.p0 && ea_peer_now.port != ea.port))
 #endif
             {
                 if (packet != NULL)
diff --git a/src/network/stk_ipv6.cpp b/src/network/stk_ipv6.cpp
deleted file mode 100644
index a91c9178caad0dc4fb2291d9d86d717c9cc78024..0000000000000000000000000000000000000000
--- a/src/network/stk_ipv6.cpp
+++ /dev/null
@@ -1,514 +0,0 @@
-//  SuperTuxKart - a fun racing game with go-kart
-//  Copyright (C) 2019 SuperTuxKart-Team
-//
-//  This program is free software; you can redistribute it and/or
-//  modify it under the terms of the GNU General Public License
-//  as published by the Free Software Foundation; either version 3
-//  of the License, or (at your option) any later version.
-//
-//  This program is distributed in the hope that it will be useful,
-//  but WITHOUT ANY WARRANTY; without even the implied warranty of
-//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-//  GNU General Public License for more details.
-//
-//  You should have received a copy of the GNU General Public License
-//  along with this program; if not, write to the Free Software
-//  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
-
-#include <string.h>
-#ifdef WIN32
-#ifdef __GNUC__
-#    include <ws2tcpip.h>    // Mingw / gcc on windows
-#    undef _WIN32_WINNT
-#    define _WIN32_WINNT 0x501
-#    include <winsock2.h>
-#    include <ws2tcpip.h>
-
-#else
-#    include <winsock2.h>
-#    include <in6addr.h>
-#    include <ws2tcpip.h>
-#endif
-
-#else
-
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#ifndef __SWITCH__
-#include <err.h>
-#endif
-#include <netdb.h>
-#include <sys/socket.h>
-#include <sys/types.h>
-#include <stdlib.h>
-#endif
-
-#include "network/network_config.hpp"
-#include <array>
-#include <string>
-#include <stddef.h>
-
-// ============================================================================
-// For Windows XP support
-#define IN6ADDRSZ       16
-#define INADDRSZ         4
-#define INT16SZ          2
-
-static int
-stk_inet_pton4(const char *src, unsigned char *dst)
-{
-    static const char digits[] = "0123456789";
-    int saw_digit, octets, ch;
-    unsigned char tmp[INADDRSZ], *tp;
-
-    saw_digit = 0;
-    octets = 0;
-    tp = tmp;
-    *tp = 0;
-    while((ch = *src++) != '\0')
-    {
-        const char *pch;
-
-        pch = strchr(digits, ch);
-        if(pch)
-        {
-            unsigned int val = *tp * 10 + (unsigned int)(pch - digits);
-
-            if(saw_digit && *tp == 0)
-                return (0);
-            if(val > 255)
-                return (0);
-            *tp = (unsigned char)val;
-            if(! saw_digit)
-            {
-                if(++octets > 4)
-                    return (0);
-                saw_digit = 1;
-            }
-        }
-        else if(ch == '.' && saw_digit)
-        {
-            if(octets == 4)
-                return (0);
-            *++tp = 0;
-            saw_digit = 0;
-        }
-        else
-            return (0);
-    }
-    if(octets < 4)
-        return (0);
-    memcpy(dst, tmp, INADDRSZ);
-    return (1);
-}
-
-static int
-stk_inet_pton6(const char *src, void *dest)
-{
-    unsigned char *dst = (unsigned char*)dest;
-    static const char xdigits_l[] = "0123456789abcdef",
-        xdigits_u[] = "0123456789ABCDEF";
-    unsigned char tmp[IN6ADDRSZ], *tp, *endp, *colonp;
-    const char *curtok;
-    int ch, saw_xdigit;
-    size_t val;
-
-    memset((tp = tmp), 0, IN6ADDRSZ);
-    endp = tp + IN6ADDRSZ;
-    colonp = NULL;
-    /* Leading :: requires some special handling. */
-    if(*src == ':')
-    {
-        if(*++src != ':')
-            return (0);
-    }
-    curtok = src;
-    saw_xdigit = 0;
-    val = 0;
-    while((ch = *src++) != '\0')
-    {
-        const char *xdigits;
-        const char *pch;
-
-        pch = strchr((xdigits = xdigits_l), ch);
-        if(!pch)
-            pch = strchr((xdigits = xdigits_u), ch);
-        if(pch != NULL)
-        {
-            val <<= 4;
-            val |= (pch - xdigits);
-            if(++saw_xdigit > 4)
-                return (0);
-            continue;
-        }
-        if(ch == ':')
-        {
-            curtok = src;
-            if(!saw_xdigit)
-            {
-                if(colonp)
-                    return (0);
-                colonp = tp;
-                continue;
-            }
-            if(tp + INT16SZ > endp)
-                return (0);
-            *tp++ = (unsigned char) ((val >> 8) & 0xff);
-            *tp++ = (unsigned char) (val & 0xff);
-            saw_xdigit = 0;
-            val = 0;
-            continue;
-        }
-        if(ch == '.' && ((tp + INADDRSZ) <= endp) &&
-            stk_inet_pton4(curtok, tp) > 0)
-        {
-            tp += INADDRSZ;
-            saw_xdigit = 0;
-            break;    /* '\0' was seen by stk_inet_pton4(). */
-        }
-        return (0);
-    }
-    if(saw_xdigit)
-    {
-        if(tp + INT16SZ > endp)
-            return (0);
-        *tp++ = (unsigned char) ((val >> 8) & 0xff);
-        *tp++ = (unsigned char) (val & 0xff);
-    }
-    if(colonp != NULL)
-    {
-        /*
-        * Since some memmove()'s erroneously fail to handle
-        * overlapping regions, we'll do the shift by hand.
-        */
-        const ptrdiff_t n = tp - colonp;
-        ptrdiff_t i;
-
-        if(tp == endp)
-            return (0);
-        for(i = 1; i <= n; i++)
-        {
-            *(endp - i) = *(colonp + n - i);
-            *(colonp + n - i) = 0;
-        }
-        tp = endp;
-    }
-    if(tp != endp)
-        return (0);
-    memcpy(dst, tmp, IN6ADDRSZ);
-    return (1);
-}
-
-// ============================================================================
-// Android STK seems to crash when using inet_ntop so we copy it from linux
-static const char *
-stk_inet_ntop4(const u_char *src, char *dst, socklen_t size)
-{
-    static const char fmt[] = "%u.%u.%u.%u";
-    char tmp[sizeof "255.255.255.255"];
-
-    if (sprintf(tmp, fmt, src[0], src[1], src[2], src[3]) >= (int)size)
-    {
-        return NULL;
-    }
-    return strcpy(dst, tmp);
-}
-
-static const char *
-stk_inet_ntop6(const uint8_t *src, char *dst, socklen_t size)
-{
-    /*
-    * Note that int32_t and int16_t need only be "at least" large enough
-    * to contain a value of the specified size.  On some systems, like
-    * Crays, there is no such thing as an integer variable with 16 bits.
-    * Keep this in mind if you think this function should have been coded
-    * to use pointer overlays.  All the world's not a VAX.
-    */
-    char tmp[sizeof "ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255"], *tp;
-    struct { int base, len; } best, cur;
-    std::array<uint32_t, 8> words;
-    int i;
-    /*
-    * Preprocess:
-    *        Copy the input (bytewise) array into a wordwise array.
-    *        Find the longest run of 0x00's in src[] for :: shorthanding.
-    */
-    words.fill(0);
-    for (i = 0; i < 16; i += 2)
-        words[i / 2] = ((uint32_t)src[i] << 8) | src[i + 1];
-    // Test for nat64 prefix (remove the possible IPv4 in the last 32bit)
-    std::array<uint32_t, 8> test_nat64 = words;
-    test_nat64[6] = 0;
-    test_nat64[7] = 0;
-
-    best.base = -1;
-    cur.base = -1;
-    best.len = 0;
-    cur.len = 0;
-    for (i = 0; i < 8; i++)
-    {
-        if (words[i] == 0)
-        {
-            if (cur.base == -1)
-                cur.base = i, cur.len = 1;
-            else
-                cur.len++;
-        }
-        else
-        {
-            if (cur.base != -1)
-            {
-                if (best.base == -1 || cur.len > best.len)
-                    best = cur;
-                cur.base = -1;
-            }
-        }
-    }
-    if (cur.base != -1)
-    {
-        if (best.base == -1 || cur.len > best.len)
-            best = cur;
-    }
-    if (best.base != -1 && best.len < 2)
-            best.base = -1;
-    /*
-    * Format the result.
-    */
-    tp = tmp;
-    for (i = 0; i < 8; i++)
-    {
-        /* Are we inside the best run of 0x00's? */
-        if (best.base != -1 && i >= best.base && i < (best.base + best.len))
-        {
-            if (i == best.base)
-                *tp++ = ':';
-            continue;
-        }
-        /* Are we following an initial run of 0x00s or any real hex? */
-        if (i != 0)
-            *tp++ = ':';
-        /* Is this address an encapsulated IPv4? */
-        if (i == 6 &&
-            ((best.base == 0 &&
-            (best.len == 6 || (best.len == 5 && words[5] == 0xffff))) ||
-            test_nat64 == NetworkConfig::get()->getNAT64PrefixData()))
-        {
-            if (!stk_inet_ntop4(src + 12, tp, sizeof tmp - (tp - tmp)))
-                return (NULL);
-            tp += strlen(tp);
-            break;
-        }
-        tp += sprintf(tp, "%x", words[i]);
-    }
-    /* Was it a trailing run of 0x00's? */
-    if (best.base != -1 && (best.base + best.len) == 8)
-        *tp++ = ':';
-    *tp++ = '\0';
-    /*
-     * Check for overflow, copy, and we're done.
-     */
-    if ((socklen_t)(tp - tmp) > size)
-    {
-        return NULL;
-    }
-    return strcpy(dst, tmp);
-}
-
-// ----------------------------------------------------------------------------
-bool isIPv4MappedAddress(const struct sockaddr_in6* in6)
-{
-    uint8_t w0 = in6->sin6_addr.s6_addr[0];
-    uint8_t w1 = in6->sin6_addr.s6_addr[1];
-    uint8_t w2 = in6->sin6_addr.s6_addr[2];
-    uint8_t w3 = in6->sin6_addr.s6_addr[3];
-    uint8_t w4 = in6->sin6_addr.s6_addr[4];
-    uint8_t w5 = in6->sin6_addr.s6_addr[5];
-    uint8_t w6 = in6->sin6_addr.s6_addr[6];
-    uint8_t w7 = in6->sin6_addr.s6_addr[7];
-    uint8_t w8 = in6->sin6_addr.s6_addr[8];
-    uint8_t w9 = in6->sin6_addr.s6_addr[9];
-    uint8_t w10 = in6->sin6_addr.s6_addr[10];
-    uint8_t w11 = in6->sin6_addr.s6_addr[11];
-    if (w0 == 0 && w1 == 0 && w2 == 0 && w3 == 0 && w4 == 0 &&
-        w5 == 0 && w6 == 0 && w7 == 0 && w8 == 0 && w9 == 0 &&
-        w10 == 0xff && w11 == 0xff)
-        return true;
-    return false;
-}   // isIPv4MappedAddress
-
-// ----------------------------------------------------------------------------
-std::string getIPV6ReadableFromIn6(const struct sockaddr_in6* in)
-{
-    std::string ipv6;
-    ipv6.resize(INET6_ADDRSTRLEN, 0);
-    stk_inet_ntop6(in->sin6_addr.s6_addr, &ipv6[0], INET6_ADDRSTRLEN);
-    size_t len = strlen(ipv6.c_str());
-    ipv6.resize(len);
-    return ipv6;
-}   // getIPV6ReadableFromIn6
-
-// ----------------------------------------------------------------------------
-bool sameIPV6(const struct sockaddr_in6* in_1, const struct sockaddr_in6* in_2)
-{
-    // Check port first, then address
-    if (in_1->sin6_port != in_2->sin6_port)
-        return false;
-
-    const struct in6_addr* a = &(in_1->sin6_addr);
-    const struct in6_addr* b = &(in_2->sin6_addr);
-    for (unsigned i = 0; i < sizeof(struct in6_addr); i++)
-    {
-        if (a->s6_addr[i] != b->s6_addr[i])
-            return false;
-    }
-    return true;
-}   // sameIPV6
-
-// ----------------------------------------------------------------------------
-/** 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
-}   // getaddrinfo_compat
-
-// ----------------------------------------------------------------------------
-void andIPv6(struct in6_addr* ipv6, const struct in6_addr* mask)
-{
-    for (unsigned i = 0; i < sizeof(struct in6_addr); i++)
-        ipv6->s6_addr[i] &= mask->s6_addr[i];
-}   // andIPv6
-
-// ----------------------------------------------------------------------------
-extern "C" int64_t upperIPv6(const char* ipv6)
-{
-    struct in6_addr v6_in;
-    if (stk_inet_pton6(ipv6, &v6_in) != 1)
-        return 0;
-    uint64_t result = 0;
-    unsigned shift = 56;
-    for (unsigned i = 0; i < 8; i++)
-    {
-        uint64_t val = v6_in.s6_addr[i];
-        result += val << shift;
-        shift -= 8;
-    }
-    return result;
-}
-
-// ----------------------------------------------------------------------------
-extern "C" int insideIPv6CIDR(const char* ipv6_cidr, const char* ipv6_in)
-{
-    const char* mask_location = strchr(ipv6_cidr, '/');
-    if (mask_location == NULL)
-        return 0;
-    struct in6_addr v6_in;
-    if (stk_inet_pton6(ipv6_in, &v6_in) != 1)
-        return 0;
-
-    char ipv6[INET6_ADDRSTRLEN] = {};
-    memcpy(ipv6, ipv6_cidr, mask_location - ipv6_cidr);
-    struct in6_addr cidr;
-    if (stk_inet_pton6(ipv6, &cidr) != 1)
-        return 0;
-
-    int mask_length = atoi(mask_location + 1);
-    if (mask_length > 128 || mask_length <= 0)
-        return 0;
-
-    struct in6_addr mask = {};
-    for (int i = mask_length, j = 0; i > 0; i -= 8, j++)
-    {
-        if (i >= 8)
-            mask.s6_addr[j] = 0xff;
-        else
-            mask.s6_addr[j] = (unsigned long)(0xffU << (8 - i));
-    }
-
-    andIPv6(&cidr, &mask);
-    andIPv6(&v6_in, &mask);
-    for (unsigned i = 0; i < sizeof(struct in6_addr); i++)
-    {
-        if (cidr.s6_addr[i] != v6_in.s6_addr[i])
-            return 0;
-    }
-    return 1;
-}   // andIPv6
-
-#ifndef ENABLE_IPV6
-// ----------------------------------------------------------------------------
-extern "C" int isIPv6Socket()
-{
-    return 0;
-}   // isIPV6
-
-// ----------------------------------------------------------------------------
-extern "C" void setIPv6Socket(int val)
-{
-}   // setIPV6
-
-#else
-#include <atomic>
-// ============================================================================
-// For client and server in same process using different thread
-std::atomic<int> g_ipv6(0);
-// ============================================================================
-extern "C" int isIPv6Socket()
-{
-    return g_ipv6.load();
-}   // isIPV6
-
-// ----------------------------------------------------------------------------
-extern "C" void setIPv6Socket(int val)
-{
-    g_ipv6.store(val);
-}   // setIPV6
-
-#endif
