diff --git a/node/IncomingPacket.cpp b/node/IncomingPacket.cpp index d5b4e9e67..6c3a09327 100644 --- a/node/IncomingPacket.cpp +++ b/node/IncomingPacket.cpp @@ -156,7 +156,10 @@ bool IncomingPacket::_doERROR(const RuntimeEnvironment *RR,const SharedPtr } break; case Packet::ERROR_UNWANTED_MULTICAST: { - // TODO: unsubscribe + uint64_t nwid = at(ZT_PROTO_VERB_ERROR_IDX_PAYLOAD); + MulticastGroup mg(MAC(field(ZT_PROTO_VERB_ERROR_IDX_PAYLOAD + 8,6),6),at(ZT_PROTO_VERB_ERROR_IDX_PAYLOAD + 14)); + TRACE("%.16llx: peer %s unsubscrubed from multicast group %s",nwid,peer->address().toString().c_str(),mg.toString().c_str()); + RR->mc->remove(nwid,mg,peer->address()); } break; default: break; diff --git a/node/Multicaster.cpp b/node/Multicaster.cpp index 3c1052363..33424e4a1 100644 --- a/node/Multicaster.cpp +++ b/node/Multicaster.cpp @@ -61,6 +61,20 @@ void Multicaster::addMultiple(uint64_t now,uint64_t nwid,const MulticastGroup &m } } +void Multicaster::remove(uint64_t nwid,const MulticastGroup &mg,const Address &member) +{ + Mutex::Lock _l(_groups_m); + std::map< std::pair,MulticastGroupStatus >::iterator g(_groups.find(std::pair(nwid,mg))); + if (g != _groups.end()) { + for(std::vector::iterator m(g->second.members.begin());m!=g->second.members.end();++m) { + if (m->address == member) { + g->second.members.erase(m); + break; + } + } + } +} + unsigned int Multicaster::gather(const Address &queryingPeer,uint64_t nwid,const MulticastGroup &mg,Packet &appendTo,unsigned int limit) const { unsigned char *p; diff --git a/node/Multicaster.hpp b/node/Multicaster.hpp index c6c93b1ff..0dd199f97 100644 --- a/node/Multicaster.hpp +++ b/node/Multicaster.hpp @@ -106,6 +106,15 @@ public: */ void addMultiple(uint64_t now,uint64_t nwid,const MulticastGroup &mg,const void *addresses,unsigned int count,unsigned int totalKnown); + /** + * Remove a multicast group member (if present) + * + * @param nwid Network ID + * @param mg Multicast group + * @param member Member to unsubscribe + */ + void remove(uint64_t nwid,const MulticastGroup &mg,const Address &member); + /** * Append gather results to a packet by choosing registered multicast recipients at random *