From ef8706995786f26df7bcb9f69b2a332419841964 Mon Sep 17 00:00:00 2001 From: Adam Ierymenko <adam.ierymenko@gmail.com> Date: Fri, 9 Sep 2016 09:32:00 -0700 Subject: [PATCH] Fix gating of multicast GATHER replies since these can come from upstream, etc., and fix an issue with sending ECHO to recheck marginal paths. --- node/IncomingPacket.cpp | 4 ++-- node/Network.cpp | 5 +++++ node/Network.hpp | 5 +++++ node/NetworkConfig.hpp | 13 +++++++++++++ node/Switch.cpp | 7 ++----- 5 files changed, 27 insertions(+), 7 deletions(-) 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<Peer> &p case Packet::VERB_MULTICAST_GATHER: { const uint64_t nwid = at<uint64_t>(ZT_PROTO_VERB_MULTICAST_GATHER__OK__IDX_NETWORK_ID); SharedPtr<Network> 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<uint32_t>(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<uint16_t>(ZT_PROTO_VERB_MULTICAST_GATHER__OK__IDX_GATHER_RESULTS + 4); @@ -469,7 +469,7 @@ bool IncomingPacket::_doOK(const RuntimeEnvironment *RR,const SharedPtr<Peer> &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> &peer,const Packet::Verb verb,const uin return false; } +bool Network::gateMulticastGather(const SharedPtr<Peer> &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> &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> &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> &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<specialistCount;++i) { + if ((a == specialists[i])&&((specialists[i] & ZT_NETWORKCONFIG_SPECIALIST_TYPE_ANCHOR) != 0)) + return true; + } + return false; + } + /** * @param fromPeer Peer attempting to bridge other Ethernet peers onto network * @return True if this network allows bridging diff --git a/node/Switch.cpp b/node/Switch.cpp index f2a0d35b7..ea92c99a9 100644 --- a/node/Switch.cpp +++ b/node/Switch.cpp @@ -759,11 +759,8 @@ bool Switch::_trySend(const Packet &packet,bool encrypt) SharedPtr<Path> 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) {