mirror of
https://github.com/zerotier/ZeroTierOne.git
synced 2025-01-30 16:13:55 +00:00
Add amSupernode to make code clearer in the check-if-self-is-supernode case.
This commit is contained in:
parent
b8e9a79d00
commit
0c7f8e247c
@ -415,11 +415,9 @@ Node::ReasonForTermination Node::run()
|
|||||||
if ((now - lastPingCheck) >= ZT_PING_CHECK_DELAY) {
|
if ((now - lastPingCheck) >= ZT_PING_CHECK_DELAY) {
|
||||||
lastPingCheck = now;
|
lastPingCheck = now;
|
||||||
try {
|
try {
|
||||||
if (_r->topology->isSupernode(_r->identity.address())) {
|
if (_r->topology->amSupernode()) {
|
||||||
// The only difference in how supernodes behave is here: they only
|
// Supernodes do not ping anyone but each other. They also don't
|
||||||
// actively ping each other and only passively listen for pings
|
// send firewall openers, since they aren't ever firewalled.
|
||||||
// from anyone else. They also don't send firewall openers, since
|
|
||||||
// they're never firewalled.
|
|
||||||
std::vector< SharedPtr<Peer> > sns(_r->topology->supernodePeers());
|
std::vector< SharedPtr<Peer> > sns(_r->topology->supernodePeers());
|
||||||
for(std::vector< SharedPtr<Peer> >::const_iterator p(sns.begin());p!=sns.end();++p) {
|
for(std::vector< SharedPtr<Peer> >::const_iterator p(sns.begin());p!=sns.end();++p) {
|
||||||
if ((now - (*p)->lastDirectSend()) > ZT_PEER_DIRECT_PING_DELAY)
|
if ((now - (*p)->lastDirectSend()) > ZT_PEER_DIRECT_PING_DELAY)
|
||||||
|
@ -450,19 +450,28 @@ bool PacketDecoder::_doMULTICAST_FRAME(const RuntimeEnvironment *_r,const Shared
|
|||||||
// Technically should not happen, since the original submitter is
|
// Technically should not happen, since the original submitter is
|
||||||
// excluded from consideration as a propagation recipient.
|
// excluded from consideration as a propagation recipient.
|
||||||
TRACE("dropped boomerang MULTICAST_FRAME received from %s(%s)",source().toString().c_str(),_remoteAddress.toString().c_str());
|
TRACE("dropped boomerang MULTICAST_FRAME received from %s(%s)",source().toString().c_str(),_remoteAddress.toString().c_str());
|
||||||
} else if ((!isDuplicate)||(_r->topology->isSupernode(_r->identity.address()))) {
|
} else if ((!isDuplicate)||(_r->topology->amSupernode())) {
|
||||||
|
//
|
||||||
// If I am a supernode, I will repeatedly propagate duplicates. That's
|
// If I am a supernode, I will repeatedly propagate duplicates. That's
|
||||||
// because supernodes are used to bridge sparse multicast groups. Non-
|
// because supernodes are used to bridge sparse multicast groups. Non-
|
||||||
// supernodes will ignore duplicates completely.
|
// supernodes will ignore duplicates completely.
|
||||||
|
//
|
||||||
|
// TODO: supernodes should keep a local bloom filter too and OR it with
|
||||||
|
// the bloom from the packet in order to pick different recipients each
|
||||||
|
// time a multicast returns to them for repropagation.
|
||||||
|
//
|
||||||
|
|
||||||
SharedPtr<Peer> originalSubmitter(_r->topology->getPeer(originalSubmitterAddress));
|
SharedPtr<Peer> originalSubmitter(_r->topology->getPeer(originalSubmitterAddress));
|
||||||
if (!originalSubmitter) {
|
if (!originalSubmitter) {
|
||||||
TRACE("requesting WHOIS on original multicast frame submitter %s",originalSubmitterAddress.toString().c_str());
|
TRACE("requesting WHOIS on original multicast frame submitter %s",originalSubmitterAddress.toString().c_str());
|
||||||
_r->sw->requestWhois(originalSubmitterAddress);
|
_r->sw->requestWhois(originalSubmitterAddress);
|
||||||
_step = DECODE_STEP_WAITING_FOR_ORIGINAL_SUBMITTER_LOOKUP;
|
_step = DECODE_STEP_WAITING_FOR_ORIGINAL_SUBMITTER_LOOKUP;
|
||||||
return false;
|
return false; // try again if/when we get OK(WHOIS)
|
||||||
} else if (Multicaster::verifyMulticastPacket(originalSubmitter->identity(),network->id(),fromMac,mg,etherType,dataAndSignature,datalen,dataAndSignature + datalen,signaturelen)) {
|
} else if (Multicaster::verifyMulticastPacket(originalSubmitter->identity(),network->id(),fromMac,mg,etherType,dataAndSignature,datalen,dataAndSignature + datalen,signaturelen)) {
|
||||||
_r->multicaster->addToDedupHistory(mccrc,now);
|
_r->multicaster->addToDedupHistory(mccrc,now);
|
||||||
|
|
||||||
|
// Even if we are a supernode, we still don't repeatedly inject
|
||||||
|
// duplicates into our own tap.
|
||||||
if (!isDuplicate)
|
if (!isDuplicate)
|
||||||
network->tap().put(fromMac,mg.mac(),etherType,dataAndSignature,datalen);
|
network->tap().put(fromMac,mg.mac(),etherType,dataAndSignature,datalen);
|
||||||
|
|
||||||
@ -494,7 +503,7 @@ bool PacketDecoder::_doMULTICAST_FRAME(const RuntimeEnvironment *_r,const Shared
|
|||||||
compress();
|
compress();
|
||||||
|
|
||||||
for(unsigned int i=0;i<np;++i) {
|
for(unsigned int i=0;i<np;++i) {
|
||||||
TRACE("propagating multicast from original node %s: %s -> %s",originalSubmitterAddress.toString().c_str(),upstream.toString().c_str(),propPeers[i]->address().toString().c_str());
|
//TRACE("propagating multicast from original node %s: %s -> %s",originalSubmitterAddress.toString().c_str(),upstream.toString().c_str(),propPeers[i]->address().toString().c_str());
|
||||||
// Re-use this packet to re-send multicast frame to everyone
|
// Re-use this packet to re-send multicast frame to everyone
|
||||||
// downstream from us.
|
// downstream from us.
|
||||||
newInitializationVector();
|
newInitializationVector();
|
||||||
@ -504,7 +513,7 @@ bool PacketDecoder::_doMULTICAST_FRAME(const RuntimeEnvironment *_r,const Shared
|
|||||||
|
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
TRACE("terminating MULTICAST_FRAME propagation from %s(%s): max depth reached",source().toString().c_str(),_remoteAddress.toString().c_str());
|
//TRACE("terminating MULTICAST_FRAME propagation from %s(%s): max depth reached",source().toString().c_str(),_remoteAddress.toString().c_str());
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
LOG("rejected MULTICAST_FRAME from %s(%s) due to failed signature check (claims original sender %s)",source().toString().c_str(),_remoteAddress.toString().c_str(),originalSubmitterAddress.toString().c_str());
|
LOG("rejected MULTICAST_FRAME from %s(%s) due to failed signature check (claims original sender %s)",source().toString().c_str(),_remoteAddress.toString().c_str(),originalSubmitterAddress.toString().c_str());
|
||||||
|
@ -39,7 +39,8 @@ namespace ZeroTier {
|
|||||||
Topology::Topology(const RuntimeEnvironment *renv,const char *dbpath)
|
Topology::Topology(const RuntimeEnvironment *renv,const char *dbpath)
|
||||||
throw(std::runtime_error) :
|
throw(std::runtime_error) :
|
||||||
Thread(),
|
Thread(),
|
||||||
_r(renv)
|
_r(renv),
|
||||||
|
_amSupernode(false)
|
||||||
{
|
{
|
||||||
if (KISSDB_open(&_dbm,dbpath,KISSDB_OPEN_MODE_RWCREAT,ZT_KISSDB_HASH_TABLE_SIZE,ZT_KISSDB_KEY_SIZE,ZT_KISSDB_VALUE_SIZE)) {
|
if (KISSDB_open(&_dbm,dbpath,KISSDB_OPEN_MODE_RWCREAT,ZT_KISSDB_HASH_TABLE_SIZE,ZT_KISSDB_KEY_SIZE,ZT_KISSDB_VALUE_SIZE)) {
|
||||||
if (KISSDB_open(&_dbm,dbpath,KISSDB_OPEN_MODE_RWREPLACE,ZT_KISSDB_HASH_TABLE_SIZE,ZT_KISSDB_KEY_SIZE,ZT_KISSDB_VALUE_SIZE))
|
if (KISSDB_open(&_dbm,dbpath,KISSDB_OPEN_MODE_RWREPLACE,ZT_KISSDB_HASH_TABLE_SIZE,ZT_KISSDB_KEY_SIZE,ZT_KISSDB_VALUE_SIZE))
|
||||||
@ -77,9 +78,11 @@ Topology::~Topology()
|
|||||||
void Topology::setSupernodes(const std::map< Identity,std::vector<InetAddress> > &sn)
|
void Topology::setSupernodes(const std::map< Identity,std::vector<InetAddress> > &sn)
|
||||||
{
|
{
|
||||||
Mutex::Lock _l(_supernodes_m);
|
Mutex::Lock _l(_supernodes_m);
|
||||||
|
|
||||||
_supernodes = sn;
|
_supernodes = sn;
|
||||||
_supernodeAddresses.clear();
|
_supernodeAddresses.clear();
|
||||||
_supernodePeers.clear();
|
_supernodePeers.clear();
|
||||||
|
|
||||||
for(std::map< Identity,std::vector<InetAddress> >::const_iterator i(sn.begin());i!=sn.end();++i) {
|
for(std::map< Identity,std::vector<InetAddress> >::const_iterator i(sn.begin());i!=sn.end();++i) {
|
||||||
if (i->first != _r->identity) {
|
if (i->first != _r->identity) {
|
||||||
SharedPtr<Peer> p(getPeer(i->first.address()));
|
SharedPtr<Peer> p(getPeer(i->first.address()));
|
||||||
@ -93,6 +96,8 @@ void Topology::setSupernodes(const std::map< Identity,std::vector<InetAddress> >
|
|||||||
}
|
}
|
||||||
_supernodeAddresses.insert(i->first.address());
|
_supernodeAddresses.insert(i->first.address());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_amSupernode = (_supernodes.find(_r->identity) != _supernodes.end());
|
||||||
}
|
}
|
||||||
|
|
||||||
void Topology::addPeer(const SharedPtr<Peer> &candidate,void (*callback)(void *,const SharedPtr<Peer> &,Topology::PeerVerifyResult),void *arg)
|
void Topology::addPeer(const SharedPtr<Peer> &candidate,void (*callback)(void *,const SharedPtr<Peer> &,Topology::PeerVerifyResult),void *arg)
|
||||||
|
@ -162,6 +162,11 @@ public:
|
|||||||
return (_supernodeAddresses.count(zta) > 0);
|
return (_supernodeAddresses.count(zta) > 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return True if this node's identity is in the supernode set
|
||||||
|
*/
|
||||||
|
inline bool amSupernode() const { return _amSupernode; }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Clean and flush database now (runs in the background)
|
* Clean and flush database now (runs in the background)
|
||||||
*/
|
*/
|
||||||
@ -305,6 +310,9 @@ private:
|
|||||||
std::vector< SharedPtr<Peer> > _supernodePeers;
|
std::vector< SharedPtr<Peer> > _supernodePeers;
|
||||||
Mutex _supernodes_m;
|
Mutex _supernodes_m;
|
||||||
|
|
||||||
|
// Set to true if my identity is in _supernodes
|
||||||
|
volatile bool _amSupernode;
|
||||||
|
|
||||||
KISSDB _dbm;
|
KISSDB _dbm;
|
||||||
Mutex _dbm_m;
|
Mutex _dbm_m;
|
||||||
};
|
};
|
||||||
|
Loading…
x
Reference in New Issue
Block a user