summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--node/Constants.hpp28
-rw-r--r--node/Node.cpp3
-rw-r--r--node/Path.hpp12
-rw-r--r--node/Peer.cpp17
-rw-r--r--node/Peer.hpp26
-rw-r--r--node/SocketManager.cpp14
-rw-r--r--node/SocketManager.hpp10
-rw-r--r--node/Switch.cpp28
-rw-r--r--node/Topology.hpp23
9 files changed, 27 insertions, 134 deletions
diff --git a/node/Constants.hpp b/node/Constants.hpp
index ca4fc37a..21360e51 100644
--- a/node/Constants.hpp
+++ b/node/Constants.hpp
@@ -275,27 +275,6 @@
#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
*/
#define ZT_NETWORK_AUTOCONF_DELAY 60000
@@ -371,12 +350,9 @@
#define ZT_MIN_UNITE_INTERVAL 30000
/**
- * Delay in milliseconds between firewall opener and real packet for NAT-t
- *
- * If firewall openers are disbled, it just waits this long before sending
- * NAT-t packets.
+ * Delay between initial direct NAT-t packet and more aggressive techniques
*/
-#define ZT_RENDEZVOUS_NAT_T_DELAY 500
+#define ZT_NAT_T_TACTICAL_ESCALATION_DELAY 2000
/**
* Size of anti-recursion history (see AntiRecursion.hpp)
diff --git a/node/Node.cpp b/node/Node.cpp
index 99732c72..62a4d9ae 100644
--- a/node/Node.cpp
+++ b/node/Node.cpp
@@ -728,9 +728,6 @@ Node::ReasonForTermination Node::run()
lastPingCheck = now;
try {
_r->topology->eachPeer(Topology::PingPeersThatNeedPing(_r,now));
-#ifdef ZT_FIREWALL_OPENER_DELAY
- _r->topology->eachPeer(Topology::OpenPeersThatNeedFirewallOpener(_r,now));
-#endif
} catch (std::exception &exc) {
LOG("unexpected exception running ping check cycle: %s",exc.what());
} catch ( ... ) {
diff --git a/node/Path.hpp b/node/Path.hpp
index e1900bbb..67dd27fc 100644
--- a/node/Path.hpp
+++ b/node/Path.hpp
@@ -39,7 +39,7 @@
#include "Utils.hpp"
#include "Buffer.hpp"
-#define ZT_PATH_SERIALIZATION_VERSION 2
+#define ZT_PATH_SERIALIZATION_VERSION 3
namespace ZeroTier {
@@ -60,7 +60,6 @@ public:
Path() :
_lastSend(0),
_lastReceived(0),
- _lastFirewallOpener(0),
_lastPing(0),
_addr(),
_type(PATH_TYPE_NULL),
@@ -75,7 +74,6 @@ public:
Path(const InetAddress &addr,Type t,bool fixed = false) :
_lastSend(0),
_lastReceived(0),
- _lastFirewallOpener(0),
_lastPing(0),
_addr(addr),
_type(t),
@@ -95,7 +93,6 @@ public:
inline uint64_t lastSend() const throw() { return _lastSend; }
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 bool fixed() const throw() { return _fixed; }
@@ -103,7 +100,6 @@ public:
inline void sent(uint64_t t) throw() { _lastSend = 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; }
/**
@@ -130,12 +126,11 @@ public:
case PATH_TYPE_TCP_OUT: t = "tcp_out"; 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,
_addr.toString().c_str(),
(long long)((_lastSend != 0) ? ((now - _lastSend) / 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),
((_fixed) ? "fixed" : (active(now) ? "active" : "inactive"))
);
@@ -161,7 +156,6 @@ public:
b.append((unsigned char)ZT_PATH_SERIALIZATION_VERSION);
b.append(_lastSend);
b.append(_lastReceived);
- b.append(_lastFirewallOpener);
b.append(_lastPing);
b.append((unsigned char)_addr.type());
switch(_addr.type()) {
@@ -189,7 +183,6 @@ public:
_lastSend = 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);
switch((InetAddress::AddressType)b[p++]) {
case InetAddress::TYPE_IPV4:
@@ -213,7 +206,6 @@ public:
private:
volatile uint64_t _lastSend;
volatile uint64_t _lastReceived;
- volatile uint64_t _lastFirewallOpener;
volatile uint64_t _lastPing;
InetAddress _addr;
Type _type;
diff --git a/node/Peer.cpp b/node/Peer.cpp
index b10cc1f2..e05352c9 100644
--- a/node/Peer.cpp
+++ b/node/Peer.cpp
@@ -181,23 +181,6 @@ Path::Type Peer::send(const RuntimeEnvironment *_r,const void *data,unsigned int
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 sent = false;
diff --git a/node/Peer.hpp b/node/Peer.hpp
index d3c3669b..05005a30 100644
--- a/node/Peer.hpp
+++ b/node/Peer.hpp
@@ -50,7 +50,7 @@
#include "NonCopyable.hpp"
#include "Mutex.hpp"
-#define ZT_PEER_SERIALIZATION_VERSION 10
+#define ZT_PEER_SERIALIZATION_VERSION 11
namespace ZeroTier {
@@ -142,17 +142,6 @@ public:
*/
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
*
@@ -194,19 +183,6 @@ public:
}
/**
- * @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
*/
inline uint64_t lastDirectReceive() const
diff --git a/node/SocketManager.cpp b/node/SocketManager.cpp
index f4ffdb23..8e3ee9e0 100644
--- a/node/SocketManager.cpp
+++ b/node/SocketManager.cpp
@@ -452,20 +452,6 @@ bool SocketManager::send(const InetAddress &to,bool tcp,bool autoConnectTcp,cons
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)
{
fd_set rfds,wfds,efds;
diff --git a/node/SocketManager.hpp b/node/SocketManager.hpp
index 8dee7e91..81d2e780 100644
--- a/node/SocketManager.hpp
+++ b/node/SocketManager.hpp
@@ -104,16 +104,6 @@ public:
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())
*
* If called concurrently, one will block until the other completes.
diff --git a/node/Switch.cpp b/node/Switch.cpp
index fa8a22c0..dd4aec21 100644
--- a/node/Switch.cpp
+++ b/node/Switch.cpp
@@ -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)
{
-#ifdef ZT_FIREWALL_OPENER_HOPS
- _r->sm->sendFirewallOpener(atAddr,ZT_FIREWALL_OPENER_HOPS);
-#endif
+ // Send simple packet directly to indicated address -- works for most NATs
+ sendHELLO(peer,atAddr);
+ 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);
- _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
@@ -484,8 +485,23 @@ unsigned long Switch::doTimerTasks()
Mutex::Lock _l(_contactQueue_m);
for(std::list<ContactQueueEntry>::iterator qi(_contactQueue.begin());qi!=_contactQueue.end();) {
if (now >= qi->fireAtTime) {
- TRACE("sending NAT-T HELLO to %s(%s)",qi->peer->address().toString().c_str(),qi->inaddr.toString().c_str());
- sendHELLO(qi->peer,qi->inaddr);
+ if (!qi->peer->hasActiveDirectPath(now)) {
+ 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++);
} else {
nextDelay = std::min(nextDelay,(unsigned long)(qi->fireAtTime - now));
diff --git a/node/Topology.hpp b/node/Topology.hpp
index 478b4fc3..6349fe87 100644
--- a/node/Topology.hpp
+++ b/node/Topology.hpp
@@ -207,29 +207,6 @@ public:
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
*