diff options
Diffstat (limited to 'node/Peer.cpp')
-rw-r--r-- | node/Peer.cpp | 43 |
1 files changed, 25 insertions, 18 deletions
diff --git a/node/Peer.cpp b/node/Peer.cpp index ce4401cd..cc581004 100644 --- a/node/Peer.cpp +++ b/node/Peer.cpp @@ -76,7 +76,7 @@ void Peer::received( // Note: findBetterEndpoint() is first since we still want to check // for a better endpoint even if we don't actually send a redirect. InetAddress redirectTo; - if ( (RR->cluster->findBetterEndpoint(redirectTo,_id.address(),remoteAddr,false)) && (verb != Packet::VERB_OK)&&(verb != Packet::VERB_ERROR)&&(verb != Packet::VERB_RENDEZVOUS)&&(verb != Packet::VERB_PUSH_DIRECT_PATHS) ) { + if ( (verb != Packet::VERB_OK) && (verb != Packet::VERB_ERROR) && (verb != Packet::VERB_RENDEZVOUS) && (verb != Packet::VERB_PUSH_DIRECT_PATHS) && (RR->cluster->findBetterEndpoint(redirectTo,_id.address(),remoteAddr,false)) ) { if (_vProto >= 5) { // For newer peers we can send a more idiomatic verb: PUSH_DIRECT_PATHS. Packet outp(_id.address(),RR->identity.address(),Packet::VERB_PUSH_DIRECT_PATHS); @@ -243,7 +243,7 @@ bool Peer::doPingAndKeepalive(uint64_t now,int inetAddressFamily) return false; } -bool Peer::pushDirectPaths(const InetAddress &localAddr,const InetAddress &toAddress,uint64_t now,bool force) +bool Peer::pushDirectPaths(const InetAddress &localAddr,const InetAddress &toAddress,uint64_t now,bool force,bool includePrivatePaths) { #ifdef ZT_ENABLE_CLUSTER // Cluster mode disables normal PUSH_DIRECT_PATHS in favor of cluster-based peer redirection @@ -257,38 +257,45 @@ bool Peer::pushDirectPaths(const InetAddress &localAddr,const InetAddress &toAdd else _lastDirectPathPushSent = now; } + std::vector<InetAddress> pathsToPush; + std::vector<InetAddress> dps(RR->node->directPaths()); + for(std::vector<InetAddress>::const_iterator i(dps.begin());i!=dps.end();++i) { + if ((includePrivatePaths)||(i->ipScope() == InetAddress::IP_SCOPE_GLOBAL)) + pathsToPush.push_back(*i); + } + std::vector<InetAddress> sym(RR->sa->getSymmetricNatPredictions()); for(unsigned long i=0,added=0;i<sym.size();++i) { InetAddress tmp(sym[(unsigned long)RR->node->prng() % sym.size()]); - if (std::find(dps.begin(),dps.end(),tmp) == dps.end()) { - dps.push_back(tmp); + if (std::find(pathsToPush.begin(),pathsToPush.end(),tmp) == pathsToPush.end()) { + pathsToPush.push_back(tmp); if (++added >= ZT_PUSH_DIRECT_PATHS_MAX_PER_SCOPE_AND_FAMILY) break; } } - if (dps.empty()) + if (pathsToPush.empty()) return false; #ifdef ZT_TRACE { std::string ps; - for(std::vector<InetAddress>::const_iterator p(dps.begin());p!=dps.end();++p) { + for(std::vector<InetAddress>::const_iterator p(pathsToPush.begin());p!=pathsToPush.end();++p) { if (ps.length() > 0) ps.push_back(','); ps.append(p->toString()); } - TRACE("pushing %u direct paths to %s: %s",(unsigned int)dps.size(),_id.address().toString().c_str(),ps.c_str()); + TRACE("pushing %u direct paths to %s: %s",(unsigned int)pathsToPush.size(),_id.address().toString().c_str(),ps.c_str()); } #endif - std::vector<InetAddress>::const_iterator p(dps.begin()); - while (p != dps.end()) { + std::vector<InetAddress>::const_iterator p(pathsToPush.begin()); + while (p != pathsToPush.end()) { Packet outp(_id.address(),RR->identity.address(),Packet::VERB_PUSH_DIRECT_PATHS); outp.addSize(2); // leave room for count unsigned int count = 0; - while ((p != dps.end())&&((outp.size() + 24) < 1200)) { + while ((p != pathsToPush.end())&&((outp.size() + 24) < 1200)) { uint8_t addressType = 4; switch(p->ss_family) { case AF_INET: @@ -475,11 +482,8 @@ void Peer::clean(uint64_t now) } } -bool Peer::_checkPath(Path &p,const uint64_t now) +void Peer::_doDeadPathDetection(Path &p,const uint64_t now) { - if (!p.active(now)) - return false; - /* Dead path detection: if we have sent something to this peer and have not * yet received a reply, double check this path. The majority of outbound * packets including Ethernet frames do generate some kind of reply either @@ -499,6 +503,7 @@ bool Peer::_checkPath(Path &p,const uint64_t now) (p.lastSend() > p.lastReceived()) && ((p.lastSend() - p.lastReceived()) >= ZT_PEER_DEAD_PATH_DETECTION_NO_ANSWER_TIMEOUT) && ((now - p.lastPing()) >= ZT_PEER_DEAD_PATH_DETECTION_NO_ANSWER_TIMEOUT) && + (!p.isClusterSuboptimal()) && (!RR->topology->amRoot()) ) { TRACE("%s(%s) does not seem to be answering in a timely manner, checking if dead (probation == %u)",_id.address().toString().c_str(),p.address().toString().c_str(),p.probation()); @@ -516,8 +521,6 @@ bool Peer::_checkPath(Path &p,const uint64_t now) p.increaseProbation(); } - - return true; } Path *Peer::_getBestPath(const uint64_t now) @@ -526,11 +529,13 @@ Path *Peer::_getBestPath(const uint64_t now) uint64_t bestPathScore = 0; for(unsigned int i=0;i<_numPaths;++i) { const uint64_t score = _paths[i].score(); - if ((score >= bestPathScore)&&(_checkPath(_paths[i],now))) { + if ((score >= bestPathScore)&&(_paths[i].active(now))) { bestPathScore = score; bestPath = &(_paths[i]); } } + if (bestPath) + _doDeadPathDetection(*bestPath,now); return bestPath; } @@ -540,11 +545,13 @@ Path *Peer::_getBestPath(const uint64_t now,int inetAddressFamily) uint64_t bestPathScore = 0; for(unsigned int i=0;i<_numPaths;++i) { const uint64_t score = _paths[i].score(); - if (((int)_paths[i].address().ss_family == inetAddressFamily)&&(score >= bestPathScore)&&(_checkPath(_paths[i],now))) { + if (((int)_paths[i].address().ss_family == inetAddressFamily)&&(score >= bestPathScore)&&(_paths[i].active(now))) { bestPathScore = score; bestPath = &(_paths[i]); } } + if (bestPath) + _doDeadPathDetection(*bestPath,now); return bestPath; } |