summaryrefslogtreecommitdiff
path: root/drivers/unix/ip_unix.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/unix/ip_unix.cpp')
-rw-r--r--drivers/unix/ip_unix.cpp97
1 files changed, 49 insertions, 48 deletions
diff --git a/drivers/unix/ip_unix.cpp b/drivers/unix/ip_unix.cpp
index 8ec1de4386..2deeb79957 100644
--- a/drivers/unix/ip_unix.cpp
+++ b/drivers/unix/ip_unix.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -36,24 +36,12 @@
#ifdef WINDOWS_ENABLED
#include <stdio.h>
-#include <winsock2.h>
-// Needs to be included after winsocks2.h
+#define WIN32_LEAN_AND_MEAN
#include <windows.h>
+#include <winsock2.h>
#include <ws2tcpip.h>
#ifndef UWP_ENABLED
-#if defined(__MINGW32__) && (!defined(__MINGW64_VERSION_MAJOR) || __MINGW64_VERSION_MAJOR < 4)
-// MinGW-w64 on Ubuntu 12.04 (our Travis build env) has bugs in this code where
-// some includes are missing in dependencies of iphlpapi.h for WINVER >= 0x0600 (Vista).
-// We don't use this Vista code for now, so working it around by disabling it.
-// MinGW-w64 >= 4.0 seems to be better judging by its headers.
-#undef _WIN32_WINNT
-#define _WIN32_WINNT 0x0501 // Windows XP, disable Vista API
-#include <iphlpapi.h>
-#undef _WIN32_WINNT
-#define _WIN32_WINNT 0x0600 // Re-enable Vista API
-#else
#include <iphlpapi.h>
-#endif // MINGW hack
#endif
#else // UNIX
#include <netdb.h>
@@ -75,8 +63,8 @@
#include <net/if.h> // Order is important on OpenBSD, leave as last
#endif
-static IP_Address _sockaddr2ip(struct sockaddr *p_addr) {
- IP_Address ip;
+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;
@@ -84,12 +72,12 @@ static IP_Address _sockaddr2ip(struct sockaddr *p_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;
-};
+}
-IP_Address IP_Unix::_resolve_hostname(const String &p_hostname, Type p_type) {
+void IPUnix::_resolve_hostname(List<IPAddress> &r_addresses, const String &p_hostname, Type p_type) const {
struct addrinfo hints;
struct addrinfo *result = nullptr;
@@ -102,35 +90,45 @@ IP_Address IP_Unix::_resolve_hostname(const String &p_hostname, Type p_type) {
} 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) {
ERR_PRINT("getaddrinfo failed! Cannot resolve hostname.");
- return IP_Address();
- };
+ return;
+ }
if (result == nullptr || result->ai_addr == nullptr) {
ERR_PRINT("Invalid response from getaddrinfo");
if (result) {
freeaddrinfo(result);
}
- return IP_Address();
- };
+ return;
+ }
- IP_Address ip = _sockaddr2ip(result->ai_addr);
+ struct addrinfo *next = result;
- freeaddrinfo(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);
- return ip;
+ freeaddrinfo(result);
}
#if defined(WINDOWS_ENABLED)
#if defined(UWP_ENABLED)
-void IP_Unix::get_local_interfaces(Map<String, Interface_Info> *r_interfaces) const {
+void IPUnix::get_local_interfaces(HashMap<String, Interface_Info> *r_interfaces) const {
using namespace Windows::Networking;
using namespace Windows::Networking::Connectivity;
@@ -140,11 +138,12 @@ void IP_Unix::get_local_interfaces(Map<String, Interface_Info> *r_interfaces) co
for (int i = 0; i < hostnames->Size; i++) {
auto hostname = hostnames->GetAt(i);
- if (hostname->Type != HostNameType::Ipv4 && hostname->Type != HostNameType::Ipv6)
+ if (hostname->Type != HostNameType::Ipv4 && hostname->Type != HostNameType::Ipv6) {
continue;
+ }
String name = hostname->RawName->Data();
- Map<String, Interface_Info>::Element *E = r_interfaces->find(name);
+ HashMap<String, Interface_Info>::Element *E = r_interfaces->find(name);
if (!E) {
Interface_Info info;
info.name = name;
@@ -156,14 +155,14 @@ void IP_Unix::get_local_interfaces(Map<String, Interface_Info> *r_interfaces) co
Interface_Info &info = E->get();
- IP_Address ip = IP_Address(hostname->CanonicalName->Data());
+ IPAddress ip = IPAddress(hostname->CanonicalName->Data());
info.ip_addresses.push_front(ip);
}
}
#else
-void IP_Unix::get_local_interfaces(Map<String, Interface_Info> *r_interfaces) const {
+void IPUnix::get_local_interfaces(HashMap<String, Interface_Info> *r_interfaces) const {
ULONG buf_size = 1024;
IP_ADAPTER_ADDRESSES *addrs;
@@ -173,14 +172,14 @@ void IP_Unix::get_local_interfaces(Map<String, Interface_Info> *r_interfaces) co
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;
@@ -193,25 +192,27 @@ void IP_Unix::get_local_interfaces(Map<String, Interface_Info> *r_interfaces) co
IP_ADAPTER_UNICAST_ADDRESS *address = adapter->FirstUnicastAddress;
while (address != nullptr) {
int family = address->Address.lpSockaddr->sa_family;
- if (family != AF_INET && family != AF_INET6)
+ 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)
+ if (info.ip_addresses.size() > 0) {
r_interfaces->insert(info.name, info);
- };
+ }
+ }
memfree(addrs);
-};
+}
#endif
#else // UNIX
-void IP_Unix::get_local_interfaces(Map<String, Interface_Info> *r_interfaces) const {
+void IPUnix::get_local_interfaces(HashMap<String, Interface_Info> *r_interfaces) const {
struct ifaddrs *ifAddrStruct = nullptr;
struct ifaddrs *ifa = nullptr;
int family;
@@ -229,7 +230,7 @@ void IP_Unix::get_local_interfaces(Map<String, Interface_Info> *r_interfaces) co
continue;
}
- Map<String, Interface_Info>::Element *E = r_interfaces->find(ifa->ifa_name);
+ HashMap<String, Interface_Info>::Iterator E = r_interfaces->find(ifa->ifa_name);
if (!E) {
Interface_Info info;
info.name = ifa->ifa_name;
@@ -239,7 +240,7 @@ void IP_Unix::get_local_interfaces(Map<String, Interface_Info> *r_interfaces) co
ERR_CONTINUE(!E);
}
- Interface_Info &info = E->get();
+ Interface_Info &info = E->value;
info.ip_addresses.push_front(_sockaddr2ip(ifa->ifa_addr));
}
@@ -249,15 +250,15 @@ void IP_Unix::get_local_interfaces(Map<String, Interface_Info> *r_interfaces) co
}
#endif
-void IP_Unix::make_default() {
+void IPUnix::make_default() {
_create = _create_unix;
}
-IP *IP_Unix::_create_unix() {
- return memnew(IP_Unix);
+IP *IPUnix::_create_unix() {
+ return memnew(IPUnix);
}
-IP_Unix::IP_Unix() {
+IPUnix::IPUnix() {
}
#endif