mirror of
https://github.com/zerotier/ZeroTierOne.git
synced 2024-12-22 06:17:48 +00:00
Pick a random secondary UDP port for uPnP mapped traffic because of broken routers.
This commit is contained in:
parent
7821d1cbdd
commit
423412df98
@ -396,6 +396,10 @@ struct TcpConnection
|
|||||||
Mutex writeBuf_m;
|
Mutex writeBuf_m;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Interface IDs -- the uptr for UDP sockets is set to point to one of these
|
||||||
|
static const int ZT1_INTERFACE_ID_DEFAULT = 0; // default, usually port 9993
|
||||||
|
static const int ZT1_INTERFACE_ID_UPNP = 1; // a randomly chosen UDP socket used with uPnP mappings, if enabled
|
||||||
|
|
||||||
class OneServiceImpl : public OneService
|
class OneServiceImpl : public OneService
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@ -417,6 +421,7 @@ public:
|
|||||||
_termReason(ONE_STILL_RUNNING),
|
_termReason(ONE_STILL_RUNNING),
|
||||||
_port(0),
|
_port(0),
|
||||||
#ifdef ZT_USE_MINIUPNPC
|
#ifdef ZT_USE_MINIUPNPC
|
||||||
|
_v4UpnpUdpSocket((PhySocket *)0),
|
||||||
_upnpClient((UPNPClient *)0),
|
_upnpClient((UPNPClient *)0),
|
||||||
#endif
|
#endif
|
||||||
_run(true)
|
_run(true)
|
||||||
@ -432,18 +437,23 @@ public:
|
|||||||
port = 40000 + (randp % 25500);
|
port = 40000 + (randp % 25500);
|
||||||
}
|
}
|
||||||
|
|
||||||
::memset((void *)&in4,0,sizeof(in4));
|
memset((void *)&in4,0,sizeof(in4));
|
||||||
in4.sin_family = AF_INET;
|
in4.sin_family = AF_INET;
|
||||||
in4.sin_port = Utils::hton((uint16_t)port);
|
in4.sin_port = Utils::hton((uint16_t)port);
|
||||||
_v4UdpSocket = _phy.udpBind((const struct sockaddr *)&in4,this,131072);
|
|
||||||
|
_v4UdpSocket = _phy.udpBind((const struct sockaddr *)&in4,reinterpret_cast<void *>(const_cast<int *>(&ZT1_INTERFACE_ID_DEFAULT)),131072);
|
||||||
|
|
||||||
if (_v4UdpSocket) {
|
if (_v4UdpSocket) {
|
||||||
in4.sin_addr.s_addr = Utils::hton((uint32_t)0x7f000001); // right now we just listen for TCP @localhost
|
in4.sin_addr.s_addr = Utils::hton((uint32_t)0x7f000001); // right now we just listen for TCP @localhost
|
||||||
_v4TcpListenSocket = _phy.tcpListen((const struct sockaddr *)&in4,this);
|
_v4TcpListenSocket = _phy.tcpListen((const struct sockaddr *)&in4,this);
|
||||||
|
|
||||||
if (_v4TcpListenSocket) {
|
if (_v4TcpListenSocket) {
|
||||||
::memset((void *)&in6,0,sizeof(in6));
|
memset((void *)&in6,0,sizeof(in6));
|
||||||
in6.sin6_family = AF_INET6;
|
in6.sin6_family = AF_INET6;
|
||||||
in6.sin6_port = in4.sin_port;
|
in6.sin6_port = in4.sin_port;
|
||||||
_v6UdpSocket = _phy.udpBind((const struct sockaddr *)&in6,this,131072);
|
|
||||||
|
_v6UdpSocket = _phy.udpBind((const struct sockaddr *)&in6,reinterpret_cast<void *>(const_cast<int *>(&ZT1_INTERFACE_ID_DEFAULT)),131072);
|
||||||
|
|
||||||
in6.sin6_addr.s6_addr[15] = 1; // listen for TCP only at localhost
|
in6.sin6_addr.s6_addr[15] = 1; // listen for TCP only at localhost
|
||||||
_v6TcpListenSocket = _phy.tcpListen((const struct sockaddr *)&in6,this);
|
_v6TcpListenSocket = _phy.tcpListen((const struct sockaddr *)&in6,this);
|
||||||
|
|
||||||
@ -465,7 +475,25 @@ public:
|
|||||||
OSUtils::writeFile((_homePath + ZT_PATH_SEPARATOR_S + "zerotier-one.port").c_str(),std::string(portstr));
|
OSUtils::writeFile((_homePath + ZT_PATH_SEPARATOR_S + "zerotier-one.port").c_str(),std::string(portstr));
|
||||||
|
|
||||||
#ifdef ZT_USE_MINIUPNPC
|
#ifdef ZT_USE_MINIUPNPC
|
||||||
_upnpClient = new UPNPClient(_port);
|
// Bind a random secondary port for use with uPnP, since some NAT routers
|
||||||
|
// (cough Ubiquity Edge cough) barf up a lung if you do both conventional
|
||||||
|
// NAT-t and uPnP from behind the same port. I think this is a bug, but
|
||||||
|
// everyone else's router bugs are our problem. :P
|
||||||
|
for(int k=0;k<256;++k) {
|
||||||
|
unsigned int randp = 0;
|
||||||
|
Utils::getSecureRandom(&randp,sizeof(randp));
|
||||||
|
unsigned int upnport = 40000 + (randp % 25500);
|
||||||
|
|
||||||
|
memset((void *)&in4,0,sizeof(in4));
|
||||||
|
in4.sin_family = AF_INET;
|
||||||
|
in4.sin_port = Utils::hton((uint16_t)upnport);
|
||||||
|
|
||||||
|
_v4UpnpUdpSocket = _phy.udpBind((const struct sockaddr *)&in4,reinterpret_cast<void *>(const_cast<int *>(&ZT1_INTERFACE_ID_UPNP)),131072);
|
||||||
|
if (_v4UpnpUdpSocket) {
|
||||||
|
_upnpClient = new UPNPClient(upnport);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -476,6 +504,7 @@ public:
|
|||||||
_phy.close(_v4TcpListenSocket);
|
_phy.close(_v4TcpListenSocket);
|
||||||
_phy.close(_v6TcpListenSocket);
|
_phy.close(_v6TcpListenSocket);
|
||||||
#ifdef ZT_USE_MINIUPNPC
|
#ifdef ZT_USE_MINIUPNPC
|
||||||
|
_phy.close(_v4UpnpUdpSocket);
|
||||||
delete _upnpClient;
|
delete _upnpClient;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
@ -750,7 +779,7 @@ public:
|
|||||||
_lastDirectReceiveFromGlobal = OSUtils::now();
|
_lastDirectReceiveFromGlobal = OSUtils::now();
|
||||||
ZT1_ResultCode rc = _node->processWirePacket(
|
ZT1_ResultCode rc = _node->processWirePacket(
|
||||||
OSUtils::now(),
|
OSUtils::now(),
|
||||||
0,
|
*(reinterpret_cast<const int *>(*uptr)), // for UDP sockets, we set uptr to point to their interface ID
|
||||||
(const struct sockaddr_storage *)from, // Phy<> uses sockaddr_storage, so it'll always be that big
|
(const struct sockaddr_storage *)from, // Phy<> uses sockaddr_storage, so it'll always be that big
|
||||||
data,
|
data,
|
||||||
len,
|
len,
|
||||||
@ -1112,6 +1141,20 @@ public:
|
|||||||
|
|
||||||
inline int nodeWirePacketSendFunction(int localInterfaceId,const struct sockaddr_storage *addr,const void *data,unsigned int len)
|
inline int nodeWirePacketSendFunction(int localInterfaceId,const struct sockaddr_storage *addr,const void *data,unsigned int len)
|
||||||
{
|
{
|
||||||
|
#ifdef ZT_USE_MINIUPNPC
|
||||||
|
if (localInterfaceId == ZT1_INTERFACE_ID_UPNP) {
|
||||||
|
#ifdef ZT_BREAK_UDP
|
||||||
|
if (!OSUtils::fileExists("/tmp/ZT_BREAK_UDP")) {
|
||||||
|
#endif
|
||||||
|
if (addr->ss_family == AF_INET)
|
||||||
|
return ((_phy.udpSend(_v4UpnpUdpSocket,(const struct sockaddr *)addr,data,len) != 0) ? 0 : -1);
|
||||||
|
else return -1;
|
||||||
|
#ifdef ZT_BREAK_UDP
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
#endif // ZT_USE_MINIUPNPC
|
||||||
|
|
||||||
int result = -1;
|
int result = -1;
|
||||||
switch(addr->ss_family) {
|
switch(addr->ss_family) {
|
||||||
case AF_INET:
|
case AF_INET:
|
||||||
@ -1300,6 +1343,7 @@ private:
|
|||||||
unsigned int _port;
|
unsigned int _port;
|
||||||
|
|
||||||
#ifdef ZT_USE_MINIUPNPC
|
#ifdef ZT_USE_MINIUPNPC
|
||||||
|
PhySocket *_v4UpnpUdpSocket;
|
||||||
UPNPClient *_upnpClient;
|
UPNPClient *_upnpClient;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user