diff options
author | Adam Ierymenko <adam.ierymenko@gmail.com> | 2013-07-08 20:53:05 -0400 |
---|---|---|
committer | Adam Ierymenko <adam.ierymenko@gmail.com> | 2013-07-08 20:53:05 -0400 |
commit | 775fef9ce9ad52c5f01e2eb88c301f6e40e42bd2 (patch) | |
tree | 25dd3dcdf243fa01a024f1b8149506fd560a93f8 | |
parent | 6eb77da0947377712bf331ba25424dfe0f7a34e0 (diff) | |
download | infinitytier-775fef9ce9ad52c5f01e2eb88c301f6e40e42bd2.tar.gz infinitytier-775fef9ce9ad52c5f01e2eb88c301f6e40e42bd2.zip |
Silly multicast propagation fix: exclude upstream sender to never send duplicate multicasts back to where they came from
-rw-r--r-- | node/Switch.cpp | 14 | ||||
-rw-r--r-- | node/Switch.hpp | 2 | ||||
-rw-r--r-- | node/Topology.cpp | 2 |
3 files changed, 6 insertions, 12 deletions
diff --git a/node/Switch.cpp b/node/Switch.cpp index 6f237a10..44d9ac68 100644 --- a/node/Switch.cpp +++ b/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 unsigned char bloom[ZT_PROTO_VERB_MULTICAST_FRAME_BLOOM_FILTER_SIZE]; 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()) { // Simple unicast frame from us to another node 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]; - 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) 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 { //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); - - // 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 { 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()); diff --git a/node/Switch.hpp b/node/Switch.hpp index ecda4de1..d0fbf02b 100644 --- a/node/Switch.hpp +++ b/node/Switch.hpp @@ -171,7 +171,7 @@ private: 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 - 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); void _doHELLO(Demarc::Port localPort,const InetAddress &fromAddr,Packet &packet); void _requestWhois(const Address &addr); diff --git a/node/Topology.cpp b/node/Topology.cpp index cbe42e8f..1b7973a6 100644 --- a/node/Topology.cpp +++ b/node/Topology.cpp @@ -242,7 +242,7 @@ unsigned int Topology::pickMulticastPropagationPeers(uint64_t nwid,const Address if (g != mgm->second.end()) { uint64_t now = Utils::now(); 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)); if (p != _activePeers.end()) { possiblePeers[numPossiblePeers++] = p->second; |