more changes

This commit is contained in:
Dominika Liberda 2023-06-12 16:31:15 +02:00
parent a6c3ae24aa
commit d7dd2e12d9
34 changed files with 75 additions and 649 deletions

View file

@ -231,9 +231,9 @@ if((UNIX AND NOT APPLE) AND USE_SYSTEM_ENET AND NOT USE_IPV6)
pkg_check_modules(ENET libenet>=1.3.4)
endif()
if (USE_IPV6)
add_definitions(-DENABLE_IPV6)
endif()
#if (USE_IPV6)
# add_definitions(-DENABLE_IPV6)
#endif()
if(ENET_FOUND AND NOT USE_IPV6)
include_directories(${ENET_INCLUDE_DIRS})

View file

@ -38,9 +38,6 @@
#include <stdlib.h>
#if !defined(__APPLE__) && !defined(__SNC__) && !defined(__ghs__) && !defined(__FreeBSD__) && !defined(__OpenBSD__) && !defined(__DragonFly__)
#include <malloc.h>
#endif
#include "as_config.h"
#include "as_memory.h"

View file

@ -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)

View file

@ -7,6 +7,7 @@
#include <cstdint>
#include <string>
#include <unordered_set>
#include <stdexcept>
namespace irr
{

View file

@ -121,7 +121,6 @@ for user-defined purpose without allocating any real GPU memory.
See documentation chapter: \ref statistics.
*/
#ifdef __cplusplus
extern "C" {
#endif
@ -2562,6 +2561,7 @@ VMA_CALL_PRE void VMA_CALL_POST vmaFreeStatsString(
#ifdef VMA_IMPLEMENTATION
#undef VMA_IMPLEMENTATION
#include <cstdio>
#include <cstdint>
#include <cstdlib>
#include <cstring>

View file

@ -10,6 +10,7 @@
#include <algorithm>
#include <chrono>
#include <stdexcept>
namespace GE
{

View file

@ -4,6 +4,7 @@
#include "ge_vulkan_driver.hpp"
#include "ge_vulkan_features.hpp"
#include <stdexcept>
#include <algorithm>
namespace GE

View file

@ -9,6 +9,7 @@
#include <memory>
#include <mutex>
#include <thread>
#include <stdexcept>
#include "../source/Irrlicht/os.h"

View file

@ -1,5 +1,6 @@
#include "ge_vulkan_depth_texture.hpp"
#include <stdexcept>
#include "ge_main.hpp"
#include "ge_vulkan_driver.hpp"

View file

@ -25,6 +25,7 @@
#include <algorithm>
#include <cmath>
#include <limits>
#include <stdexcept>
#include "../source/Irrlicht/os.h"
#include "quaternion.h"

View file

@ -6,6 +6,7 @@
#include <array>
#include <exception>
#include <stdexcept>
namespace GE
{

View file

@ -2,6 +2,7 @@
#define HEADER_GE_VULKAN_FBO_TEXTURE_HPP
#include "ge_vulkan_texture.hpp"
#include <stdexcept>
namespace GE
{

View file

@ -12,6 +12,7 @@
#include <array>
#include <cstdint>
#include <unordered_map>
#include <stdexcept>
namespace GE
{

View file

@ -9,6 +9,7 @@
#include "ge_vulkan_command_loader.hpp"
#include "ge_vulkan_features.hpp"
#include "ge_vulkan_driver.hpp"
#include <stdexcept>
extern "C"
{

View file

@ -4,6 +4,7 @@
#include "ge_vulkan_driver.hpp"
#include "ge_vulkan_texture.hpp"
#include <stdexcept>
#include <algorithm>
#include <exception>

View file

@ -1,6 +1,7 @@
// Copyright (C) 2002-2012 Nikolaus Gebhardt
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#define _DEBUG 1
#ifndef __IRR_COMPILE_CONFIG_H_INCLUDED__
#define __IRR_COMPILE_CONFIG_H_INCLUDED__
@ -23,6 +24,7 @@
//! _IRR_WINDOWS_API_ for Windows or XBox
//! _IRR_LINUX_PLATFORM_ for Linux (it is defined here if no other os is defined)
//! _IRR_HAIKU_PLATFORM_ for Haiku
//! _IRR_SERENITY_PLATFORM_ for SerenityOS
//! _IRR_SOLARIS_PLATFORM_ for Solaris
//! _IRR_OSX_PLATFORM_ for Apple systems running OSX
//! _IRR_IOS_PLATFORM_ for Apple devices running iOS
@ -94,11 +96,15 @@
#endif
#endif
#if defined(HAIKU)
//#if defined(HAIKU)
#define _IRR_HAIKU_PLATFORM_
//#endif
/*
#if defined(__serenity__)
#define _IRR_SERENITY_PLATFORM_
#endif
#if defined(_IRR_HAIKU_PLATFORM_)
*/
#if defined(_IRR_HAIKU_PLATFORM_) || defined(_IRR_SERENITY_PLATFORM_)
#define _IRR_COMPILE_WITH_SDL_DEVICE_
#define _IRR_COMPILE_WITH_OPENGL_
#endif
@ -113,7 +119,10 @@
#define _IRR_COMPILE_WITH_OGLES2_
#endif
#if !defined(_IRR_WINDOWS_API_) && !defined(_IRR_OSX_PLATFORM_) && !defined(_IRR_ANDROID_PLATFORM_) && !defined(_IRR_HAIKU_PLATFORM_)
#define _IRR_POSIX_API_
#if !defined(_IRR_WINDOWS_API_) && !defined(_IRR_OSX_PLATFORM_) && !defined(_IRR_ANDROID_PLATFORM_) && !defined(_IRR_HAIKU_PLATFORM_) && !defined(_IRR_SERENITY_PLATFORM_)
#ifndef _IRR_SOLARIS_PLATFORM_
#define _IRR_LINUX_PLATFORM_
#endif

View file

@ -314,6 +314,7 @@ bool CGUIEnvironment::hasFocus(IGUIElement* element) const
//! returns the current video driver
video::IVideoDriver* CGUIEnvironment::getVideoDriver() const
{
printf("CGUI\n");
return Driver;
}

View file

@ -129,8 +129,8 @@ CIrrDeviceSDL::CIrrDeviceSDL(const SIrrlichtCreationParameters& param)
// Switch doesn't support GetWindowWMInfo
#ifndef __SWITCH__
if (!SDL_GetWindowWMInfo(Window, &Info))
return;
//if (!SDL_GetWindowWMInfo(Window, &Info))
// return;
#endif
#ifdef IOS_STK
init_objc(&Info, &TopPadding, &BottomPadding, &LeftPadding, &RightPadding);
@ -362,7 +362,7 @@ extern "C" void update_fullscreen_desktop(int val)
// Used in OptionsScreenVideo for live updating vertical sync config
extern "C" void update_swap_interval(int swap_interval)
{
#ifndef IOS_STK
#if 0
// iOS always use vertical sync
if (swap_interval > 1)
swap_interval = 1;
@ -452,7 +452,7 @@ bool CIrrDeviceSDL::createWindow()
#if SDL_VERSION_ATLEAST(2, 0, 12)
SDL_SetHint(SDL_HINT_VIDEO_EXTERNAL_CONTEXT, "1");
#endif
flags |= SDL_WINDOW_VULKAN;
// flags |= SDL_WINDOW_VULKAN;
}
#ifdef MOBILE_STK

View file

@ -108,6 +108,7 @@ void CIrrDeviceStub::createGUIAndScene()
//! returns the video driver
video::IVideoDriver* CIrrDeviceStub::getVideoDriver()
{
printf("videostub\n");
return VideoDriver;
}

View file

@ -454,6 +454,7 @@ bool COGLES2MaterialRenderer::setPixelShaderConstant(s32 index, const s32* ints,
IVideoDriver* COGLES2MaterialRenderer::getVideoDriver()
{
printf("iwi\n");
return Driver;
}

View file

@ -4187,6 +4187,7 @@ s32 COpenGLDriver::addHighLevelShaderMaterial(
//! IMaterialRendererServices)
IVideoDriver* COpenGLDriver::getVideoDriver()
{
printf("uwu\n");
return this;
}

View file

@ -691,6 +691,7 @@ void COpenGLSLMaterialRenderer::setPixelShaderConstant(const f32* data, s32 star
IVideoDriver* COpenGLSLMaterialRenderer::getVideoDriver()
{
printf("kiwi\n");
return Driver;
}

View file

@ -160,8 +160,10 @@ namespace irr
#endif
#ifdef _IRR_COMPILE_WITH_SDL_DEVICE_
if (creation_params.DeviceType == EIDT_SDL || (!dev && creation_params.DeviceType == EIDT_BEST))
if (creation_params.DeviceType == EIDT_SDL || (!dev && creation_params.DeviceType == EIDT_BEST)) {
printf("meow\n");
dev = new CIrrDeviceSDL(creation_params);
}
#endif
#ifdef _IRR_COMPILE_WITH_ANDROID_DEVICE_
@ -177,6 +179,7 @@ namespace irr
dev = 0;
}
printf("nyaa\n");
return dev;
}

View file

@ -3435,7 +3435,7 @@ search:
if (! fullname) /* Non-existent or directory */
return FALSE;
if (standard && included( fullname)) /* Once included */
goto true;
goto foo;
if ((max_open != 0 && max_open <= include_nest)
/* Exceed the known limit of open files */
@ -3462,12 +3462,12 @@ search:
if ((fp = fopen( fullname, "r")) == NULL) {
file->fp = fopen( cur_fullname, "r");
fseek( file->fp, file->pos, SEEK_SET);
goto false;
goto bar;
}
if (max_open == 0) /* Remember the limit of the system */
max_open = include_nest;
} else if (fp == NULL) /* No read permission */
goto false;
goto bar;
/* Truncate buffer of the includer to save memory */
len = (int) (file->bptr - file->buffer);
if (len) {
@ -3514,9 +3514,9 @@ search:
if (mkdep && ((mkdep & MD_SYSHEADER) || ! infile->sys_header))
put_depend( fullname); /* Output dependency line */
true:
foo:
return TRUE;
false:
bar:
free( fullname);
return FALSE;
}

View file

@ -266,6 +266,7 @@ void FontManager::shape(const std::u32string& text,
std::vector<irr::gui::GlyphLayout>& gls,
u32 shape_flag)
{
return;
// Helper struct
struct ShapeGlyph
{
@ -834,7 +835,7 @@ void FontManager::loadFonts()
checkFTError(FT_Set_Pixel_Sizes(face, 0, m_shaping_dpi),
"setting DPI");
}
m_hb_fonts.push_back(hb_ft_font_create(face, NULL));
//m_hb_fonts.push_back(hb_ft_font_create(face, NULL));
}
#endif

View file

@ -186,7 +186,7 @@ IrrDriver::IrrDriver()
p.WindowSize = core::dimension2d<u32>(1280,720);
p.ForceLegacyDevice = UserConfigParams::m_force_legacy_device;
#else
p.DriverType = video::EDT_NULL;
p.DriverType = video::EDT_OPENGL;
p.Bits = 16U;
p.WindowSize = core::dimension2d<u32>(640,480);
#endif

View file

@ -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

View file

@ -26,6 +26,7 @@
#include "utils/time.hpp"
#include "utils/vs.hpp"
#include "main_loop.hpp"
#include <sys/select.h>
#include <iostream>
#include <limits>

View file

@ -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)
{

View file

@ -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);

View file

@ -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)

View file

@ -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

View file

@ -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)

View file

@ -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