Several bug fixes in newly refactored code.

This commit is contained in:
Adam Ierymenko 2013-07-12 16:40:59 -04:00
parent a86e1cdb88
commit f934b81703
7 changed files with 42 additions and 30 deletions

View File

@ -6,12 +6,12 @@ ARCH=$(shell uname -m)
DEFS=-DZT_ARCH="$(ARCH)" -DZT_OSNAME="linux" -DZT_TRACE DEFS=-DZT_ARCH="$(ARCH)" -DZT_OSNAME="linux" -DZT_TRACE
# Uncomment for a release optimized build # Uncomment for a release optimized build
CFLAGS=-Wall -O3 -fno-unroll-loops -fstack-protector -pthread $(INCLUDES) -DNDEBUG $(DEFS) #CFLAGS=-Wall -O3 -fno-unroll-loops -fstack-protector -pthread $(INCLUDES) -DNDEBUG $(DEFS)
STRIP=strip --strip-all #STRIP=strip --strip-all
# Uncomment for a debug build # Uncomment for a debug build
#CFLAGS=-Wall -g -pthread $(INCLUDES) -DZT_TRACE -DZT_LOG_STDOUT $(DEFS) CFLAGS=-Wall -g -pthread $(INCLUDES) -DZT_TRACE -DZT_LOG_STDOUT $(DEFS)
#STRIP=echo STRIP=echo
CXXFLAGS=$(CFLAGS) -fno-rtti CXXFLAGS=$(CFLAGS) -fno-rtti

View File

@ -266,7 +266,7 @@ public:
// Sort in descending order of most recent direct unicast frame, picking // Sort in descending order of most recent direct unicast frame, picking
// peers with whom we have recently communicated. This is "implicit social // peers with whom we have recently communicated. This is "implicit social
// switching." // 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 // Decay a few random bits in bloom filter to probabilistically eliminate
// false positives as we go. The odds of decaying an already-set bit // 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 // LIKEs and so can act to bridge sparse multicast groups. We do not remember them
// in the bloom filter. // in the bloom filter.
if (!picked) { if (!picked) {
P peer = topology.getBestSupernode(); Address avoid[2];
avoid[0] = upstream;
avoid[1] = originalSubmitter;
P peer = topology.getBestSupernode(avoid,2,true);
if (peer) if (peer)
peers[picked++] = peer; peers[picked++] = peer;
} }
@ -305,7 +308,7 @@ private:
{ {
inline bool operator()(const P &p1,const P &p2) const inline bool operator()(const P &p1,const P &p2) const
{ {
return (p1->lastUnicastFrame() >= p2->lastUnicastFrame()); return (p1->lastUnicastFrame() > p2->lastUnicastFrame());
} }
}; };

View File

@ -152,7 +152,7 @@ void NodeConfig::__CBautoconfHandler(const std::string &lastModified,const std::
if (rawAddr.length() == ZT_ADDRESS_LENGTH) { if (rawAddr.length() == ZT_ADDRESS_LENGTH) {
Address addr(rawAddr.data()); Address addr(rawAddr.data());
if ((addr)&&(!addr.isReserved())) { 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); nw->_members.insert(addr);
} }
} }

View File

@ -472,6 +472,7 @@ bool PacketDecoder::_doMULTICAST_FRAME(const RuntimeEnvironment *_r,const Shared
propPeers, propPeers,
Utils::now()); Utils::now());
setSource(_r->identity.address());
(*this)[ZT_PROTO_VERB_MULTICAST_FRAME_IDX_HOP_COUNT] = hops; (*this)[ZT_PROTO_VERB_MULTICAST_FRAME_IDX_HOP_COUNT] = hops;
compress(); compress();

View File

@ -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) 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) { if (supernode) {
Packet outp(supernode->address(),_r->identity.address(),Packet::VERB_WHOIS); Packet outp(supernode->address(),_r->identity.address(),Packet::VERB_WHOIS);
outp.append(addr.data(),ZT_ADDRESS_LENGTH); outp.append(addr.data(),ZT_ADDRESS_LENGTH);

View File

@ -25,6 +25,7 @@
* LLC. Start here: http://www.zerotier.com/ * LLC. Start here: http://www.zerotier.com/
*/ */
#include <algorithm>
#include "Topology.hpp" #include "Topology.hpp"
#include "NodeConfig.hpp" #include "NodeConfig.hpp"
@ -145,23 +146,32 @@ SharedPtr<Peer> Topology::getPeer(const Address &zta)
return SharedPtr<Peer>(); 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; SharedPtr<Peer> bestSupernode;
unsigned long bestSupernodeLatency = 0xffff; unsigned int bestSupernodeLatency = 0xffff;
uint64_t now = Utils::now(); uint64_t now = Utils::now();
Mutex::Lock _l(_supernodes_m); Mutex::Lock _l(_supernodes_m);
if (_supernodePeers.empty())
return bestSupernode;
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();) {
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; 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(); unsigned int l = (*sn)->latency();
if ((l)&&(l <= bestSupernodeLatency)) { if (bestSupernode) {
bestSupernodeLatency = l; if ((l)&&(l < bestSupernodeLatency)) {
bestSupernodeLatency = l;
bestSupernode = *sn;
}
} else {
if (l)
bestSupernodeLatency = l;
bestSupernode = *sn; bestSupernode = *sn;
} }
} }
@ -169,14 +179,20 @@ skip_and_try_next_supernode:
++sn; ++sn;
} }
if (bestSupernode) if ((bestSupernode)||(strictAvoid))
return bestSupernode; return bestSupernode;
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)) { // only consider those that responded to pings if ((*sn)->hasActiveDirectPath(now)) {
unsigned int l = (*sn)->latency(); unsigned int l = (*sn)->latency();
if ((l)&&(l <= bestSupernodeLatency)) { if (bestSupernode) {
bestSupernodeLatency = l; if ((l)&&(l < bestSupernodeLatency)) {
bestSupernodeLatency = l;
bestSupernode = *sn;
}
} else {
if (l)
bestSupernodeLatency = l;
bestSupernode = *sn; bestSupernode = *sn;
} }
} }
@ -185,16 +201,7 @@ skip_and_try_next_supernode:
if (bestSupernode) if (bestSupernode)
return bestSupernode; return bestSupernode;
uint64_t bestSupernodeLastDirectReceive = 0; return _supernodePeers[Utils::randomInt<unsigned int>() % _supernodePeers.size()];
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;
} }
void Topology::clean() void Topology::clean()

View File

@ -134,7 +134,7 @@ public:
*/ */
inline SharedPtr<Peer> getBestSupernode() const 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 avoid Nodes to avoid
* @param avoidCount Number of 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 * @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 * @param zta ZeroTier address