summaryrefslogtreecommitdiff
path: root/node/Topology.cpp
diff options
context:
space:
mode:
authorAdam Ierymenko <adam.ierymenko@gmail.com>2013-07-12 16:40:59 -0400
committerAdam Ierymenko <adam.ierymenko@gmail.com>2013-07-12 16:40:59 -0400
commitf934b81703eedbc152f07a90a179847f9cc3caea (patch)
tree94692e9447873fa469981ede977ed20e9b32b140 /node/Topology.cpp
parenta86e1cdb8874d88c8c84543379ad5552c8ce8701 (diff)
downloadinfinitytier-f934b81703eedbc152f07a90a179847f9cc3caea.tar.gz
infinitytier-f934b81703eedbc152f07a90a179847f9cc3caea.zip
Several bug fixes in newly refactored code.
Diffstat (limited to 'node/Topology.cpp')
-rw-r--r--node/Topology.cpp45
1 files changed, 26 insertions, 19 deletions
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()