diff --git a/drivers/unix/ip_unix.cpp b/drivers/unix/ip_unix.cpp index 5987c1675d7..5a1a26e8745 100644 --- a/drivers/unix/ip_unix.cpp +++ b/drivers/unix/ip_unix.cpp @@ -28,23 +28,10 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ +#if defined(UNIX_ENABLED) + #include "ip_unix.h" -#if defined(UNIX_ENABLED) || defined(WINDOWS_ENABLED) - -#ifdef WINDOWS_ENABLED - -#define WIN32_LEAN_AND_MEAN -#include -#include -#include - -#include - -#include - -#else // UNIX - #include #ifdef ANDROID_ENABLED @@ -67,8 +54,6 @@ #include // Order is important on OpenBSD, leave as last. -#endif // UNIX - #include static IPAddress _sockaddr2ip(struct sockaddr *p_addr) { @@ -108,7 +93,7 @@ void IPUnix::_resolve_hostname(List &r_addresses, const String &p_hos } if (result == nullptr || result->ai_addr == nullptr) { - print_verbose("Invalid response from getaddrinfo"); + print_verbose("Invalid response from getaddrinfo."); if (result) { freeaddrinfo(result); } @@ -132,56 +117,6 @@ void IPUnix::_resolve_hostname(List &r_addresses, const String &p_hos freeaddrinfo(result); } -#if defined(WINDOWS_ENABLED) - -void IPUnix::get_local_interfaces(HashMap *r_interfaces) const { - ULONG buf_size = 1024; - IP_ADAPTER_ADDRESSES *addrs; - - while (true) { - addrs = (IP_ADAPTER_ADDRESSES *)memalloc(buf_size); - int err = GetAdaptersAddresses(AF_UNSPEC, GAA_FLAG_SKIP_ANYCAST | GAA_FLAG_SKIP_MULTICAST | GAA_FLAG_SKIP_DNS_SERVER | GAA_FLAG_SKIP_FRIENDLY_NAME, - nullptr, addrs, &buf_size); - if (err == NO_ERROR) { - break; - } - memfree(addrs); - if (err == ERROR_BUFFER_OVERFLOW) { - continue; // will go back and alloc the right size - } - - ERR_FAIL_MSG("Call to GetAdaptersAddresses failed with error " + itos(err) + "."); - } - - IP_ADAPTER_ADDRESSES *adapter = addrs; - - while (adapter != nullptr) { - Interface_Info info; - info.name = adapter->AdapterName; - info.name_friendly = adapter->FriendlyName; - info.index = String::num_uint64(adapter->IfIndex); - - IP_ADAPTER_UNICAST_ADDRESS *address = adapter->FirstUnicastAddress; - while (address != nullptr) { - int family = address->Address.lpSockaddr->sa_family; - if (family != AF_INET && family != AF_INET6) { - continue; - } - info.ip_addresses.push_front(_sockaddr2ip(address->Address.lpSockaddr)); - address = address->Next; - } - adapter = adapter->Next; - // Only add interface if it has at least one IP - if (info.ip_addresses.size() > 0) { - r_interfaces->insert(info.name, info); - } - } - - memfree(addrs); -} - -#else // UNIX - void IPUnix::get_local_interfaces(HashMap *r_interfaces) const { struct ifaddrs *ifAddrStruct = nullptr; struct ifaddrs *ifa = nullptr; @@ -219,8 +154,6 @@ void IPUnix::get_local_interfaces(HashMap *r_interfaces) } } -#endif // UNIX - void IPUnix::make_default() { _create = _create_unix; } @@ -232,4 +165,4 @@ IP *IPUnix::_create_unix() { IPUnix::IPUnix() { } -#endif // UNIX_ENABLED || WINDOWS_ENABLED +#endif // UNIX_ENABLED diff --git a/drivers/unix/ip_unix.h b/drivers/unix/ip_unix.h index 274b7c561e7..7e496629ef4 100644 --- a/drivers/unix/ip_unix.h +++ b/drivers/unix/ip_unix.h @@ -31,9 +31,9 @@ #ifndef IP_UNIX_H #define IP_UNIX_H -#include "core/io/ip.h" +#if defined(UNIX_ENABLED) -#if defined(UNIX_ENABLED) || defined(WINDOWS_ENABLED) +#include "core/io/ip.h" class IPUnix : public IP { GDCLASS(IPUnix, IP); @@ -49,6 +49,6 @@ public: IPUnix(); }; -#endif +#endif // UNIX_ENABLED #endif // IP_UNIX_H diff --git a/drivers/windows/ip_windows.cpp b/drivers/windows/ip_windows.cpp new file mode 100644 index 00000000000..4ff368d3f45 --- /dev/null +++ b/drivers/windows/ip_windows.cpp @@ -0,0 +1,164 @@ +/**************************************************************************/ +/* ip_windows.cpp */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/**************************************************************************/ + +#if defined(WINDOWS_ENABLED) + +#include "ip_windows.h" + +#define WIN32_LEAN_AND_MEAN +#include +#include +#include + +#include + +#include + +#include + +static IPAddress _sockaddr2ip(struct sockaddr *p_addr) { + IPAddress ip; + + if (p_addr->sa_family == AF_INET) { + struct sockaddr_in *addr = (struct sockaddr_in *)p_addr; + ip.set_ipv4((uint8_t *)&(addr->sin_addr)); + } else if (p_addr->sa_family == AF_INET6) { + struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *)p_addr; + ip.set_ipv6(addr6->sin6_addr.s6_addr); + } + + return ip; +} + +void IPWindows::_resolve_hostname(List &r_addresses, const String &p_hostname, Type p_type) const { + struct addrinfo hints; + struct addrinfo *result = nullptr; + + memset(&hints, 0, sizeof(struct addrinfo)); + if (p_type == TYPE_IPV4) { + hints.ai_family = AF_INET; + } else if (p_type == TYPE_IPV6) { + hints.ai_family = AF_INET6; + hints.ai_flags = 0; + } else { + hints.ai_family = AF_UNSPEC; + hints.ai_flags = AI_ADDRCONFIG; + } + hints.ai_flags &= ~AI_NUMERICHOST; + + int s = getaddrinfo(p_hostname.utf8().get_data(), nullptr, &hints, &result); + if (s != 0) { + print_verbose("getaddrinfo failed! Cannot resolve hostname."); + return; + } + + if (result == nullptr || result->ai_addr == nullptr) { + print_verbose("Invalid response from getaddrinfo."); + if (result) { + freeaddrinfo(result); + } + return; + } + + struct addrinfo *next = result; + + do { + if (next->ai_addr == nullptr) { + next = next->ai_next; + continue; + } + IPAddress ip = _sockaddr2ip(next->ai_addr); + if (ip.is_valid() && !r_addresses.find(ip)) { + r_addresses.push_back(ip); + } + next = next->ai_next; + } while (next); + + freeaddrinfo(result); +} + +void IPWindows::get_local_interfaces(HashMap *r_interfaces) const { + ULONG buf_size = 1024; + IP_ADAPTER_ADDRESSES *addrs; + + while (true) { + addrs = (IP_ADAPTER_ADDRESSES *)memalloc(buf_size); + int err = GetAdaptersAddresses(AF_UNSPEC, GAA_FLAG_SKIP_ANYCAST | GAA_FLAG_SKIP_MULTICAST | GAA_FLAG_SKIP_DNS_SERVER | GAA_FLAG_SKIP_FRIENDLY_NAME, + nullptr, addrs, &buf_size); + if (err == NO_ERROR) { + break; + } + memfree(addrs); + if (err == ERROR_BUFFER_OVERFLOW) { + continue; // Will go back and alloc the right size. + } + + ERR_FAIL_MSG("Call to GetAdaptersAddresses failed with error " + itos(err) + "."); + } + + IP_ADAPTER_ADDRESSES *adapter = addrs; + + while (adapter != nullptr) { + Interface_Info info; + info.name = adapter->AdapterName; + info.name_friendly = adapter->FriendlyName; + info.index = String::num_uint64(adapter->IfIndex); + + IP_ADAPTER_UNICAST_ADDRESS *address = adapter->FirstUnicastAddress; + while (address != nullptr) { + int family = address->Address.lpSockaddr->sa_family; + if (family != AF_INET && family != AF_INET6) { + continue; + } + info.ip_addresses.push_front(_sockaddr2ip(address->Address.lpSockaddr)); + address = address->Next; + } + adapter = adapter->Next; + // Only add interface if it has at least one IP. + if (info.ip_addresses.size() > 0) { + r_interfaces->insert(info.name, info); + } + } + + memfree(addrs); +} + +void IPWindows::make_default() { + _create = _create_unix; +} + +IP *IPWindows::_create_unix() { + return memnew(IPWindows); +} + +IPWindows::IPWindows() { +} + +#endif // WINDOWS_ENABLED diff --git a/drivers/windows/ip_windows.h b/drivers/windows/ip_windows.h new file mode 100644 index 00000000000..5788d33ee2f --- /dev/null +++ b/drivers/windows/ip_windows.h @@ -0,0 +1,54 @@ +/**************************************************************************/ +/* ip_windows.h */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/**************************************************************************/ + +#ifndef IP_WINDOWS_H +#define IP_WINDOWS_H + +#if defined(WINDOWS_ENABLED) + +#include "core/io/ip.h" + +class IPWindows : public IP { + GDCLASS(IPWindows, IP); + + virtual void _resolve_hostname(List &r_addresses, const String &p_hostname, Type p_type = TYPE_ANY) const override; + + static IP *_create_unix(); + +public: + virtual void get_local_interfaces(HashMap *r_interfaces) const override; + + static void make_default(); + IPWindows(); +}; + +#endif // WINDOWS_ENABLED + +#endif // IP_WINDOWS_H diff --git a/platform/windows/display_server_windows.h b/platform/windows/display_server_windows.h index 0462d3f8fa7..32ed8823d30 100644 --- a/platform/windows/display_server_windows.h +++ b/platform/windows/display_server_windows.h @@ -40,7 +40,6 @@ #include "core/input/input.h" #include "core/io/image.h" #include "core/os/os.h" -#include "drivers/unix/ip_unix.h" #include "drivers/wasapi/audio_driver_wasapi.h" #include "drivers/winmidi/midi_driver_winmidi.h" #include "servers/audio_server.h" diff --git a/platform/windows/os_windows.cpp b/platform/windows/os_windows.cpp index 0d151668ba1..4d4a85e22a7 100644 --- a/platform/windows/os_windows.cpp +++ b/platform/windows/os_windows.cpp @@ -43,6 +43,7 @@ #include "drivers/windows/dir_access_windows.h" #include "drivers/windows/file_access_windows.h" #include "drivers/windows/file_access_windows_pipe.h" +#include "drivers/windows/ip_windows.h" #include "drivers/windows/net_socket_winsock.h" #include "main/main.h" #include "servers/audio_server.h" @@ -228,7 +229,7 @@ void OS_Windows::initialize() { current_pi.pi.hProcess = GetCurrentProcess(); process_map->insert(GetCurrentProcessId(), current_pi); - IPUnix::make_default(); + IPWindows::make_default(); main_loop = nullptr; HRESULT hr = DWriteCreateFactory(DWRITE_FACTORY_TYPE_SHARED, __uuidof(IDWriteFactory), reinterpret_cast(&dwrite_factory)); diff --git a/platform/windows/os_windows.h b/platform/windows/os_windows.h index 34af0048229..a8efd440eeb 100644 --- a/platform/windows/os_windows.h +++ b/platform/windows/os_windows.h @@ -37,7 +37,6 @@ #include "core/config/project_settings.h" #include "core/input/input.h" #include "core/os/os.h" -#include "drivers/unix/ip_unix.h" #include "drivers/wasapi/audio_driver_wasapi.h" #include "drivers/winmidi/midi_driver_winmidi.h" #include "servers/audio_server.h"