diff --git a/node/Path.hpp b/node/Path.hpp index 960b08b35..09ed1f9ea 100644 --- a/node/Path.hpp +++ b/node/Path.hpp @@ -87,19 +87,6 @@ public: return ((_addr)&&((_fixed)||((now - _lastReceived) < ZT_PEER_PATH_ACTIVITY_TIMEOUT))); } - /** - * @return True if it appears that a ping has gone unanswered - */ - inline bool pingUnanswered(uint64_t now) const - throw() - { - uint64_t lp = _lastPing; - uint64_t lr = _lastReceived; - if (lp) - return ((lr < lp)&&((lp - lr) > ZT_PING_UNANSWERED_AFTER)); - return false; - } - /** * @return Human-readable address and other information about this path, some computed as of current time */ diff --git a/node/Peer.cpp b/node/Peer.cpp index f8ff9ba63..0cd829098 100644 --- a/node/Peer.cpp +++ b/node/Peer.cpp @@ -150,18 +150,24 @@ bool Peer::sendPing(const RuntimeEnvironment *_r,uint64_t now,bool firstSinceRes { bool sent = false; SharedPtr self(this); + Mutex::Lock _l(_lock); + // NOTE: this will never ping a peer that has *only* TCP paths. Right + // now there's never such a thing as TCP is only for failover. + bool pingTcp; if (!firstSinceReset) { // Do not use TCP if one of our UDP endpoints has answered recently. - pingTcp = true; + uint64_t lastPing = 0; + uint64_t lastDirectReceive = 0; + for(std::vector::iterator p(_paths.begin());p!=_paths.end();++p) { - if (!p->pingUnanswered(now)) { - pingTcp = false; - break; - } + lastPing = std::max(lastPing,p->lastPing()); + lastDirectReceive = std::max(lastDirectReceive,p->lastReceived()); } + + pingTcp = ( (lastDirectReceive < lastPing) && ((lastPing - lastDirectReceive) >= ZT_PING_UNANSWERED_AFTER) ); } else pingTcp = false; TRACE("PING %s (pingTcp==%d)",_id.address().toString().c_str(),(int)pingTcp);