diff options
Diffstat (limited to 'node')
-rw-r--r-- | node/Multicaster.hpp | 9 | ||||
-rw-r--r-- | node/NodeConfig.cpp | 2 | ||||
-rw-r--r-- | node/PacketDecoder.cpp | 1 | ||||
-rw-r--r-- | node/Switch.cpp | 2 | ||||
-rw-r--r-- | node/Topology.cpp | 45 | ||||
-rw-r--r-- | node/Topology.hpp | 5 |
6 files changed, 38 insertions, 26 deletions
diff --git a/node/Multicaster.hpp b/node/Multicaster.hpp index daa53358..d9d12607 100644 --- a/node/Multicaster.hpp +++ b/node/Multicaster.hpp @@ -266,7 +266,7 @@ public: // Sort in descending order of most recent direct unicast frame, picking // peers with whom we have recently communicated. This is "implicit social // switching." - std::sort(&(toConsider[0]),&(toConsider[sampleSize]),PeerPropagationPrioritySortOrder<P>()); + std::sort(toConsider,toConsider + sampleSize,PeerPropagationPrioritySortOrder<P>()); // Decay a few random bits in bloom filter to probabilistically eliminate // false positives as we go. The odds of decaying an already-set bit @@ -290,7 +290,10 @@ public: // LIKEs and so can act to bridge sparse multicast groups. We do not remember them // in the bloom filter. if (!picked) { - P peer = topology.getBestSupernode(); + Address avoid[2]; + avoid[0] = upstream; + avoid[1] = originalSubmitter; + P peer = topology.getBestSupernode(avoid,2,true); if (peer) peers[picked++] = peer; } @@ -305,7 +308,7 @@ private: { inline bool operator()(const P &p1,const P &p2) const { - return (p1->lastUnicastFrame() >= p2->lastUnicastFrame()); + return (p1->lastUnicastFrame() > p2->lastUnicastFrame()); } }; diff --git a/node/NodeConfig.cpp b/node/NodeConfig.cpp index 47310050..fcbbc6bd 100644 --- a/node/NodeConfig.cpp +++ b/node/NodeConfig.cpp @@ -152,7 +152,7 @@ void NodeConfig::__CBautoconfHandler(const std::string &lastModified,const std:: if (rawAddr.length() == ZT_ADDRESS_LENGTH) { Address addr(rawAddr.data()); if ((addr)&&(!addr.isReserved())) { - TRACE("network %llu member: %s",nwid,addr.toString().c_str()); + //TRACE("network %llu member: %s",nwid,addr.toString().c_str()); nw->_members.insert(addr); } } diff --git a/node/PacketDecoder.cpp b/node/PacketDecoder.cpp index 93126e16..9bcf3b43 100644 --- a/node/PacketDecoder.cpp +++ b/node/PacketDecoder.cpp @@ -472,6 +472,7 @@ bool PacketDecoder::_doMULTICAST_FRAME(const RuntimeEnvironment *_r,const Shared propPeers, Utils::now()); + setSource(_r->identity.address()); (*this)[ZT_PROTO_VERB_MULTICAST_FRAME_IDX_HOP_COUNT] = hops; compress(); diff --git a/node/Switch.cpp b/node/Switch.cpp index 2a95906c..3172d7a9 100644 --- a/node/Switch.cpp +++ b/node/Switch.cpp @@ -557,7 +557,7 @@ void Switch::_handleRemotePacketHead(Demarc::Port localPort,const InetAddress &f Address Switch::_sendWhoisRequest(const Address &addr,const Address *peersAlreadyConsulted,unsigned int numPeersAlreadyConsulted) { - SharedPtr<Peer> supernode(_r->topology->getBestSupernode(peersAlreadyConsulted,numPeersAlreadyConsulted)); + SharedPtr<Peer> supernode(_r->topology->getBestSupernode(peersAlreadyConsulted,numPeersAlreadyConsulted,false)); if (supernode) { Packet outp(supernode->address(),_r->identity.address(),Packet::VERB_WHOIS); outp.append(addr.data(),ZT_ADDRESS_LENGTH); diff --git a/node/Topology.cpp b/node/Topology.cpp index 5fd9939d..de65de3b 100644 --- a/node/Topology.cpp +++ b/node/Topology.cpp @@ -25,6 +25,7 @@ * LLC. Start here: http://www.zerotier.com/ */ +#include <algorithm> #include "Topology.hpp" #include "NodeConfig.hpp" @@ -145,23 +146,32 @@ SharedPtr<Peer> Topology::getPeer(const Address &zta) return SharedPtr<Peer>(); } -SharedPtr<Peer> Topology::getBestSupernode(const Address *avoid,unsigned int avoidCount) const +SharedPtr<Peer> Topology::getBestSupernode(const Address *avoid,unsigned int avoidCount,bool strictAvoid) const { SharedPtr<Peer> bestSupernode; - unsigned long bestSupernodeLatency = 0xffff; + unsigned int bestSupernodeLatency = 0xffff; uint64_t now = Utils::now(); Mutex::Lock _l(_supernodes_m); + if (_supernodePeers.empty()) + return bestSupernode; + for(std::vector< SharedPtr<Peer> >::const_iterator sn=_supernodePeers.begin();sn!=_supernodePeers.end();) { for(unsigned int i=0;i<avoidCount;++i) { if (avoid[i] == (*sn)->address()) goto skip_and_try_next_supernode; } - if ((*sn)->hasActiveDirectPath(now)) { // only consider those that responded to pings + if ((*sn)->hasActiveDirectPath(now)) { unsigned int l = (*sn)->latency(); - if ((l)&&(l <= bestSupernodeLatency)) { - bestSupernodeLatency = l; + if (bestSupernode) { + if ((l)&&(l < bestSupernodeLatency)) { + bestSupernodeLatency = l; + bestSupernode = *sn; + } + } else { + if (l) + bestSupernodeLatency = l; bestSupernode = *sn; } } @@ -169,14 +179,20 @@ skip_and_try_next_supernode: ++sn; } - if (bestSupernode) + if ((bestSupernode)||(strictAvoid)) return bestSupernode; for(std::vector< SharedPtr<Peer> >::const_iterator sn=_supernodePeers.begin();sn!=_supernodePeers.end();++sn) { - if ((*sn)->hasActiveDirectPath(now)) { // only consider those that responded to pings + if ((*sn)->hasActiveDirectPath(now)) { unsigned int l = (*sn)->latency(); - if ((l)&&(l <= bestSupernodeLatency)) { - bestSupernodeLatency = l; + if (bestSupernode) { + if ((l)&&(l < bestSupernodeLatency)) { + bestSupernodeLatency = l; + bestSupernode = *sn; + } + } else { + if (l) + bestSupernodeLatency = l; bestSupernode = *sn; } } @@ -185,16 +201,7 @@ skip_and_try_next_supernode: if (bestSupernode) return bestSupernode; - uint64_t bestSupernodeLastDirectReceive = 0; - for(std::vector< SharedPtr<Peer> >::const_iterator sn=_supernodePeers.begin();sn!=_supernodePeers.end();++sn) { - uint64_t l = (*sn)->lastDirectReceive(); - if (l > bestSupernodeLastDirectReceive) { - bestSupernodeLastDirectReceive = l; - bestSupernode = *sn; - } - } - - return bestSupernode; + return _supernodePeers[Utils::randomInt<unsigned int>() % _supernodePeers.size()]; } void Topology::clean() diff --git a/node/Topology.hpp b/node/Topology.hpp index 19e41e08..ae1a15b4 100644 --- a/node/Topology.hpp +++ b/node/Topology.hpp @@ -134,7 +134,7 @@ public: */ inline SharedPtr<Peer> getBestSupernode() const { - return getBestSupernode((const Address *)0,0); + return getBestSupernode((const Address *)0,0,false); } /** @@ -146,9 +146,10 @@ public: * * @param avoid Nodes to avoid * @param avoidCount Number of nodes to avoid + * @param strictAvoid If false, consider avoided supernodes anyway if no non-avoid supernodes are available * @return Supernode or NULL if none */ - SharedPtr<Peer> getBestSupernode(const Address *avoid,unsigned int avoidCount) const; + SharedPtr<Peer> getBestSupernode(const Address *avoid,unsigned int avoidCount,bool strictAvoid) const; /** * @param zta ZeroTier address |