diff --git a/node/Constants.hpp b/node/Constants.hpp index 0260219f0..5d4849c2e 100644 --- a/node/Constants.hpp +++ b/node/Constants.hpp @@ -250,11 +250,6 @@ */ #define ZT_MULTICAST_TRANSMIT_TIMEOUT 5000 -/** - * Default number of endpoints to implicitly gather from peers with each multicast frame - */ -#define ZT_MULTICAST_DEFAULT_IMPLICIT_GATHER 8 - /** * Default maximum number of peers to address with a single multicast (if unspecified in network) */ diff --git a/node/IncomingPacket.cpp b/node/IncomingPacket.cpp index 9d7461ca6..ef45ddacf 100644 --- a/node/IncomingPacket.cpp +++ b/node/IncomingPacket.cpp @@ -796,7 +796,7 @@ bool IncomingPacket::_doMULTICAST_LIKE(const RuntimeEnvironment *RR,const Shared // Iterate through 18-byte network,MAC,ADI tuples for(unsigned int ptr=ZT_PACKET_IDX_PAYLOAD;ptrmc->subscribe(now,at(ptr),MulticastGroup(MAC(field(ptr + 8,6),6),at(ptr + 14)),Address(),src); + RR->mc->add(now,at(ptr),MulticastGroup(MAC(field(ptr + 8,6),6),at(ptr + 14)),Address(),src); peer->receive(RR,_fromSock,_remoteAddress,hops(),packetId(),Packet::VERB_MULTICAST_LIKE,0,Packet::VERB_NOP,now); } catch (std::exception &ex) { diff --git a/node/Multicaster.cpp b/node/Multicaster.cpp index a3e600d98..8e3e3e297 100644 --- a/node/Multicaster.cpp +++ b/node/Multicaster.cpp @@ -107,7 +107,6 @@ restart_member_scan: void Multicaster::send( const CertificateOfMembership *com, unsigned int limit, - unsigned int gatherLimit, uint64_t now, uint64_t nwid, const MulticastGroup &mg, @@ -129,7 +128,7 @@ void Multicaster::send( nwid, com, limit, - gatherLimit, + 0, src, mg, etherType, @@ -143,7 +142,31 @@ void Multicaster::send( break; } } else { - // If we don't already have enough members, send to the ones we have and then gather (if allowed within gather rate limit delay) + unsigned int gatherLimit = (limit - (unsigned int)gs.members.size()) + 1; + + if ((now - gs.lastExplicitGather) >= ZT_MULTICAST_GATHER_DELAY) { + gs.lastExplicitGather = now; + + // TODO / INPROGRESS: right now supernodes track multicast LIKEs, a relic + // from the old algorithm. The next step will be to devolve this duty + // somewhere else, such as node(s) nominated by netconf masters. But + // we'll keep announcing LIKEs to supernodes for the near future to + // gradually migrate from old multicast to new without losing old nodes. + SharedPtr sn(RR->topology->getBestSupernode()); + if (sn) { + Packet outp(sn->address(),RR->identity.address(),Packet::VERB_MULTICAST_GATHER); + outp.append(nwid); + outp.append((uint8_t)0); + mg.mac().appendTo(outp); + outp.append((uint32_t)mg.adi()); + outp.append((uint32_t)gatherLimit); // +1 just means we'll have an extra in the queue if available + outp.armor(sn->key(),true); + sn->send(RR,outp.data(),outp.size(),now); + } + + gatherLimit = 0; // once we've done this we don't need to do it implicitly + } + gs.txQueue.push_back(OutboundMulticast()); OutboundMulticast &out = gs.txQueue.back(); @@ -162,27 +185,6 @@ void Multicaster::send( for(std::vector::const_reverse_iterator m(gs.members.rbegin());m!=gs.members.rend();++m) out.sendAndLog(*(RR->sw),m->address); - - if ((now - gs.lastExplicitGather) >= ZT_MULTICAST_GATHER_DELAY) { - gs.lastExplicitGather = now; - - // TODO / INPROGRESS: right now supernodes track multicast LIKEs, a relic - // from the old algorithm. The next step will be to devolve this duty - // somewhere else, such as node(s) nominated by netconf masters. But - // we'll keep announcing LIKEs to supernodes for the near future to - // gradually migrate from old multicast to new without losing old nodes. - SharedPtr sn(RR->topology->getBestSupernode()); - if (sn) { - Packet outp(sn->address(),RR->identity.address(),Packet::VERB_MULTICAST_GATHER); - outp.append(nwid); - outp.append((uint8_t)0); - mg.mac().appendTo(outp); - outp.append((uint32_t)mg.adi()); - outp.append((uint32_t)((limit - (unsigned int)gs.members.size()) + 1)); // +1 just means we'll have an extra in the queue if available - outp.armor(sn->key(),true); - sn->send(RR,outp.data(),outp.size(),now); - } - } } } diff --git a/node/Multicaster.hpp b/node/Multicaster.hpp index 96207aa03..ae62456cf 100644 --- a/node/Multicaster.hpp +++ b/node/Multicaster.hpp @@ -92,7 +92,7 @@ public: * @param learnedFrom Address from which we learned this member or NULL/0 Address if direct * @param member New member address */ - inline void subscribe(uint64_t now,uint64_t nwid,const MulticastGroup &mg,const Address &learnedFrom,const Address &member) + inline void add(uint64_t now,uint64_t nwid,const MulticastGroup &mg,const Address &learnedFrom,const Address &member) { Mutex::Lock _l(_groups_m); _add(now,nwid,_groups[std::pair(nwid,mg)],learnedFrom,member); @@ -124,7 +124,6 @@ public: * @param nwid Network ID * @param com Certificate of membership to include or NULL for none * @param limit Multicast limit - * @param gatherLimit Limit to pass for implicit gather with MULTICAST_FRAME * @param now Current time * @param mg Multicast group * @param from Source Ethernet MAC address @@ -135,7 +134,6 @@ public: void send( const CertificateOfMembership *com, unsigned int limit, - unsigned int gatherLimit, uint64_t now, uint64_t nwid, const MulticastGroup &mg, diff --git a/node/Switch.cpp b/node/Switch.cpp index c254c7626..32190a87a 100644 --- a/node/Switch.cpp +++ b/node/Switch.cpp @@ -153,7 +153,6 @@ void Switch::onLocalEthernet(const SharedPtr &network,const MAC &from,c RR->mc->send( ((!nconf->isPublic())&&(nconf->com())) ? &(nconf->com()) : (const CertificateOfMembership *)0, nconf->multicastLimit(), - network->wantMulticastGroup(mg) ? ZT_MULTICAST_DEFAULT_IMPLICIT_GATHER : 0, now, network->id(), mg,