mirror of
https://github.com/zerotier/ZeroTierOne.git
synced 2025-02-07 20:00:13 +00:00
Rip out dead "firewall opener" code, replace in pipeline with anti-symmetric-NAT tactics.
This commit is contained in:
parent
d02ecfb288
commit
4e9280fc7a
@ -274,27 +274,6 @@
|
|||||||
*/
|
*/
|
||||||
#define ZT_PEER_DIRECT_PING_DELAY 120000
|
#define ZT_PEER_DIRECT_PING_DELAY 120000
|
||||||
|
|
||||||
/**
|
|
||||||
* Delay in ms between firewall opener packets to direct links
|
|
||||||
*
|
|
||||||
* This should be lower than the UDP conversation entry timeout in most
|
|
||||||
* stateful firewalls.
|
|
||||||
*
|
|
||||||
* Uncomment to disable firewall openers.
|
|
||||||
*/
|
|
||||||
//#define ZT_FIREWALL_OPENER_DELAY 30000
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Number of hops to open via firewall opener packets
|
|
||||||
*
|
|
||||||
* The firewall opener code iterates from 1 to this value (inclusive), sending
|
|
||||||
* a tiny packet with each TTL value.
|
|
||||||
*
|
|
||||||
* 2 should permit traversal of double-NAT configurations, such as from inside
|
|
||||||
* a VM running behind local NAT on a host that is itself behind NAT.
|
|
||||||
*/
|
|
||||||
//#define ZT_FIREWALL_OPENER_HOPS 2
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Delay between requests for updated network autoconf information
|
* Delay between requests for updated network autoconf information
|
||||||
*/
|
*/
|
||||||
@ -371,12 +350,9 @@
|
|||||||
#define ZT_MIN_UNITE_INTERVAL 30000
|
#define ZT_MIN_UNITE_INTERVAL 30000
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Delay in milliseconds between firewall opener and real packet for NAT-t
|
* Delay between initial direct NAT-t packet and more aggressive techniques
|
||||||
*
|
|
||||||
* If firewall openers are disbled, it just waits this long before sending
|
|
||||||
* NAT-t packets.
|
|
||||||
*/
|
*/
|
||||||
#define ZT_RENDEZVOUS_NAT_T_DELAY 500
|
#define ZT_NAT_T_TACTICAL_ESCALATION_DELAY 2000
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Size of anti-recursion history (see AntiRecursion.hpp)
|
* Size of anti-recursion history (see AntiRecursion.hpp)
|
||||||
|
@ -728,9 +728,6 @@ Node::ReasonForTermination Node::run()
|
|||||||
lastPingCheck = now;
|
lastPingCheck = now;
|
||||||
try {
|
try {
|
||||||
_r->topology->eachPeer(Topology::PingPeersThatNeedPing(_r,now));
|
_r->topology->eachPeer(Topology::PingPeersThatNeedPing(_r,now));
|
||||||
#ifdef ZT_FIREWALL_OPENER_DELAY
|
|
||||||
_r->topology->eachPeer(Topology::OpenPeersThatNeedFirewallOpener(_r,now));
|
|
||||||
#endif
|
|
||||||
} catch (std::exception &exc) {
|
} catch (std::exception &exc) {
|
||||||
LOG("unexpected exception running ping check cycle: %s",exc.what());
|
LOG("unexpected exception running ping check cycle: %s",exc.what());
|
||||||
} catch ( ... ) {
|
} catch ( ... ) {
|
||||||
|
@ -39,7 +39,7 @@
|
|||||||
#include "Utils.hpp"
|
#include "Utils.hpp"
|
||||||
#include "Buffer.hpp"
|
#include "Buffer.hpp"
|
||||||
|
|
||||||
#define ZT_PATH_SERIALIZATION_VERSION 2
|
#define ZT_PATH_SERIALIZATION_VERSION 3
|
||||||
|
|
||||||
namespace ZeroTier {
|
namespace ZeroTier {
|
||||||
|
|
||||||
@ -60,7 +60,6 @@ public:
|
|||||||
Path() :
|
Path() :
|
||||||
_lastSend(0),
|
_lastSend(0),
|
||||||
_lastReceived(0),
|
_lastReceived(0),
|
||||||
_lastFirewallOpener(0),
|
|
||||||
_lastPing(0),
|
_lastPing(0),
|
||||||
_addr(),
|
_addr(),
|
||||||
_type(PATH_TYPE_NULL),
|
_type(PATH_TYPE_NULL),
|
||||||
@ -75,7 +74,6 @@ public:
|
|||||||
Path(const InetAddress &addr,Type t,bool fixed = false) :
|
Path(const InetAddress &addr,Type t,bool fixed = false) :
|
||||||
_lastSend(0),
|
_lastSend(0),
|
||||||
_lastReceived(0),
|
_lastReceived(0),
|
||||||
_lastFirewallOpener(0),
|
|
||||||
_lastPing(0),
|
_lastPing(0),
|
||||||
_addr(addr),
|
_addr(addr),
|
||||||
_type(t),
|
_type(t),
|
||||||
@ -95,7 +93,6 @@ public:
|
|||||||
|
|
||||||
inline uint64_t lastSend() const throw() { return _lastSend; }
|
inline uint64_t lastSend() const throw() { return _lastSend; }
|
||||||
inline uint64_t lastReceived() const throw() { return _lastReceived; }
|
inline uint64_t lastReceived() const throw() { return _lastReceived; }
|
||||||
inline uint64_t lastFirewallOpener() const throw() { return _lastFirewallOpener; }
|
|
||||||
inline uint64_t lastPing() const throw() { return _lastPing; }
|
inline uint64_t lastPing() const throw() { return _lastPing; }
|
||||||
|
|
||||||
inline bool fixed() const throw() { return _fixed; }
|
inline bool fixed() const throw() { return _fixed; }
|
||||||
@ -103,7 +100,6 @@ public:
|
|||||||
|
|
||||||
inline void sent(uint64_t t) throw() { _lastSend = t; }
|
inline void sent(uint64_t t) throw() { _lastSend = t; }
|
||||||
inline void received(uint64_t t) throw() { _lastReceived = t; }
|
inline void received(uint64_t t) throw() { _lastReceived = t; }
|
||||||
inline void firewallOpenerSent(uint64_t t) throw() { _lastFirewallOpener = t; }
|
|
||||||
inline void pinged(uint64_t t) throw() { _lastPing = t; }
|
inline void pinged(uint64_t t) throw() { _lastPing = t; }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -130,12 +126,11 @@ public:
|
|||||||
case PATH_TYPE_TCP_OUT: t = "tcp_out"; break;
|
case PATH_TYPE_TCP_OUT: t = "tcp_out"; break;
|
||||||
case PATH_TYPE_TCP_IN: t = "tcp_in"; break;
|
case PATH_TYPE_TCP_IN: t = "tcp_in"; break;
|
||||||
}
|
}
|
||||||
Utils::snprintf(tmp,sizeof(tmp),"%s;%s;%lld;%lld;%lld;%lld;%s",
|
Utils::snprintf(tmp,sizeof(tmp),"%s;%s;%lld;%lld;%lld;%s",
|
||||||
t,
|
t,
|
||||||
_addr.toString().c_str(),
|
_addr.toString().c_str(),
|
||||||
(long long)((_lastSend != 0) ? ((now - _lastSend) / 1000LL) : -1),
|
(long long)((_lastSend != 0) ? ((now - _lastSend) / 1000LL) : -1),
|
||||||
(long long)((_lastReceived != 0) ? ((now - _lastReceived) / 1000LL) : -1),
|
(long long)((_lastReceived != 0) ? ((now - _lastReceived) / 1000LL) : -1),
|
||||||
(long long)((_lastFirewallOpener != 0) ? ((now - _lastFirewallOpener) / 1000LL) : -1),
|
|
||||||
(long long)((_lastPing != 0) ? ((now - _lastPing) / 1000LL) : -1),
|
(long long)((_lastPing != 0) ? ((now - _lastPing) / 1000LL) : -1),
|
||||||
((_fixed) ? "fixed" : (active(now) ? "active" : "inactive"))
|
((_fixed) ? "fixed" : (active(now) ? "active" : "inactive"))
|
||||||
);
|
);
|
||||||
@ -161,7 +156,6 @@ public:
|
|||||||
b.append((unsigned char)ZT_PATH_SERIALIZATION_VERSION);
|
b.append((unsigned char)ZT_PATH_SERIALIZATION_VERSION);
|
||||||
b.append(_lastSend);
|
b.append(_lastSend);
|
||||||
b.append(_lastReceived);
|
b.append(_lastReceived);
|
||||||
b.append(_lastFirewallOpener);
|
|
||||||
b.append(_lastPing);
|
b.append(_lastPing);
|
||||||
b.append((unsigned char)_addr.type());
|
b.append((unsigned char)_addr.type());
|
||||||
switch(_addr.type()) {
|
switch(_addr.type()) {
|
||||||
@ -189,7 +183,6 @@ public:
|
|||||||
|
|
||||||
_lastSend = b.template at<uint64_t>(p); p += sizeof(uint64_t);
|
_lastSend = b.template at<uint64_t>(p); p += sizeof(uint64_t);
|
||||||
_lastReceived = b.template at<uint64_t>(p); p += sizeof(uint64_t);
|
_lastReceived = b.template at<uint64_t>(p); p += sizeof(uint64_t);
|
||||||
_lastFirewallOpener = b.template at<uint64_t>(p); p += sizeof(uint64_t);
|
|
||||||
_lastPing = b.template at<uint64_t>(p); p += sizeof(uint64_t);
|
_lastPing = b.template at<uint64_t>(p); p += sizeof(uint64_t);
|
||||||
switch((InetAddress::AddressType)b[p++]) {
|
switch((InetAddress::AddressType)b[p++]) {
|
||||||
case InetAddress::TYPE_IPV4:
|
case InetAddress::TYPE_IPV4:
|
||||||
@ -213,7 +206,6 @@ public:
|
|||||||
private:
|
private:
|
||||||
volatile uint64_t _lastSend;
|
volatile uint64_t _lastSend;
|
||||||
volatile uint64_t _lastReceived;
|
volatile uint64_t _lastReceived;
|
||||||
volatile uint64_t _lastFirewallOpener;
|
|
||||||
volatile uint64_t _lastPing;
|
volatile uint64_t _lastPing;
|
||||||
InetAddress _addr;
|
InetAddress _addr;
|
||||||
Type _type;
|
Type _type;
|
||||||
|
@ -181,23 +181,6 @@ Path::Type Peer::send(const RuntimeEnvironment *_r,const void *data,unsigned int
|
|||||||
return Path::PATH_TYPE_NULL;
|
return Path::PATH_TYPE_NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef ZT_FIREWALL_OPENER_DELAY
|
|
||||||
bool Peer::sendFirewallOpener(const RuntimeEnvironment *_r,uint64_t now)
|
|
||||||
{
|
|
||||||
bool sent = false;
|
|
||||||
Mutex::Lock _l(_lock);
|
|
||||||
|
|
||||||
for(std::vector<Path>::iterator p(_paths.begin());p!=_paths.end();++p) {
|
|
||||||
if (p->type() == Path::PATH_TYPE_UDP) {
|
|
||||||
for(unsigned int h=1;h<=ZT_FIREWALL_OPENER_HOPS;++h)
|
|
||||||
sent |= _r->sm->sendFirewallOpener(p->address(),h);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return sent;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
bool Peer::sendPing(const RuntimeEnvironment *_r,uint64_t now)
|
bool Peer::sendPing(const RuntimeEnvironment *_r,uint64_t now)
|
||||||
{
|
{
|
||||||
bool sent = false;
|
bool sent = false;
|
||||||
|
@ -50,7 +50,7 @@
|
|||||||
#include "NonCopyable.hpp"
|
#include "NonCopyable.hpp"
|
||||||
#include "Mutex.hpp"
|
#include "Mutex.hpp"
|
||||||
|
|
||||||
#define ZT_PEER_SERIALIZATION_VERSION 10
|
#define ZT_PEER_SERIALIZATION_VERSION 11
|
||||||
|
|
||||||
namespace ZeroTier {
|
namespace ZeroTier {
|
||||||
|
|
||||||
@ -142,17 +142,6 @@ public:
|
|||||||
*/
|
*/
|
||||||
Path::Type send(const RuntimeEnvironment *_r,const void *data,unsigned int len,uint64_t now);
|
Path::Type send(const RuntimeEnvironment *_r,const void *data,unsigned int len,uint64_t now);
|
||||||
|
|
||||||
#ifdef ZT_FIREWALL_OPENER_DELAY
|
|
||||||
/**
|
|
||||||
* Send firewall opener to all UDP paths
|
|
||||||
*
|
|
||||||
* @param _r Runtime environment
|
|
||||||
* @param now Current time
|
|
||||||
* @return True if send appears successful for at least one address type
|
|
||||||
*/
|
|
||||||
bool sendFirewallOpener(const RuntimeEnvironment *_r,uint64_t now);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Send HELLO to a peer via all direct paths available
|
* Send HELLO to a peer via all direct paths available
|
||||||
*
|
*
|
||||||
@ -193,19 +182,6 @@ public:
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @return Last successfully sent firewall opener for any path
|
|
||||||
*/
|
|
||||||
inline uint64_t lastFirewallOpener() const
|
|
||||||
throw()
|
|
||||||
{
|
|
||||||
uint64_t x = 0;
|
|
||||||
Mutex::Lock _l(_lock);
|
|
||||||
for(std::vector<Path>::const_iterator p(_paths.begin());p!=_paths.end();++p)
|
|
||||||
x = std::max(x,p->lastFirewallOpener());
|
|
||||||
return x;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return Time of last direct packet receive for any path
|
* @return Time of last direct packet receive for any path
|
||||||
*/
|
*/
|
||||||
|
@ -452,20 +452,6 @@ bool SocketManager::send(const InetAddress &to,bool tcp,bool autoConnectTcp,cons
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef ZT_FIREWALL_OPENER_DELAY
|
|
||||||
bool SocketManager::sendFirewallOpener(const InetAddress &to,int hopLimit)
|
|
||||||
{
|
|
||||||
if (to.isV4()) {
|
|
||||||
if (_udpV4Socket)
|
|
||||||
return ((UdpSocket *)_udpV4Socket.ptr())->sendWithHopLimit(to,"",1,hopLimit);
|
|
||||||
} else if (to.isV6()) {
|
|
||||||
if (_udpV6Socket)
|
|
||||||
return ((UdpSocket *)_udpV6Socket.ptr())->sendWithHopLimit(to,"",1,hopLimit);
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void SocketManager::poll(unsigned long timeout)
|
void SocketManager::poll(unsigned long timeout)
|
||||||
{
|
{
|
||||||
fd_set rfds,wfds,efds;
|
fd_set rfds,wfds,efds;
|
||||||
|
@ -103,16 +103,6 @@ public:
|
|||||||
*/
|
*/
|
||||||
inline bool sendUdp(const InetAddress &to,const void *msg,unsigned int msglen) { return send(to,false,false,msg,msglen); }
|
inline bool sendUdp(const InetAddress &to,const void *msg,unsigned int msglen) { return send(to,false,false,msg,msglen); }
|
||||||
|
|
||||||
/**
|
|
||||||
* Send a UDP packet with a limited IP TTL
|
|
||||||
*
|
|
||||||
* @param to Destination address
|
|
||||||
* @param hopLimit IP TTL
|
|
||||||
*/
|
|
||||||
#ifdef ZT_FIREWALL_OPENER_DELAY
|
|
||||||
bool sendFirewallOpener(const InetAddress &to,int hopLimit);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Perform I/O polling operation (e.g. select())
|
* Perform I/O polling operation (e.g. select())
|
||||||
*
|
*
|
||||||
|
@ -461,13 +461,14 @@ bool Switch::unite(const Address &p1,const Address &p2,bool force)
|
|||||||
|
|
||||||
void Switch::contact(const SharedPtr<Peer> &peer,const InetAddress &atAddr)
|
void Switch::contact(const SharedPtr<Peer> &peer,const InetAddress &atAddr)
|
||||||
{
|
{
|
||||||
#ifdef ZT_FIREWALL_OPENER_HOPS
|
// Send simple packet directly to indicated address -- works for most NATs
|
||||||
_r->sm->sendFirewallOpener(atAddr,ZT_FIREWALL_OPENER_HOPS);
|
sendHELLO(peer,atAddr);
|
||||||
#endif
|
TRACE("sending NAT-t HELLO to %s(%s)",peer->address().toString().c_str(),atAddr.toString().c_str());
|
||||||
|
|
||||||
|
// If we have not punched through after this timeout, open refreshing can of whupass
|
||||||
{
|
{
|
||||||
Mutex::Lock _l(_contactQueue_m);
|
Mutex::Lock _l(_contactQueue_m);
|
||||||
_contactQueue.push_back(ContactQueueEntry(peer,Utils::now() + ZT_RENDEZVOUS_NAT_T_DELAY,atAddr));
|
_contactQueue.push_back(ContactQueueEntry(peer,Utils::now() + ZT_NAT_T_TACTICAL_ESCALATION_DELAY,atAddr));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Kick main loop out of wait so that it can pick up this
|
// Kick main loop out of wait so that it can pick up this
|
||||||
@ -484,8 +485,23 @@ unsigned long Switch::doTimerTasks()
|
|||||||
Mutex::Lock _l(_contactQueue_m);
|
Mutex::Lock _l(_contactQueue_m);
|
||||||
for(std::list<ContactQueueEntry>::iterator qi(_contactQueue.begin());qi!=_contactQueue.end();) {
|
for(std::list<ContactQueueEntry>::iterator qi(_contactQueue.begin());qi!=_contactQueue.end();) {
|
||||||
if (now >= qi->fireAtTime) {
|
if (now >= qi->fireAtTime) {
|
||||||
TRACE("sending NAT-T HELLO to %s(%s)",qi->peer->address().toString().c_str(),qi->inaddr.toString().c_str());
|
if (!qi->peer->hasActiveDirectPath(now)) {
|
||||||
sendHELLO(qi->peer,qi->inaddr);
|
TRACE("deploying aggressive NAT-t against %s(%s)",qi->peer->address().toString().c_str(),qi->inaddr.toString().c_str());
|
||||||
|
|
||||||
|
/* Shotgun approach -- literally -- against symmetric NATs. Most of these
|
||||||
|
* either increment or decrement ports so this gets a good number. Also try
|
||||||
|
* the original port one more time for good measure, since sometimes it
|
||||||
|
* fails first time around. */
|
||||||
|
int p = (int)qi->inaddr.port() - 2;
|
||||||
|
for(int k=0;k<5;++k) {
|
||||||
|
if ((p > 0)&&(p <= 0xffff)) {
|
||||||
|
qi->inaddr.setPort((unsigned int)p);
|
||||||
|
sendHELLO(qi->peer,qi->inaddr);
|
||||||
|
}
|
||||||
|
++p;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
_contactQueue.erase(qi++);
|
_contactQueue.erase(qi++);
|
||||||
} else {
|
} else {
|
||||||
nextDelay = std::min(nextDelay,(unsigned long)(qi->fireAtTime - now));
|
nextDelay = std::min(nextDelay,(unsigned long)(qi->fireAtTime - now));
|
||||||
|
@ -207,29 +207,6 @@ public:
|
|||||||
f(*this,*p);
|
f(*this,*p);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef ZT_FIREWALL_OPENER_DELAY
|
|
||||||
/**
|
|
||||||
* Function object to collect peers that need a firewall opener sent
|
|
||||||
*/
|
|
||||||
class OpenPeersThatNeedFirewallOpener
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
OpenPeersThatNeedFirewallOpener(const RuntimeEnvironment *renv,uint64_t now) throw() :
|
|
||||||
_now(now),
|
|
||||||
_r(renv) {}
|
|
||||||
|
|
||||||
inline void operator()(Topology &t,const SharedPtr<Peer> &p)
|
|
||||||
{
|
|
||||||
if ((p->hasDirectPath())&&((_now - std::max(p->lastFirewallOpener(),p->lastDirectSend())) >= ZT_FIREWALL_OPENER_DELAY))
|
|
||||||
p->sendFirewallOpener(_r,_now);
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
uint64_t _now;
|
|
||||||
const RuntimeEnvironment *_r;
|
|
||||||
};
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Pings all peers that need a ping sent, excluding supernodes
|
* Pings all peers that need a ping sent, excluding supernodes
|
||||||
*
|
*
|
||||||
|
Loading…
x
Reference in New Issue
Block a user