Skip to content

Commit 29e6ef4

Browse files
committed
Merge pull request #99597 from Faless/upnp/custom_instance
[UPNP] Allow disabling UPNP implementation on the Web
2 parents 20d4755 + 0df602a commit 29e6ef4

File tree

10 files changed

+734
-488
lines changed

10 files changed

+734
-488
lines changed

modules/upnp/SCsub

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ env_upnp = env_modules.Clone()
1010

1111
thirdparty_obj = []
1212

13-
if env["builtin_miniupnpc"]:
13+
if env["builtin_miniupnpc"] and env["platform"] != "web":
1414
thirdparty_dir = "#thirdparty/miniupnpc/"
1515
thirdparty_sources = [
1616
"igd_desc_parse.c",

modules/upnp/register_types.cpp

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,15 +33,25 @@
3333
#include "upnp.h"
3434
#include "upnp_device.h"
3535

36+
#ifndef WEB_ENABLED
37+
#include "upnp_device_miniupnp.h"
38+
#include "upnp_miniupnp.h"
39+
#endif
40+
3641
#include "core/error/error_macros.h"
3742

3843
void initialize_upnp_module(ModuleInitializationLevel p_level) {
3944
if (p_level != MODULE_INITIALIZATION_LEVEL_SCENE) {
4045
return;
4146
}
4247

43-
GDREGISTER_CLASS(UPNP);
44-
GDREGISTER_CLASS(UPNPDevice);
48+
ClassDB::register_custom_instance_class<UPNP>();
49+
ClassDB::register_custom_instance_class<UPNPDevice>();
50+
51+
#ifndef WEB_ENABLED
52+
UPNPMiniUPNP::make_default();
53+
UPNPDeviceMiniUPNP::make_default();
54+
#endif
4555
}
4656

4757
void uninitialize_upnp_module(ModuleInitializationLevel p_level) {

modules/upnp/upnp.cpp

Lines changed: 1 addition & 298 deletions
Original file line numberDiff line numberDiff line change
@@ -30,298 +30,7 @@
3030

3131
#include "upnp.h"
3232

33-
#include <miniwget.h>
34-
#include <upnpcommands.h>
35-
36-
#include <stdlib.h>
37-
38-
bool UPNP::is_common_device(const String &dev) const {
39-
return dev.is_empty() ||
40-
dev.contains("InternetGatewayDevice") ||
41-
dev.contains("WANIPConnection") ||
42-
dev.contains("WANPPPConnection") ||
43-
dev.contains("rootdevice");
44-
}
45-
46-
int UPNP::discover(int timeout, int ttl, const String &device_filter) {
47-
ERR_FAIL_COND_V_MSG(timeout < 0, UPNP_RESULT_INVALID_PARAM, "The response's wait time can't be negative.");
48-
ERR_FAIL_COND_V_MSG(ttl < 0 || ttl > 255, UPNP_RESULT_INVALID_PARAM, "The time-to-live must be set between 0 and 255 (inclusive).");
49-
50-
devices.clear();
51-
52-
int error = 0;
53-
struct UPNPDev *devlist;
54-
55-
CharString cs = discover_multicast_if.utf8();
56-
const char *m_if = cs.length() ? cs.get_data() : nullptr;
57-
if (is_common_device(device_filter)) {
58-
devlist = upnpDiscover(timeout, m_if, nullptr, discover_local_port, discover_ipv6, ttl, &error);
59-
} else {
60-
devlist = upnpDiscoverAll(timeout, m_if, nullptr, discover_local_port, discover_ipv6, ttl, &error);
61-
}
62-
63-
if (error != UPNPDISCOVER_SUCCESS) {
64-
switch (error) {
65-
case UPNPDISCOVER_SOCKET_ERROR:
66-
return UPNP_RESULT_SOCKET_ERROR;
67-
case UPNPDISCOVER_MEMORY_ERROR:
68-
return UPNP_RESULT_MEM_ALLOC_ERROR;
69-
default:
70-
return UPNP_RESULT_UNKNOWN_ERROR;
71-
}
72-
}
73-
74-
if (!devlist) {
75-
return UPNP_RESULT_NO_DEVICES;
76-
}
77-
78-
struct UPNPDev *dev = devlist;
79-
80-
while (dev) {
81-
if (device_filter.is_empty() || strstr(dev->st, device_filter.utf8().get_data())) {
82-
add_device_to_list(dev, devlist);
83-
}
84-
85-
dev = dev->pNext;
86-
}
87-
88-
freeUPNPDevlist(devlist);
89-
90-
return UPNP_RESULT_SUCCESS;
91-
}
92-
93-
void UPNP::add_device_to_list(UPNPDev *dev, UPNPDev *devlist) {
94-
Ref<UPNPDevice> new_device;
95-
new_device.instantiate();
96-
97-
new_device->set_description_url(dev->descURL);
98-
new_device->set_service_type(dev->st);
99-
100-
parse_igd(new_device, devlist);
101-
102-
devices.push_back(new_device);
103-
}
104-
105-
char *UPNP::load_description(const String &url, int *size, int *status_code) const {
106-
return (char *)miniwget(url.utf8().get_data(), size, 0, status_code);
107-
}
108-
109-
void UPNP::parse_igd(Ref<UPNPDevice> dev, UPNPDev *devlist) {
110-
int size = 0;
111-
int status_code = -1;
112-
char *xml = load_description(dev->get_description_url(), &size, &status_code);
113-
114-
if (status_code != 200) {
115-
dev->set_igd_status(UPNPDevice::IGD_STATUS_HTTP_ERROR);
116-
return;
117-
}
118-
119-
if (!xml || size < 1) {
120-
dev->set_igd_status(UPNPDevice::IGD_STATUS_HTTP_EMPTY);
121-
return;
122-
}
123-
124-
struct UPNPUrls urls = {};
125-
struct IGDdatas data;
126-
127-
parserootdesc(xml, size, &data);
128-
free(xml);
129-
xml = nullptr;
130-
131-
GetUPNPUrls(&urls, &data, dev->get_description_url().utf8().get_data(), 0);
132-
133-
char addr[16];
134-
#if MINIUPNPC_API_VERSION >= 18
135-
int i = UPNP_GetValidIGD(devlist, &urls, &data, (char *)&addr, 16, nullptr, 0);
136-
#else
137-
int i = UPNP_GetValidIGD(devlist, &urls, &data, (char *)&addr, 16);
138-
#endif
139-
140-
if (i != 1) {
141-
FreeUPNPUrls(&urls);
142-
143-
switch (i) {
144-
case 0:
145-
dev->set_igd_status(UPNPDevice::IGD_STATUS_NO_IGD);
146-
return;
147-
case 2:
148-
dev->set_igd_status(UPNPDevice::IGD_STATUS_DISCONNECTED);
149-
return;
150-
case 3:
151-
dev->set_igd_status(UPNPDevice::IGD_STATUS_UNKNOWN_DEVICE);
152-
return;
153-
default:
154-
dev->set_igd_status(UPNPDevice::IGD_STATUS_UNKNOWN_ERROR);
155-
return;
156-
}
157-
}
158-
159-
if (urls.controlURL[0] == '\0') {
160-
FreeUPNPUrls(&urls);
161-
dev->set_igd_status(UPNPDevice::IGD_STATUS_INVALID_CONTROL);
162-
return;
163-
}
164-
165-
dev->set_igd_control_url(urls.controlURL);
166-
dev->set_igd_service_type(data.first.servicetype);
167-
dev->set_igd_our_addr(addr);
168-
dev->set_igd_status(UPNPDevice::IGD_STATUS_OK);
169-
170-
FreeUPNPUrls(&urls);
171-
}
172-
173-
int UPNP::upnp_result(int in) {
174-
switch (in) {
175-
case UPNPCOMMAND_SUCCESS:
176-
return UPNP_RESULT_SUCCESS;
177-
case UPNPCOMMAND_UNKNOWN_ERROR:
178-
return UPNP_RESULT_UNKNOWN_ERROR;
179-
case UPNPCOMMAND_INVALID_ARGS:
180-
return UPNP_RESULT_INVALID_ARGS;
181-
case UPNPCOMMAND_HTTP_ERROR:
182-
return UPNP_RESULT_HTTP_ERROR;
183-
case UPNPCOMMAND_INVALID_RESPONSE:
184-
return UPNP_RESULT_INVALID_RESPONSE;
185-
case UPNPCOMMAND_MEM_ALLOC_ERROR:
186-
return UPNP_RESULT_MEM_ALLOC_ERROR;
187-
188-
case 402:
189-
return UPNP_RESULT_INVALID_ARGS;
190-
case 403:
191-
return UPNP_RESULT_NOT_AUTHORIZED;
192-
case 501:
193-
return UPNP_RESULT_ACTION_FAILED;
194-
case 606:
195-
return UPNP_RESULT_NOT_AUTHORIZED;
196-
case 714:
197-
return UPNP_RESULT_NO_SUCH_ENTRY_IN_ARRAY;
198-
case 715:
199-
return UPNP_RESULT_SRC_IP_WILDCARD_NOT_PERMITTED;
200-
case 716:
201-
return UPNP_RESULT_EXT_PORT_WILDCARD_NOT_PERMITTED;
202-
case 718:
203-
return UPNP_RESULT_CONFLICT_WITH_OTHER_MAPPING;
204-
case 724:
205-
return UPNP_RESULT_SAME_PORT_VALUES_REQUIRED;
206-
case 725:
207-
return UPNP_RESULT_ONLY_PERMANENT_LEASE_SUPPORTED;
208-
case 726:
209-
return UPNP_RESULT_REMOTE_HOST_MUST_BE_WILDCARD;
210-
case 727:
211-
return UPNP_RESULT_EXT_PORT_MUST_BE_WILDCARD;
212-
case 728:
213-
return UPNP_RESULT_NO_PORT_MAPS_AVAILABLE;
214-
case 729:
215-
return UPNP_RESULT_CONFLICT_WITH_OTHER_MECHANISM;
216-
case 732:
217-
return UPNP_RESULT_INT_PORT_WILDCARD_NOT_PERMITTED;
218-
case 733:
219-
return UPNP_RESULT_INCONSISTENT_PARAMETERS;
220-
}
221-
222-
return UPNP_RESULT_UNKNOWN_ERROR;
223-
}
224-
225-
int UPNP::get_device_count() const {
226-
return devices.size();
227-
}
228-
229-
Ref<UPNPDevice> UPNP::get_device(int index) const {
230-
ERR_FAIL_INDEX_V(index, devices.size(), nullptr);
231-
232-
return devices.get(index);
233-
}
234-
235-
void UPNP::add_device(Ref<UPNPDevice> device) {
236-
ERR_FAIL_COND(device.is_null());
237-
238-
devices.push_back(device);
239-
}
240-
241-
void UPNP::set_device(int index, Ref<UPNPDevice> device) {
242-
ERR_FAIL_INDEX(index, devices.size());
243-
ERR_FAIL_COND(device.is_null());
244-
245-
devices.set(index, device);
246-
}
247-
248-
void UPNP::remove_device(int index) {
249-
ERR_FAIL_INDEX(index, devices.size());
250-
251-
devices.remove_at(index);
252-
}
253-
254-
void UPNP::clear_devices() {
255-
devices.clear();
256-
}
257-
258-
Ref<UPNPDevice> UPNP::get_gateway() const {
259-
ERR_FAIL_COND_V_MSG(devices.is_empty(), nullptr, "Couldn't find any UPNPDevices.");
260-
261-
for (int i = 0; i < devices.size(); i++) {
262-
Ref<UPNPDevice> dev = get_device(i);
263-
264-
if (dev.is_valid() && dev->is_valid_gateway()) {
265-
return dev;
266-
}
267-
}
268-
269-
return nullptr;
270-
}
271-
272-
void UPNP::set_discover_multicast_if(const String &m_if) {
273-
discover_multicast_if = m_if;
274-
}
275-
276-
String UPNP::get_discover_multicast_if() const {
277-
return discover_multicast_if;
278-
}
279-
280-
void UPNP::set_discover_local_port(int port) {
281-
discover_local_port = port;
282-
}
283-
284-
int UPNP::get_discover_local_port() const {
285-
return discover_local_port;
286-
}
287-
288-
void UPNP::set_discover_ipv6(bool ipv6) {
289-
discover_ipv6 = ipv6;
290-
}
291-
292-
bool UPNP::is_discover_ipv6() const {
293-
return discover_ipv6;
294-
}
295-
296-
String UPNP::query_external_address() const {
297-
Ref<UPNPDevice> dev = get_gateway();
298-
299-
if (dev.is_null()) {
300-
return "";
301-
}
302-
303-
return dev->query_external_address();
304-
}
305-
306-
int UPNP::add_port_mapping(int port, int port_internal, String desc, String proto, int duration) const {
307-
Ref<UPNPDevice> dev = get_gateway();
308-
309-
if (dev.is_null()) {
310-
return UPNP_RESULT_NO_GATEWAY;
311-
}
312-
313-
return dev->add_port_mapping(port, port_internal, desc, proto, duration);
314-
}
315-
316-
int UPNP::delete_port_mapping(int port, String proto) const {
317-
Ref<UPNPDevice> dev = get_gateway();
318-
319-
if (dev.is_null()) {
320-
return UPNP_RESULT_NO_GATEWAY;
321-
}
322-
323-
return dev->delete_port_mapping(port, proto);
324-
}
33+
UPNP *(*UPNP::_create)(bool p_notify_postinitialize) = nullptr;
32534

32635
void UPNP::_bind_methods() {
32736
ClassDB::bind_method(D_METHOD("get_device_count"), &UPNP::get_device_count);
@@ -382,9 +91,3 @@ void UPNP::_bind_methods() {
38291
BIND_ENUM_CONSTANT(UPNP_RESULT_NO_DEVICES);
38392
BIND_ENUM_CONSTANT(UPNP_RESULT_UNKNOWN_ERROR);
38493
}
385-
386-
UPNP::UPNP() {
387-
}
388-
389-
UPNP::~UPNP() {
390-
}

0 commit comments

Comments
 (0)