Consolidation of multipath logic. Better system separation

This commit is contained in:
Joseph Henry 2021-09-01 21:37:49 -07:00
parent 19391858d4
commit e1af003e4f
No known key found for this signature in database
GPG key ID: C45B33FF5EBC9344
23 changed files with 2004 additions and 3162 deletions

View file

@ -50,12 +50,7 @@ Peer::Peer(const RuntimeEnvironment *renv,const Identity &myIdentity,const Ident
_directPathPushCutoffCount(0),
_credentialsCutoffCount(0),
_echoRequestCutoffCount(0),
_uniqueAlivePathCount(0),
_localMultipathSupported(false),
_remoteMultipathSupported(false),
_canUseMultipath(false),
_shouldCollectPathStatistics(0),
_bondingPolicy(0),
_lastComputedAggregateMeanLatency(0)
{
if (!myIdentity.agree(peerIdentity,_key))
@ -229,7 +224,8 @@ void Peer::received(
SharedPtr<Path> Peer::getAppropriatePath(int64_t now, bool includeExpired, int32_t flowId)
{
if (!_bondToPeer) {
Mutex::Lock _l(_bond_m);
if (!_bond) {
Mutex::Lock _l(_paths_m);
unsigned int bestPath = ZT_MAX_PEER_NETWORK_PATHS;
/**
@ -253,7 +249,7 @@ SharedPtr<Path> Peer::getAppropriatePath(int64_t now, bool includeExpired, int32
}
return SharedPtr<Path>();
}
return _bondToPeer->getAppropriatePath(now, flowId);
return _bond->getAppropriatePath(now, flowId);
}
void Peer::introduce(void *const tPtr,const int64_t now,const SharedPtr<Peer> &other) const
@ -444,39 +440,22 @@ void Peer::tryMemorizedPath(void *tPtr,int64_t now)
void Peer::performMultipathStateCheck(void *tPtr, int64_t now)
{
Mutex::Lock _l(_bond_m);
/**
* Check for conditions required for multipath bonding and create a bond
* if allowed.
*/
_localMultipathSupported = ((RR->bc->inUse()) && (ZT_PROTO_VERSION > 9));
if (_localMultipathSupported) {
int currAlivePathCount = 0;
int duplicatePathsFound = 0;
for (unsigned int i=0;i<ZT_MAX_PEER_NETWORK_PATHS;++i) {
if (_paths[i].p) {
currAlivePathCount++;
for (unsigned int j=0;j<ZT_MAX_PEER_NETWORK_PATHS;++j) {
if (_paths[i].p && _paths[j].p && _paths[i].p->address().ipsEqual2(_paths[j].p->address()) && i != j) {
duplicatePathsFound+=1;
break;
}
}
}
}
_uniqueAlivePathCount = (currAlivePathCount - (duplicatePathsFound / 2));
_remoteMultipathSupported = _vProto > 9;
_canUseMultipath = _localMultipathSupported && _remoteMultipathSupported && (_uniqueAlivePathCount > 1);
}
if (_canUseMultipath && !_bondToPeer) {
if (_localMultipathSupported && !_bond) {
if (RR->bc) {
_bondToPeer = RR->bc->createTransportTriggeredBond(RR, this);
_bond = RR->bc->createTransportTriggeredBond(RR, this);
/**
* Allow new bond to retroactively learn all paths known to this peer
*/
if (_bondToPeer) {
if (_bond) {
for (unsigned int i=0;i<ZT_MAX_PEER_NETWORK_PATHS;++i) {
if (_paths[i].p) {
_bondToPeer->nominatePath(_paths[i].p, now);
_bond->nominatePathToBond(_paths[i].p, now);
}
}
}
@ -510,8 +489,7 @@ unsigned int Peer::doPingAndKeepalive(void *tPtr,int64_t now)
if (_paths[i].p) {
// Clean expired and reduced priority paths
if ( ((now - _paths[i].lr) < ZT_PEER_PATH_EXPIRATION) && (_paths[i].priority == maxPriority) ) {
if ((sendFullHello)||(_paths[i].p->needsHeartbeat(now))
|| (_canUseMultipath && _paths[i].p->needsGratuitousHeartbeat(now))) {
if ((sendFullHello)||(_paths[i].p->needsHeartbeat(now))) {
attemptToContactAt(tPtr,_paths[i].p->localSocket(),_paths[i].p->address(),now,sendFullHello);
_paths[i].p->sent(now);
sent |= (_paths[i].p->address().ss_family == AF_INET) ? 0x1 : 0x2;
@ -591,27 +569,27 @@ void Peer::resetWithinScope(void *tPtr,InetAddress::IpScope scope,int inetAddres
void Peer::recordOutgoingPacket(const SharedPtr<Path> &path, const uint64_t packetId,
uint16_t payloadLength, const Packet::Verb verb, const int32_t flowId, int64_t now)
{
if (!_shouldCollectPathStatistics || !_bondToPeer) {
if (!_shouldCollectPathStatistics || !_bond) {
return;
}
_bondToPeer->recordOutgoingPacket(path, packetId, payloadLength, verb, flowId, now);
_bond->recordOutgoingPacket(path, packetId, payloadLength, verb, flowId, now);
}
void Peer::recordIncomingInvalidPacket(const SharedPtr<Path>& path)
{
if (!_shouldCollectPathStatistics || !_bondToPeer) {
if (!_shouldCollectPathStatistics || !_bond) {
return;
}
_bondToPeer->recordIncomingInvalidPacket(path);
_bond->recordIncomingInvalidPacket(path);
}
void Peer::recordIncomingPacket(const SharedPtr<Path> &path, const uint64_t packetId,
uint16_t payloadLength, const Packet::Verb verb, const int32_t flowId, int64_t now)
{
if (!_shouldCollectPathStatistics || !_bondToPeer) {
if (!_shouldCollectPathStatistics || !_bond) {
return;
}
_bondToPeer->recordIncomingPacket(path, packetId, payloadLength, verb, flowId, now);
_bond->recordIncomingPacket(path, packetId, payloadLength, verb, flowId, now);
}
} // namespace ZeroTier