diff options
-rw-r--r-- | node/IncomingPacket.cpp | 4 | ||||
-rw-r--r-- | node/Network.cpp | 5 | ||||
-rw-r--r-- | node/Network.hpp | 5 | ||||
-rw-r--r-- | node/NetworkConfig.hpp | 13 | ||||
-rw-r--r-- | node/Switch.cpp | 7 |
5 files changed, 27 insertions, 7 deletions
diff --git a/node/IncomingPacket.cpp b/node/IncomingPacket.cpp index c8364415..1ce942c9 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 710e70dd..a9b14942 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 e8d6e2a5..d80b13b9 100644 --- a/node/Network.hpp +++ b/node/Network.hpp @@ -258,6 +258,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 b5ab9ccb..ad1cafa5 100644 --- a/node/NetworkConfig.hpp +++ b/node/NetworkConfig.hpp @@ -286,6 +286,19 @@ public: } /** + * @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 f2a0d35b..ea92c99a 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) { |