From 812908e236e83db368dfef49b8badb9a6182e1de Mon Sep 17 00:00:00 2001 From: Fabio Alessandrelli Date: Fri, 28 Oct 2016 04:18:17 +0200 Subject: Fix windows debugger connection problems. Unify network socket creation between platform. Ensure IPV6_V6ONLY flag is not set on sockets (allow IPv4 connection in IPv6 socket, dual-stack). --- drivers/unix/socket_helpers.h | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) (limited to 'drivers/unix/socket_helpers.h') diff --git a/drivers/unix/socket_helpers.h b/drivers/unix/socket_helpers.h index 4ee40e3d3..b432a028b 100644 --- a/drivers/unix/socket_helpers.h +++ b/drivers/unix/socket_helpers.h @@ -45,6 +45,27 @@ static size_t _set_listen_sockaddr(struct sockaddr_storage* p_addr, int p_port, }; }; +static int _socket_create(IP_Address::AddrType p_type, int type, int protocol) { + + ERR_FAIL_COND_V(p_type > IP_Address::TYPE_ANY || p_type < IP_Address::TYPE_NONE, ERR_INVALID_PARAMETER); + + int family = p_type == IP_Address::TYPE_IPV4 ? AF_INET : AF_INET6; + int sockfd = socket(family, type, protocol); + + ERR_FAIL_COND_V( sockfd == -1, -1 ); + + if(family == AF_INET6) { + // Ensure IPv4 over IPv6 is enabled + int v6_only = 0; + if(setsockopt(sockfd, IPPROTO_IPV6, IPV6_V6ONLY, (const char*)&v6_only, sizeof(v6_only)) != 0) { + WARN_PRINT("Unable to set IPv4 address mapping over IPv6"); + } + } + + return sockfd; +} + + static void _set_ip_addr_port(IP_Address& r_ip, int& r_port, struct sockaddr_storage* p_addr) { if (p_addr->ss_family == AF_INET) { -- cgit v1.2.3-70-g09d2 From eb27e993f0f2fb3de48b7b8aa01c74cc1635a178 Mon Sep 17 00:00:00 2001 From: Fabio Alessandrelli Date: Fri, 28 Oct 2016 23:11:53 +0200 Subject: TCP/UDP Listen sockets can now be set to IPv6 only --- drivers/unix/ip_unix.cpp | 9 +++++++++ drivers/unix/packet_peer_udp_posix.cpp | 15 ++++++++++++--- drivers/unix/socket_helpers.h | 4 ++-- drivers/unix/tcp_server_posix.cpp | 8 ++++++++ platform/windows/packet_peer_udp_winsock.cpp | 14 +++++++++++--- platform/windows/tcp_server_winsock.cpp | 8 ++++++++ 6 files changed, 50 insertions(+), 8 deletions(-) (limited to 'drivers/unix/socket_helpers.h') diff --git a/drivers/unix/ip_unix.cpp b/drivers/unix/ip_unix.cpp index d6d1be339..e3d32618e 100644 --- a/drivers/unix/ip_unix.cpp +++ b/drivers/unix/ip_unix.cpp @@ -33,6 +33,13 @@ #include #ifdef WINDOWS_ENABLED + // Workaround mingw missing flags! + #ifndef AI_ADDRCONFIG + #define AI_ADDRCONFIG 0x00000400 + #endif + #ifndef AI_V4MAPPED + #define AI_V4MAPPED 0x00000800 + #endif #ifdef WINRT_ENABLED #include #include @@ -90,8 +97,10 @@ IP_Address IP_Unix::_resolve_hostname(const String& p_hostname, IP_Address::Addr hints.ai_family = AF_INET; } else if (p_type == IP_Address::TYPE_IPV6) { hints.ai_family = AF_INET6; + hints.ai_flags = 0; } else { hints.ai_family = AF_UNSPEC; + hints.ai_flags = (AI_V4MAPPED | AI_ADDRCONFIG); }; int s = getaddrinfo(p_hostname.utf8().get_data(), NULL, &hints, &result); diff --git a/drivers/unix/packet_peer_udp_posix.cpp b/drivers/unix/packet_peer_udp_posix.cpp index 01c26420a..ed295f045 100644 --- a/drivers/unix/packet_peer_udp_posix.cpp +++ b/drivers/unix/packet_peer_udp_posix.cpp @@ -119,15 +119,24 @@ int PacketPeerUDPPosix::get_max_packet_size() const{ return 512; // uhm maybe not } -Error PacketPeerUDPPosix::listen(int p_port, IP_Address::AddrType p_address_type, int p_recv_buffer_size) { +Error PacketPeerUDPPosix::listen(int p_port, IP_Address::AddrType p_type, int p_recv_buffer_size) { close(); - int sock = _get_socket(p_address_type); + int sock = _get_socket(p_type); + if (sock == -1 ) return ERR_CANT_CREATE; + if(p_type == IP_Address::TYPE_IPV6) { + // Use IPv6 only socket + int yes = 1; + if(setsockopt(sockfd, IPPROTO_IPV6, IPV6_V6ONLY, (const char*)&yes, sizeof(yes)) != 0) { + WARN_PRINT("Unable to unset IPv4 address mapping over IPv6"); + } + } + sockaddr_storage addr = {0}; - size_t addr_size = _set_listen_sockaddr(&addr, p_port, p_address_type, NULL); + size_t addr_size = _set_listen_sockaddr(&addr, p_port, p_type, NULL); if (bind(sock, (struct sockaddr*)&addr, addr_size) == -1 ) { close(); diff --git a/drivers/unix/socket_helpers.h b/drivers/unix/socket_helpers.h index b432a028b..80e013ad6 100644 --- a/drivers/unix/socket_helpers.h +++ b/drivers/unix/socket_helpers.h @@ -56,8 +56,8 @@ static int _socket_create(IP_Address::AddrType p_type, int type, int protocol) { if(family == AF_INET6) { // Ensure IPv4 over IPv6 is enabled - int v6_only = 0; - if(setsockopt(sockfd, IPPROTO_IPV6, IPV6_V6ONLY, (const char*)&v6_only, sizeof(v6_only)) != 0) { + int no = 0; + if(setsockopt(sockfd, IPPROTO_IPV6, IPV6_V6ONLY, (const char*)&no, sizeof(no)) != 0) { WARN_PRINT("Unable to set IPv4 address mapping over IPv6"); } } diff --git a/drivers/unix/tcp_server_posix.cpp b/drivers/unix/tcp_server_posix.cpp index 32fda618b..7028c1a10 100644 --- a/drivers/unix/tcp_server_posix.cpp +++ b/drivers/unix/tcp_server_posix.cpp @@ -74,6 +74,14 @@ Error TCPServerPosix::listen(uint16_t p_port, IP_Address::AddrType p_type, const sockfd = _socket_create(p_type, SOCK_STREAM, IPPROTO_TCP); ERR_FAIL_COND_V(sockfd == -1, FAILED); + + if(p_type == IP_Address::TYPE_IPV6) { + // Use IPv6 only socket + int yes = 1; + if(setsockopt(sockfd, IPPROTO_IPV6, IPV6_V6ONLY, (const char*)&yes, sizeof(yes)) != 0) { + WARN_PRINT("Unable to unset IPv4 address mapping over IPv6"); + } + } #ifndef NO_FCNTL fcntl(sockfd, F_SETFL, O_NONBLOCK); #else diff --git a/platform/windows/packet_peer_udp_winsock.cpp b/platform/windows/packet_peer_udp_winsock.cpp index 6c661db0c..73c6116aa 100644 --- a/platform/windows/packet_peer_udp_winsock.cpp +++ b/platform/windows/packet_peer_udp_winsock.cpp @@ -112,15 +112,23 @@ void PacketPeerUDPWinsock::_set_blocking(bool p_blocking) { }; } -Error PacketPeerUDPWinsock::listen(int p_port, IP_Address::AddrType p_address_type, int p_recv_buffer_size) { +Error PacketPeerUDPWinsock::listen(int p_port, IP_Address::AddrType p_type, int p_recv_buffer_size) { close(); - int sock = _get_socket(p_address_type); + int sock = _get_socket(p_type); if (sock == -1 ) return ERR_CANT_CREATE; + if(p_type == IP_Address::TYPE_IPV6) { + // Use IPv6 only socket + int yes = 1; + if(setsockopt(sockfd, IPPROTO_IPV6, IPV6_V6ONLY, (const char*)&yes, sizeof(yes)) != 0) { + WARN_PRINT("Unable to unset IPv4 address mapping over IPv6"); + } + } + struct sockaddr_storage addr = {0}; - size_t addr_size = _set_listen_sockaddr(&addr, p_port, p_address_type, NULL); + size_t addr_size = _set_listen_sockaddr(&addr, p_port, p_type, NULL); if (bind(sock, (struct sockaddr*)&addr, addr_size) == -1 ) { close(); diff --git a/platform/windows/tcp_server_winsock.cpp b/platform/windows/tcp_server_winsock.cpp index a4eb3a769..38a6b0410 100644 --- a/platform/windows/tcp_server_winsock.cpp +++ b/platform/windows/tcp_server_winsock.cpp @@ -69,6 +69,14 @@ Error TCPServerWinsock::listen(uint16_t p_port, IP_Address::AddrType p_type,cons sockfd = _socket_create(p_type, SOCK_STREAM, IPPROTO_TCP); ERR_FAIL_COND_V(sockfd == INVALID_SOCKET, FAILED); + if(p_type == IP_Address::TYPE_IPV6) { + // Use IPv6 only socket + int yes = 1; + if(setsockopt(sockfd, IPPROTO_IPV6, IPV6_V6ONLY, (const char*)&yes, sizeof(yes)) != 0) { + WARN_PRINT("Unable to unset IPv4 address mapping over IPv6"); + } + } + unsigned long par = 1; if (ioctlsocket(sockfd, FIONBIO, &par)) { perror("setting non-block mode"); -- cgit v1.2.3-70-g09d2 From bdc7ca84cac727f3f94663f23e1229450230bd2e Mon Sep 17 00:00:00 2001 From: Fabio Alessandrelli Date: Sun, 30 Oct 2016 22:58:15 +0100 Subject: Define IPV6_V6ONLY flag if not defined on windows (old mingw versions) --- drivers/unix/socket_helpers.h | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'drivers/unix/socket_helpers.h') diff --git a/drivers/unix/socket_helpers.h b/drivers/unix/socket_helpers.h index 80e013ad6..9693911ac 100644 --- a/drivers/unix/socket_helpers.h +++ b/drivers/unix/socket_helpers.h @@ -3,6 +3,13 @@ #include +#ifdef WINDOWS_ENABLED + // Workaround mingw missing flags! + #ifndef IPV6_V6ONLY + #define IPV6_V6ONLY 27 + #endif +#endif + // helpers for sockaddr -> IP_Address and back, should work for posix and winsock. All implementations should use this static size_t _set_sockaddr(struct sockaddr_storage* p_addr, const IP_Address& p_ip, int p_port) { -- cgit v1.2.3-70-g09d2 From 4160b3c9feb32e7762ea121bb44b30ba65676760 Mon Sep 17 00:00:00 2001 From: George Marques Date: Mon, 31 Oct 2016 21:39:45 -0200 Subject: Fix IPv6 linking for UWP --- drivers/unix/socket_helpers.h | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'drivers/unix/socket_helpers.h') diff --git a/drivers/unix/socket_helpers.h b/drivers/unix/socket_helpers.h index 9693911ac..3aaae82da 100644 --- a/drivers/unix/socket_helpers.h +++ b/drivers/unix/socket_helpers.h @@ -10,6 +10,10 @@ #endif #endif +#ifdef WINRT_ENABLED +#define in6addr_any IN6ADDR_ANY_INIT +#endif + // helpers for sockaddr -> IP_Address and back, should work for posix and winsock. All implementations should use this static size_t _set_sockaddr(struct sockaddr_storage* p_addr, const IP_Address& p_ip, int p_port) { -- cgit v1.2.3-70-g09d2 From b113c7b7a3e63581ae268b0ae7f827d55e381b82 Mon Sep 17 00:00:00 2001 From: George Marques Date: Wed, 2 Nov 2016 18:57:35 -0200 Subject: Rename WINRT_ENABLED to UWP_ENABLED --- drivers/unix/ip_unix.cpp | 4 ++-- drivers/unix/socket_helpers.h | 2 +- drivers/windows/dir_access_windows.cpp | 2 +- drivers/windows/file_access_windows.cpp | 2 +- drivers/windows/mutex_windows.cpp | 2 +- drivers/windows/semaphore_windows.cpp | 2 +- drivers/windows/shell_windows.cpp | 2 +- drivers/windows/thread_windows.cpp | 2 +- main/input_default.cpp | 2 +- platform/uwp/detect.py | 2 +- platform/uwp/thread_uwp.h | 2 +- thirdparty/enet/win32.c | 6 +++--- thirdparty/openssl/crypto/rand/rand_win.c | 10 +++++----- thirdparty/openssl/openssl/dtls1.h | 2 +- thirdparty/openssl/uwp.cpp | 4 ++-- thirdparty/openssl/uwp_fix.patch | 12 ++++++------ thirdparty/rtaudio/RtAudio.h | 2 +- 17 files changed, 30 insertions(+), 30 deletions(-) (limited to 'drivers/unix/socket_helpers.h') diff --git a/drivers/unix/ip_unix.cpp b/drivers/unix/ip_unix.cpp index e3d32618e..d998c63df 100644 --- a/drivers/unix/ip_unix.cpp +++ b/drivers/unix/ip_unix.cpp @@ -40,7 +40,7 @@ #ifndef AI_V4MAPPED #define AI_V4MAPPED 0x00000800 #endif - #ifdef WINRT_ENABLED + #ifdef UWP_ENABLED #include #include #include @@ -124,7 +124,7 @@ IP_Address IP_Unix::_resolve_hostname(const String& p_hostname, IP_Address::Addr #if defined(WINDOWS_ENABLED) -#if defined(WINRT_ENABLED) +#if defined(UWP_ENABLED) void IP_Unix::get_local_addresses(List *r_addresses) const { diff --git a/drivers/unix/socket_helpers.h b/drivers/unix/socket_helpers.h index 3aaae82da..5e8e8dfd7 100644 --- a/drivers/unix/socket_helpers.h +++ b/drivers/unix/socket_helpers.h @@ -10,7 +10,7 @@ #endif #endif -#ifdef WINRT_ENABLED +#ifdef UWP_ENABLED #define in6addr_any IN6ADDR_ANY_INIT #endif diff --git a/drivers/windows/dir_access_windows.cpp b/drivers/windows/dir_access_windows.cpp index ad4e8f301..00d9afe51 100644 --- a/drivers/windows/dir_access_windows.cpp +++ b/drivers/windows/dir_access_windows.cpp @@ -349,7 +349,7 @@ DirAccessWindows::DirAccessWindows() { drive_count=0; -#ifdef WINRT_ENABLED +#ifdef UWP_ENABLED Windows::Storage::StorageFolder ^install_folder = Windows::ApplicationModel::Package::Current->InstalledLocation; change_dir(install_folder->Path->Data()); diff --git a/drivers/windows/file_access_windows.cpp b/drivers/windows/file_access_windows.cpp index 36dcab1d6..e28d68221 100644 --- a/drivers/windows/file_access_windows.cpp +++ b/drivers/windows/file_access_windows.cpp @@ -125,7 +125,7 @@ void FileAccessWindows::close() { bool rename_error; -#ifdef WINRT_ENABLED +#ifdef UWP_ENABLED // WinRT has no PathFileExists, so we check attributes instead DWORD fileAttr; diff --git a/drivers/windows/mutex_windows.cpp b/drivers/windows/mutex_windows.cpp index f63415d0f..f533626c3 100644 --- a/drivers/windows/mutex_windows.cpp +++ b/drivers/windows/mutex_windows.cpp @@ -81,7 +81,7 @@ MutexWindows::MutexWindows() { #ifdef WINDOWS_USE_MUTEX mutex = CreateMutex( NULL, FALSE, NULL ); #else - #ifdef WINRT_ENABLED + #ifdef UWP_ENABLED InitializeCriticalSectionEx( &mutex, 0, 0 ); #else InitializeCriticalSection( &mutex ); diff --git a/drivers/windows/semaphore_windows.cpp b/drivers/windows/semaphore_windows.cpp index 8d11d1b1c..5ea98f341 100644 --- a/drivers/windows/semaphore_windows.cpp +++ b/drivers/windows/semaphore_windows.cpp @@ -71,7 +71,7 @@ void SemaphoreWindows::make_default() { SemaphoreWindows::SemaphoreWindows() { -#ifdef WINRT_ENABLED +#ifdef UWP_ENABLED semaphore=CreateSemaphoreEx( NULL, 0, diff --git a/drivers/windows/shell_windows.cpp b/drivers/windows/shell_windows.cpp index c69d371a6..283a453be 100644 --- a/drivers/windows/shell_windows.cpp +++ b/drivers/windows/shell_windows.cpp @@ -28,7 +28,7 @@ /*************************************************************************/ #ifdef WINDOWS_ENABLED -#ifdef WINRT_ENABLED +#ifdef UWP_ENABLED // Use Launcher class on windows 8 diff --git a/drivers/windows/thread_windows.cpp b/drivers/windows/thread_windows.cpp index 884575e81..205611341 100644 --- a/drivers/windows/thread_windows.cpp +++ b/drivers/windows/thread_windows.cpp @@ -28,7 +28,7 @@ /*************************************************************************/ #include "thread_windows.h" -#if defined(WINDOWS_ENABLED) && !defined(WINRT_ENABLED) +#if defined(WINDOWS_ENABLED) && !defined(UWP_ENABLED) #include "os/memory.h" diff --git a/main/input_default.cpp b/main/input_default.cpp index c60fcd224..09b1d53c5 100644 --- a/main/input_default.cpp +++ b/main/input_default.cpp @@ -739,7 +739,7 @@ static const char *s_ControllerMappings [] = "c2a94d6963726f736f66742058626f78,Wireless X360 Controller,leftx:a0,lefty:a1,dpdown:b14,rightstick:b10,rightshoulder:b5,rightx:a3,start:b7,righty:a4,dpleft:b11,lefttrigger:a2,x:b2,dpup:b13,back:b6,leftstick:b9,leftshoulder:b4,y:b3,a:b0,dpright:b12,righttrigger:a5,b:b1,", #endif - #ifdef WINRT_ENABLED + #ifdef UWP_ENABLED "__WINRT_GAMEPAD__,Xbox Controller,a:b2,b:b3,x:b4,y:b5,start:b0,back:b1,leftstick:b12,rightstick:b13,leftshoulder:b10,rightshoulder:b11,dpup:b6,dpdown:b7,dpleft:b8,dpright:b9,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:a4,righttrigger:a5,", #endif NULL diff --git a/platform/uwp/detect.py b/platform/uwp/detect.py index 85d6d54a7..a78a7fec7 100644 --- a/platform/uwp/detect.py +++ b/platform/uwp/detect.py @@ -139,7 +139,7 @@ def configure(env): env["OBJSUFFIX"] = "." + arch + env["OBJSUFFIX"] env["LIBSUFFIX"] = "." + arch + env["LIBSUFFIX"] - env.Append(CCFLAGS=['/DWINRT_ENABLED']) + env.Append(CCFLAGS=['/DUWP_ENABLED']) env.Append(CCFLAGS=['/DWINDOWS_ENABLED']) env.Append(CCFLAGS=['/DTYPED_METHOD_BIND']) diff --git a/platform/uwp/thread_uwp.h b/platform/uwp/thread_uwp.h index e0d386a31..328d29bdc 100644 --- a/platform/uwp/thread_uwp.h +++ b/platform/uwp/thread_uwp.h @@ -29,7 +29,7 @@ #ifndef THREAD_WINRT_H #define THREAD_WINRT_H -#ifdef WINRT_ENABLED +#ifdef UWP_ENABLED #include "os/thread.h" diff --git a/thirdparty/enet/win32.c b/thirdparty/enet/win32.c index 15edd7acb..f8e0d4efd 100644 --- a/thirdparty/enet/win32.c +++ b/thirdparty/enet/win32.c @@ -28,7 +28,7 @@ enet_initialize (void) return -1; } -#ifndef WINRT_ENABLED +#ifndef UWP_ENABLED timeBeginPeriod (1); #endif @@ -38,14 +38,14 @@ enet_initialize (void) void enet_deinitialize (void) { -#ifndef WINRT_ENABLED +#ifndef UWP_ENABLED timeEndPeriod (1); #endif WSACleanup (); } -#ifdef WINRT_ENABLED +#ifdef UWP_ENABLED enet_uint32 timeGetTime() { ULONGLONG ticks = GetTickCount64(); diff --git a/thirdparty/openssl/crypto/rand/rand_win.c b/thirdparty/openssl/crypto/rand/rand_win.c index 70fd52a7a..da4c935a5 100644 --- a/thirdparty/openssl/crypto/rand/rand_win.c +++ b/thirdparty/openssl/crypto/rand/rand_win.c @@ -118,7 +118,7 @@ # ifndef _WIN32_WINNT # define _WIN32_WINNT 0x0400 # endif -#ifndef WINRT_ENABLED +#ifndef UWP_ENABLED # include # include #endif @@ -163,7 +163,7 @@ typedef struct tagCURSORINFO { # define CURSOR_SHOWING 0x00000001 # endif /* CURSOR_SHOWING */ -# if !defined(OPENSSL_SYS_WINCE) && !defined(WINRT_ENABLED) +# if !defined(OPENSSL_SYS_WINCE) && !defined(UWP_ENABLED) typedef BOOL(WINAPI *CRYPTACQUIRECONTEXTW) (HCRYPTPROV *, LPCWSTR, LPCWSTR, DWORD, DWORD); typedef BOOL(WINAPI *CRYPTGENRANDOM) (HCRYPTPROV, DWORD, BYTE *); @@ -198,7 +198,7 @@ typedef NET_API_STATUS(NET_API_FUNCTION *NETFREE) (LPBYTE); # endif /* 1 */ # endif /* !OPENSSL_SYS_WINCE */ -#if !defined(WINRT_ENABLED) +#if !defined(UWP_ENABLED) int RAND_poll(void) { MEMORYSTATUS m; @@ -583,7 +583,7 @@ int RAND_poll(void) return (1); } -#endif // WINRT_ENABLED +#endif // UWP_ENABLED int RAND_event(UINT iMsg, WPARAM wParam, LPARAM lParam) { @@ -687,7 +687,7 @@ static void readtimer(void) static void readscreen(void) { -# if !defined(OPENSSL_SYS_WINCE) && !defined(OPENSSL_SYS_WIN32_CYGWIN) && !defined(WINRT_ENABLED) +# if !defined(OPENSSL_SYS_WINCE) && !defined(OPENSSL_SYS_WIN32_CYGWIN) && !defined(UWP_ENABLED) HDC hScrDC; /* screen DC */ HBITMAP hBitmap; /* handle for our bitmap */ BITMAP bm; /* bitmap properties */ diff --git a/thirdparty/openssl/openssl/dtls1.h b/thirdparty/openssl/openssl/dtls1.h index a58aca248..cdd1e4d86 100644 --- a/thirdparty/openssl/openssl/dtls1.h +++ b/thirdparty/openssl/openssl/dtls1.h @@ -81,7 +81,7 @@ # include # endif # endif -#ifdef WINRT_ENABLED +#ifdef UWP_ENABLED #include #endif diff --git a/thirdparty/openssl/uwp.cpp b/thirdparty/openssl/uwp.cpp index c3a6f8bfc..6bb0c2252 100644 --- a/thirdparty/openssl/uwp.cpp +++ b/thirdparty/openssl/uwp.cpp @@ -44,7 +44,7 @@ int RAND_poll(void) return 1; } -#if defined(WINRT_ENABLED) +#if defined(UWP_ENABLED) extern "C" { #include @@ -152,4 +152,4 @@ extern "C" void *OPENSSL_UplinkTable [26]= {0}; } //extern C -#endif /*defined(WINRT_ENABLED)*/ +#endif /*defined(UWP_ENABLED)*/ diff --git a/thirdparty/openssl/uwp_fix.patch b/thirdparty/openssl/uwp_fix.patch index caf180a75..00d8b64d0 100644 --- a/thirdparty/openssl/uwp_fix.patch +++ b/thirdparty/openssl/uwp_fix.patch @@ -6,7 +6,7 @@ index 06670ae..70fd52a 100644 # ifndef _WIN32_WINNT # define _WIN32_WINNT 0x0400 # endif -+#ifndef WINRT_ENABLED ++#ifndef UWP_ENABLED # include # include +#endif @@ -18,7 +18,7 @@ index 06670ae..70fd52a 100644 # endif /* CURSOR_SHOWING */ -# if !defined(OPENSSL_SYS_WINCE) -+# if !defined(OPENSSL_SYS_WINCE) && !defined(WINRT_ENABLED) ++# if !defined(OPENSSL_SYS_WINCE) && !defined(UWP_ENABLED) typedef BOOL(WINAPI *CRYPTACQUIRECONTEXTW) (HCRYPTPROV *, LPCWSTR, LPCWSTR, DWORD, DWORD); typedef BOOL(WINAPI *CRYPTGENRANDOM) (HCRYPTPROV, DWORD, BYTE *); @@ -26,7 +26,7 @@ index 06670ae..70fd52a 100644 # endif /* 1 */ # endif /* !OPENSSL_SYS_WINCE */ -+#if !defined(WINRT_ENABLED) ++#if !defined(UWP_ENABLED) int RAND_poll(void) { MEMORYSTATUS m; @@ -34,7 +34,7 @@ index 06670ae..70fd52a 100644 return (1); } -+#endif // WINRT_ENABLED ++#endif // UWP_ENABLED + int RAND_event(UINT iMsg, WPARAM wParam, LPARAM lParam) { @@ -44,7 +44,7 @@ index 06670ae..70fd52a 100644 static void readscreen(void) { -# if !defined(OPENSSL_SYS_WINCE) && !defined(OPENSSL_SYS_WIN32_CYGWIN) -+# if !defined(OPENSSL_SYS_WINCE) && !defined(OPENSSL_SYS_WIN32_CYGWIN) && !defined(WINRT_ENABLED) ++# if !defined(OPENSSL_SYS_WINCE) && !defined(OPENSSL_SYS_WIN32_CYGWIN) && !defined(UWP_ENABLED) HDC hScrDC; /* screen DC */ HBITMAP hBitmap; /* handle for our bitmap */ BITMAP bm; /* bitmap properties */ @@ -56,7 +56,7 @@ index 64ad3c8..a58aca2 100644 # include # endif # endif -+#ifdef WINRT_ENABLED ++#ifdef UWP_ENABLED +#include +#endif diff --git a/thirdparty/rtaudio/RtAudio.h b/thirdparty/rtaudio/RtAudio.h index 4392e95f3..aab109d90 100644 --- a/thirdparty/rtaudio/RtAudio.h +++ b/thirdparty/rtaudio/RtAudio.h @@ -7,7 +7,7 @@ #elif defined(UNIX_ENABLED) #define __LINUX_ALSA__ #elif defined(WINDOWS_ENABLED) - #if defined(WINRT_ENABLED) + #if defined(UWP_ENABLED) #define __RTAUDIO_DUMMY__ #else #define __WINDOWS_DS__ -- cgit v1.2.3-70-g09d2 From cdc1ca0f1301bb907121292db83f98706722ff1e Mon Sep 17 00:00:00 2001 From: Fabio Alessandrelli Date: Fri, 2 Dec 2016 04:10:55 +0100 Subject: Fix _set_ip_addr_port not setting the address. --- drivers/unix/socket_helpers.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/unix/socket_helpers.h') diff --git a/drivers/unix/socket_helpers.h b/drivers/unix/socket_helpers.h index 5e8e8dfd7..84b1ca574 100644 --- a/drivers/unix/socket_helpers.h +++ b/drivers/unix/socket_helpers.h @@ -92,7 +92,7 @@ static void _set_ip_addr_port(IP_Address& r_ip, int& r_port, struct sockaddr_sto r_ip.type = IP_Address::TYPE_IPV6; struct sockaddr_in6* addr6 = (struct sockaddr_in6*)p_addr; - copymem(&addr6->sin6_addr.s6_addr, r_ip.field8, 16); + copymem(&r_ip.field8, addr6->sin6_addr.s6_addr, 16); r_port = ntohs(addr6->sin6_port); }; -- cgit v1.2.3-70-g09d2 From 9200da58e4c2498c833d9f2505600c7049e80940 Mon Sep 17 00:00:00 2001 From: Fabio Alessandrelli Date: Thu, 1 Dec 2016 04:23:57 +0100 Subject: Automatically map IPv4 address to IPv6 when needed --- drivers/unix/packet_peer_udp_posix.cpp | 2 +- drivers/unix/socket_helpers.h | 20 ++++++++++++++++---- drivers/unix/stream_peer_tcp_posix.cpp | 4 ++-- platform/windows/packet_peer_udp_winsock.cpp | 2 +- platform/windows/stream_peer_winsock.cpp | 4 ++-- 5 files changed, 22 insertions(+), 10 deletions(-) (limited to 'drivers/unix/socket_helpers.h') diff --git a/drivers/unix/packet_peer_udp_posix.cpp b/drivers/unix/packet_peer_udp_posix.cpp index 52f2c0713..b1049582c 100644 --- a/drivers/unix/packet_peer_udp_posix.cpp +++ b/drivers/unix/packet_peer_udp_posix.cpp @@ -99,7 +99,7 @@ Error PacketPeerUDPPosix::put_packet(const uint8_t *p_buffer,int p_buffer_size){ int sock = _get_socket(); ERR_FAIL_COND_V( sock == -1, FAILED ); struct sockaddr_storage addr; - size_t addr_size = _set_sockaddr(&addr, peer_addr, peer_port); + size_t addr_size = _set_sockaddr(&addr, peer_addr, peer_port, ip_type); errno = 0; int err; diff --git a/drivers/unix/socket_helpers.h b/drivers/unix/socket_helpers.h index 84b1ca574..a860c2f80 100644 --- a/drivers/unix/socket_helpers.h +++ b/drivers/unix/socket_helpers.h @@ -16,18 +16,30 @@ // helpers for sockaddr -> IP_Address and back, should work for posix and winsock. All implementations should use this -static size_t _set_sockaddr(struct sockaddr_storage* p_addr, const IP_Address& p_ip, int p_port) { +static size_t _set_sockaddr(struct sockaddr_storage* p_addr, const IP_Address& p_ip, int p_port, IP_Address::AddrType p_sock_type = IP_Address::TYPE_ANY) { memset(p_addr, 0, sizeof(struct sockaddr_storage)); - if (p_ip.type == IP_Address::TYPE_IPV6) { + + // Dual stack (ANY) or matching ip type is required + ERR_FAIL_COND_V(p_sock_type != IP_Address::TYPE_ANY && p_sock_type != p_ip.type,0); + + // IPv6 socket + if (p_sock_type == IP_Address::TYPE_IPV6 || p_sock_type == IP_Address::TYPE_ANY) { struct sockaddr_in6* addr6 = (struct sockaddr_in6*)p_addr; addr6->sin6_family = AF_INET6; addr6->sin6_port = htons(p_port); - copymem(&addr6->sin6_addr.s6_addr, p_ip.field8, 16); + if(p_ip.type == IP_Address::TYPE_IPV4) { + // Remapping needed + uint16_t base[8] = {0x0, 0x0, 0x0, 0x0, 0x0, 0xffff, p_ip.field16[0], p_ip.field16[1]}; + copymem(&addr6->sin6_addr.s6_addr, base, 16); + + } else { + copymem(&addr6->sin6_addr.s6_addr, p_ip.field8, 16); + } return sizeof(sockaddr_in6); - } else { + } else { // IPv4 socket struct sockaddr_in* addr4 = (struct sockaddr_in*)p_addr; addr4->sin_family = AF_INET; // host byte order diff --git a/drivers/unix/stream_peer_tcp_posix.cpp b/drivers/unix/stream_peer_tcp_posix.cpp index 95e56aa40..8aae1e77a 100644 --- a/drivers/unix/stream_peer_tcp_posix.cpp +++ b/drivers/unix/stream_peer_tcp_posix.cpp @@ -98,7 +98,7 @@ Error StreamPeerTCPPosix::_poll_connection(bool p_block) const { }; struct sockaddr_storage their_addr; - size_t addr_size = _set_sockaddr(&their_addr, peer_host, peer_port); + size_t addr_size = _set_sockaddr(&their_addr, peer_host, peer_port, ip_type); if (::connect(sockfd, (struct sockaddr *)&their_addr,addr_size) == -1) { @@ -159,7 +159,7 @@ Error StreamPeerTCPPosix::connect(const IP_Address& p_host, uint16_t p_port) { #endif struct sockaddr_storage their_addr; - size_t addr_size = _set_sockaddr(&their_addr, p_host, p_port); + size_t addr_size = _set_sockaddr(&their_addr, p_host, p_port, ip_type); errno = 0; if (::connect(sockfd, (struct sockaddr *)&their_addr,addr_size) == -1 && errno != EINPROGRESS) { diff --git a/platform/windows/packet_peer_udp_winsock.cpp b/platform/windows/packet_peer_udp_winsock.cpp index 595f1edd8..9a5f6c6a3 100644 --- a/platform/windows/packet_peer_udp_winsock.cpp +++ b/platform/windows/packet_peer_udp_winsock.cpp @@ -74,7 +74,7 @@ Error PacketPeerUDPWinsock::put_packet(const uint8_t *p_buffer,int p_buffer_size int sock = _get_socket(); ERR_FAIL_COND_V( sock == -1, FAILED ); struct sockaddr_storage addr; - size_t addr_size = _set_sockaddr(&addr, peer_addr, peer_port); + size_t addr_size = _set_sockaddr(&addr, peer_addr, peer_port, ip_type); _set_blocking(true); diff --git a/platform/windows/stream_peer_winsock.cpp b/platform/windows/stream_peer_winsock.cpp index d11724eb8..f03ecca22 100644 --- a/platform/windows/stream_peer_winsock.cpp +++ b/platform/windows/stream_peer_winsock.cpp @@ -88,7 +88,7 @@ Error StreamPeerWinsock::_poll_connection(bool p_block) const { }; struct sockaddr_storage their_addr; - size_t addr_size = _set_sockaddr(&their_addr, peer_host, peer_port); + size_t addr_size = _set_sockaddr(&their_addr, peer_host, peer_port, ip_type); if (::connect(sockfd, (struct sockaddr *)&their_addr,addr_size) == SOCKET_ERROR) { @@ -318,7 +318,7 @@ Error StreamPeerWinsock::connect(const IP_Address& p_host, uint16_t p_port) { }; struct sockaddr_storage their_addr; - size_t addr_size = _set_sockaddr(&their_addr, p_host, p_port); + size_t addr_size = _set_sockaddr(&their_addr, p_host, p_port, ip_type); if (::connect(sockfd, (struct sockaddr *)&their_addr,addr_size) == SOCKET_ERROR) { -- cgit v1.2.3-70-g09d2 From 4d90a4fcd5fcdca42df47062f94a1fa4e5635a94 Mon Sep 17 00:00:00 2001 From: Fabio Alessandrelli Date: Thu, 1 Dec 2016 05:05:44 +0100 Subject: Move V6ONLY flag selection inside helpers --- drivers/unix/packet_peer_udp_posix.cpp | 8 -------- drivers/unix/socket_helpers.h | 8 ++++---- drivers/unix/tcp_server_posix.cpp | 7 ------- platform/windows/packet_peer_udp_winsock.cpp | 8 -------- platform/windows/tcp_server_winsock.cpp | 8 -------- 5 files changed, 4 insertions(+), 35 deletions(-) (limited to 'drivers/unix/socket_helpers.h') diff --git a/drivers/unix/packet_peer_udp_posix.cpp b/drivers/unix/packet_peer_udp_posix.cpp index b1049582c..44a3e65e0 100644 --- a/drivers/unix/packet_peer_udp_posix.cpp +++ b/drivers/unix/packet_peer_udp_posix.cpp @@ -127,14 +127,6 @@ Error PacketPeerUDPPosix::listen(int p_port, int p_recv_buffer_size) { if (sock == -1 ) return ERR_CANT_CREATE; - if(ip_type == IP_Address::TYPE_IPV6) { - // Use IPv6 only socket - int yes = 1; - if(setsockopt(sockfd, IPPROTO_IPV6, IPV6_V6ONLY, (const char*)&yes, sizeof(yes)) != 0) { - WARN_PRINT("Unable to unset IPv4 address mapping over IPv6"); - } - } - sockaddr_storage addr = {0}; size_t addr_size = _set_listen_sockaddr(&addr, p_port, ip_type, NULL); diff --git a/drivers/unix/socket_helpers.h b/drivers/unix/socket_helpers.h index a860c2f80..aec4ec884 100644 --- a/drivers/unix/socket_helpers.h +++ b/drivers/unix/socket_helpers.h @@ -78,10 +78,10 @@ static int _socket_create(IP_Address::AddrType p_type, int type, int protocol) { ERR_FAIL_COND_V( sockfd == -1, -1 ); if(family == AF_INET6) { - // Ensure IPv4 over IPv6 is enabled - int no = 0; - if(setsockopt(sockfd, IPPROTO_IPV6, IPV6_V6ONLY, (const char*)&no, sizeof(no)) != 0) { - WARN_PRINT("Unable to set IPv4 address mapping over IPv6"); + // Select IPv4 over IPv6 mapping + int opt = p_type != IP_Address::TYPE_ANY; + if(setsockopt(sockfd, IPPROTO_IPV6, IPV6_V6ONLY, (const char*)&opt, sizeof(opt)) != 0) { + WARN_PRINT("Unable to set/unset IPv4 address mapping over IPv6"); } } diff --git a/drivers/unix/tcp_server_posix.cpp b/drivers/unix/tcp_server_posix.cpp index e6f3614cb..bf3b7369e 100644 --- a/drivers/unix/tcp_server_posix.cpp +++ b/drivers/unix/tcp_server_posix.cpp @@ -75,13 +75,6 @@ Error TCPServerPosix::listen(uint16_t p_port,const List *p_accepted_host ERR_FAIL_COND_V(sockfd == -1, FAILED); - if(ip_type == IP_Address::TYPE_IPV6) { - // Use IPv6 only socket - int yes = 1; - if(setsockopt(sockfd, IPPROTO_IPV6, IPV6_V6ONLY, (const char*)&yes, sizeof(yes)) != 0) { - WARN_PRINT("Unable to unset IPv4 address mapping over IPv6"); - } - } #ifndef NO_FCNTL fcntl(sockfd, F_SETFL, O_NONBLOCK); #else diff --git a/platform/windows/packet_peer_udp_winsock.cpp b/platform/windows/packet_peer_udp_winsock.cpp index 9a5f6c6a3..4201a3e86 100644 --- a/platform/windows/packet_peer_udp_winsock.cpp +++ b/platform/windows/packet_peer_udp_winsock.cpp @@ -119,14 +119,6 @@ Error PacketPeerUDPWinsock::listen(int p_port, int p_recv_buffer_size) { if (sock == -1 ) return ERR_CANT_CREATE; - if(ip_type == IP_Address::TYPE_IPV6) { - // Use IPv6 only socket - int yes = 1; - if(setsockopt(sockfd, IPPROTO_IPV6, IPV6_V6ONLY, (const char*)&yes, sizeof(yes)) != 0) { - WARN_PRINT("Unable to unset IPv4 address mapping over IPv6"); - } - } - struct sockaddr_storage addr = {0}; size_t addr_size = _set_listen_sockaddr(&addr, p_port, ip_type, NULL); diff --git a/platform/windows/tcp_server_winsock.cpp b/platform/windows/tcp_server_winsock.cpp index eed03c9b8..89460eeaa 100644 --- a/platform/windows/tcp_server_winsock.cpp +++ b/platform/windows/tcp_server_winsock.cpp @@ -69,14 +69,6 @@ Error TCPServerWinsock::listen(uint16_t p_port,const List *p_accepted_ho sockfd = _socket_create(ip_type, SOCK_STREAM, IPPROTO_TCP); ERR_FAIL_COND_V(sockfd == INVALID_SOCKET, FAILED); - if(ip_type == IP_Address::TYPE_IPV6) { - // Use IPv6 only socket - int yes = 1; - if(setsockopt(sockfd, IPPROTO_IPV6, IPV6_V6ONLY, (const char*)&yes, sizeof(yes)) != 0) { - WARN_PRINT("Unable to unset IPv4 address mapping over IPv6"); - } - } - unsigned long par = 1; if (ioctlsocket(sockfd, FIONBIO, &par)) { perror("setting non-block mode"); -- cgit v1.2.3-70-g09d2 From c18c5013f837ea7d4de2f022d36f84e0abce6439 Mon Sep 17 00:00:00 2001 From: Fabio Alessandrelli Date: Thu, 1 Dec 2016 06:34:05 +0100 Subject: Migrate int.IP_TYPE_ constants to IP.TYPE_ --- core/io/http_client.cpp | 6 ++---- core/io/http_client.h | 2 +- core/io/ip.cpp | 17 +++++++++------- core/io/ip.h | 18 +++++++++-------- core/io/packet_peer_udp.cpp | 4 +--- core/io/packet_peer_udp.h | 3 ++- core/io/stream_peer_tcp.cpp | 4 +--- core/io/stream_peer_tcp.h | 2 +- core/io/tcp_server.cpp | 4 +--- core/io/tcp_server.h | 2 +- core/variant_call.cpp | 4 ---- doc/base/classes.xml | 30 ++++++++-------------------- drivers/unix/ip_unix.cpp | 6 +++--- drivers/unix/ip_unix.h | 2 +- drivers/unix/packet_peer_udp_posix.cpp | 2 +- drivers/unix/socket_helpers.h | 18 ++++++++--------- drivers/unix/stream_peer_tcp_posix.cpp | 4 ++-- drivers/unix/stream_peer_tcp_posix.h | 2 +- drivers/unix/tcp_server_posix.cpp | 2 +- platform/windows/packet_peer_udp_winsock.cpp | 2 +- platform/windows/stream_peer_winsock.cpp | 4 ++-- platform/windows/stream_peer_winsock.h | 2 +- platform/windows/tcp_server_winsock.cpp | 2 +- 23 files changed, 61 insertions(+), 81 deletions(-) (limited to 'drivers/unix/socket_helpers.h') diff --git a/core/io/http_client.cpp b/core/io/http_client.cpp index e3289b452..c9c674d4f 100644 --- a/core/io/http_client.cpp +++ b/core/io/http_client.cpp @@ -29,9 +29,7 @@ #include "http_client.h" #include "io/stream_peer_ssl.h" -VARIANT_ENUM_CAST(IP_Address::AddrType); - -Error HTTPClient::connect(const String &p_host, int p_port, bool p_ssl,bool p_verify_host, IP_Address::AddrType p_addr_type){ +Error HTTPClient::connect(const String &p_host, int p_port, bool p_ssl,bool p_verify_host, IP::Type p_addr_type){ close(); conn_port=p_port; @@ -636,7 +634,7 @@ Error HTTPClient::_get_http_data(uint8_t* p_buffer, int p_bytes,int &r_received) void HTTPClient::_bind_methods() { - ObjectTypeDB::bind_method(_MD("connect:Error","host","port","use_ssl","verify_host"),&HTTPClient::connect,DEFVAL(false),DEFVAL(true),DEFVAL(IP_Address::TYPE_ANY)); + ObjectTypeDB::bind_method(_MD("connect:Error","host","port","use_ssl","verify_host"),&HTTPClient::connect,DEFVAL(false),DEFVAL(true),DEFVAL(IP::TYPE_ANY)); ObjectTypeDB::bind_method(_MD("set_connection","connection:StreamPeer"),&HTTPClient::set_connection); ObjectTypeDB::bind_method(_MD("get_connection:StreamPeer"),&HTTPClient::get_connection); ObjectTypeDB::bind_method(_MD("request_raw","method","url","headers","body"),&HTTPClient::request_raw); diff --git a/core/io/http_client.h b/core/io/http_client.h index ba464c34c..34812616d 100644 --- a/core/io/http_client.h +++ b/core/io/http_client.h @@ -165,7 +165,7 @@ public: //Error connect_and_get(const String& p_url,bool p_verify_host=true); //connects to a full url and perform request - Error connect(const String &p_host,int p_port,bool p_ssl=false,bool p_verify_host=true, IP_Address::AddrType p_addr_type = IP_Address::TYPE_ANY); + Error connect(const String &p_host,int p_port,bool p_ssl=false,bool p_verify_host=true, IP::Type p_addr_type = IP::TYPE_ANY); void set_connection(const Ref& p_connection); Ref get_connection() const; diff --git a/core/io/ip.cpp b/core/io/ip.cpp index f0f273af1..00835c26d 100644 --- a/core/io/ip.cpp +++ b/core/io/ip.cpp @@ -32,7 +32,6 @@ #include "hash_map.h" VARIANT_ENUM_CAST(IP::ResolverStatus); -VARIANT_ENUM_CAST(IP_Address::AddrType); /************* RESOLVER ******************/ @@ -44,12 +43,12 @@ struct _IP_ResolverPrivate { volatile IP::ResolverStatus status; IP_Address response; String hostname; - IP_Address::AddrType type; + IP::Type type; void clear() { status = IP::RESOLVER_STATUS_NONE; response = IP_Address(); - type = IP_Address::TYPE_NONE; + type = IP::TYPE_NONE; hostname=""; }; @@ -112,7 +111,7 @@ struct _IP_ResolverPrivate { -IP_Address IP::resolve_hostname(const String& p_hostname, IP_Address::AddrType p_type) { +IP_Address IP::resolve_hostname(const String& p_hostname, IP::Type p_type) { GLOBAL_LOCK_FUNCTION; @@ -126,7 +125,7 @@ IP_Address IP::resolve_hostname(const String& p_hostname, IP_Address::AddrType p return res; } -IP::ResolverID IP::resolve_hostname_queue_item(const String& p_hostname, IP_Address::AddrType p_type) { +IP::ResolverID IP::resolve_hostname_queue_item(const String& p_hostname, IP::Type p_type) { GLOBAL_LOCK_FUNCTION; @@ -212,8 +211,8 @@ Array IP::_get_local_addresses() const { void IP::_bind_methods() { - ObjectTypeDB::bind_method(_MD("resolve_hostname","host","ip_type"),&IP::resolve_hostname,DEFVAL(IP_Address::TYPE_ANY)); - ObjectTypeDB::bind_method(_MD("resolve_hostname_queue_item","host","ip_type"),&IP::resolve_hostname_queue_item,DEFVAL(IP_Address::TYPE_ANY)); + ObjectTypeDB::bind_method(_MD("resolve_hostname","host","ip_type"),&IP::resolve_hostname,DEFVAL(IP::TYPE_ANY)); + ObjectTypeDB::bind_method(_MD("resolve_hostname_queue_item","host","ip_type"),&IP::resolve_hostname_queue_item,DEFVAL(IP::TYPE_ANY)); ObjectTypeDB::bind_method(_MD("get_resolve_item_status","id"),&IP::get_resolve_item_status); ObjectTypeDB::bind_method(_MD("get_resolve_item_address","id"),&IP::get_resolve_item_address); ObjectTypeDB::bind_method(_MD("erase_resolve_item","id"),&IP::erase_resolve_item); @@ -228,6 +227,10 @@ void IP::_bind_methods() { BIND_CONSTANT( RESOLVER_MAX_QUERIES ); BIND_CONSTANT( RESOLVER_INVALID_ID ); + BIND_CONSTANT( TYPE_NONE ); + BIND_CONSTANT( TYPE_IPV4 ); + BIND_CONSTANT( TYPE_IPV6 ); + BIND_CONSTANT( TYPE_ANY ); } diff --git a/core/io/ip.h b/core/io/ip.h index 742dd0e74..64360b9a7 100644 --- a/core/io/ip.h +++ b/core/io/ip.h @@ -48,12 +48,12 @@ public: RESOLVER_STATUS_ERROR, }; - enum AddressType { + enum Type { - ADDRESS_IPV4 = 1, - ADDRESS_IPV6 = 2, - - ADDRESS_ANY = 3, + TYPE_NONE = 0, + TYPE_IPV4 = 1, + TYPE_IPV6 = 2, + TYPE_ANY = 3, }; enum { @@ -73,7 +73,7 @@ protected: static IP*singleton; static void _bind_methods(); - virtual IP_Address _resolve_hostname(const String& p_hostname, IP_Address::AddrType p_type = IP_Address::TYPE_ANY)=0; + virtual IP_Address _resolve_hostname(const String& p_hostname, Type p_type = TYPE_ANY)=0; Array _get_local_addresses() const; static IP* (*_create)(); @@ -81,9 +81,9 @@ public: - IP_Address resolve_hostname(const String& p_hostname, IP_Address::AddrType p_type = IP_Address::TYPE_ANY); + IP_Address resolve_hostname(const String& p_hostname, Type p_type = TYPE_ANY); // async resolver hostname - ResolverID resolve_hostname_queue_item(const String& p_hostname, IP_Address::AddrType p_type = IP_Address::TYPE_ANY); + ResolverID resolve_hostname_queue_item(const String& p_hostname, Type p_type = TYPE_ANY); ResolverStatus get_resolve_item_status(ResolverID p_id) const; IP_Address get_resolve_item_address(ResolverID p_id) const; virtual void get_local_addresses(List *r_addresses) const=0; @@ -101,4 +101,6 @@ public: }; +VARIANT_ENUM_CAST(IP::Type); + #endif // IP_H diff --git a/core/io/packet_peer_udp.cpp b/core/io/packet_peer_udp.cpp index 810664791..dadef8a6f 100644 --- a/core/io/packet_peer_udp.cpp +++ b/core/io/packet_peer_udp.cpp @@ -31,8 +31,6 @@ PacketPeerUDP* (*PacketPeerUDP::_create)()=NULL; -VARIANT_ENUM_CAST(IP_Address::AddrType); - String PacketPeerUDP::_get_packet_ip() const { return get_packet_address(); @@ -83,5 +81,5 @@ PacketPeerUDP* PacketPeerUDP::create() { PacketPeerUDP::PacketPeerUDP() { - ip_type = IP_Address::TYPE_ANY; + ip_type = IP::TYPE_ANY; } diff --git a/core/io/packet_peer_udp.h b/core/io/packet_peer_udp.h index 011e8dd9a..821007a62 100644 --- a/core/io/packet_peer_udp.h +++ b/core/io/packet_peer_udp.h @@ -30,6 +30,7 @@ #define PACKET_PEER_UDP_H +#include "io/ip.h" #include "io/packet_peer.h" class PacketPeerUDP : public PacketPeer { @@ -37,7 +38,7 @@ class PacketPeerUDP : public PacketPeer { protected: - IP_Address::AddrType ip_type; + IP::Type ip_type; static PacketPeerUDP* (*_create)(); static void _bind_methods(); diff --git a/core/io/stream_peer_tcp.cpp b/core/io/stream_peer_tcp.cpp index b18bba4d2..d374f54a8 100644 --- a/core/io/stream_peer_tcp.cpp +++ b/core/io/stream_peer_tcp.cpp @@ -30,8 +30,6 @@ StreamPeerTCP* (*StreamPeerTCP::_create)()=NULL; -VARIANT_ENUM_CAST(IP_Address::AddrType); - Error StreamPeerTCP::_connect(const String& p_address,int p_port) { IP_Address ip; @@ -79,7 +77,7 @@ StreamPeerTCP* StreamPeerTCP::create() { StreamPeerTCP::StreamPeerTCP() { - ip_type = IP_Address::TYPE_ANY; + ip_type = IP::TYPE_ANY; } StreamPeerTCP::~StreamPeerTCP() { diff --git a/core/io/stream_peer_tcp.h b/core/io/stream_peer_tcp.h index 10e061972..f44784d2b 100644 --- a/core/io/stream_peer_tcp.h +++ b/core/io/stream_peer_tcp.h @@ -51,7 +51,7 @@ public: protected: - IP_Address::AddrType ip_type; + IP::Type ip_type; virtual Error _connect(const String& p_address, int p_port); static StreamPeerTCP* (*_create)(); diff --git a/core/io/tcp_server.cpp b/core/io/tcp_server.cpp index 29e8bd0c0..0dcec8001 100644 --- a/core/io/tcp_server.cpp +++ b/core/io/tcp_server.cpp @@ -30,8 +30,6 @@ TCP_Server* (*TCP_Server::_create)()=NULL; -VARIANT_ENUM_CAST(IP_Address::AddrType); - Ref TCP_Server::create_ref() { if (!_create) @@ -68,5 +66,5 @@ void TCP_Server::_bind_methods() { TCP_Server::TCP_Server() { - ip_type = IP_Address::TYPE_ANY; + ip_type = IP::TYPE_ANY; } diff --git a/core/io/tcp_server.h b/core/io/tcp_server.h index c380db52d..aef62eb71 100644 --- a/core/io/tcp_server.h +++ b/core/io/tcp_server.h @@ -38,7 +38,7 @@ class TCP_Server : public Reference { OBJ_TYPE( TCP_Server, Reference ); protected: - IP_Address::AddrType ip_type; + IP::Type ip_type; static TCP_Server* (*_create)(); diff --git a/core/variant_call.cpp b/core/variant_call.cpp index 0379ae019..99d5d1065 100644 --- a/core/variant_call.cpp +++ b/core/variant_call.cpp @@ -1825,10 +1825,6 @@ _VariantCall::addfunc(Variant::m_vtype,Variant::m_ret,_SCS(#m_method),VCALL(m_cl _VariantCall::add_constant(Variant::IMAGE,"INTERPOLATE_BILINEAR",Image::INTERPOLATE_BILINEAR); _VariantCall::add_constant(Variant::IMAGE,"INTERPOLATE_CUBIC",Image::INTERPOLATE_CUBIC); - _VariantCall::add_constant(Variant::INT, "IP_TYPE_NONE", IP_Address::TYPE_NONE); - _VariantCall::add_constant(Variant::INT, "IP_TYPE_IPV4", IP_Address::TYPE_IPV4); - _VariantCall::add_constant(Variant::INT, "IP_TYPE_IPV6", IP_Address::TYPE_IPV6); - _VariantCall::add_constant(Variant::INT, "IP_TYPE_ANY", IP_Address::TYPE_ANY); } void unregister_variant_methods() { diff --git a/doc/base/classes.xml b/doc/base/classes.xml index 07e2f719f..f1809d9e2 100644 --- a/doc/base/classes.xml +++ b/doc/base/classes.xml @@ -16082,7 +16082,7 @@ - + Resolve a given hostname, blocking. Resolved hostname is returned as an IPv4 or IPv6 depending on "ip_type". @@ -16093,7 +16093,7 @@ - + Create a queue item for resolving a given hostname to an IPv4 or IPv6 depending on "ip_type". The queue ID is returned, or RESOLVER_INVALID_ID on error. @@ -25375,15 +25375,10 @@ - - - + - Make this [PacketPeerUDP] listen on the "port" using protocol "ip_type" and a buffer size "recv_buf_size". Listens on all available adresses. - IP_TYPE_IPV4 = IPv4 only - IP_TYPE_IPV6 = IPv6 only - IP_TYPE_ANY = Dual stack (supports both IPv6 and IPv4 connections). + Make this [PacketPeerUDP] listen on the "port" with a buffer size "recv_buf_size". Listens on all available addresses. @@ -25393,10 +25388,8 @@ - - - Set the destination address and port for sending packets and variables, a hostname will be resolved using "ip_type" (v4/v6/any) if valid. + Set the destination address and port for sending packets and variables, a hostname will be resolved using if valid. @@ -39206,10 +39199,8 @@ - - - Connect to the specified host:port pair. A hostname will be resolved using "ip_type" (v4/v6/any) if valid. Returns [OK] on success or [FAILED] on failure. + Connect to the specified host:port pair. A hostname will be resolved if valid. Returns [OK] on success or [FAILED] on failure. @@ -40532,15 +40523,10 @@ - - - + - Listen on a port using protocol "ip_type", alternatively give a white-list of accepted hosts. - IP_TYPE_IPV4 = IPv4 only - IP_TYPE_IPV6 = IPv6 only - IP_TYPE_ANY = Dual stack (supports both IPv6 and IPv4 connections). + Listen on a port using protocol, alternatively give a white-list of accepted hosts. diff --git a/drivers/unix/ip_unix.cpp b/drivers/unix/ip_unix.cpp index 8b8e09c91..ad49d0dca 100644 --- a/drivers/unix/ip_unix.cpp +++ b/drivers/unix/ip_unix.cpp @@ -87,15 +87,15 @@ static IP_Address _sockaddr2ip(struct sockaddr* p_addr) { return ip; }; -IP_Address IP_Unix::_resolve_hostname(const String& p_hostname, IP_Address::AddrType p_type) { +IP_Address IP_Unix::_resolve_hostname(const String& p_hostname, Type p_type) { struct addrinfo hints; struct addrinfo* result; memset(&hints, 0, sizeof(struct addrinfo)); - if (p_type == IP_Address::TYPE_IPV4) { + if (p_type == TYPE_IPV4) { hints.ai_family = AF_INET; - } else if (p_type == IP_Address::TYPE_IPV6) { + } else if (p_type == TYPE_IPV6) { hints.ai_family = AF_INET6; hints.ai_flags = 0; } else { diff --git a/drivers/unix/ip_unix.h b/drivers/unix/ip_unix.h index d198a330e..9959d45a1 100644 --- a/drivers/unix/ip_unix.h +++ b/drivers/unix/ip_unix.h @@ -36,7 +36,7 @@ class IP_Unix : public IP { OBJ_TYPE(IP_Unix, IP); - virtual IP_Address _resolve_hostname(const String& p_hostname, IP_Address::AddrType p_type); + virtual IP_Address _resolve_hostname(const String& p_hostname, IP::Type p_type); static IP* _create_unix(); public: diff --git a/drivers/unix/packet_peer_udp_posix.cpp b/drivers/unix/packet_peer_udp_posix.cpp index 44a3e65e0..2b007f546 100644 --- a/drivers/unix/packet_peer_udp_posix.cpp +++ b/drivers/unix/packet_peer_udp_posix.cpp @@ -251,7 +251,7 @@ PacketPeerUDPPosix::PacketPeerUDPPosix() { packet_port=0; queue_count=0; peer_port=0; - ip_type = IP_Address::TYPE_ANY; + ip_type = IP::TYPE_ANY; } PacketPeerUDPPosix::~PacketPeerUDPPosix() { diff --git a/drivers/unix/socket_helpers.h b/drivers/unix/socket_helpers.h index aec4ec884..ffe201594 100644 --- a/drivers/unix/socket_helpers.h +++ b/drivers/unix/socket_helpers.h @@ -16,15 +16,15 @@ // helpers for sockaddr -> IP_Address and back, should work for posix and winsock. All implementations should use this -static size_t _set_sockaddr(struct sockaddr_storage* p_addr, const IP_Address& p_ip, int p_port, IP_Address::AddrType p_sock_type = IP_Address::TYPE_ANY) { +static size_t _set_sockaddr(struct sockaddr_storage* p_addr, const IP_Address& p_ip, int p_port, IP::Type p_sock_type = IP::TYPE_ANY) { memset(p_addr, 0, sizeof(struct sockaddr_storage)); // Dual stack (ANY) or matching ip type is required - ERR_FAIL_COND_V(p_sock_type != IP_Address::TYPE_ANY && p_sock_type != p_ip.type,0); + ERR_FAIL_COND_V(p_sock_type != IP::TYPE_ANY && p_sock_type != p_ip.type,0); // IPv6 socket - if (p_sock_type == IP_Address::TYPE_IPV6 || p_sock_type == IP_Address::TYPE_ANY) { + if (p_sock_type == IP::TYPE_IPV6 || p_sock_type == IP::TYPE_ANY) { struct sockaddr_in6* addr6 = (struct sockaddr_in6*)p_addr; addr6->sin6_family = AF_INET6; @@ -49,10 +49,10 @@ static size_t _set_sockaddr(struct sockaddr_storage* p_addr, const IP_Address& p }; }; -static size_t _set_listen_sockaddr(struct sockaddr_storage* p_addr, int p_port, IP_Address::AddrType p_address_type, const List *p_accepted_hosts) { +static size_t _set_listen_sockaddr(struct sockaddr_storage* p_addr, int p_port, IP::Type p_sock_type, const List *p_accepted_hosts) { memset(p_addr, 0, sizeof(struct sockaddr_storage)); - if (p_address_type == IP_Address::TYPE_IPV4) { + if (p_sock_type == IP::TYPE_IPV4) { struct sockaddr_in* addr4 = (struct sockaddr_in*)p_addr; addr4->sin_family = AF_INET; addr4->sin_port = htons(p_port); @@ -68,18 +68,18 @@ static size_t _set_listen_sockaddr(struct sockaddr_storage* p_addr, int p_port, }; }; -static int _socket_create(IP_Address::AddrType p_type, int type, int protocol) { +static int _socket_create(IP::Type p_type, int type, int protocol) { - ERR_FAIL_COND_V(p_type > IP_Address::TYPE_ANY || p_type < IP_Address::TYPE_NONE, ERR_INVALID_PARAMETER); + ERR_FAIL_COND_V(p_type > IP::TYPE_ANY || p_type < IP::TYPE_NONE, ERR_INVALID_PARAMETER); - int family = p_type == IP_Address::TYPE_IPV4 ? AF_INET : AF_INET6; + int family = p_type == IP::TYPE_IPV4 ? AF_INET : AF_INET6; int sockfd = socket(family, type, protocol); ERR_FAIL_COND_V( sockfd == -1, -1 ); if(family == AF_INET6) { // Select IPv4 over IPv6 mapping - int opt = p_type != IP_Address::TYPE_ANY; + int opt = p_type != IP::TYPE_ANY; if(setsockopt(sockfd, IPPROTO_IPV6, IPV6_V6ONLY, (const char*)&opt, sizeof(opt)) != 0) { WARN_PRINT("Unable to set/unset IPv4 address mapping over IPv6"); } diff --git a/drivers/unix/stream_peer_tcp_posix.cpp b/drivers/unix/stream_peer_tcp_posix.cpp index 8aae1e77a..fc6b08e64 100644 --- a/drivers/unix/stream_peer_tcp_posix.cpp +++ b/drivers/unix/stream_peer_tcp_posix.cpp @@ -122,7 +122,7 @@ Error StreamPeerTCPPosix::_poll_connection(bool p_block) const { return OK; }; -void StreamPeerTCPPosix::set_socket(int p_sockfd, IP_Address p_host, int p_port, IP_Address::AddrType p_ip_type) { +void StreamPeerTCPPosix::set_socket(int p_sockfd, IP_Address p_host, int p_port, IP::Type p_ip_type) { ip_type = p_ip_type; sockfd = p_sockfd; @@ -393,7 +393,7 @@ StreamPeerTCPPosix::StreamPeerTCPPosix() { sockfd = -1; status = STATUS_NONE; peer_port = 0; - ip_type = IP_Address::TYPE_ANY; + ip_type = IP::TYPE_ANY; }; StreamPeerTCPPosix::~StreamPeerTCPPosix() { diff --git a/drivers/unix/stream_peer_tcp_posix.h b/drivers/unix/stream_peer_tcp_posix.h index 1d3e94c7c..e4e912117 100644 --- a/drivers/unix/stream_peer_tcp_posix.h +++ b/drivers/unix/stream_peer_tcp_posix.h @@ -69,7 +69,7 @@ public: virtual int get_available_bytes() const; - void set_socket(int p_sockfd, IP_Address p_host, int p_port, IP_Address::AddrType p_ip_type); + void set_socket(int p_sockfd, IP_Address p_host, int p_port, IP::Type p_ip_type); virtual IP_Address get_connected_host() const; virtual uint16_t get_connected_port() const; diff --git a/drivers/unix/tcp_server_posix.cpp b/drivers/unix/tcp_server_posix.cpp index bf3b7369e..dd00e0bf7 100644 --- a/drivers/unix/tcp_server_posix.cpp +++ b/drivers/unix/tcp_server_posix.cpp @@ -176,7 +176,7 @@ void TCPServerPosix::stop() { TCPServerPosix::TCPServerPosix() { listen_sockfd = -1; - ip_type = IP_Address::TYPE_ANY; + ip_type = IP::TYPE_ANY; }; TCPServerPosix::~TCPServerPosix() { diff --git a/platform/windows/packet_peer_udp_winsock.cpp b/platform/windows/packet_peer_udp_winsock.cpp index 4201a3e86..53524f807 100644 --- a/platform/windows/packet_peer_udp_winsock.cpp +++ b/platform/windows/packet_peer_udp_winsock.cpp @@ -269,7 +269,7 @@ PacketPeerUDPWinsock::PacketPeerUDPWinsock() { packet_port=0; queue_count=0; peer_port=0; - ip_type = IP_Address::TYPE_ANY; + ip_type = IP::TYPE_ANY; } PacketPeerUDPWinsock::~PacketPeerUDPWinsock() { diff --git a/platform/windows/stream_peer_winsock.cpp b/platform/windows/stream_peer_winsock.cpp index f03ecca22..d40504b2d 100644 --- a/platform/windows/stream_peer_winsock.cpp +++ b/platform/windows/stream_peer_winsock.cpp @@ -289,7 +289,7 @@ void StreamPeerWinsock::disconnect() { peer_port = 0; }; -void StreamPeerWinsock::set_socket(int p_sockfd, IP_Address p_host, int p_port, IP_Address::AddrType p_ip_type) { +void StreamPeerWinsock::set_socket(int p_sockfd, IP_Address p_host, int p_port, IP::Type p_ip_type) { ip_type = p_ip_type; sockfd = p_sockfd; @@ -368,7 +368,7 @@ StreamPeerWinsock::StreamPeerWinsock() { sockfd = INVALID_SOCKET; status = STATUS_NONE; peer_port = 0; - ip_type = IP_Address::TYPE_ANY; + ip_type = IP::TYPE_ANY; }; StreamPeerWinsock::~StreamPeerWinsock() { diff --git a/platform/windows/stream_peer_winsock.h b/platform/windows/stream_peer_winsock.h index 7a7ceab8a..c2b63e1ff 100644 --- a/platform/windows/stream_peer_winsock.h +++ b/platform/windows/stream_peer_winsock.h @@ -68,7 +68,7 @@ public: virtual int get_available_bytes() const; - void set_socket(int p_sockfd, IP_Address p_host, int p_port, IP_Address::AddrType p_ip_type); + void set_socket(int p_sockfd, IP_Address p_host, int p_port, IP::Type p_ip_type); virtual IP_Address get_connected_host() const; virtual uint16_t get_connected_port() const; diff --git a/platform/windows/tcp_server_winsock.cpp b/platform/windows/tcp_server_winsock.cpp index 89460eeaa..ac37f80e7 100644 --- a/platform/windows/tcp_server_winsock.cpp +++ b/platform/windows/tcp_server_winsock.cpp @@ -168,7 +168,7 @@ void TCPServerWinsock::stop() { TCPServerWinsock::TCPServerWinsock() { listen_sockfd = INVALID_SOCKET; - ip_type = IP_Address::TYPE_ANY; + ip_type = IP::TYPE_ANY; }; TCPServerWinsock::~TCPServerWinsock() { -- cgit v1.2.3-70-g09d2 From 1aff508dd9713abf0db0d0436fa7f7c4788c5a4a Mon Sep 17 00:00:00 2001 From: Fabio Alessandrelli Date: Mon, 5 Dec 2016 16:32:38 +0100 Subject: IP_Address now handle IPv4 and IPv6 transparently IP_Address changes: - Converts to and from String transparently while handling IPv4 as IPv6 mapped (::ffff:[IP]) address internally. - Completely remove AddrType enum. - Setting/Getting of ip array is now only possible through dedicated functions (ie. set_ipv4, get_ipv4, set_ipv6, get_ipv6) - Add function to know if the address is a valid IPv4 (for IP implementation and enet) --- bin/tests/test_string.cpp | 2 +- core/io/ip.cpp | 9 ++- core/io/ip_address.cpp | 82 +++++++++++++++++----------- core/io/ip_address.h | 21 +++---- drivers/unix/ip_unix.cpp | 16 ++---- drivers/unix/packet_peer_udp_posix.cpp | 20 ++++--- drivers/unix/socket_helpers.h | 30 +++++----- drivers/unix/stream_peer_tcp_posix.cpp | 2 +- modules/enet/networked_multiplayer_enet.cpp | 11 ++-- platform/windows/packet_peer_udp_winsock.cpp | 18 +++--- platform/windows/stream_peer_winsock.cpp | 2 +- 11 files changed, 112 insertions(+), 101 deletions(-) (limited to 'drivers/unix/socket_helpers.h') diff --git a/bin/tests/test_string.cpp b/bin/tests/test_string.cpp index 4990c5889..d99ad4476 100644 --- a/bin/tests/test_string.cpp +++ b/bin/tests/test_string.cpp @@ -842,7 +842,7 @@ bool test_29() { IP_Address ip0("2001:0db8:85a3:0000:0000:8a2e:0370:7334"); OS::get_singleton()->print("ip0 is %ls\n", String(ip0).c_str()); - IP_Address ip(0x0123, 0x4567, 0x89ab, 0xcdef, IP_Address::TYPE_IPV6); + IP_Address ip(0x0123, 0x4567, 0x89ab, 0xcdef, true); OS::get_singleton()->print("ip6 is %ls\n", String(ip).c_str()); IP_Address ip2("fe80::52e5:49ff:fe93:1baf"); diff --git a/core/io/ip.cpp b/core/io/ip.cpp index 00835c26d..113be976a 100644 --- a/core/io/ip.cpp +++ b/core/io/ip.cpp @@ -82,7 +82,7 @@ struct _IP_ResolverPrivate { continue; queue[i].response=IP::get_singleton()->resolve_hostname(queue[i].hostname, queue[i].type); - if (queue[i].response.type==IP_Address::TYPE_NONE) + if (queue[i].response==IP_Address()) queue[i].status=IP::RESOLVER_STATUS_ERROR; else queue[i].status=IP::RESOLVER_STATUS_DONE; @@ -116,7 +116,8 @@ IP_Address IP::resolve_hostname(const String& p_hostname, IP::Type p_type) { GLOBAL_LOCK_FUNCTION; if (resolver->cache.has(p_hostname)) - if (resolver->cache[p_hostname].type & p_type != 0) + if ((resolver->cache[p_hostname].is_ipv4() && p_type != IP::TYPE_IPV6) || + (!resolver->cache[p_hostname].is_ipv4() && p_type != IP::TYPE_IPV4)) return resolver->cache[p_hostname]; // requested type is different from type in cache. continue resolution, if successful it'll overwrite cache @@ -138,7 +139,9 @@ IP::ResolverID IP::resolve_hostname_queue_item(const String& p_hostname, IP::Typ resolver->queue[id].hostname=p_hostname; resolver->queue[id].type = p_type; - if (resolver->cache.has(p_hostname) && (resolver->cache[p_hostname].type & p_type) != 0) { + if (resolver->cache.has(p_hostname) && + ((resolver->cache[p_hostname].is_ipv4() && p_type != IP::TYPE_IPV6) || + (!resolver->cache[p_hostname].is_ipv4() && p_type != IP::TYPE_IPV4))) { resolver->queue[id].response=resolver->cache[p_hostname]; resolver->queue[id].status=IP::RESOLVER_STATUS_DONE; } else { diff --git a/core/io/ip_address.cpp b/core/io/ip_address.cpp index 9887cd132..7df5fe79e 100644 --- a/core/io/ip_address.cpp +++ b/core/io/ip_address.cpp @@ -38,21 +38,18 @@ IP_Address::operator Variant() const { IP_Address::operator String() const { - if (type == TYPE_NONE) - return "0.0.0.0"; - if (type == TYPE_IPV4) - return itos(field8[0])+"."+itos(field8[1])+"."+itos(field8[2])+"."+itos(field8[3]); - else { - String ret; - for (int i=0; i<8; i++) { - if (i > 0) - ret = ret + ":"; - uint16_t num = (field8[i*2] << 8) + field8[i*2+1]; - ret = ret + String::num_int64(num, 16); - }; - - return ret; + if(is_ipv4()) + // IPv4 address mapped to IPv6 + return itos(field8[12])+"."+itos(field8[13])+"."+itos(field8[14])+"."+itos(field8[15]); + String ret; + for (int i=0; i<8; i++) { + if (i > 0) + ret = ret + ":"; + uint16_t num = (field8[i*2] << 8) + field8[i*2+1]; + ret = ret + String::num_int64(num, 16); }; + + return ret; } static void _parse_hex(const String& p_string, int p_start, uint8_t* p_dst) { @@ -176,17 +173,41 @@ void IP_Address::clear() { memset(&field8[0], 0, sizeof(field8)); }; +bool IP_Address::is_ipv4() const{ + return (field32[0]==0 && field32[1]==0 && field16[4]==0 && field16[5]==0xffff); +} + +const uint8_t *IP_Address::get_ipv4() const{ + ERR_FAIL_COND_V(!is_ipv4(),0); + return &(field8[12]); +} + +void IP_Address::set_ipv4(const uint8_t *p_ip) { + clear(); + field16[5]=0xffff; + field32[3]=*((const uint32_t *)p_ip); +} + +const uint8_t *IP_Address::get_ipv6() const{ + return field8; +} + +void IP_Address::set_ipv6(const uint8_t *p_buf) { + clear(); + for (int i=0; i<16; i++) + field8[i] = p_buf[i]; +} + IP_Address::IP_Address(const String& p_string) { clear(); if (p_string.find(":") >= 0) { _parse_ipv6(p_string); - type = TYPE_IPV6; } else { - - _parse_ipv4(p_string, 0, &field8[0]); - type = TYPE_IPV4; + // Mapped to IPv6 + field16[5] = 0xffff; + _parse_ipv4(p_string, 0, &field8[12]); }; } @@ -198,25 +219,22 @@ _FORCE_INLINE_ static void _32_to_buf(uint8_t* p_dst, uint32_t p_n) { p_dst[3] = (p_n >> 0) & 0xff; }; -IP_Address::IP_Address(uint32_t p_a,uint32_t p_b,uint32_t p_c,uint32_t p_d, IP_Address::AddrType p_type) { +IP_Address::IP_Address(uint32_t p_a,uint32_t p_b,uint32_t p_c,uint32_t p_d, bool is_v6) { - type = p_type; - memset(&field8[0], 0, sizeof(field8)); - if (p_type == TYPE_IPV4) { - field8[0]=p_a; - field8[1]=p_b; - field8[2]=p_c; - field8[3]=p_d; - } else if (type == TYPE_IPV6) { + clear(); + if (!is_v6) { + // Mapped to IPv6 + field16[5]=0xffff; + field8[12]=p_a; + field8[13]=p_b; + field8[14]=p_c; + field8[15]=p_d; + } else { _32_to_buf(&field8[0], p_a); _32_to_buf(&field8[4], p_b); _32_to_buf(&field8[8], p_c); _32_to_buf(&field8[12], p_d); - } else { - type = TYPE_NONE; - ERR_EXPLAIN("Invalid type specified for IP_Address (use TYPE_IPV4 or TYPE_IPV6"); - ERR_FAIL(); - }; + } } diff --git a/core/io/ip_address.h b/core/io/ip_address.h index fe13d7061..b7c164954 100644 --- a/core/io/ip_address.h +++ b/core/io/ip_address.h @@ -33,16 +33,7 @@ struct IP_Address { -public: - enum AddrType { - TYPE_NONE = 0, - TYPE_IPV4 = 1, - TYPE_IPV6 = 2, - - TYPE_ANY = 3, - }; - - AddrType type; +private: union { uint8_t field8[16]; @@ -70,11 +61,17 @@ public: } void clear(); + bool is_ipv4() const; + const uint8_t *get_ipv4() const; + void set_ipv4(const uint8_t *p_ip); + + const uint8_t *get_ipv6() const; + void set_ipv6(const uint8_t *buf); operator String() const; IP_Address(const String& p_string); - IP_Address(uint32_t p_a,uint32_t p_b,uint32_t p_c,uint32_t p_d, AddrType p_type=TYPE_IPV4); - IP_Address() { clear(); type=TYPE_NONE; } + IP_Address(uint32_t p_a,uint32_t p_b,uint32_t p_c,uint32_t p_d, bool is_v6=false); + IP_Address() { clear(); } }; diff --git a/drivers/unix/ip_unix.cpp b/drivers/unix/ip_unix.cpp index ad49d0dca..42c93c351 100644 --- a/drivers/unix/ip_unix.cpp +++ b/drivers/unix/ip_unix.cpp @@ -75,13 +75,10 @@ static IP_Address _sockaddr2ip(struct sockaddr* p_addr) { IP_Address ip; if (p_addr->sa_family == AF_INET) { struct sockaddr_in* addr = (struct sockaddr_in*)p_addr; - ip.field32[0] = *((unsigned long*)&addr->sin_addr); - ip.type = IP_Address::TYPE_IPV4; + ip.set_ipv4((uint8_t *)&(addr->sin_addr)); } else { struct sockaddr_in6* addr6 = (struct sockaddr_in6*)p_addr; - for (int i=0; i<16; i++) - ip.field8[i] = addr6->sin6_addr.s6_addr[i]; - ip.type = IP_Address::TYPE_IPV6; + ip.set_ipv6(addr6->sin6_addr.s6_addr); }; return ip; @@ -189,15 +186,12 @@ void IP_Unix::get_local_addresses(List *r_addresses) const { SOCKADDR_IN* ipv4 = reinterpret_cast(address->Address.lpSockaddr); - ip.field32[0] = *((unsigned long*)&ipv4->sin_addr); - ip.type = IP_Address::TYPE_IPV4; + ip.set_ipv4((uint8_t *)&(ipv4->sin_addr)); } else { // ipv6 SOCKADDR_IN6* ipv6 = reinterpret_cast(address->Address.lpSockaddr); - for (int i=0; i<16; i++) { - ip.field8[i] = ipv6->sin6_addr.s6_addr[i]; - }; - ip.type = IP_Address::TYPE_IPV6; + + ip.set_ipv6(ipv6->sin6_addr.s6_addr); }; diff --git a/drivers/unix/packet_peer_udp_posix.cpp b/drivers/unix/packet_peer_udp_posix.cpp index 2b007f546..62290c417 100644 --- a/drivers/unix/packet_peer_udp_posix.cpp +++ b/drivers/unix/packet_peer_udp_posix.cpp @@ -76,12 +76,14 @@ Error PacketPeerUDPPosix::get_packet(const uint8_t **r_buffer,int &r_buffer_size uint32_t size; uint8_t type; rb.read(&type, 1, true); - if (type == IP_Address::TYPE_IPV4) { - rb.read((uint8_t*)&packet_ip.field8,4,true); - packet_ip.type = IP_Address::TYPE_IPV4; + if (type == IP::TYPE_IPV4) { + uint8_t ip[4]; + rb.read(ip,4,true); + packet_ip.set_ipv4(ip); } else { - rb.read((uint8_t*)&packet_ip.field8,16,true); - packet_ip.type = IP_Address::TYPE_IPV6; + uint8_t ipv6[16]; + rb.read(ipv6,16,true); + packet_ip.set_ipv6(ipv6); }; rb.read((uint8_t*)&packet_port,4,true); rb.read((uint8_t*)&size,4,true); @@ -94,7 +96,7 @@ Error PacketPeerUDPPosix::get_packet(const uint8_t **r_buffer,int &r_buffer_size } Error PacketPeerUDPPosix::put_packet(const uint8_t *p_buffer,int p_buffer_size){ - ERR_FAIL_COND_V(peer_addr.type == IP_Address::TYPE_NONE, ERR_UNCONFIGURED); + ERR_FAIL_COND_V(peer_addr == IP_Address(), ERR_UNCONFIGURED); int sock = _get_socket(); ERR_FAIL_COND_V( sock == -1, FAILED ); @@ -163,7 +165,7 @@ Error PacketPeerUDPPosix::_poll(bool p_wait) { uint32_t port = 0; if (from.ss_family == AF_INET) { - uint8_t type = (uint8_t)IP_Address::TYPE_IPV4; + uint8_t type = (uint8_t)IP::TYPE_IPV4; rb.write(&type, 1); struct sockaddr_in* sin_from = (struct sockaddr_in*)&from; rb.write((uint8_t*)&sin_from->sin_addr, 4); @@ -171,7 +173,7 @@ Error PacketPeerUDPPosix::_poll(bool p_wait) { } else if (from.ss_family == AF_INET6) { - uint8_t type = (uint8_t)IP_Address::TYPE_IPV6; + uint8_t type = (uint8_t)IP::TYPE_IPV6; rb.write(&type, 1); struct sockaddr_in6* s6_from = (struct sockaddr_in6*)&from; @@ -181,7 +183,7 @@ Error PacketPeerUDPPosix::_poll(bool p_wait) { } else { // WARN_PRINT("Ignoring packet with unknown address family"); - uint8_t type = (uint8_t)IP_Address::TYPE_NONE; + uint8_t type = (uint8_t)IP::TYPE_NONE; rb.write(&type, 1); }; diff --git a/drivers/unix/socket_helpers.h b/drivers/unix/socket_helpers.h index ffe201594..962f228c3 100644 --- a/drivers/unix/socket_helpers.h +++ b/drivers/unix/socket_helpers.h @@ -20,31 +20,30 @@ static size_t _set_sockaddr(struct sockaddr_storage* p_addr, const IP_Address& p memset(p_addr, 0, sizeof(struct sockaddr_storage)); - // Dual stack (ANY) or matching ip type is required - ERR_FAIL_COND_V(p_sock_type != IP::TYPE_ANY && p_sock_type != p_ip.type,0); + ERR_FAIL_COND_V(p_ip==IP_Address(),0); // IPv6 socket if (p_sock_type == IP::TYPE_IPV6 || p_sock_type == IP::TYPE_ANY) { + // IPv6 only socket with IPv4 address + ERR_FAIL_COND_V(p_sock_type == IP::TYPE_IPV6 && p_ip.is_ipv4(),0); + struct sockaddr_in6* addr6 = (struct sockaddr_in6*)p_addr; addr6->sin6_family = AF_INET6; addr6->sin6_port = htons(p_port); - if(p_ip.type == IP_Address::TYPE_IPV4) { - // Remapping needed - uint16_t base[8] = {0x0, 0x0, 0x0, 0x0, 0x0, 0xffff, p_ip.field16[0], p_ip.field16[1]}; - copymem(&addr6->sin6_addr.s6_addr, base, 16); - - } else { - copymem(&addr6->sin6_addr.s6_addr, p_ip.field8, 16); - } + copymem(&addr6->sin6_addr.s6_addr, p_ip.get_ipv6(), 16); return sizeof(sockaddr_in6); } else { // IPv4 socket + // IPv4 socket with IPv6 address + ERR_FAIL_COND_V(!p_ip.is_ipv4(),0); + + uint32_t ipv4 = *((uint32_t *)p_ip.get_ipv4()); struct sockaddr_in* addr4 = (struct sockaddr_in*)p_addr; - addr4->sin_family = AF_INET; // host byte order + addr4->sin_family = AF_INET; addr4->sin_port = htons(p_port); // short, network byte order - addr4->sin_addr = *((struct in_addr*)&p_ip.field32[0]); + copymem(&addr4->sin_addr.s_addr, p_ip.get_ipv4(), 16); return sizeof(sockaddr_in); }; }; @@ -92,19 +91,16 @@ static int _socket_create(IP::Type p_type, int type, int protocol) { static void _set_ip_addr_port(IP_Address& r_ip, int& r_port, struct sockaddr_storage* p_addr) { if (p_addr->ss_family == AF_INET) { - r_ip.type = IP_Address::TYPE_IPV4; struct sockaddr_in* addr4 = (struct sockaddr_in*)p_addr; - r_ip.field32[0] = (uint32_t)addr4->sin_addr.s_addr; + r_ip.set_ipv4((uint8_t *)&(addr4->sin_addr.s_addr)); r_port = ntohs(addr4->sin_port); } else if (p_addr->ss_family == AF_INET6) { - r_ip.type = IP_Address::TYPE_IPV6; - struct sockaddr_in6* addr6 = (struct sockaddr_in6*)p_addr; - copymem(&r_ip.field8, addr6->sin6_addr.s6_addr, 16); + r_ip.set_ipv6(addr6->sin6_addr.s6_addr); r_port = ntohs(addr6->sin6_port); }; diff --git a/drivers/unix/stream_peer_tcp_posix.cpp b/drivers/unix/stream_peer_tcp_posix.cpp index fc6b08e64..8889f997f 100644 --- a/drivers/unix/stream_peer_tcp_posix.cpp +++ b/drivers/unix/stream_peer_tcp_posix.cpp @@ -141,7 +141,7 @@ void StreamPeerTCPPosix::set_socket(int p_sockfd, IP_Address p_host, int p_port, Error StreamPeerTCPPosix::connect(const IP_Address& p_host, uint16_t p_port) { - ERR_FAIL_COND_V( p_host.type == IP_Address::TYPE_NONE, ERR_INVALID_PARAMETER); + ERR_FAIL_COND_V( p_host == IP_Address(), ERR_INVALID_PARAMETER); sockfd = _socket_create(ip_type, SOCK_STREAM, IPPROTO_TCP); if (sockfd == -1) { diff --git a/modules/enet/networked_multiplayer_enet.cpp b/modules/enet/networked_multiplayer_enet.cpp index a82283591..7a28f59ab 100644 --- a/modules/enet/networked_multiplayer_enet.cpp +++ b/modules/enet/networked_multiplayer_enet.cpp @@ -77,7 +77,7 @@ Error NetworkedMultiplayerENet::create_server(int p_port, int p_max_clients, int Error NetworkedMultiplayerENet::create_client(const IP_Address& p_ip, int p_port, int p_in_bandwidth, int p_out_bandwidth){ ERR_FAIL_COND_V(active,ERR_ALREADY_IN_USE); - ERR_FAIL_COND_V(p_ip.type != IP_Address::TYPE_IPV4, ERR_INVALID_PARAMETER); + ERR_FAIL_COND_V(!p_ip.is_ipv4(), ERR_INVALID_PARAMETER); host = enet_host_create (NULL /* create a client host */, 1 /* only allow 1 outgoing connection */, @@ -91,7 +91,7 @@ Error NetworkedMultiplayerENet::create_client(const IP_Address& p_ip, int p_port _setup_compressor(); ENetAddress address; - address.host=p_ip.field32[0]; + address.host=*((uint32_t *)p_ip.get_ipv4()); address.port=p_port; //enet_address_set_host (& address, "localhost"); @@ -150,8 +150,7 @@ void NetworkedMultiplayerENet::poll(){ } IP_Address ip; - ip.type = IP_Address::TYPE_IPV4; - ip.field32[0]=event.peer -> address.host; + ip.set_ipv4((uint8_t *)&(event.peer -> address.host)); int *new_id = memnew( int ); *new_id = event.data; @@ -685,6 +684,6 @@ NetworkedMultiplayerENet::~NetworkedMultiplayerENet(){ // sets IP for ENet to bind when using create_server // if no IP is set, then ENet bind to ENET_HOST_ANY void NetworkedMultiplayerENet::set_bind_ip(const IP_Address& p_ip){ - ERR_FAIL_COND(p_ip.type != IP_Address::TYPE_IPV4); - bind_ip=p_ip.field32[0]; + ERR_FAIL_COND(!p_ip.is_ipv4()); + bind_ip=*(uint32_t *)p_ip.get_ipv4(); } diff --git a/platform/windows/packet_peer_udp_winsock.cpp b/platform/windows/packet_peer_udp_winsock.cpp index 53524f807..bad967eed 100644 --- a/platform/windows/packet_peer_udp_winsock.cpp +++ b/platform/windows/packet_peer_udp_winsock.cpp @@ -53,12 +53,14 @@ Error PacketPeerUDPWinsock::get_packet(const uint8_t **r_buffer,int &r_buffer_si uint32_t size; uint8_t type; rb.read(&type, 1, true); - if (type == IP_Address::TYPE_IPV4) { - rb.read((uint8_t*)&packet_ip.field8,4,true); - packet_ip.type = IP_Address::TYPE_IPV4; + if (type == IP::TYPE_IPV4) { + uint8_t ip[4]; + rb.read(ip,4,true); + packet_ip.set_ipv4(ip); } else { - rb.read((uint8_t*)&packet_ip.field8,16,true); - packet_ip.type = IP_Address::TYPE_IPV6; + uint8_t ip[16]; + rb.read(ip,16,true); + packet_ip.set_ipv6(ip); }; rb.read((uint8_t*)&packet_port,4,true); rb.read((uint8_t*)&size,4,true); @@ -162,7 +164,7 @@ Error PacketPeerUDPWinsock::_poll(bool p_wait) { uint32_t port = 0; if (from.ss_family == AF_INET) { - uint8_t type = (uint8_t)IP_Address::TYPE_IPV4; + uint8_t type = (uint8_t)IP::TYPE_IPV4; rb.write(&type, 1); struct sockaddr_in* sin_from = (struct sockaddr_in*)&from; rb.write((uint8_t*)&sin_from->sin_addr, 4); @@ -170,7 +172,7 @@ Error PacketPeerUDPWinsock::_poll(bool p_wait) { } else if (from.ss_family == AF_INET6) { - uint8_t type = (uint8_t)IP_Address::TYPE_IPV6; + uint8_t type = (uint8_t)IP::TYPE_IPV6; rb.write(&type, 1); struct sockaddr_in6* s6_from = (struct sockaddr_in6*)&from; @@ -180,7 +182,7 @@ Error PacketPeerUDPWinsock::_poll(bool p_wait) { } else { // WARN_PRINT("Ignoring packet with unknown address family"); - uint8_t type = (uint8_t)IP_Address::TYPE_NONE; + uint8_t type = (uint8_t)IP::TYPE_NONE; rb.write(&type, 1); }; diff --git a/platform/windows/stream_peer_winsock.cpp b/platform/windows/stream_peer_winsock.cpp index d40504b2d..e9a017a0f 100644 --- a/platform/windows/stream_peer_winsock.cpp +++ b/platform/windows/stream_peer_winsock.cpp @@ -300,7 +300,7 @@ void StreamPeerWinsock::set_socket(int p_sockfd, IP_Address p_host, int p_port, Error StreamPeerWinsock::connect(const IP_Address& p_host, uint16_t p_port) { - ERR_FAIL_COND_V( p_host.type == IP_Address::TYPE_NONE, ERR_INVALID_PARAMETER); + ERR_FAIL_COND_V( p_host == IP_Address(), ERR_INVALID_PARAMETER); sockfd = _socket_create(ip_type, SOCK_STREAM, IPPROTO_TCP); if (sockfd == INVALID_SOCKET) { -- cgit v1.2.3-70-g09d2