Tweaks to new Path code for dual-stack operation, and other fixes.
This commit is contained in:
parent
01aa469591
commit
eebcf08084
8 changed files with 50 additions and 50 deletions
|
@ -264,7 +264,7 @@
|
|||
/**
|
||||
* Peers forget paths that have not spoken in this long
|
||||
*/
|
||||
#define ZT_PEER_PATH_EXPIRATION ((ZT_PEER_PING_PERIOD * 3) + 3000)
|
||||
#define ZT_PEER_PATH_EXPIRATION ((ZT_PEER_PING_PERIOD * 4) + 3000)
|
||||
|
||||
/**
|
||||
* Timeout for overall peer activity (measured from last receive)
|
||||
|
|
|
@ -36,7 +36,7 @@
|
|||
#include "Peer.hpp"
|
||||
|
||||
// Uncomment to make the rules engine dump trace info to stdout
|
||||
#define ZT_RULES_ENGINE_DEBUGGING 1
|
||||
//#define ZT_RULES_ENGINE_DEBUGGING 1
|
||||
|
||||
namespace ZeroTier {
|
||||
|
||||
|
|
|
@ -243,7 +243,7 @@ public:
|
|||
lastReceiveFromUpstream = std::max(p->lastReceive(),lastReceiveFromUpstream);
|
||||
} else if (p->activelyTransferringFrames(_now)) {
|
||||
// Normal nodes get their preferred link kept alive if the node has generated frame traffic recently
|
||||
p->doPingAndKeepalive(_now,0);
|
||||
p->doPingAndKeepalive(_now,-1);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -422,7 +422,6 @@ ZT_PeerList *Node::peers() const
|
|||
memcpy(&(p->paths[p->pathCount].address),&((*path)->address()),sizeof(struct sockaddr_storage));
|
||||
p->paths[p->pathCount].lastSend = (*path)->lastOut();
|
||||
p->paths[p->pathCount].lastReceive = (*path)->lastIn();
|
||||
p->paths[p->pathCount].active = (*path)->alive(_now) ? 1 : 0;
|
||||
p->paths[p->pathCount].preferred = (*path == bestp) ? 1 : 0;
|
||||
p->paths[p->pathCount].trustedPathId = RR->topology->getOutboundPathTrust((*path)->address());
|
||||
++p->pathCount;
|
||||
|
|
|
@ -122,10 +122,11 @@ void Peer::received(
|
|||
{
|
||||
Mutex::Lock _l(_paths_m);
|
||||
for(unsigned int p=0;p<_numPaths;++p) {
|
||||
if (_paths[p].path == path) { // paths are canonicalized so pointer compare is good here
|
||||
if (_paths[p].path->address() == path->address()) {
|
||||
_paths[p].lastReceive = now;
|
||||
_paths[p].path = path; // local address may have changed!
|
||||
#ifdef ZT_ENABLE_CLUSTER
|
||||
_paths[p].clusterSuboptimal = suboptimalPath;
|
||||
_paths[p].clusterWeights = (unsigned int)(!suboptimalPath);
|
||||
#endif
|
||||
pathIsConfirmed = true;
|
||||
break;
|
||||
|
@ -141,25 +142,26 @@ void Peer::received(
|
|||
if (_numPaths < ZT_MAX_PEER_NETWORK_PATHS) {
|
||||
slot = _numPaths++;
|
||||
} else {
|
||||
uint64_t oldest = 0ULL;
|
||||
unsigned int oldestPath = 0;
|
||||
uint64_t worstScore = 0xffffffffffffffffULL;
|
||||
unsigned int worstPath = ZT_MAX_PEER_NETWORK_PATHS-1;
|
||||
for(unsigned int p=0;p<_numPaths;++p) {
|
||||
if (_paths[p].lastReceive < oldest) {
|
||||
oldest = _paths[p].lastReceive;
|
||||
oldestPath = p;
|
||||
const uint64_t s = _pathScore(p);
|
||||
if (s < worstScore) {
|
||||
worstScore = s;
|
||||
worstPath = p;
|
||||
}
|
||||
}
|
||||
slot = oldestPath;
|
||||
slot = worstPath;
|
||||
}
|
||||
|
||||
_paths[slot].path = path;
|
||||
_paths[slot].lastReceive = now;
|
||||
_paths[slot].path = path;
|
||||
#ifdef ZT_ENABLE_CLUSTER
|
||||
_paths[slot].clusterSuboptimal = suboptimalPath;
|
||||
_paths[slot].clusterWeights = (unsigned int)(!suboptimalPath);
|
||||
if (RR->cluster)
|
||||
RR->cluster->broadcastHavePeer(_id);
|
||||
#else
|
||||
_paths[slot].clusterSuboptimal = false;
|
||||
_paths[slot].clusterWeights = 1;
|
||||
#endif
|
||||
} else {
|
||||
|
||||
|
@ -201,17 +203,19 @@ void Peer::setClusterOptimal(const InetAddress &addr)
|
|||
{
|
||||
Mutex::Lock _l(_paths_m);
|
||||
|
||||
int have = -1;
|
||||
int opt = -1;
|
||||
for(unsigned int p=0;p<_numPaths;++p) {
|
||||
if (_paths[p].path->address() == addr) {
|
||||
have = (int)p;
|
||||
opt = (int)p;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (have >= 0) {
|
||||
for(unsigned int p=0;p<_numPaths;++p)
|
||||
_paths[p].clusterSuboptimal = (p != have);
|
||||
if (opt >= 0) { // only change anything if we have the optimal path
|
||||
for(unsigned int p=0;p<_numPaths;++p) {
|
||||
if (_paths[p].path->address().ss_family == addr.ss_family)
|
||||
_paths[p].clusterWeights = ((int)p == opt) ? 2 : 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -282,10 +286,12 @@ bool Peer::doPingAndKeepalive(uint64_t now,int inetAddressFamily)
|
|||
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 ((inetAddressFamily < 0)||(_paths[p].path->address().ss_family == inetAddressFamily)) {
|
||||
const uint64_t s = _pathScore(p);
|
||||
if (s >= best) {
|
||||
best = s;
|
||||
bestp = (int)p;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -325,11 +331,9 @@ bool Peer::resetWithinScope(InetAddress::IpScope scope,uint64_t now)
|
|||
sendHELLO(_paths[x].path->localAddress(),_paths[x].path->address(),now);
|
||||
} else {
|
||||
if (x != y) {
|
||||
_paths[y].path = _paths[x].path;
|
||||
_paths[y].lastReceive = _paths[x].lastReceive;
|
||||
#ifdef ZT_ENABLE_CLUSTER
|
||||
_paths[y].clusterSuboptimal = _paths[x].clusterSuboptimal;
|
||||
#endif
|
||||
_paths[y].path = _paths[x].path;
|
||||
_paths[y].clusterWeights = _paths[x].clusterWeights;
|
||||
}
|
||||
++y;
|
||||
}
|
||||
|
@ -376,11 +380,9 @@ void Peer::clean(uint64_t now)
|
|||
while (x < np) {
|
||||
if ((now - _paths[x].lastReceive) <= ZT_PEER_PATH_EXPIRATION) {
|
||||
if (y != x) {
|
||||
_paths[y].path = _paths[x].path;
|
||||
_paths[y].lastReceive = _paths[x].lastReceive;
|
||||
#ifdef ZT_ENABLE_CLUSTER
|
||||
_paths[y].clusterSuboptimal = _paths[x].clusterSuboptimal;
|
||||
#endif
|
||||
_paths[y].path = _paths[x].path;
|
||||
_paths[y].clusterWeights = _paths[x].clusterWeights;
|
||||
}
|
||||
++y;
|
||||
}
|
||||
|
|
|
@ -121,7 +121,9 @@ public:
|
|||
bool hasActivePathTo(uint64_t now,const InetAddress &addr) const;
|
||||
|
||||
/**
|
||||
* If we have a confirmed path to this address, mark others as cluster suboptimal
|
||||
* Set which known path for an address family is optimal
|
||||
*
|
||||
* This only modifies paths within the same address family
|
||||
*
|
||||
* @param addr Address to make exclusive
|
||||
*/
|
||||
|
@ -161,7 +163,7 @@ public:
|
|||
* Send pings or keepalives depending on configured timeouts
|
||||
*
|
||||
* @param now Current time
|
||||
* @param inetAddressFamily Keep this address family alive, or 0 to simply pick current best ignoring family
|
||||
* @param inetAddressFamily Keep this address family alive, or -1 for any
|
||||
* @return True if we have at least one direct path
|
||||
*/
|
||||
bool doPingAndKeepalive(uint64_t now,int inetAddressFamily);
|
||||
|
@ -285,7 +287,7 @@ public:
|
|||
inline bool hasClusterOptimalPath(uint64_t now) const
|
||||
{
|
||||
for(unsigned int p=0,np=_numPaths;p<np;++p) {
|
||||
if ( (_paths[p].path->alive(now)) && (!_paths[p].clusterSuboptimal) )
|
||||
if ( (_paths[p].path->alive(now)) && ((_paths[p].clusterWeights & 1) != 0) )
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
@ -365,7 +367,9 @@ private:
|
|||
|
||||
inline uint64_t _pathScore(const unsigned int p) const
|
||||
{
|
||||
return ( (_paths[p].path->lastIn() + (_paths[p].path->preferenceRank() * (ZT_PEER_PING_PERIOD / ZT_PATH_MAX_PREFERENCE_RANK))) - ((ZT_PEER_PING_PERIOD * 10) * (uint64_t)_paths[p].clusterSuboptimal) );
|
||||
return ( _paths[p].path->lastIn() +
|
||||
(uint64_t)(_paths[p].path->preferenceRank() * (ZT_PEER_PING_PERIOD / ZT_PATH_MAX_PREFERENCE_RANK)) +
|
||||
(uint64_t)(_paths[p].clusterWeights * ZT_PEER_PING_PERIOD) );
|
||||
}
|
||||
|
||||
unsigned char _key[ZT_PEER_SECRET_KEY_LENGTH];
|
||||
|
@ -384,9 +388,9 @@ private:
|
|||
uint16_t _vRevision;
|
||||
Identity _id;
|
||||
struct {
|
||||
SharedPtr<Path> path;
|
||||
uint64_t lastReceive;
|
||||
bool clusterSuboptimal;
|
||||
SharedPtr<Path> path;
|
||||
unsigned int clusterWeights;
|
||||
} _paths[ZT_MAX_PEER_NETWORK_PATHS];
|
||||
Mutex _paths_m;
|
||||
unsigned int _numPaths;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue