|
|
|
|
@ -415,38 +415,58 @@ public:
|
|
|
|
|
_nextBackgroundTaskDeadline(0), |
|
|
|
|
_tcpFallbackTunnel((TcpConnection *)0), |
|
|
|
|
_termReason(ONE_STILL_RUNNING), |
|
|
|
|
_port(port), |
|
|
|
|
_port(0), |
|
|
|
|
#ifdef ZT_USE_MINIUPNPC |
|
|
|
|
_upnpClient((int)port), |
|
|
|
|
_upnpClient((UPNPClient *)0), |
|
|
|
|
#endif |
|
|
|
|
_run(true) |
|
|
|
|
{ |
|
|
|
|
struct sockaddr_in in4; |
|
|
|
|
struct sockaddr_in6 in6; |
|
|
|
|
|
|
|
|
|
::memset((void *)&in4,0,sizeof(in4)); |
|
|
|
|
in4.sin_family = AF_INET; |
|
|
|
|
in4.sin_port = Utils::hton((uint16_t)port); |
|
|
|
|
_v4UdpSocket = _phy.udpBind((const struct sockaddr *)&in4,this,131072); |
|
|
|
|
if (!_v4UdpSocket) |
|
|
|
|
throw std::runtime_error("cannot bind to port (UDP/IPv4)"); |
|
|
|
|
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); |
|
|
|
|
if (!_v4TcpListenSocket) { |
|
|
|
|
_phy.close(_v4UdpSocket); |
|
|
|
|
throw std::runtime_error("cannot bind to port (TCP/IPv4)"); |
|
|
|
|
const int portTrials = (port == 0) ? 256 : 1; // if port is 0, pick random
|
|
|
|
|
for(int k=0;k<portTrials;++k) { |
|
|
|
|
if (port == 0) { |
|
|
|
|
unsigned int randp = 0; |
|
|
|
|
Utils::getSecureRandom(&randp,sizeof(randp)); |
|
|
|
|
port = 40000 + (randp % 25500); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
::memset((void *)&in4,0,sizeof(in4)); |
|
|
|
|
in4.sin_family = AF_INET; |
|
|
|
|
in4.sin_port = Utils::hton((uint16_t)port); |
|
|
|
|
_v4UdpSocket = _phy.udpBind((const struct sockaddr *)&in4,this,131072); |
|
|
|
|
if (_v4UdpSocket) { |
|
|
|
|
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); |
|
|
|
|
if (_v4TcpListenSocket) { |
|
|
|
|
::memset((void *)&in6,0,sizeof(in6)); |
|
|
|
|
in6.sin6_family = AF_INET6; |
|
|
|
|
in6.sin6_port = in4.sin_port; |
|
|
|
|
_v6UdpSocket = _phy.udpBind((const struct sockaddr *)&in6,this,131072); |
|
|
|
|
in6.sin6_addr.s6_addr[15] = 1; // listen for TCP only at localhost
|
|
|
|
|
_v6TcpListenSocket = _phy.tcpListen((const struct sockaddr *)&in6,this); |
|
|
|
|
|
|
|
|
|
_port = port; |
|
|
|
|
break; // success!
|
|
|
|
|
} else { |
|
|
|
|
_phy.close(_v4UdpSocket,false); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
port = 0; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
::memset((void *)&in6,0,sizeof(in6)); |
|
|
|
|
in6.sin6_family = AF_INET6; |
|
|
|
|
in6.sin6_port = in4.sin_port; |
|
|
|
|
_v6UdpSocket = _phy.udpBind((const struct sockaddr *)&in6,this,131072); |
|
|
|
|
in6.sin6_addr.s6_addr[15] = 1; // listen for TCP only at localhost
|
|
|
|
|
_v6TcpListenSocket = _phy.tcpListen((const struct sockaddr *)&in6,this); |
|
|
|
|
if (_port == 0) |
|
|
|
|
throw std::runtime_error("cannot bind to port"); |
|
|
|
|
|
|
|
|
|
char portstr[64]; |
|
|
|
|
Utils::snprintf(portstr,sizeof(portstr),"%u",port); |
|
|
|
|
Utils::snprintf(portstr,sizeof(portstr),"%u",_port); |
|
|
|
|
OSUtils::writeFile((_homePath + ZT_PATH_SEPARATOR_S + "zerotier-one.port").c_str(),std::string(portstr)); |
|
|
|
|
|
|
|
|
|
#ifdef ZT_USE_MINIUPNPC |
|
|
|
|
_upnpClient = new UPNPClient(_port); |
|
|
|
|
#endif |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
virtual ~OneServiceImpl() |
|
|
|
|
@ -455,6 +475,9 @@ public:
|
|
|
|
|
_phy.close(_v6UdpSocket); |
|
|
|
|
_phy.close(_v4TcpListenSocket); |
|
|
|
|
_phy.close(_v6TcpListenSocket); |
|
|
|
|
#ifdef ZT_USE_MINIUPNPC |
|
|
|
|
delete _upnpClient; |
|
|
|
|
#endif |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
virtual ReasonForTermination run() |
|
|
|
|
@ -583,7 +606,7 @@ public:
|
|
|
|
|
_node->clearLocalInterfaceAddresses(); |
|
|
|
|
|
|
|
|
|
#ifdef ZT_USE_MINIUPNPC |
|
|
|
|
std::vector<InetAddress> upnpAddresses(_upnpClient.get()); |
|
|
|
|
std::vector<InetAddress> upnpAddresses(_upnpClient->get()); |
|
|
|
|
for(std::vector<InetAddress>::const_iterator ext(upnpAddresses.begin());ext!=upnpAddresses.end();++ext) |
|
|
|
|
_node->addLocalInterfaceAddress(reinterpret_cast<const struct sockaddr_storage *>(&(*ext)),0,ZT1_LOCAL_INTERFACE_ADDRESS_TRUST_NORMAL); |
|
|
|
|
#endif |
|
|
|
|
@ -1087,7 +1110,7 @@ public:
|
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
inline int nodeWirePacketSendFunction(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) |
|
|
|
|
{ |
|
|
|
|
int result = -1; |
|
|
|
|
switch(addr->ss_family) { |
|
|
|
|
@ -1144,6 +1167,7 @@ public:
|
|
|
|
|
#endif // ZT1_TCP_FALLBACK_RELAY
|
|
|
|
|
|
|
|
|
|
break; |
|
|
|
|
|
|
|
|
|
case AF_INET6: |
|
|
|
|
#ifdef ZT_BREAK_UDP |
|
|
|
|
if (!OSUtils::fileExists("/tmp/ZT_BREAK_UDP")) { |
|
|
|
|
@ -1154,6 +1178,7 @@ public:
|
|
|
|
|
} |
|
|
|
|
#endif |
|
|
|
|
break; |
|
|
|
|
|
|
|
|
|
default: |
|
|
|
|
return -1; |
|
|
|
|
} |
|
|
|
|
@ -1275,7 +1300,7 @@ private:
|
|
|
|
|
unsigned int _port; |
|
|
|
|
|
|
|
|
|
#ifdef ZT_USE_MINIUPNPC |
|
|
|
|
UPNPClient _upnpClient; |
|
|
|
|
UPNPClient *_upnpClient; |
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
bool _run; |
|
|
|
|
@ -1291,7 +1316,7 @@ static long SnodeDataStoreGetFunction(ZT1_Node *node,void *uptr,const char *name
|
|
|
|
|
static int SnodeDataStorePutFunction(ZT1_Node *node,void *uptr,const char *name,const void *data,unsigned long len,int secure) |
|
|
|
|
{ return reinterpret_cast<OneServiceImpl *>(uptr)->nodeDataStorePutFunction(name,data,len,secure); } |
|
|
|
|
static int SnodeWirePacketSendFunction(ZT1_Node *node,void *uptr,int localInterfaceId,const struct sockaddr_storage *addr,const void *data,unsigned int len) |
|
|
|
|
{ return reinterpret_cast<OneServiceImpl *>(uptr)->nodeWirePacketSendFunction(addr,data,len); } |
|
|
|
|
{ return reinterpret_cast<OneServiceImpl *>(uptr)->nodeWirePacketSendFunction(localInterfaceId,addr,data,len); } |
|
|
|
|
static void SnodeVirtualNetworkFrameFunction(ZT1_Node *node,void *uptr,uint64_t nwid,uint64_t sourceMac,uint64_t destMac,unsigned int etherType,unsigned int vlanId,const void *data,unsigned int len) |
|
|
|
|
{ reinterpret_cast<OneServiceImpl *>(uptr)->nodeVirtualNetworkFrameFunction(nwid,sourceMac,destMac,etherType,vlanId,data,len); } |
|
|
|
|
|
|
|
|
|
|