Browse Source

Add amSupernode to make code clearer in the check-if-self-is-supernode case.

Adam Ierymenko 12 years ago
parent
commit
0c7f8e247c
4 changed files with 30 additions and 10 deletions
  1. 3 5
      node/Node.cpp
  2. 13 4
      node/PacketDecoder.cpp
  3. 6 1
      node/Topology.cpp
  4. 8 0
      node/Topology.hpp

+ 3 - 5
node/Node.cpp

@@ -415,11 +415,9 @@ Node::ReasonForTermination Node::run()
 			if ((now - lastPingCheck) >= ZT_PING_CHECK_DELAY) {
 				lastPingCheck = now;
 				try {
-					if (_r->topology->isSupernode(_r->identity.address())) {
-						// The only difference in how supernodes behave is here: they only
-						// actively ping each other and only passively listen for pings
-						// from anyone else. They also don't send firewall openers, since
-						// they're never firewalled.
+					if (_r->topology->amSupernode()) {
+						// Supernodes do not ping anyone but each other. They also don't
+						// send firewall openers, since they aren't ever firewalled.
 						std::vector< SharedPtr<Peer> > sns(_r->topology->supernodePeers());
 						for(std::vector< SharedPtr<Peer> >::const_iterator p(sns.begin());p!=sns.end();++p) {
 							if ((now - (*p)->lastDirectSend()) > ZT_PEER_DIRECT_PING_DELAY)

+ 13 - 4
node/PacketDecoder.cpp

@@ -450,19 +450,28 @@ bool PacketDecoder::_doMULTICAST_FRAME(const RuntimeEnvironment *_r,const Shared
 						// Technically should not happen, since the original submitter is
 						// excluded from consideration as a propagation recipient.
 						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
 						// because supernodes are used to bridge sparse multicast groups. Non-
 						// 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));
 						if (!originalSubmitter) {
 							TRACE("requesting WHOIS on original multicast frame submitter %s",originalSubmitterAddress.toString().c_str());
 							_r->sw->requestWhois(originalSubmitterAddress);
 							_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)) {
 							_r->multicaster->addToDedupHistory(mccrc,now);
 
+							// Even if we are a supernode, we still don't repeatedly inject
+							// duplicates into our own tap.
 							if (!isDuplicate)
 								network->tap().put(fromMac,mg.mac(),etherType,dataAndSignature,datalen);
 
@@ -494,7 +503,7 @@ bool PacketDecoder::_doMULTICAST_FRAME(const RuntimeEnvironment *_r,const Shared
 								compress();
 
 								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
 									// downstream from us.
 									newInitializationVector();
@@ -504,7 +513,7 @@ bool PacketDecoder::_doMULTICAST_FRAME(const RuntimeEnvironment *_r,const Shared
 
 								return true;
 							} 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 {
 							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());

+ 6 - 1
node/Topology.cpp

@@ -39,7 +39,8 @@ namespace ZeroTier {
 Topology::Topology(const RuntimeEnvironment *renv,const char *dbpath)
 	throw(std::runtime_error) :
 	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_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)
 {
 	Mutex::Lock _l(_supernodes_m);
+
 	_supernodes = sn;
 	_supernodeAddresses.clear();
 	_supernodePeers.clear();
+
 	for(std::map< Identity,std::vector<InetAddress> >::const_iterator i(sn.begin());i!=sn.end();++i) {
 		if (i->first != _r->identity) {
 			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());
 	}
+
+	_amSupernode = (_supernodes.find(_r->identity) != _supernodes.end());
 }
 
 void Topology::addPeer(const SharedPtr<Peer> &candidate,void (*callback)(void *,const SharedPtr<Peer> &,Topology::PeerVerifyResult),void *arg)

+ 8 - 0
node/Topology.hpp

@@ -162,6 +162,11 @@ public:
 		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)
 	 */
@@ -305,6 +310,9 @@ private:
 	std::vector< SharedPtr<Peer> > _supernodePeers;
 	Mutex _supernodes_m;
 
+	// Set to true if my identity is in _supernodes
+	volatile bool _amSupernode;
+
 	KISSDB _dbm;
 	Mutex _dbm_m;
 };