diff options
Diffstat (limited to 'node/Peer.cpp')
| -rw-r--r-- | node/Peer.cpp | 117 |
1 files changed, 45 insertions, 72 deletions
diff --git a/node/Peer.cpp b/node/Peer.cpp index abbbea72..a2a91769 100644 --- a/node/Peer.cpp +++ b/node/Peer.cpp @@ -27,6 +27,14 @@ #include "Cluster.hpp" #include "Packet.hpp" +#ifndef AF_MAX +#if AF_INET > AF_INET6 +#define AF_MAX AF_INET +#else +#define AF_MAX AF_INET6 +#endif +#endif + namespace ZeroTier { // Used to send varying values for NAT keepalive @@ -150,7 +158,7 @@ void Peer::received( uint64_t worstScore = 0xffffffffffffffffULL; for(unsigned int p=0;p<_numPaths;++p) { if (_paths[p].path->address().ss_family == path->address().ss_family) { - const uint64_t s = _pathScore(p); + const uint64_t s = _pathScore(p,now); if (s < worstScore) { worstScore = s; worstSlot = (int)p; @@ -163,7 +171,7 @@ void Peer::received( // If we can't find one with the same family, replace the worst of any family slot = ZT_MAX_PEER_NETWORK_PATHS - 1; for(unsigned int p=0;p<_numPaths;++p) { - const uint64_t s = _pathScore(p); + const uint64_t s = _pathScore(p,now); if (s < worstScore) { worstScore = s; slot = p; @@ -210,7 +218,7 @@ bool Peer::hasActivePathTo(uint64_t now,const InetAddress &addr) const { Mutex::Lock _l(_paths_m); for(unsigned int p=0;p<_numPaths;++p) { - if ( (_paths[p].path->address() == addr) && (_paths[p].path->alive(now)) ) + if ( (_paths[p].path->address() == addr) && ((now - _paths[p].lastReceive) <= ZT_PEER_PATH_EXPIRATION) && (_paths[p].path->alive(now)) ) return true; } return false; @@ -223,8 +231,8 @@ bool Peer::sendDirect(const void *data,unsigned int len,uint64_t now,bool forceE int bestp = -1; uint64_t best = 0ULL; for(unsigned int p=0;p<_numPaths;++p) { - if (_paths[p].path->alive(now)||(forceEvenIfDead)) { - const uint64_t s = _pathScore(p); + if ( ((now - _paths[p].lastReceive) <= ZT_PEER_PATH_EXPIRATION) && (_paths[p].path->alive(now)||(forceEvenIfDead)) ) { + const uint64_t s = _pathScore(p,now); if (s >= best) { best = s; bestp = (int)p; @@ -239,17 +247,19 @@ bool Peer::sendDirect(const void *data,unsigned int len,uint64_t now,bool forceE } } -SharedPtr<Path> Peer::getBestPath(uint64_t now) +SharedPtr<Path> Peer::getBestPath(uint64_t now,bool includeExpired) { Mutex::Lock _l(_paths_m); int bestp = -1; uint64_t best = 0ULL; for(unsigned int p=0;p<_numPaths;++p) { - const uint64_t s = _pathScore(p); - if (s >= best) { - best = s; - bestp = (int)p; + if ( ((now - _paths[p].lastReceive) < ZT_PEER_PATH_EXPIRATION) || (includeExpired) ) { + const uint64_t s = _pathScore(p,now); + if (s >= best) { + best = s; + bestp = (int)p; + } } } @@ -283,8 +293,8 @@ bool Peer::doPingAndKeepalive(uint64_t now,int inetAddressFamily) int bestp = -1; uint64_t best = 0ULL; for(unsigned int p=0;p<_numPaths;++p) { - if ((inetAddressFamily < 0)||((int)_paths[p].path->address().ss_family == inetAddressFamily)) { - const uint64_t s = _pathScore(p); + if ( ((now - _paths[p].lastReceive) <= ZT_PEER_PATH_EXPIRATION) && ((inetAddressFamily < 0)||((int)_paths[p].path->address().ss_family == inetAddressFamily)) ) { + const uint64_t s = _pathScore(p,now); if (s >= best) { best = s; bestp = (int)p; @@ -293,7 +303,7 @@ bool Peer::doPingAndKeepalive(uint64_t now,int inetAddressFamily) } if (bestp >= 0) { - if ((now - _paths[bestp].lastReceive) >= ZT_PEER_PING_PERIOD) { + if ((now - _paths[best].lastReceive) >= ZT_PEER_PING_PERIOD) { sendHELLO(_paths[bestp].path->localAddress(),_paths[bestp].path->address(),now); } else if (_paths[bestp].path->needsHeartbeat(now)) { _natKeepaliveBuf += (uint32_t)((now * 0x9e3779b1) >> 1); // tumble this around to send constantly varying (meaningless) payloads @@ -309,39 +319,24 @@ bool Peer::hasActiveDirectPath(uint64_t now) const { Mutex::Lock _l(_paths_m); for(unsigned int p=0;p<_numPaths;++p) { - if (_paths[p].path->alive(now)) + if (((now - _paths[p].lastReceive) <= ZT_PEER_PATH_EXPIRATION)&&(_paths[p].path->alive(now))) return true; } return false; } -bool Peer::resetWithinScope(InetAddress::IpScope scope,uint64_t now) +bool Peer::resetWithinScope(InetAddress::IpScope scope,int inetAddressFamily,uint64_t now) { Mutex::Lock _l(_paths_m); - unsigned int np = _numPaths; - unsigned int x = 0; - unsigned int y = 0; - while (x < np) { - if (_paths[x].path->address().ipScope() == scope) { - // Resetting a path means sending a HELLO and then forgetting it. If we - // get OK(HELLO) then it will be re-learned. - sendHELLO(_paths[x].path->localAddress(),_paths[x].path->address(),now); - } else { - if (x != y) { - _paths[y].lastReceive = _paths[x].lastReceive; - _paths[y].path = _paths[x].path; -#ifdef ZT_ENABLE_CLUSTER - _paths[y].localClusterSuboptimal = _paths[x].localClusterSuboptimal; -#endif - } - ++y; + bool resetSomething = false; + for(unsigned int p=0;p<_numPaths;++p) { + if ( (_paths[p].path->address().ss_family == inetAddressFamily) && (_paths[p].path->address().ipScope() == scope) ) { + sendHELLO(_paths[p].path->localAddress(),_paths[p].path->address(),now); + _paths[p].lastReceive >>= 2; // de-prioritize heavily vs. other paths, will get reset if we get OK(HELLO) or other traffic + resetSomething = true; } - ++x; } - _numPaths = y; - while (y < ZT_MAX_PEER_NETWORK_PATHS) - _paths[y++].path.zero(); // let go of unused SmartPtr<>'s - return (_numPaths < np); + return resetSomething; } void Peer::getBestActiveAddresses(uint64_t now,InetAddress &v4,InetAddress &v6) const @@ -351,17 +346,19 @@ void Peer::getBestActiveAddresses(uint64_t now,InetAddress &v4,InetAddress &v6) int bestp4 = -1,bestp6 = -1; uint64_t best4 = 0ULL,best6 = 0ULL; for(unsigned int p=0;p<_numPaths;++p) { - if (_paths[p].path->address().ss_family == AF_INET) { - const uint64_t s = _pathScore(p); - if (s >= best4) { - best4 = s; - bestp4 = (int)p; - } - } else if (_paths[p].path->address().ss_family == AF_INET6) { - const uint64_t s = _pathScore(p); - if (s >= best6) { - best6 = s; - bestp6 = (int)p; + if ( ((now - _paths[p].lastReceive) <= ZT_PEER_PATH_EXPIRATION) && (_paths[p].path->alive(now)) ) { + if (_paths[p].path->address().ss_family == AF_INET) { + const uint64_t s = _pathScore(p,now); + if (s >= best4) { + best4 = s; + bestp4 = (int)p; + } + } else if (_paths[p].path->address().ss_family == AF_INET6) { + const uint64_t s = _pathScore(p,now); + if (s >= best6) { + best6 = s; + bestp6 = (int)p; + } } } } @@ -372,30 +369,6 @@ void Peer::getBestActiveAddresses(uint64_t now,InetAddress &v4,InetAddress &v6) v6 = _paths[bestp6].path->address(); } -void Peer::clean(uint64_t now) -{ - Mutex::Lock _l(_paths_m); - unsigned int np = _numPaths; - unsigned int x = 0; - unsigned int y = 0; - while (x < np) { - if ((now - _paths[x].lastReceive) <= ZT_PEER_PATH_EXPIRATION) { - if (y != x) { - _paths[y].lastReceive = _paths[x].lastReceive; - _paths[y].path = _paths[x].path; -#ifdef ZT_ENABLE_CLUSTER - _paths[y].localClusterSuboptimal = _paths[x].localClusterSuboptimal; -#endif - } - ++y; - } - ++x; - } - _numPaths = y; - while (y < ZT_MAX_PEER_NETWORK_PATHS) - _paths[y++].path.zero(); // let go of unused SmartPtr<>'s -} - bool Peer::_pushDirectPaths(const SharedPtr<Path> &path,uint64_t now) { #ifdef ZT_ENABLE_CLUSTER |
