Browse Source

Silly multicast propagation fix: exclude upstream sender to never send duplicate multicasts back to where they came from

Adam Ierymenko 12 years ago
parent
commit
775fef9ce9
3 changed files with 6 additions and 12 deletions
  1. 4 10
      node/Switch.cpp
  2. 1 1
      node/Switch.hpp
  3. 1 1
      node/Topology.cpp

+ 4 - 10
node/Switch.cpp

@@ -266,7 +266,7 @@ void Switch::onLocalEthernet(const SharedPtr<Network> &network,const MAC &from,c
 		// Start multicast propagation with empty bloom filter
 		// Start multicast propagation with empty bloom filter
 		unsigned char bloom[ZT_PROTO_VERB_MULTICAST_FRAME_BLOOM_FILTER_SIZE];
 		unsigned char bloom[ZT_PROTO_VERB_MULTICAST_FRAME_BLOOM_FILTER_SIZE];
 		memset(bloom,0,sizeof(bloom));
 		memset(bloom,0,sizeof(bloom));
-		_propagateMulticast(network,bloom,mg,0,0,from,etherType,data.data(),data.size());
+		_propagateMulticast(network,_r->identity.address(),bloom,mg,0,0,from,etherType,data.data(),data.size());
 	} else if (to.isZeroTier()) {
 	} else if (to.isZeroTier()) {
 		// Simple unicast frame from us to another node
 		// Simple unicast frame from us to another node
 		Address toZT(to.data + 1);
 		Address toZT(to.data + 1);
@@ -568,10 +568,10 @@ void Switch::_CBaddPeerFromWhois(void *arg,const SharedPtr<Peer> &p,Topology::Pe
 	}
 	}
 }
 }
 
 
-void Switch::_propagateMulticast(const SharedPtr<Network> &network,unsigned char *bloom,const MulticastGroup &mg,unsigned int mcHops,unsigned int mcLoadFactor,const MAC &from,unsigned int etherType,const void *data,unsigned int len)
+void Switch::_propagateMulticast(const SharedPtr<Network> &network,const Address &upstream,unsigned char *bloom,const MulticastGroup &mg,unsigned int mcHops,unsigned int mcLoadFactor,const MAC &from,unsigned int etherType,const void *data,unsigned int len)
 {
 {
 	SharedPtr<Peer> propPeers[ZT_MULTICAST_PROPAGATION_BREADTH];
 	SharedPtr<Peer> propPeers[ZT_MULTICAST_PROPAGATION_BREADTH];
-	unsigned int np = _r->topology->pickMulticastPropagationPeers(network->id(),Address(),bloom,ZT_PROTO_VERB_MULTICAST_FRAME_BLOOM_FILTER_SIZE * 8,ZT_MULTICAST_PROPAGATION_BREADTH,mg,propPeers);
+	unsigned int np = _r->topology->pickMulticastPropagationPeers(network->id(),upstream,bloom,ZT_PROTO_VERB_MULTICAST_FRAME_BLOOM_FILTER_SIZE * 8,ZT_MULTICAST_PROPAGATION_BREADTH,mg,propPeers);
 
 
 	for(unsigned int i=0;i<np;++i)
 	for(unsigned int i=0;i<np;++i)
 		Utils::bloomAdd(bloom,ZT_PROTO_VERB_MULTICAST_FRAME_BLOOM_FILTER_SIZE,propPeers[i]->address().sum());
 		Utils::bloomAdd(bloom,ZT_PROTO_VERB_MULTICAST_FRAME_BLOOM_FILTER_SIZE,propPeers[i]->address().sum());
@@ -774,13 +774,7 @@ Switch::PacketServiceAttemptResult Switch::_tryHandleRemotePacket(Demarc::Port l
 									} else {
 									} else {
 										//TRACE("MULTICAST_FRAME: %s -> %s (adi: %.8lx), %u bytes, net: %llu",fromMac.toString().c_str(),mg.mac().toString().c_str(),(unsigned long)mg.adi(),packet.size() - ZT_PROTO_VERB_MULTICAST_FRAME_IDX_PAYLOAD,network->id());
 										//TRACE("MULTICAST_FRAME: %s -> %s (adi: %.8lx), %u bytes, net: %llu",fromMac.toString().c_str(),mg.mac().toString().c_str(),(unsigned long)mg.adi(),packet.size() - ZT_PROTO_VERB_MULTICAST_FRAME_IDX_PAYLOAD,network->id());
 										network->tap().put(fromMac,mg.mac(),etherType,packet.data() + ZT_PROTO_VERB_MULTICAST_FRAME_IDX_PAYLOAD,packet.size() - ZT_PROTO_VERB_MULTICAST_FRAME_IDX_PAYLOAD);
 										network->tap().put(fromMac,mg.mac(),etherType,packet.data() + ZT_PROTO_VERB_MULTICAST_FRAME_IDX_PAYLOAD,packet.size() - ZT_PROTO_VERB_MULTICAST_FRAME_IDX_PAYLOAD);
-
-										// TODO: implement load factor based propagation rate limitation
-										// How it will work: each node will adjust loadFactor based on
-										// its current load of multicast traffic. Then it will probabilistically
-										// fail to propagate, with the probability being based on load factor.
-										// This will need some in-the-field testing and tuning to get right.
-										_propagateMulticast(network,bloom,mg,hops+1,loadFactor,fromMac,etherType,packet.data() + ZT_PROTO_VERB_MULTICAST_FRAME_IDX_PAYLOAD,packet.size() - ZT_PROTO_VERB_MULTICAST_FRAME_IDX_PAYLOAD);
+										_propagateMulticast(network,source,bloom,mg,hops+1,loadFactor,fromMac,etherType,packet.data() + ZT_PROTO_VERB_MULTICAST_FRAME_IDX_PAYLOAD,packet.size() - ZT_PROTO_VERB_MULTICAST_FRAME_IDX_PAYLOAD);
 									}
 									}
 								} else {
 								} else {
 									TRACE("dropped MULTICAST_FRAME from %s: ultimate sender %s not a member of closed network %llu",source.toString().c_str(),fromMac.toString().c_str(),network->id());
 									TRACE("dropped MULTICAST_FRAME from %s: ultimate sender %s not a member of closed network %llu",source.toString().c_str(),fromMac.toString().c_str(),network->id());

+ 1 - 1
node/Switch.hpp

@@ -171,7 +171,7 @@ private:
 	static void _CBaddPeerFromHello(void *arg,const SharedPtr<Peer> &p,Topology::PeerVerifyResult result);
 	static void _CBaddPeerFromHello(void *arg,const SharedPtr<Peer> &p,Topology::PeerVerifyResult result);
 	static void _CBaddPeerFromWhois(void *arg,const SharedPtr<Peer> &p,Topology::PeerVerifyResult result); // arg == this
 	static void _CBaddPeerFromWhois(void *arg,const SharedPtr<Peer> &p,Topology::PeerVerifyResult result); // arg == this
 
 
-	void _propagateMulticast(const SharedPtr<Network> &network,unsigned char *bloom,const MulticastGroup &mg,unsigned int mcHops,unsigned int mcLoadFactor,const MAC &from,unsigned int etherType,const void *data,unsigned int len);
+	void _propagateMulticast(const SharedPtr<Network> &network,const Address &upstream,unsigned char *bloom,const MulticastGroup &mg,unsigned int mcHops,unsigned int mcLoadFactor,const MAC &from,unsigned int etherType,const void *data,unsigned int len);
 	PacketServiceAttemptResult _tryHandleRemotePacket(Demarc::Port localPort,const InetAddress &fromAddr,Packet &packet);
 	PacketServiceAttemptResult _tryHandleRemotePacket(Demarc::Port localPort,const InetAddress &fromAddr,Packet &packet);
 	void _doHELLO(Demarc::Port localPort,const InetAddress &fromAddr,Packet &packet);
 	void _doHELLO(Demarc::Port localPort,const InetAddress &fromAddr,Packet &packet);
 	void _requestWhois(const Address &addr);
 	void _requestWhois(const Address &addr);

+ 1 - 1
node/Topology.cpp

@@ -242,7 +242,7 @@ unsigned int Topology::pickMulticastPropagationPeers(uint64_t nwid,const Address
 			if (g != mgm->second.end()) {
 			if (g != mgm->second.end()) {
 				uint64_t now = Utils::now();
 				uint64_t now = Utils::now();
 				for(std::map< Address,uint64_t >::iterator m(g->second.begin());m!=g->second.end();) {
 				for(std::map< Address,uint64_t >::iterator m(g->second.begin());m!=g->second.end();) {
-					if ((now - m->second) < ZT_MULTICAST_LIKE_EXPIRE) {
+					if (((now - m->second) < ZT_MULTICAST_LIKE_EXPIRE)&&(m->first != exclude)) {
 						std::map< Address,SharedPtr<Peer> >::const_iterator p(_activePeers.find(m->first));
 						std::map< Address,SharedPtr<Peer> >::const_iterator p(_activePeers.find(m->first));
 						if (p != _activePeers.end()) {
 						if (p != _activePeers.end()) {
 							possiblePeers[numPossiblePeers++] = p->second;
 							possiblePeers[numPossiblePeers++] = p->second;