mirror of
https://github.com/zerotier/ZeroTierOne.git
synced 2025-02-21 10:01:46 +00:00
Add a simple but very nice mechanism for avoiding potentially dead supernodes.
This commit is contained in:
parent
bf5f09a0c7
commit
d04e5a1fe0
@ -304,6 +304,11 @@ error_no_byte_order_defined;
|
|||||||
*/
|
*/
|
||||||
#define ZT_PEER_LINK_ACTIVITY_TIMEOUT ((ZT_PEER_DIRECT_PING_DELAY * 2) + 1000)
|
#define ZT_PEER_LINK_ACTIVITY_TIMEOUT ((ZT_PEER_DIRECT_PING_DELAY * 2) + 1000)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Stop relaying via peers that have not responded to direct sends in this long
|
||||||
|
*/
|
||||||
|
#define ZT_PEER_RELAY_CONVERSATION_LATENCY_THRESHOLD 10000
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Number of outgoing verb/packetId pairs to keep for sends expecting responses
|
* Number of outgoing verb/packetId pairs to keep for sends expecting responses
|
||||||
*/
|
*/
|
||||||
|
@ -134,19 +134,31 @@ void Topology::saveIdentity(const Identity &id)
|
|||||||
SharedPtr<Peer> Topology::getBestSupernode(const Address *avoid,unsigned int avoidCount,bool strictAvoid) const
|
SharedPtr<Peer> Topology::getBestSupernode(const Address *avoid,unsigned int avoidCount,bool strictAvoid) const
|
||||||
{
|
{
|
||||||
SharedPtr<Peer> bestSupernode;
|
SharedPtr<Peer> bestSupernode;
|
||||||
unsigned int bestSupernodeLatency = 0xffff;
|
unsigned int bestSupernodeLatency = 65536;
|
||||||
uint64_t now = Utils::now();
|
uint64_t now = Utils::now();
|
||||||
|
|
||||||
Mutex::Lock _l(_supernodes_m);
|
Mutex::Lock _l(_supernodes_m);
|
||||||
|
|
||||||
if (_supernodePeers.empty())
|
// First look for a best supernode by comparing latencies, but exclude
|
||||||
return bestSupernode;
|
// supernodes that have not responded to direct messages in order to
|
||||||
|
// try to exclude any that are dead or unreachable.
|
||||||
for(std::vector< SharedPtr<Peer> >::const_iterator sn=_supernodePeers.begin();sn!=_supernodePeers.end();) {
|
for(std::vector< SharedPtr<Peer> >::const_iterator sn=_supernodePeers.begin();sn!=_supernodePeers.end();) {
|
||||||
|
// Skip explicitly avoided relays
|
||||||
for(unsigned int i=0;i<avoidCount;++i) {
|
for(unsigned int i=0;i<avoidCount;++i) {
|
||||||
if (avoid[i] == (*sn)->address())
|
if (avoid[i] == (*sn)->address()) {
|
||||||
goto skip_and_try_next_supernode;
|
++sn;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Skip possibly comatose or unreachable relays
|
||||||
|
uint64_t lds = (*sn)->lastDirectSend();
|
||||||
|
uint64_t ldr = (*sn)->lastDirectReceive();
|
||||||
|
if ((lds)&&(ldr > lds)&&((lds - ldr) > ZT_PEER_RELAY_CONVERSATION_LATENCY_THRESHOLD)) {
|
||||||
|
++sn;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if ((*sn)->hasActiveDirectPath(now)) {
|
if ((*sn)->hasActiveDirectPath(now)) {
|
||||||
unsigned int l = (*sn)->latency();
|
unsigned int l = (*sn)->latency();
|
||||||
if (bestSupernode) {
|
if (bestSupernode) {
|
||||||
@ -160,8 +172,6 @@ SharedPtr<Peer> Topology::getBestSupernode(const Address *avoid,unsigned int avo
|
|||||||
bestSupernode = *sn;
|
bestSupernode = *sn;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
skip_and_try_next_supernode:
|
|
||||||
++sn;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bestSupernode) {
|
if (bestSupernode) {
|
||||||
@ -170,6 +180,7 @@ skip_and_try_next_supernode:
|
|||||||
} else if (strictAvoid)
|
} else if (strictAvoid)
|
||||||
return SharedPtr<Peer>();
|
return SharedPtr<Peer>();
|
||||||
|
|
||||||
|
// If we have nothing from above, just pick one without avoidance criteria.
|
||||||
for(std::vector< SharedPtr<Peer> >::const_iterator sn=_supernodePeers.begin();sn!=_supernodePeers.end();++sn) {
|
for(std::vector< SharedPtr<Peer> >::const_iterator sn=_supernodePeers.begin();sn!=_supernodePeers.end();++sn) {
|
||||||
if ((*sn)->hasActiveDirectPath(now)) {
|
if ((*sn)->hasActiveDirectPath(now)) {
|
||||||
unsigned int l = (*sn)->latency();
|
unsigned int l = (*sn)->latency();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user