|
|
|
|
@ -29,6 +29,13 @@
|
|
|
|
|
// Uncomment to dump debug messages
|
|
|
|
|
//#define ZT_PORTMAPPER_TRACE 1
|
|
|
|
|
|
|
|
|
|
#ifdef __ANDROID__ |
|
|
|
|
#include <android/log.h> |
|
|
|
|
#define PM_TRACE(...) ((void)__android_log_print(ANDROID_LOG_DEBUG, "PortMapper", __VA_ARGS__)) |
|
|
|
|
#else |
|
|
|
|
#define PM_TRACE(...) fprintf(stderr, __VA_ARGS__) |
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
#include <stdio.h> |
|
|
|
|
#include <stdlib.h> |
|
|
|
|
#include <string.h> |
|
|
|
|
@ -53,15 +60,24 @@
|
|
|
|
|
#include <miniupnpc/miniupnpc.h> |
|
|
|
|
#include <miniupnpc/upnpcommands.h> |
|
|
|
|
#else |
|
|
|
|
#ifdef __ANDROID__ |
|
|
|
|
#include "miniupnpc.h" |
|
|
|
|
#include "upnpcommands.h" |
|
|
|
|
#else |
|
|
|
|
#include "../ext/miniupnpc/miniupnpc.h" |
|
|
|
|
#include "../ext/miniupnpc/upnpcommands.h" |
|
|
|
|
#endif |
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
#ifdef ZT_USE_SYSTEM_NATPMP |
|
|
|
|
#include <natpmp.h> |
|
|
|
|
#else |
|
|
|
|
#ifdef __ANDROID__ |
|
|
|
|
#include "natpmp.h" |
|
|
|
|
#else |
|
|
|
|
#include "../ext/libnatpmp/natpmp.h" |
|
|
|
|
#endif |
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
namespace ZeroTier { |
|
|
|
|
|
|
|
|
|
@ -83,7 +99,7 @@ public:
|
|
|
|
|
int mode = 0; // 0 == NAT-PMP, 1 == UPnP
|
|
|
|
|
|
|
|
|
|
#ifdef ZT_PORTMAPPER_TRACE |
|
|
|
|
fprintf(stderr,"PortMapper: started for UDP port %d"ZT_EOL_S,localPort); |
|
|
|
|
fprintf(stderr,"PortMapper: started for UDP port %d" ZT_EOL_S,localPort); |
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
while (run) { |
|
|
|
|
@ -108,7 +124,7 @@ public:
|
|
|
|
|
if (initnatpmp(&natpmp,0,0) != 0) { |
|
|
|
|
mode = 1; |
|
|
|
|
#ifdef ZT_PORTMAPPER_TRACE |
|
|
|
|
fprintf(stderr,"PortMapper: NAT-PMP: init failed, switching to UPnP mode"ZT_EOL_S); |
|
|
|
|
PM_TRACE("PortMapper: NAT-PMP: init failed, switching to UPnP mode" ZT_EOL_S); |
|
|
|
|
#endif |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
@ -131,7 +147,7 @@ public:
|
|
|
|
|
publicAddress = InetAddress((uint32_t)response.pnu.publicaddress.addr.s_addr,0); |
|
|
|
|
} else { |
|
|
|
|
#ifdef ZT_PORTMAPPER_TRACE |
|
|
|
|
fprintf(stderr,"PortMapper: NAT-PMP: request for external address failed, aborting..."ZT_EOL_S); |
|
|
|
|
PM_TRACE("PortMapper: NAT-PMP: request for external address failed, aborting..." ZT_EOL_S); |
|
|
|
|
#endif |
|
|
|
|
closenatpmp(&natpmp); |
|
|
|
|
break; |
|
|
|
|
@ -153,7 +169,8 @@ public:
|
|
|
|
|
if (r == 0) { |
|
|
|
|
publicAddress.setPort(response.pnu.newportmapping.mappedpublicport); |
|
|
|
|
#ifdef ZT_PORTMAPPER_TRACE |
|
|
|
|
fprintf(stderr,"PortMapper: NAT-PMP: mapped %u to %s"ZT_EOL_S,(unsigned int)localPort,publicAddress.toString().c_str()); |
|
|
|
|
char paddr[128]; |
|
|
|
|
PM_TRACE("PortMapper: NAT-PMP: mapped %u to %s" ZT_EOL_S,(unsigned int)localPort,publicAddress.toString(paddr)); |
|
|
|
|
#endif |
|
|
|
|
Mutex::Lock sl(surface_l); |
|
|
|
|
surface.clear(); |
|
|
|
|
@ -170,7 +187,7 @@ public:
|
|
|
|
|
if (!natPmpSuccess) { |
|
|
|
|
mode = 1; |
|
|
|
|
#ifdef ZT_PORTMAPPER_TRACE |
|
|
|
|
fprintf(stderr,"PortMapper: NAT-PMP: request failed, switching to UPnP mode"ZT_EOL_S); |
|
|
|
|
PM_TRACE("PortMapper: NAT-PMP: request failed, switching to UPnP mode" ZT_EOL_S); |
|
|
|
|
#endif |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
@ -195,7 +212,7 @@ public:
|
|
|
|
|
{ |
|
|
|
|
UPNPDev *dev = devlist; |
|
|
|
|
while (dev) { |
|
|
|
|
fprintf(stderr,"PortMapper: found UPnP device at URL '%s': %s"ZT_EOL_S,dev->descURL,dev->st); |
|
|
|
|
PM_TRACE("PortMapper: found UPnP device at URL '%s': %s" ZT_EOL_S,dev->descURL,dev->st); |
|
|
|
|
dev = dev->pNext; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
@ -209,11 +226,11 @@ public:
|
|
|
|
|
|
|
|
|
|
if ((UPNP_GetValidIGD(devlist,&urls,&data,lanaddr,sizeof(lanaddr)))&&(lanaddr[0])) { |
|
|
|
|
#ifdef ZT_PORTMAPPER_TRACE |
|
|
|
|
fprintf(stderr,"PortMapper: UPnP: my LAN IP address: %s"ZT_EOL_S,lanaddr); |
|
|
|
|
PM_TRACE("PortMapper: UPnP: my LAN IP address: %s" ZT_EOL_S,lanaddr); |
|
|
|
|
#endif |
|
|
|
|
if ((UPNP_GetExternalIPAddress(urls.controlURL,data.first.servicetype,externalip) == UPNPCOMMAND_SUCCESS)&&(externalip[0])) { |
|
|
|
|
#ifdef ZT_PORTMAPPER_TRACE |
|
|
|
|
fprintf(stderr,"PortMapper: UPnP: my external IP address: %s"ZT_EOL_S,externalip); |
|
|
|
|
PM_TRACE("PortMapper: UPnP: my external IP address: %s" ZT_EOL_S,externalip); |
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
for(int tries=0;tries<60;++tries) { |
|
|
|
|
@ -239,7 +256,7 @@ public:
|
|
|
|
|
memset(haveLeaseDuration,0,sizeof(haveLeaseDuration)); |
|
|
|
|
if ((UPNP_GetSpecificPortMappingEntry(urls.controlURL,data.first.servicetype,outport,"UDP",(const char *)0,haveIntClient,haveIntPort,haveDesc,haveEnabled,haveLeaseDuration) == UPNPCOMMAND_SUCCESS)&&(uniqueName == haveDesc)) { |
|
|
|
|
#ifdef ZT_PORTMAPPER_TRACE |
|
|
|
|
fprintf(stderr,"PortMapper: UPnP: reusing previously reserved external port: %s"ZT_EOL_S,outport); |
|
|
|
|
PM_TRACE("PortMapper: UPnP: reusing previously reserved external port: %s" ZT_EOL_S,outport); |
|
|
|
|
#endif |
|
|
|
|
Mutex::Lock sl(surface_l); |
|
|
|
|
surface.clear(); |
|
|
|
|
@ -254,7 +271,7 @@ public:
|
|
|
|
|
int mapResult = 0; |
|
|
|
|
if ((mapResult = UPNP_AddPortMapping(urls.controlURL,data.first.servicetype,outport,inport,lanaddr,uniqueName.c_str(),"UDP",(const char *)0,"0")) == UPNPCOMMAND_SUCCESS) { |
|
|
|
|
#ifdef ZT_PORTMAPPER_TRACE |
|
|
|
|
fprintf(stderr,"PortMapper: UPnP: reserved external port: %s"ZT_EOL_S,outport); |
|
|
|
|
PM_TRACE("PortMapper: UPnP: reserved external port: %s" ZT_EOL_S,outport); |
|
|
|
|
#endif |
|
|
|
|
Mutex::Lock sl(surface_l); |
|
|
|
|
surface.clear(); |
|
|
|
|
@ -264,7 +281,7 @@ public:
|
|
|
|
|
break; |
|
|
|
|
} else { |
|
|
|
|
#ifdef ZT_PORTMAPPER_TRACE |
|
|
|
|
fprintf(stderr,"PortMapper: UPnP: UPNP_AddPortMapping(%s) failed: %d"ZT_EOL_S,outport,mapResult); |
|
|
|
|
PM_TRACE("PortMapper: UPnP: UPNP_AddPortMapping(%s) failed: %d" ZT_EOL_S,outport,mapResult); |
|
|
|
|
#endif |
|
|
|
|
Thread::sleep(1000); |
|
|
|
|
} |
|
|
|
|
@ -273,13 +290,13 @@ public:
|
|
|
|
|
} else { |
|
|
|
|
mode = 0; |
|
|
|
|
#ifdef ZT_PORTMAPPER_TRACE |
|
|
|
|
fprintf(stderr,"PortMapper: UPnP: UPNP_GetExternalIPAddress failed, returning to NAT-PMP mode"ZT_EOL_S); |
|
|
|
|
PM_TRACE("PortMapper: UPnP: UPNP_GetExternalIPAddress failed, returning to NAT-PMP mode" ZT_EOL_S); |
|
|
|
|
#endif |
|
|
|
|
} |
|
|
|
|
} else { |
|
|
|
|
mode = 0; |
|
|
|
|
#ifdef ZT_PORTMAPPER_TRACE |
|
|
|
|
fprintf(stderr,"PortMapper: UPnP: UPNP_GetValidIGD failed, returning to NAT-PMP mode"ZT_EOL_S); |
|
|
|
|
PM_TRACE("PortMapper: UPnP: UPNP_GetValidIGD failed, returning to NAT-PMP mode" ZT_EOL_S); |
|
|
|
|
#endif |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@ -288,14 +305,14 @@ public:
|
|
|
|
|
} else { |
|
|
|
|
mode = 0; |
|
|
|
|
#ifdef ZT_PORTMAPPER_TRACE |
|
|
|
|
fprintf(stderr,"PortMapper: upnpDiscover failed, returning to NAT-PMP mode: %d"ZT_EOL_S,upnpError); |
|
|
|
|
PM_TRACE("PortMapper: upnpDiscover failed, returning to NAT-PMP mode: %d" ZT_EOL_S,upnpError); |
|
|
|
|
#endif |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
// ---------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
#ifdef ZT_PORTMAPPER_TRACE |
|
|
|
|
fprintf(stderr,"UPNPClient: rescanning in %d ms"ZT_EOL_S,ZT_PORTMAPPER_REFRESH_DELAY); |
|
|
|
|
PM_TRACE("UPNPClient: rescanning in %d ms" ZT_EOL_S,ZT_PORTMAPPER_REFRESH_DELAY); |
|
|
|
|
#endif |
|
|
|
|
Thread::sleep(ZT_PORTMAPPER_REFRESH_DELAY); |
|
|
|
|
} |
|
|
|
|
|