diff options
| author | Adam Ierymenko <adam.ierymenko@gmail.com> | 2014-03-27 18:23:02 -0700 |
|---|---|---|
| committer | Adam Ierymenko <adam.ierymenko@gmail.com> | 2014-03-27 18:23:02 -0700 |
| commit | b73c36acbf03431fd7fa3584e8621875fdcbebf4 (patch) | |
| tree | a08a976e4d4a63efecc2892bc969cc60141b4c5f /node/Peer.cpp | |
| parent | 181369964f501c3c702971b30c82b9e84eed58db (diff) | |
| parent | d2c5d7150253a5ae5613cac1d65e84b3aa5d33bc (diff) | |
| download | infinitytier-b73c36acbf03431fd7fa3584e8621875fdcbebf4.tar.gz infinitytier-b73c36acbf03431fd7fa3584e8621875fdcbebf4.zip | |
Merge branch 'adamierymenko-dev' of ssh://shub-niggurath.zerotier.com:222/git/ZeroTierOne into adamierymenko-dev
Diffstat (limited to 'node/Peer.cpp')
| -rw-r--r-- | node/Peer.cpp | 44 |
1 files changed, 30 insertions, 14 deletions
diff --git a/node/Peer.cpp b/node/Peer.cpp index b9b9b0c7..fa8ab3e8 100644 --- a/node/Peer.cpp +++ b/node/Peer.cpp @@ -69,6 +69,8 @@ void Peer::receive( Packet::Verb inReVerb, uint64_t now) { + *((const_cast<uint64_t *>(&(_r->timeOfLastPacketReceived)))) = now; + if (!hops) { // direct packet { Mutex::Lock _l(_lock); @@ -91,6 +93,7 @@ void Peer::receive( } // Announce multicast LIKEs to peers to whom we have a direct link + // Lock can't be locked here or it'll recurse and deadlock. if ((now - _lastAnnouncedTo) >= ((ZT_MULTICAST_LIKE_EXPIRE / 2) - 1000)) { _lastAnnouncedTo = now; _r->sw->announceMulticastGroups(SharedPtr<Peer>(this)); @@ -107,19 +110,23 @@ bool Peer::send(const RuntimeEnvironment *_r,const void *data,unsigned int len,u { Mutex::Lock _l(_lock); - if (_paths.empty()) + std::vector<Path>::iterator p(_paths.begin()); + if (p == _paths.end()) { + TRACE("send to %s failed: no paths available",_id.address().toString().c_str()); return false; - - uint64_t bestPathLastReceived = 0; - std::vector<Path>::iterator bestPath; - for(std::vector<Path>::iterator p(_paths.begin());p!=_paths.end();++p) { + } + uint64_t bestPathLastReceived = p->lastReceived(); + std::vector<Path>::iterator bestPath = p; + while (++p != _paths.end()) { uint64_t lr = p->lastReceived(); - if (lr >= bestPathLastReceived) { + if (lr > bestPathLastReceived) { bestPathLastReceived = lr; bestPath = p; } } + TRACE("send to %s: using path: %s",_id.address().toString().c_str(),bestPath->toString().c_str()); + if (_r->sm->send(bestPath->address(),bestPath->tcp(),data,len)) { bestPath->sent(now); return true; @@ -145,21 +152,30 @@ bool Peer::sendPing(const RuntimeEnvironment *_r,uint64_t now,bool firstSinceRes { bool sent = false; SharedPtr<Peer> self(this); + Mutex::Lock _l(_lock); - bool allPingsUnanswered; + // 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) { - allPingsUnanswered = true; + // Do not use TCP if one of our UDP endpoints has answered recently. + uint64_t lastPing = 0; + uint64_t lastDirectReceive = 0; + for(std::vector<Path>::iterator p(_paths.begin());p!=_paths.end();++p) { - if (!p->pingUnanswered(now)) { - allPingsUnanswered = false; - break; - } + lastPing = std::max(lastPing,p->lastPing()); + lastDirectReceive = std::max(lastDirectReceive,p->lastReceived()); } - } else allPingsUnanswered = false; + + pingTcp = ( (lastDirectReceive < lastPing) && ((lastPing - lastDirectReceive) >= ZT_PING_UNANSWERED_AFTER) ); + } else pingTcp = false; + + TRACE("PING %s (pingTcp==%d)",_id.address().toString().c_str(),(int)pingTcp); for(std::vector<Path>::iterator p(_paths.begin());p!=_paths.end();++p) { - if ((allPingsUnanswered)||(!p->tcp())) { + if ((pingTcp)||(!p->tcp())) { if (_r->sw->sendHELLO(self,p->address(),p->tcp())) { p->sent(now); p->pinged(now); |
