1 /** 2 UPNP network functions. 3 4 Copyright: 5 Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. 6 Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) 7 Copyright (c) 2017-2018 Godot-D contributors 8 9 License: $(LINK2 https://opensource.org/licenses/MIT, MIT License) 10 11 12 */ 13 module godot.upnp; 14 import std.meta : AliasSeq, staticIndexOf; 15 import std.traits : Unqual; 16 import godot.d.traits; 17 import godot.core; 18 import godot.c; 19 import godot.d.bind; 20 import godot.d.reference; 21 import godot.globalenums; 22 import godot.object; 23 import godot.classdb; 24 import godot.reference; 25 import godot.upnpdevice; 26 /** 27 UPNP network functions. 28 29 Provides UPNP functionality to discover $(D UPNPDevice)s on the local network and execute commands on them, like managing port mappings (port forwarding) and querying the local and remote network IP address. Note that methods on this class are synchronous and block the calling thread. 30 To forward a specific port: 31 32 33 const PORT = 7777 34 var upnp = UPNP.new() 35 upnp.discover(2000, 2, "InternetGatewayDevice") 36 upnp.add_port_mapping(port) 37 38 39 To close a specific port (e.g. after you have finished using it): 40 41 42 upnp.delete_port_mapping(port) 43 44 45 */ 46 @GodotBaseClass struct UPNP 47 { 48 package(godot) enum string _GODOT_internal_name = "UPNP"; 49 public: 50 @nogc nothrow: 51 union { /** */ godot_object _godot_object; /** */ Reference _GODOT_base; } 52 alias _GODOT_base this; 53 alias BaseClasses = AliasSeq!(typeof(_GODOT_base), typeof(_GODOT_base).BaseClasses); 54 package(godot) __gshared bool _classBindingInitialized = false; 55 package(godot) static struct GDNativeClassBinding 56 { 57 __gshared: 58 @GodotName("add_device") GodotMethod!(void, UPNPDevice) addDevice; 59 @GodotName("add_port_mapping") GodotMethod!(long, long, long, String, String, long) addPortMapping; 60 @GodotName("clear_devices") GodotMethod!(void) clearDevices; 61 @GodotName("delete_port_mapping") GodotMethod!(long, long, String) deletePortMapping; 62 @GodotName("discover") GodotMethod!(long, long, long, String) discover; 63 @GodotName("get_device") GodotMethod!(UPNPDevice, long) getDevice; 64 @GodotName("get_device_count") GodotMethod!(long) getDeviceCount; 65 @GodotName("get_discover_local_port") GodotMethod!(long) getDiscoverLocalPort; 66 @GodotName("get_discover_multicast_if") GodotMethod!(String) getDiscoverMulticastIf; 67 @GodotName("get_gateway") GodotMethod!(UPNPDevice) getGateway; 68 @GodotName("is_discover_ipv6") GodotMethod!(bool) isDiscoverIpv6; 69 @GodotName("query_external_address") GodotMethod!(String) queryExternalAddress; 70 @GodotName("remove_device") GodotMethod!(void, long) removeDevice; 71 @GodotName("set_device") GodotMethod!(void, long, UPNPDevice) setDevice; 72 @GodotName("set_discover_ipv6") GodotMethod!(void, bool) setDiscoverIpv6; 73 @GodotName("set_discover_local_port") GodotMethod!(void, long) setDiscoverLocalPort; 74 @GodotName("set_discover_multicast_if") GodotMethod!(void, String) setDiscoverMulticastIf; 75 } 76 /// 77 pragma(inline, true) bool opEquals(in UPNP other) const 78 { return _godot_object.ptr is other._godot_object.ptr; } 79 /// 80 pragma(inline, true) typeof(null) opAssign(typeof(null) n) 81 { _godot_object.ptr = n; return null; } 82 /// 83 pragma(inline, true) bool opEquals(typeof(null) n) const 84 { return _godot_object.ptr is n; } 85 /// 86 size_t toHash() const @trusted { return cast(size_t)_godot_object.ptr; } 87 mixin baseCasts; 88 /// Construct a new instance of UPNP. 89 /// Note: use `memnew!UPNP` instead. 90 static UPNP _new() 91 { 92 static godot_class_constructor constructor; 93 if(constructor is null) constructor = _godot_api.godot_get_class_constructor("UPNP"); 94 if(constructor is null) return typeof(this).init; 95 return cast(UPNP)(constructor()); 96 } 97 @disable new(size_t s); 98 /// 99 enum UPNPResult : int 100 { 101 /** 102 UPNP command or discovery was successful. 103 */ 104 upnpResultSuccess = 0, 105 /** 106 Not authorized to use the command on the $(D UPNPDevice). May be returned when the user disabled UPNP on their router. 107 */ 108 upnpResultNotAuthorized = 1, 109 /** 110 No port mapping was found for the given port, protocol combination on the given $(D UPNPDevice). 111 */ 112 upnpResultPortMappingNotFound = 2, 113 /** 114 Inconsistent parameters. 115 */ 116 upnpResultInconsistentParameters = 3, 117 /** 118 No such entry in array. May be returned if a given port, protocol combination is not found on an $(D UPNPDevice). 119 */ 120 upnpResultNoSuchEntryInArray = 4, 121 /** 122 The action failed. 123 */ 124 upnpResultActionFailed = 5, 125 /** 126 The $(D UPNPDevice) does not allow wildcard values for the source IP address. 127 */ 128 upnpResultSrcIpWildcardNotPermitted = 6, 129 /** 130 The $(D UPNPDevice) does not allow wildcard values for the external port. 131 */ 132 upnpResultExtPortWildcardNotPermitted = 7, 133 /** 134 The $(D UPNPDevice) does not allow wildcard values for the internal port. 135 */ 136 upnpResultIntPortWildcardNotPermitted = 8, 137 /** 138 The remote host value must be a wildcard. 139 */ 140 upnpResultRemoteHostMustBeWildcard = 9, 141 /** 142 The external port value must be a wildcard. 143 */ 144 upnpResultExtPortMustBeWildcard = 10, 145 /** 146 No port maps are available. May also be returned if port mapping functionality is not available. 147 */ 148 upnpResultNoPortMapsAvailable = 11, 149 /** 150 Conflict with other mechanism. May be returned instead of $(D constant UPNP_RESULT_CONFLICT_WITH_OTHER_MAPPING) if a port mapping conflicts with an existing one. 151 */ 152 upnpResultConflictWithOtherMechanism = 12, 153 /** 154 Conflict with an existing port mapping. 155 */ 156 upnpResultConflictWithOtherMapping = 13, 157 /** 158 External and internal port values must be the same. 159 */ 160 upnpResultSamePortValuesRequired = 14, 161 /** 162 Only permanent leases are supported. Do not use the `duration` parameter when adding port mappings. 163 */ 164 upnpResultOnlyPermanentLeaseSupported = 15, 165 /** 166 Invalid gateway. 167 */ 168 upnpResultInvalidGateway = 16, 169 /** 170 Invalid port. 171 */ 172 upnpResultInvalidPort = 17, 173 /** 174 Invalid protocol. 175 */ 176 upnpResultInvalidProtocol = 18, 177 /** 178 Invalid duration. 179 */ 180 upnpResultInvalidDuration = 19, 181 /** 182 Invalid arguments. 183 */ 184 upnpResultInvalidArgs = 20, 185 /** 186 Invalid response. 187 */ 188 upnpResultInvalidResponse = 21, 189 /** 190 Invalid parameter. 191 */ 192 upnpResultInvalidParam = 22, 193 /** 194 HTTP error. 195 */ 196 upnpResultHttpError = 23, 197 /** 198 Socket error. 199 */ 200 upnpResultSocketError = 24, 201 /** 202 Error allocating memory. 203 */ 204 upnpResultMemAllocError = 25, 205 /** 206 No gateway available. You may need to call $(D discover) first, or discovery didn't detect any valid IGDs (InternetGatewayDevices). 207 */ 208 upnpResultNoGateway = 26, 209 /** 210 No devices available. You may need to call $(D discover) first, or discovery didn't detect any valid $(D UPNPDevice)s. 211 */ 212 upnpResultNoDevices = 27, 213 /** 214 Unknown error. 215 */ 216 upnpResultUnknownError = 28, 217 } 218 /// 219 enum Constants : int 220 { 221 upnpResultSuccess = 0, 222 upnpResultNotAuthorized = 1, 223 upnpResultPortMappingNotFound = 2, 224 upnpResultInconsistentParameters = 3, 225 upnpResultNoSuchEntryInArray = 4, 226 upnpResultActionFailed = 5, 227 upnpResultSrcIpWildcardNotPermitted = 6, 228 upnpResultExtPortWildcardNotPermitted = 7, 229 upnpResultIntPortWildcardNotPermitted = 8, 230 upnpResultRemoteHostMustBeWildcard = 9, 231 upnpResultExtPortMustBeWildcard = 10, 232 upnpResultNoPortMapsAvailable = 11, 233 upnpResultConflictWithOtherMechanism = 12, 234 upnpResultConflictWithOtherMapping = 13, 235 upnpResultSamePortValuesRequired = 14, 236 upnpResultOnlyPermanentLeaseSupported = 15, 237 upnpResultInvalidGateway = 16, 238 upnpResultInvalidPort = 17, 239 upnpResultInvalidProtocol = 18, 240 upnpResultInvalidDuration = 19, 241 upnpResultInvalidArgs = 20, 242 upnpResultInvalidResponse = 21, 243 upnpResultInvalidParam = 22, 244 upnpResultHttpError = 23, 245 upnpResultSocketError = 24, 246 upnpResultMemAllocError = 25, 247 upnpResultNoGateway = 26, 248 upnpResultNoDevices = 27, 249 upnpResultUnknownError = 28, 250 } 251 /** 252 Adds the given $(D UPNPDevice) to the list of discovered devices. 253 */ 254 void addDevice(UPNPDevice device) 255 { 256 checkClassBinding!(typeof(this))(); 257 ptrcall!(void)(GDNativeClassBinding.addDevice, _godot_object, device); 258 } 259 /** 260 Adds a mapping to forward the external `port` (between 1 and 65535) on the default gateway (see $(D getGateway)) to the `internal_port` on the local machine for the given protocol `proto` (either `TCP` or `UDP`, with UDP being the default). If a port mapping for the given port and protocol combination already exists on that gateway device, this method tries to overwrite it. If that is not desired, you can retrieve the gateway manually with $(D getGateway) and call $(D addPortMapping) on it, if any. 261 If `internal_port` is `0` (the default), the same port number is used for both the external and the internal port (the `port` value). 262 The description (`desc`) is shown in some router UIs and can be used to point out which application added the mapping. The mapping's lease duration can be limited by specifying a `duration` (in seconds). However, some routers are incompatible with one or both of these, so use with caution and add fallback logic in case of errors to retry without them if in doubt. 263 See $(D upnpresult) for possible return values. 264 */ 265 long addPortMapping(in long port, in long port_internal = 0, in String desc = gs!"", in String proto = gs!"UDP", in long duration = 0) const 266 { 267 checkClassBinding!(typeof(this))(); 268 return ptrcall!(long)(GDNativeClassBinding.addPortMapping, _godot_object, port, port_internal, desc, proto, duration); 269 } 270 /** 271 Clears the list of discovered devices. 272 */ 273 void clearDevices() 274 { 275 checkClassBinding!(typeof(this))(); 276 ptrcall!(void)(GDNativeClassBinding.clearDevices, _godot_object); 277 } 278 /** 279 Deletes the port mapping for the given port and protocol combination on the default gateway (see $(D getGateway)) if one exists. `port` must be a valid port between 1 and 65535, `proto` can be either `TCP` or `UDP`. See $(D upnpresult) for possible return values. 280 */ 281 long deletePortMapping(in long port, in String proto = gs!"UDP") const 282 { 283 checkClassBinding!(typeof(this))(); 284 return ptrcall!(long)(GDNativeClassBinding.deletePortMapping, _godot_object, port, proto); 285 } 286 /** 287 Discovers local $(D UPNPDevice)s. Clears the list of previously discovered devices. 288 Filters for IGD (InternetGatewayDevice) type devices by default, as those manage port forwarding. `timeout` is the time to wait for responses in milliseconds. `ttl` is the time-to-live; only touch this if you know what you're doing. 289 See $(D upnpresult) for possible return values. 290 */ 291 long discover(in long timeout = 2000, in long ttl = 2, in String device_filter = gs!"InternetGatewayDevice") 292 { 293 checkClassBinding!(typeof(this))(); 294 return ptrcall!(long)(GDNativeClassBinding.discover, _godot_object, timeout, ttl, device_filter); 295 } 296 /** 297 Returns the $(D UPNPDevice) at the given `index`. 298 */ 299 Ref!UPNPDevice getDevice(in long index) const 300 { 301 checkClassBinding!(typeof(this))(); 302 return ptrcall!(UPNPDevice)(GDNativeClassBinding.getDevice, _godot_object, index); 303 } 304 /** 305 Returns the number of discovered $(D UPNPDevice)s. 306 */ 307 long getDeviceCount() const 308 { 309 checkClassBinding!(typeof(this))(); 310 return ptrcall!(long)(GDNativeClassBinding.getDeviceCount, _godot_object); 311 } 312 /** 313 314 */ 315 long getDiscoverLocalPort() const 316 { 317 checkClassBinding!(typeof(this))(); 318 return ptrcall!(long)(GDNativeClassBinding.getDiscoverLocalPort, _godot_object); 319 } 320 /** 321 322 */ 323 String getDiscoverMulticastIf() const 324 { 325 checkClassBinding!(typeof(this))(); 326 return ptrcall!(String)(GDNativeClassBinding.getDiscoverMulticastIf, _godot_object); 327 } 328 /** 329 Returns the default gateway. That is the first discovered $(D UPNPDevice) that is also a valid IGD (InternetGatewayDevice). 330 */ 331 Ref!UPNPDevice getGateway() const 332 { 333 checkClassBinding!(typeof(this))(); 334 return ptrcall!(UPNPDevice)(GDNativeClassBinding.getGateway, _godot_object); 335 } 336 /** 337 338 */ 339 bool isDiscoverIpv6() const 340 { 341 checkClassBinding!(typeof(this))(); 342 return ptrcall!(bool)(GDNativeClassBinding.isDiscoverIpv6, _godot_object); 343 } 344 /** 345 Returns the external $(D IP) address of the default gateway (see $(D getGateway)) as string. Returns an empty string on error. 346 */ 347 String queryExternalAddress() const 348 { 349 checkClassBinding!(typeof(this))(); 350 return ptrcall!(String)(GDNativeClassBinding.queryExternalAddress, _godot_object); 351 } 352 /** 353 Removes the device at `index` from the list of discovered devices. 354 */ 355 void removeDevice(in long index) 356 { 357 checkClassBinding!(typeof(this))(); 358 ptrcall!(void)(GDNativeClassBinding.removeDevice, _godot_object, index); 359 } 360 /** 361 Sets the device at `index` from the list of discovered devices to `device`. 362 */ 363 void setDevice(in long index, UPNPDevice device) 364 { 365 checkClassBinding!(typeof(this))(); 366 ptrcall!(void)(GDNativeClassBinding.setDevice, _godot_object, index, device); 367 } 368 /** 369 370 */ 371 void setDiscoverIpv6(in bool ipv6) 372 { 373 checkClassBinding!(typeof(this))(); 374 ptrcall!(void)(GDNativeClassBinding.setDiscoverIpv6, _godot_object, ipv6); 375 } 376 /** 377 378 */ 379 void setDiscoverLocalPort(in long port) 380 { 381 checkClassBinding!(typeof(this))(); 382 ptrcall!(void)(GDNativeClassBinding.setDiscoverLocalPort, _godot_object, port); 383 } 384 /** 385 386 */ 387 void setDiscoverMulticastIf(in String m_if) 388 { 389 checkClassBinding!(typeof(this))(); 390 ptrcall!(void)(GDNativeClassBinding.setDiscoverMulticastIf, _godot_object, m_if); 391 } 392 /** 393 If `true`, IPv6 is used for $(D UPNPDevice) discovery. 394 */ 395 @property bool discoverIpv6() 396 { 397 return isDiscoverIpv6(); 398 } 399 /// ditto 400 @property void discoverIpv6(bool v) 401 { 402 setDiscoverIpv6(v); 403 } 404 /** 405 If `0`, the local port to use for discovery is chosen automatically by the system. If `1`, discovery will be done from the source port 1900 (same as destination port). Otherwise, the value will be used as the port. 406 */ 407 @property long discoverLocalPort() 408 { 409 return getDiscoverLocalPort(); 410 } 411 /// ditto 412 @property void discoverLocalPort(long v) 413 { 414 setDiscoverLocalPort(v); 415 } 416 /** 417 Multicast interface to use for discovery. Uses the default multicast interface if empty. 418 */ 419 @property String discoverMulticastIf() 420 { 421 return getDiscoverMulticastIf(); 422 } 423 /// ditto 424 @property void discoverMulticastIf(String v) 425 { 426 setDiscoverMulticastIf(v); 427 } 428 }