diff options
Diffstat (limited to 'node/Peer.cpp')
-rw-r--r-- | node/Peer.cpp | 95 |
1 files changed, 27 insertions, 68 deletions
diff --git a/node/Peer.cpp b/node/Peer.cpp index f0f43399..340f0c10 100644 --- a/node/Peer.cpp +++ b/node/Peer.cpp @@ -53,7 +53,6 @@ Peer::Peer(const Identity &myIdentity,const Identity &peerIdentity) _lastUnicastFrame(0), _lastMulticastFrame(0), _lastAnnouncedTo(0), - _lastPathConfirmationSent(0), _lastDirectPathPushSent(0), _lastDirectPathPushReceive(0), _lastPathSort(0), @@ -132,7 +131,6 @@ void Peer::received( const uint64_t now = RR->node->now(); bool needMulticastGroupAnnounce = false; - bool pathIsConfirmed = false; { // begin _lock Mutex::Lock _l(_lock); @@ -149,6 +147,7 @@ void Peer::received( } if (hops == 0) { + bool pathIsConfirmed = false; unsigned int np = _numPaths; for(unsigned int p=0;p<np;++p) { if ((_paths[p].address() == remoteAddr)&&(_paths[p].localAddress() == localAddr)) { @@ -183,8 +182,6 @@ void Peer::received( slot->setClusterSuboptimal(suboptimalPath); #endif _numPaths = np; - pathIsConfirmed = true; - _sortPaths(now); } #ifdef ZT_ENABLE_CLUSTER @@ -194,13 +191,14 @@ void Peer::received( } else { - /* If this path is not known, send a HELLO. We don't learn - * paths without confirming that a bidirectional link is in - * fact present, but any packet that decodes and authenticates - * correctly is considered valid. */ - if ((now - _lastPathConfirmationSent) >= ZT_MIN_PATH_CONFIRMATION_INTERVAL) { - _lastPathConfirmationSent = now; - TRACE("got %s via unknown path %s(%s), confirming...",Packet::verbString(verb),_id.address().toString().c_str(),remoteAddr.toString().c_str()); + TRACE("got %s via unknown path %s(%s), confirming...",Packet::verbString(verb),_id.address().toString().c_str(),remoteAddr.toString().c_str()); + + if ( (_vProto >= 5) && ( !((_vMajor == 1)&&(_vMinor == 1)&&(_vRevision == 0)) ) ) { + // 1.1.1 and newer nodes support ECHO, which is smaller -- but 1.1.0 has a bug so use HELLO there too + Packet outp(_id.address(),RR->identity.address(),Packet::VERB_ECHO); + outp.armor(_key,true); + RR->node->putPacket(localAddr,remoteAddr,outp.data(),outp.size()); + } else { sendHELLO(RR,localAddr,remoteAddr,now); } @@ -314,21 +312,7 @@ void Peer::pushDirectPaths(const RuntimeEnvironment *RR,Path *path,uint64_t now, continue; } - uint8_t flags = 0; - /* TODO: path trust is not implemented yet - switch(p->trust()) { - default: - break; - case Path::TRUST_PRIVACY: - flags |= 0x04; // no encryption - break; - case Path::TRUST_ULTIMATE: - flags |= (0x04 | 0x08); // no encryption, no authentication (redundant but go ahead and set both) - break; - } - */ - - outp.append(flags); + outp.append((uint8_t)0); // no flags outp.append((uint16_t)0); // no extensions outp.append(addressType); outp.append((uint8_t)((addressType == 4) ? 6 : 18)); @@ -363,7 +347,6 @@ bool Peer::resetWithinScope(const RuntimeEnvironment *RR,InetAddress::IpScope sc ++x; } _numPaths = y; - _sortPaths(now); return (y < np); } @@ -502,58 +485,34 @@ void Peer::clean(const RuntimeEnvironment *RR,uint64_t now) } } -struct _SortPathsByQuality -{ - uint64_t _now; - _SortPathsByQuality(const uint64_t now) : _now(now) {} - inline bool operator()(const Path &a,const Path &b) const - { - const uint64_t qa = ( - ((uint64_t)a.active(_now) << 63) | - (((uint64_t)(a.preferenceRank() & 0xfff)) << 51) | - ((uint64_t)a.lastReceived() & 0x7ffffffffffffULL) ); - const uint64_t qb = ( - ((uint64_t)b.active(_now) << 63) | - (((uint64_t)(b.preferenceRank() & 0xfff)) << 51) | - ((uint64_t)b.lastReceived() & 0x7ffffffffffffULL) ); - return (qb < qa); // invert sense to sort in descending order - } -}; -void Peer::_sortPaths(const uint64_t now) -{ - // assumes _lock is locked - _lastPathSort = now; - std::sort(&(_paths[0]),&(_paths[_numPaths]),_SortPathsByQuality(now)); -} - Path *Peer::_getBestPath(const uint64_t now) { // assumes _lock is locked - if ((now - _lastPathSort) >= ZT_PEER_PATH_SORT_INTERVAL) - _sortPaths(now); - if (_paths[0].active(now)) { - return &(_paths[0]); - } else { - _sortPaths(now); - if (_paths[0].active(now)) - return &(_paths[0]); + Path *bestPath = (Path *)0; + uint64_t bestPathScore = 0; + for(unsigned int i=0;i<_numPaths;++i) { + const uint64_t score = _paths[i].score(); + if ((score >= bestPathScore)&&(_paths[i].active(now))) { + bestPathScore = score; + bestPath = &(_paths[i]); + } } - return (Path *)0; + return bestPath; } Path *Peer::_getBestPath(const uint64_t now,int inetAddressFamily) { // assumes _lock is locked - if ((now - _lastPathSort) >= ZT_PEER_PATH_SORT_INTERVAL) - _sortPaths(now); - for(int k=0;k<2;++k) { // try once, and if it fails sort and try one more time - for(unsigned int i=0;i<_numPaths;++i) { - if ((_paths[i].active(now))&&((int)_paths[i].address().ss_family == inetAddressFamily)) - return &(_paths[i]); + Path *bestPath = (Path *)0; + 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)&&(_paths[i].active(now))) { + bestPathScore = score; + bestPath = &(_paths[i]); } - _sortPaths(now); } - return (Path *)0; + return bestPath; } } // namespace ZeroTier |