Skip to content

Commit 1dcb686

Browse files
committed
Merge pull request #99026 from Faless/net/split_ip
[Net] Split Unix/Windows IP implementation
2 parents 8811b39 + 168a2a1 commit 1dcb686

File tree

7 files changed

+227
-77
lines changed

7 files changed

+227
-77
lines changed

drivers/unix/ip_unix.cpp

+4-71
Original file line numberDiff line numberDiff line change
@@ -28,22 +28,9 @@
2828
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
2929
/**************************************************************************/
3030

31-
#include "ip_unix.h"
32-
33-
#if defined(UNIX_ENABLED) || defined(WINDOWS_ENABLED)
34-
35-
#ifdef WINDOWS_ENABLED
36-
37-
#define WIN32_LEAN_AND_MEAN
38-
#include <windows.h>
39-
#include <winsock2.h>
40-
#include <ws2tcpip.h>
41-
42-
#include <iphlpapi.h>
43-
44-
#include <stdio.h>
31+
#if defined(UNIX_ENABLED)
4532

46-
#else // UNIX
33+
#include "ip_unix.h"
4734

4835
#include <netdb.h>
4936

@@ -67,8 +54,6 @@
6754

6855
#include <net/if.h> // Order is important on OpenBSD, leave as last.
6956

70-
#endif // UNIX
71-
7257
#include <string.h>
7358

7459
static IPAddress _sockaddr2ip(struct sockaddr *p_addr) {
@@ -108,7 +93,7 @@ void IPUnix::_resolve_hostname(List<IPAddress> &r_addresses, const String &p_hos
10893
}
10994

11095
if (result == nullptr || result->ai_addr == nullptr) {
111-
print_verbose("Invalid response from getaddrinfo");
96+
print_verbose("Invalid response from getaddrinfo.");
11297
if (result) {
11398
freeaddrinfo(result);
11499
}
@@ -132,56 +117,6 @@ void IPUnix::_resolve_hostname(List<IPAddress> &r_addresses, const String &p_hos
132117
freeaddrinfo(result);
133118
}
134119

135-
#if defined(WINDOWS_ENABLED)
136-
137-
void IPUnix::get_local_interfaces(HashMap<String, Interface_Info> *r_interfaces) const {
138-
ULONG buf_size = 1024;
139-
IP_ADAPTER_ADDRESSES *addrs;
140-
141-
while (true) {
142-
addrs = (IP_ADAPTER_ADDRESSES *)memalloc(buf_size);
143-
int err = GetAdaptersAddresses(AF_UNSPEC, GAA_FLAG_SKIP_ANYCAST | GAA_FLAG_SKIP_MULTICAST | GAA_FLAG_SKIP_DNS_SERVER | GAA_FLAG_SKIP_FRIENDLY_NAME,
144-
nullptr, addrs, &buf_size);
145-
if (err == NO_ERROR) {
146-
break;
147-
}
148-
memfree(addrs);
149-
if (err == ERROR_BUFFER_OVERFLOW) {
150-
continue; // will go back and alloc the right size
151-
}
152-
153-
ERR_FAIL_MSG("Call to GetAdaptersAddresses failed with error " + itos(err) + ".");
154-
}
155-
156-
IP_ADAPTER_ADDRESSES *adapter = addrs;
157-
158-
while (adapter != nullptr) {
159-
Interface_Info info;
160-
info.name = adapter->AdapterName;
161-
info.name_friendly = adapter->FriendlyName;
162-
info.index = String::num_uint64(adapter->IfIndex);
163-
164-
IP_ADAPTER_UNICAST_ADDRESS *address = adapter->FirstUnicastAddress;
165-
while (address != nullptr) {
166-
int family = address->Address.lpSockaddr->sa_family;
167-
if (family != AF_INET && family != AF_INET6) {
168-
continue;
169-
}
170-
info.ip_addresses.push_front(_sockaddr2ip(address->Address.lpSockaddr));
171-
address = address->Next;
172-
}
173-
adapter = adapter->Next;
174-
// Only add interface if it has at least one IP
175-
if (info.ip_addresses.size() > 0) {
176-
r_interfaces->insert(info.name, info);
177-
}
178-
}
179-
180-
memfree(addrs);
181-
}
182-
183-
#else // UNIX
184-
185120
void IPUnix::get_local_interfaces(HashMap<String, Interface_Info> *r_interfaces) const {
186121
struct ifaddrs *ifAddrStruct = nullptr;
187122
struct ifaddrs *ifa = nullptr;
@@ -219,8 +154,6 @@ void IPUnix::get_local_interfaces(HashMap<String, Interface_Info> *r_interfaces)
219154
}
220155
}
221156

222-
#endif // UNIX
223-
224157
void IPUnix::make_default() {
225158
_create = _create_unix;
226159
}
@@ -232,4 +165,4 @@ IP *IPUnix::_create_unix() {
232165
IPUnix::IPUnix() {
233166
}
234167

235-
#endif // UNIX_ENABLED || WINDOWS_ENABLED
168+
#endif // UNIX_ENABLED

drivers/unix/ip_unix.h

+3-3
Original file line numberDiff line numberDiff line change
@@ -31,9 +31,9 @@
3131
#ifndef IP_UNIX_H
3232
#define IP_UNIX_H
3333

34-
#include "core/io/ip.h"
34+
#if defined(UNIX_ENABLED)
3535

36-
#if defined(UNIX_ENABLED) || defined(WINDOWS_ENABLED)
36+
#include "core/io/ip.h"
3737

3838
class IPUnix : public IP {
3939
GDCLASS(IPUnix, IP);
@@ -49,6 +49,6 @@ class IPUnix : public IP {
4949
IPUnix();
5050
};
5151

52-
#endif
52+
#endif // UNIX_ENABLED
5353

5454
#endif // IP_UNIX_H

drivers/windows/ip_windows.cpp

+164
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,164 @@
1+
/**************************************************************************/
2+
/* ip_windows.cpp */
3+
/**************************************************************************/
4+
/* This file is part of: */
5+
/* GODOT ENGINE */
6+
/* https://godotengine.org */
7+
/**************************************************************************/
8+
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
9+
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
10+
/* */
11+
/* Permission is hereby granted, free of charge, to any person obtaining */
12+
/* a copy of this software and associated documentation files (the */
13+
/* "Software"), to deal in the Software without restriction, including */
14+
/* without limitation the rights to use, copy, modify, merge, publish, */
15+
/* distribute, sublicense, and/or sell copies of the Software, and to */
16+
/* permit persons to whom the Software is furnished to do so, subject to */
17+
/* the following conditions: */
18+
/* */
19+
/* The above copyright notice and this permission notice shall be */
20+
/* included in all copies or substantial portions of the Software. */
21+
/* */
22+
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
23+
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
24+
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
25+
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
26+
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
27+
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
28+
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
29+
/**************************************************************************/
30+
31+
#if defined(WINDOWS_ENABLED)
32+
33+
#include "ip_windows.h"
34+
35+
#define WIN32_LEAN_AND_MEAN
36+
#include <windows.h>
37+
#include <winsock2.h>
38+
#include <ws2tcpip.h>
39+
40+
#include <iphlpapi.h>
41+
42+
#include <stdio.h>
43+
44+
#include <string.h>
45+
46+
static IPAddress _sockaddr2ip(struct sockaddr *p_addr) {
47+
IPAddress ip;
48+
49+
if (p_addr->sa_family == AF_INET) {
50+
struct sockaddr_in *addr = (struct sockaddr_in *)p_addr;
51+
ip.set_ipv4((uint8_t *)&(addr->sin_addr));
52+
} else if (p_addr->sa_family == AF_INET6) {
53+
struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *)p_addr;
54+
ip.set_ipv6(addr6->sin6_addr.s6_addr);
55+
}
56+
57+
return ip;
58+
}
59+
60+
void IPWindows::_resolve_hostname(List<IPAddress> &r_addresses, const String &p_hostname, Type p_type) const {
61+
struct addrinfo hints;
62+
struct addrinfo *result = nullptr;
63+
64+
memset(&hints, 0, sizeof(struct addrinfo));
65+
if (p_type == TYPE_IPV4) {
66+
hints.ai_family = AF_INET;
67+
} else if (p_type == TYPE_IPV6) {
68+
hints.ai_family = AF_INET6;
69+
hints.ai_flags = 0;
70+
} else {
71+
hints.ai_family = AF_UNSPEC;
72+
hints.ai_flags = AI_ADDRCONFIG;
73+
}
74+
hints.ai_flags &= ~AI_NUMERICHOST;
75+
76+
int s = getaddrinfo(p_hostname.utf8().get_data(), nullptr, &hints, &result);
77+
if (s != 0) {
78+
print_verbose("getaddrinfo failed! Cannot resolve hostname.");
79+
return;
80+
}
81+
82+
if (result == nullptr || result->ai_addr == nullptr) {
83+
print_verbose("Invalid response from getaddrinfo.");
84+
if (result) {
85+
freeaddrinfo(result);
86+
}
87+
return;
88+
}
89+
90+
struct addrinfo *next = result;
91+
92+
do {
93+
if (next->ai_addr == nullptr) {
94+
next = next->ai_next;
95+
continue;
96+
}
97+
IPAddress ip = _sockaddr2ip(next->ai_addr);
98+
if (ip.is_valid() && !r_addresses.find(ip)) {
99+
r_addresses.push_back(ip);
100+
}
101+
next = next->ai_next;
102+
} while (next);
103+
104+
freeaddrinfo(result);
105+
}
106+
107+
void IPWindows::get_local_interfaces(HashMap<String, Interface_Info> *r_interfaces) const {
108+
ULONG buf_size = 1024;
109+
IP_ADAPTER_ADDRESSES *addrs;
110+
111+
while (true) {
112+
addrs = (IP_ADAPTER_ADDRESSES *)memalloc(buf_size);
113+
int err = GetAdaptersAddresses(AF_UNSPEC, GAA_FLAG_SKIP_ANYCAST | GAA_FLAG_SKIP_MULTICAST | GAA_FLAG_SKIP_DNS_SERVER | GAA_FLAG_SKIP_FRIENDLY_NAME,
114+
nullptr, addrs, &buf_size);
115+
if (err == NO_ERROR) {
116+
break;
117+
}
118+
memfree(addrs);
119+
if (err == ERROR_BUFFER_OVERFLOW) {
120+
continue; // Will go back and alloc the right size.
121+
}
122+
123+
ERR_FAIL_MSG("Call to GetAdaptersAddresses failed with error " + itos(err) + ".");
124+
}
125+
126+
IP_ADAPTER_ADDRESSES *adapter = addrs;
127+
128+
while (adapter != nullptr) {
129+
Interface_Info info;
130+
info.name = adapter->AdapterName;
131+
info.name_friendly = adapter->FriendlyName;
132+
info.index = String::num_uint64(adapter->IfIndex);
133+
134+
IP_ADAPTER_UNICAST_ADDRESS *address = adapter->FirstUnicastAddress;
135+
while (address != nullptr) {
136+
int family = address->Address.lpSockaddr->sa_family;
137+
if (family != AF_INET && family != AF_INET6) {
138+
continue;
139+
}
140+
info.ip_addresses.push_front(_sockaddr2ip(address->Address.lpSockaddr));
141+
address = address->Next;
142+
}
143+
adapter = adapter->Next;
144+
// Only add interface if it has at least one IP.
145+
if (info.ip_addresses.size() > 0) {
146+
r_interfaces->insert(info.name, info);
147+
}
148+
}
149+
150+
memfree(addrs);
151+
}
152+
153+
void IPWindows::make_default() {
154+
_create = _create_unix;
155+
}
156+
157+
IP *IPWindows::_create_unix() {
158+
return memnew(IPWindows);
159+
}
160+
161+
IPWindows::IPWindows() {
162+
}
163+
164+
#endif // WINDOWS_ENABLED

drivers/windows/ip_windows.h

+54
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
/**************************************************************************/
2+
/* ip_windows.h */
3+
/**************************************************************************/
4+
/* This file is part of: */
5+
/* GODOT ENGINE */
6+
/* https://godotengine.org */
7+
/**************************************************************************/
8+
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
9+
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
10+
/* */
11+
/* Permission is hereby granted, free of charge, to any person obtaining */
12+
/* a copy of this software and associated documentation files (the */
13+
/* "Software"), to deal in the Software without restriction, including */
14+
/* without limitation the rights to use, copy, modify, merge, publish, */
15+
/* distribute, sublicense, and/or sell copies of the Software, and to */
16+
/* permit persons to whom the Software is furnished to do so, subject to */
17+
/* the following conditions: */
18+
/* */
19+
/* The above copyright notice and this permission notice shall be */
20+
/* included in all copies or substantial portions of the Software. */
21+
/* */
22+
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
23+
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
24+
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
25+
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
26+
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
27+
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
28+
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
29+
/**************************************************************************/
30+
31+
#ifndef IP_WINDOWS_H
32+
#define IP_WINDOWS_H
33+
34+
#if defined(WINDOWS_ENABLED)
35+
36+
#include "core/io/ip.h"
37+
38+
class IPWindows : public IP {
39+
GDCLASS(IPWindows, IP);
40+
41+
virtual void _resolve_hostname(List<IPAddress> &r_addresses, const String &p_hostname, Type p_type = TYPE_ANY) const override;
42+
43+
static IP *_create_unix();
44+
45+
public:
46+
virtual void get_local_interfaces(HashMap<String, Interface_Info> *r_interfaces) const override;
47+
48+
static void make_default();
49+
IPWindows();
50+
};
51+
52+
#endif // WINDOWS_ENABLED
53+
54+
#endif // IP_WINDOWS_H

platform/windows/display_server_windows.h

-1
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,6 @@
4040
#include "core/input/input.h"
4141
#include "core/io/image.h"
4242
#include "core/os/os.h"
43-
#include "drivers/unix/ip_unix.h"
4443
#include "drivers/wasapi/audio_driver_wasapi.h"
4544
#include "drivers/winmidi/midi_driver_winmidi.h"
4645
#include "servers/audio_server.h"

platform/windows/os_windows.cpp

+2-1
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@
4343
#include "drivers/windows/dir_access_windows.h"
4444
#include "drivers/windows/file_access_windows.h"
4545
#include "drivers/windows/file_access_windows_pipe.h"
46+
#include "drivers/windows/ip_windows.h"
4647
#include "drivers/windows/net_socket_winsock.h"
4748
#include "main/main.h"
4849
#include "servers/audio_server.h"
@@ -275,7 +276,7 @@ void OS_Windows::initialize() {
275276
current_pi.pi.hProcess = GetCurrentProcess();
276277
process_map->insert(GetCurrentProcessId(), current_pi);
277278

278-
IPUnix::make_default();
279+
IPWindows::make_default();
279280
main_loop = nullptr;
280281

281282
HRESULT hr = DWriteCreateFactory(DWRITE_FACTORY_TYPE_SHARED, __uuidof(IDWriteFactory), reinterpret_cast<IUnknown **>(&dwrite_factory));

platform/windows/os_windows.h

-1
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,6 @@
3737
#include "core/config/project_settings.h"
3838
#include "core/input/input.h"
3939
#include "core/os/os.h"
40-
#include "drivers/unix/ip_unix.h"
4140
#include "drivers/wasapi/audio_driver_wasapi.h"
4241
#include "drivers/winmidi/midi_driver_winmidi.h"
4342
#include "servers/audio_server.h"

0 commit comments

Comments
 (0)