diff --git a/node/IncomingPacket.cpp b/node/IncomingPacket.cpp index c83644152..1ce942c9a 100644 --- a/node/IncomingPacket.cpp +++ b/node/IncomingPacket.cpp @@ -443,7 +443,7 @@ bool IncomingPacket::_doOK(const RuntimeEnvironment *RR,const SharedPtr &p case Packet::VERB_MULTICAST_GATHER: { const uint64_t nwid = at(ZT_PROTO_VERB_MULTICAST_GATHER__OK__IDX_NETWORK_ID); SharedPtr network(RR->node->network(nwid)); - if ((network)&&(network->gate(peer,verb(),packetId()))) { + if ((network)&&(network->gateMulticastGather(peer,verb(),packetId()))) { const MulticastGroup mg(MAC(field(ZT_PROTO_VERB_MULTICAST_GATHER__OK__IDX_MAC,6),6),at(ZT_PROTO_VERB_MULTICAST_GATHER__OK__IDX_ADI)); //TRACE("%s(%s): OK(MULTICAST_GATHER) %.16llx/%s length %u",source().toString().c_str(),_path->address().toString().c_str(),nwid,mg.toString().c_str(),size()); const unsigned int count = at(ZT_PROTO_VERB_MULTICAST_GATHER__OK__IDX_GATHER_RESULTS + 4); @@ -469,7 +469,7 @@ bool IncomingPacket::_doOK(const RuntimeEnvironment *RR,const SharedPtr &p network->addCredential(com); } - if (network->gate(peer,verb(),packetId())) { + if (network->gateMulticastGather(peer,verb(),packetId())) { if ((flags & 0x02) != 0) { // OK(MULTICAST_FRAME) includes implicit gather results offset += ZT_PROTO_VERB_MULTICAST_FRAME__OK__IDX_COM_AND_GATHER_RESULTS; diff --git a/node/Network.cpp b/node/Network.cpp index 710e70ddf..a9b149420 100644 --- a/node/Network.cpp +++ b/node/Network.cpp @@ -1093,6 +1093,11 @@ bool Network::gate(const SharedPtr &peer,const Packet::Verb verb,const uin return false; } +bool Network::gateMulticastGather(const SharedPtr &peer,const Packet::Verb verb,const uint64_t packetId) +{ + return ( (peer->address() == controller()) || RR->topology->isUpstream(peer->identity()) || gate(peer,verb,packetId) || _config.isAnchor(peer->address()) ); +} + bool Network::recentlyAllowedOnNetwork(const SharedPtr &peer) const { Mutex::Lock _l(_lock); diff --git a/node/Network.hpp b/node/Network.hpp index e8d6e2a54..d80b13b9e 100644 --- a/node/Network.hpp +++ b/node/Network.hpp @@ -257,6 +257,11 @@ public: */ bool gate(const SharedPtr &peer,const Packet::Verb verb,const uint64_t packetId); + /** + * Check whether this peer is allowed to provide multicast info for this network + */ + bool gateMulticastGather(const SharedPtr &peer,const Packet::Verb verb,const uint64_t packetId); + /** * @param peer Peer to check * @return True if peer has recently been a valid member of this network diff --git a/node/NetworkConfig.hpp b/node/NetworkConfig.hpp index b5ab9ccb2..ad1cafa50 100644 --- a/node/NetworkConfig.hpp +++ b/node/NetworkConfig.hpp @@ -285,6 +285,19 @@ public: return r; } + /** + * @param a Address to check + * @return True if address is an anchor + */ + inline bool isAnchor(const Address &a) const + { + for(unsigned int i=0;i viaPath(peer->getBestPath(now,false)); if ( (viaPath) && (!viaPath->alive(now)) && (!RR->topology->isRoot(peer->identity())) ) { - if ((now - viaPath->lastOut()) > std::max((now - viaPath->lastIn()) >> 2,(uint64_t)ZT_PATH_MIN_REACTIVATE_INTERVAL)) { - Packet outp(peer->address(),RR->identity.address(),Packet::VERB_ECHO); - outp.armor(peer->key(),true); - viaPath->send(RR,outp.data(),outp.size(),now); - } + if ((now - viaPath->lastOut()) > std::max((now - viaPath->lastIn()) * 4,(uint64_t)ZT_PATH_MIN_REACTIVATE_INTERVAL)) + peer->attemptToContactAt(viaPath->localAddress(),viaPath->address(),now); viaPath.zero(); } if (!viaPath) {