summaryrefslogtreecommitdiff
path: root/node
diff options
context:
space:
mode:
Diffstat (limited to 'node')
-rw-r--r--node/Peer.cpp57
-rw-r--r--node/Peer.hpp11
-rw-r--r--node/Topology.hpp4
-rw-r--r--node/UdpSocket.cpp1
4 files changed, 32 insertions, 41 deletions
diff --git a/node/Peer.cpp b/node/Peer.cpp
index db6ad261..d2f8705b 100644
--- a/node/Peer.cpp
+++ b/node/Peer.cpp
@@ -120,25 +120,24 @@ void Peer::receive(
bool Peer::send(const RuntimeEnvironment *_r,const void *data,unsigned int len,uint64_t now)
{
- // Note: we'll still use TCP here if that's all we have, but if this
- // is false we will prefer UDP.
- bool useTcp = isTcpFailoverTime(_r,now);
-
Mutex::Lock _l(_lock);
+ bool useTcp = _isTcpFailoverTime(_r,now);
std::vector<Path>::iterator p(_paths.begin());
+ if (useTcp) {
+ while ((p->tcp())&&(p != _paths.end()))
+ ++p;
+ }
if (p == _paths.end())
return false;
uint64_t bestPathLastReceived = p->lastReceived();
std::vector<Path>::iterator bestPath = p;
- bool bestPathIsTcp = p->tcp();
while (++p != _paths.end()) {
uint64_t lr = p->lastReceived();
- if ( (lr > bestPathLastReceived) || ((bestPathIsTcp)&&(!useTcp)) ) {
+ if ( (lr > bestPathLastReceived) && ((useTcp)||(!p->tcp())) ) {
bestPathLastReceived = lr;
bestPath = p;
- bestPathIsTcp = p->tcp();
}
}
@@ -167,13 +166,11 @@ bool Peer::sendPing(const RuntimeEnvironment *_r,uint64_t now)
{
bool sent = false;
SharedPtr<Peer> self(this);
-
- // In the ping case we will never send TCP unless this returns true.
- bool useTcp = isTcpFailoverTime(_r,now);
+ Mutex::Lock _l(_lock);
+ bool useTcp = _isTcpFailoverTime(_r,now);
TRACE("PING %s (useTcp==%d)",_id.address().toString().c_str(),(int)useTcp);
- Mutex::Lock _l(_lock);
for(std::vector<Path>::iterator p(_paths.begin());p!=_paths.end();++p) {
if ((useTcp)||(!p->tcp())) {
p->pinged(now); // we log pings sent even if the send "fails", since what we want to track is when we last tried to ping
@@ -187,9 +184,22 @@ bool Peer::sendPing(const RuntimeEnvironment *_r,uint64_t now)
return sent;
}
-bool Peer::isTcpFailoverTime(const RuntimeEnvironment *_r,uint64_t now) const
+void Peer::clean(uint64_t now)
+{
+ Mutex::Lock _l(_lock);
+ unsigned long i = 0,o = 0,l = (unsigned long)_paths.size();
+ while (i != l) {
+ if (_paths[i].active(now))
+ _paths[o++] = _paths[i];
+ ++i;
+ }
+ _paths.resize(o);
+}
+
+bool Peer::_isTcpFailoverTime(const RuntimeEnvironment *_r,uint64_t now) const
throw()
{
+ // assumes _lock is locked
uint64_t lastResync = _r->timeOfLastResynchronize;
if ((now - lastResync) >= ZT_TCP_TUNNEL_FAILOVER_TIMEOUT) {
if ((now - _r->timeOfLastPacketReceived) >= ZT_TCP_TUNNEL_FAILOVER_TIMEOUT)
@@ -198,13 +208,10 @@ bool Peer::isTcpFailoverTime(const RuntimeEnvironment *_r,uint64_t now) const
uint64_t lastUdpPingSent = 0;
uint64_t lastUdpReceive = 0;
- {
- Mutex::Lock _l(_lock);
- for(std::vector<Path>::const_iterator p(_paths.begin());p!=_paths.end();++p) {
- if (p->type() == Path::PATH_TYPE_UDP) {
- lastUdpPingSent = std::max(lastUdpPingSent,p->lastPing());
- lastUdpReceive = std::max(lastUdpReceive,p->lastReceived());
- }
+ for(std::vector<Path>::const_iterator p(_paths.begin());p!=_paths.end();++p) {
+ if (p->type() == Path::PATH_TYPE_UDP) {
+ lastUdpPingSent = std::max(lastUdpPingSent,p->lastPing());
+ lastUdpReceive = std::max(lastUdpReceive,p->lastReceived());
}
}
@@ -213,16 +220,4 @@ bool Peer::isTcpFailoverTime(const RuntimeEnvironment *_r,uint64_t now) const
return false;
}
-void Peer::clean(uint64_t now)
-{
- Mutex::Lock _l(_lock);
- unsigned long i = 0,o = 0,l = (unsigned long)_paths.size();
- while (i != l) {
- if (_paths[i].active(now))
- _paths[o++] = _paths[i];
- ++i;
- }
- _paths.resize(o);
-}
-
} // namespace ZeroTier
diff --git a/node/Peer.hpp b/node/Peer.hpp
index 864fea70..89a6ab26 100644
--- a/node/Peer.hpp
+++ b/node/Peer.hpp
@@ -283,14 +283,6 @@ public:
}
/**
- * @param _r Runtime environment
- * @param now Current time
- * @return True if it's time to attempt TCP failover (if we have TCP_OUT paths)
- */
- bool isTcpFailoverTime(const RuntimeEnvironment *_r,uint64_t now) const
- throw();
-
- /**
* @return Current latency or 0 if unknown (max: 65535)
*/
inline unsigned int latency() const
@@ -508,6 +500,9 @@ public:
}
private:
+ bool _isTcpFailoverTime(const RuntimeEnvironment *_r,uint64_t now) const
+ throw();
+
unsigned char _key[ZT_PEER_SECRET_KEY_LENGTH];
Identity _id;
diff --git a/node/Topology.hpp b/node/Topology.hpp
index 792b2fa7..024b5ca8 100644
--- a/node/Topology.hpp
+++ b/node/Topology.hpp
@@ -235,7 +235,7 @@ public:
* than time of last send in order to only count full round trips. */
if ( (!_supernodeAddresses.count(p->address())) &&
((_now - p->lastFrame()) < ZT_PEER_PATH_ACTIVITY_TIMEOUT) &&
- ((_now - p->lastDirectReceive()) > ZT_PEER_DIRECT_PING_DELAY) ) {
+ ((_now - p->lastDirectReceive()) > ZT_PEER_DIRECT_PING_DELAY) ) {
p->sendPing(_r,_now);
}
}
@@ -261,7 +261,7 @@ public:
/* For supernodes we always ping even if no frames have been seen, and
* we ping aggressively if pings are unanswered. The limit to this
* frequency is set in the main loop to no more than ZT_STARTUP_AGGRO. */
- if ( (p->pingUnanswered(_r,_now)) || ((_now - p->lastDirectReceive()) > ZT_PEER_DIRECT_PING_DELAY) )
+ if ( (p->pingUnanswered(_r,_now)) || ((_now - p->lastDirectReceive()) > ZT_PEER_DIRECT_PING_DELAY) || (p->lastDirectReceive() < _r->timeOfLastResynchronize) )
p->sendPing(_r,_now);
}
diff --git a/node/UdpSocket.cpp b/node/UdpSocket.cpp
index b0453b1c..60884a53 100644
--- a/node/UdpSocket.cpp
+++ b/node/UdpSocket.cpp
@@ -49,6 +49,7 @@
#endif
// Uncomment to intentionally break UDP in order to test TCP fallback
+// This is here so I can commit it to the repo and drive myself insane.
//#define ZT_BREAK_UDP
namespace ZeroTier {