From 5cf410490e677f524eda5fd5c790e37f81ba7753 Mon Sep 17 00:00:00 2001 From: Adam Ierymenko Date: Thu, 4 Aug 2016 10:18:33 -0700 Subject: [PATCH] . --- node/CertificateOfMembership.cpp | 3 ++ node/IncomingPacket.cpp | 12 +++--- node/Membership.hpp | 5 +++ node/Network.cpp | 69 +++++++++++++++++--------------- node/Topology.hpp | 8 ++++ 5 files changed, 58 insertions(+), 39 deletions(-) diff --git a/node/CertificateOfMembership.cpp b/node/CertificateOfMembership.cpp index 7b99f2c74..0c36aa459 100644 --- a/node/CertificateOfMembership.cpp +++ b/node/CertificateOfMembership.cpp @@ -155,6 +155,9 @@ bool CertificateOfMembership::agreesWith(const CertificateOfMembership &other) c unsigned int myidx = 0; unsigned int otheridx = 0; + if ((_qualifierCount == 0)||(other._qualifierCount == 0)) + return false; + while (myidx < _qualifierCount) { // Fail if we're at the end of other, since this means the field is // missing. diff --git a/node/IncomingPacket.cpp b/node/IncomingPacket.cpp index c7e6e4397..029570f1d 100644 --- a/node/IncomingPacket.cpp +++ b/node/IncomingPacket.cpp @@ -446,7 +446,7 @@ bool IncomingPacket::_doOK(const RuntimeEnvironment *RR,const SharedPtr &p if ((flags & 0x01) != 0) { // deprecated but still used by older peers CertificateOfMembership com; offset += com.deserialize(*this,ZT_PROTO_VERB_MULTICAST_FRAME__OK__IDX_COM_AND_GATHER_RESULTS); - LockingPtr m = peer->membership(com.networkId(),true); + LockingPtr m(peer->membership(com.networkId(),true)); if (m) m->addCredential(RR,RR->node->now(),com); } @@ -586,7 +586,7 @@ bool IncomingPacket::_doEXT_FRAME(const RuntimeEnvironment *RR,const SharedPtr

m = peer->membership(com.networkId(),true); + LockingPtr m(peer->membership(com.networkId(),true)); if (m) m->addCredential(RR,RR->node->now(),com); } @@ -707,7 +707,7 @@ bool IncomingPacket::_doNETWORK_CREDENTIALS(const RuntimeEnvironment *RR,const S unsigned int p = ZT_PACKET_IDX_PAYLOAD; while ((p < size())&&((*this)[p])) { p += com.deserialize(*this,p); - LockingPtr m = peer->membership(com.networkId(),true); + LockingPtr m(peer->membership(com.networkId(),true)); if (!m) return true; // sanity check if (m->addCredential(RR,now,com) == 1) return false; // wait for WHOIS } @@ -717,7 +717,7 @@ bool IncomingPacket::_doNETWORK_CREDENTIALS(const RuntimeEnvironment *RR,const S const unsigned int numCapabilities = at(p); p += 2; for(unsigned int i=0;i m = peer->membership(cap.networkId(),true); + LockingPtr m(peer->membership(cap.networkId(),true)); if (!m) return true; // sanity check if (m->addCredential(RR,now,cap) == 1) return false; // wait for WHOIS } @@ -725,7 +725,7 @@ bool IncomingPacket::_doNETWORK_CREDENTIALS(const RuntimeEnvironment *RR,const S const unsigned int numTags = at(p); p += 2; for(unsigned int i=0;i m = peer->membership(tag.networkId(),true); + LockingPtr m(peer->membership(tag.networkId(),true)); if (!m) return true; // sanity check if (m->addCredential(RR,now,tag) == 1) return false; // wait for WHOIS } @@ -868,7 +868,7 @@ bool IncomingPacket::_doMULTICAST_FRAME(const RuntimeEnvironment *RR,const Share if ((flags & 0x01) != 0) { // deprecated but still used by older peers CertificateOfMembership com; offset += com.deserialize(*this,ZT_PROTO_VERB_MULTICAST_FRAME_IDX_COM); - LockingPtr m = peer->membership(com.networkId(),true); + LockingPtr m(peer->membership(com.networkId(),true)); if (m) m->addCredential(RR,RR->node->now(),com); } diff --git a/node/Membership.hpp b/node/Membership.hpp index abfff9e35..0e72b7b16 100644 --- a/node/Membership.hpp +++ b/node/Membership.hpp @@ -114,6 +114,11 @@ public: return sendCredentialsIfNeeded(RR,now,peer,nconf,(const uint32_t *)0,0,(const uint32_t *)0,0); } + /** + * @return This peer's COM if they have sent one + */ + inline const CertificateOfMembership &com() const { return _com; } + /** * @param nconf Network configuration * @param id Tag ID diff --git a/node/Network.cpp b/node/Network.cpp index 061cca073..d9ad7838d 100644 --- a/node/Network.cpp +++ b/node/Network.cpp @@ -29,6 +29,7 @@ #include "Buffer.hpp" #include "NetworkController.hpp" #include "Node.hpp" +#include "Peer.hpp" #include "../version.h" @@ -384,17 +385,20 @@ bool Network::_isAllowed(const SharedPtr &peer) const { // Assumes _lock is locked try { - if (!_config) - return false; - if (_config.isPublic()) - return true; - return ((_config.com)&&(peer->networkMembershipCertificatesAgree(_id,_config.com))); - } catch (std::exception &exc) { - TRACE("isAllowed() check failed for peer %s: unexpected exception: %s",peer->address().toString().c_str(),exc.what()); + if (_config) { + if (_config.isPublic()) { + return true; + } else { + LockingPtr m(peer->membership(_id,false)); + if (m) { + return _config.com.agreesWith(m->com()); + } + } + } } catch ( ... ) { - TRACE("isAllowed() check failed for peer %s: unexpected exception: unknown exception",peer->address().toString().c_str()); + TRACE("isAllowed() check failed for peer %s: unexpected exception: unexpected exception",peer->address().toString().c_str()); } - return false; // default position on any failure + return false; } class _MulticastAnnounceAll @@ -405,13 +409,13 @@ public: _controller(nw->controller()), _network(nw), _anchors(nw->config().anchors()), - _rootAddresses(renv->topology->rootAddresses()) + _upstreamAddresses(renv->topology->upstreamAddresses()) {} inline void operator()(Topology &t,const SharedPtr &p) { - if ( (_network->_isAllowed(p)) || // FIXME: this causes multicast LIKEs for public networks to get spammed + if ( (_network->_isAllowed(p)) || // FIXME: this causes multicast LIKEs for public networks to get spammed, which isn't terrible but is a bit stupid (p->address() == _controller) || - (std::find(_rootAddresses.begin(),_rootAddresses.end(),p->address()) != _rootAddresses.end()) || + (std::find(_upstreamAddresses.begin(),_upstreamAddresses.end(),p->address()) != _upstreamAddresses.end()) || (std::find(_anchors.begin(),_anchors.end(),p->address()) != _anchors.end()) ) { peers.push_back(p); } @@ -422,7 +426,7 @@ private: const Address _controller; Network *const _network; const std::vector

_anchors; - const std::vector
_rootAddresses; + const std::vector
_upstreamAddresses; }; void Network::_announceMulticastGroups() { @@ -438,31 +442,30 @@ void Network::_announceMulticastGroupsTo(const SharedPtr &peer,const std:: { // Assumes _lock is locked - // We push COMs ahead of MULTICAST_LIKE since they're used for access control -- a COM is a public - // credential so "over-sharing" isn't really an issue (and we only do so with roots). - if ((_config)&&(_config.com)&&(!_config.isPublic())&&(peer->needsOurNetworkMembershipCertificate(_id,RR->node->now(),true))) { - Packet outp(peer->address(),RR->identity.address(),Packet::VERB_NETWORK_MEMBERSHIP_CERTIFICATE); - _config.com.serialize(outp); - RR->sw->send(outp,true,0); + // Anyone we announce multicast groups to will need our COM to authenticate GATHER requests. + { + LockingPtr m(peer->membership(_id,false)); + if (m) m->sendCredentialsIfNeeded(RR,RR->node->now(),*peer,_config); } - { - Packet outp(peer->address(),RR->identity.address(),Packet::VERB_MULTICAST_LIKE); + Packet outp(peer->address(),RR->identity.address(),Packet::VERB_MULTICAST_LIKE); - for(std::vector::const_iterator mg(allMulticastGroups.begin());mg!=allMulticastGroups.end();++mg) { - if ((outp.size() + 18) >= ZT_UDP_DEFAULT_PAYLOAD_MTU) { - RR->sw->send(outp,true,0); - outp.reset(peer->address(),RR->identity.address(),Packet::VERB_MULTICAST_LIKE); - } - - // network ID, MAC, ADI - outp.append((uint64_t)_id); - mg->mac().appendTo(outp); - outp.append((uint32_t)mg->adi()); + for(std::vector::const_iterator mg(allMulticastGroups.begin());mg!=allMulticastGroups.end();++mg) { + if ((outp.size() + 24) >= ZT_PROTO_MAX_PACKET_LENGTH) { + outp.compress(); + RR->sw->send(outp,true,0); + outp.reset(peer->address(),RR->identity.address(),Packet::VERB_MULTICAST_LIKE); } - if (outp.size() > ZT_PROTO_MIN_PACKET_LENGTH) - RR->sw->send(outp,true,0); + // network ID, MAC, ADI + outp.append((uint64_t)_id); + mg->mac().appendTo(outp); + outp.append((uint32_t)mg->adi()); + } + + if (outp.size() > ZT_PROTO_MIN_PACKET_LENGTH) { + outp.compress(); + RR->sw->send(outp,true,0); } } diff --git a/node/Topology.hpp b/node/Topology.hpp index 03c491e50..b8213cf8b 100644 --- a/node/Topology.hpp +++ b/node/Topology.hpp @@ -153,6 +153,14 @@ public: return _rootAddresses; } + /** + * @return Vector of active upstream addresses (including roots) + */ + inline std::vector
upstreamAddresses() const + { + return rootAddresses(); + } + /** * @return Current World (copy) */