diff options
author | Adam Ierymenko <adam.ierymenko@gmail.com> | 2015-10-23 14:50:07 -0700 |
---|---|---|
committer | Adam Ierymenko <adam.ierymenko@gmail.com> | 2015-10-23 14:50:07 -0700 |
commit | 35676217e8fea27d271bbc3b976165e1f8436da1 (patch) | |
tree | 5cb468ac7ce0b2cdcab19249cfc50ea6c2564bed /node/Network.cpp | |
parent | e9648a6cdf5bd1d9f9e08c7cfef50265114c09d3 (diff) | |
download | infinitytier-35676217e8fea27d271bbc3b976165e1f8436da1.tar.gz infinitytier-35676217e8fea27d271bbc3b976165e1f8436da1.zip |
Refactor multicast group announcement to work directly or indirectly.
Diffstat (limited to 'node/Network.cpp')
-rw-r--r-- | node/Network.cpp | 120 |
1 files changed, 66 insertions, 54 deletions
diff --git a/node/Network.cpp b/node/Network.cpp index 46f93241..cd30e386 100644 --- a/node/Network.cpp +++ b/node/Network.cpp @@ -144,7 +144,15 @@ void Network::multicastUnsubscribe(const MulticastGroup &mg) bool Network::tryAnnounceMulticastGroupsTo(const SharedPtr<Peer> &peer) { Mutex::Lock _l(_lock); - return _tryAnnounceMulticastGroupsTo(RR->topology->rootAddresses(),_allMulticastGroups(),peer,RR->node->now()); + if ( + (_isAllowed(peer)) || + (peer->address() == this->controller()) || + (RR->topology->isRoot(peer->identity())) + ) { + _announceMulticastGroupsTo(peer->address(),_allMulticastGroups()); + return true; + } + return false; } bool Network::applyConfiguration(const SharedPtr<NetworkConfig> &conf) @@ -400,77 +408,80 @@ bool Network::_isAllowed(const SharedPtr<Peer> &peer) const return false; // default position on any failure } -bool Network::_tryAnnounceMulticastGroupsTo(const std::vector<Address> &alwaysAddresses,const std::vector<MulticastGroup> &allMulticastGroups,const SharedPtr<Peer> &peer,uint64_t now) const -{ - // assumes _lock is locked - if ( - (_isAllowed(peer)) || - (peer->address() == this->controller()) || - (std::find(alwaysAddresses.begin(),alwaysAddresses.end(),peer->address()) != alwaysAddresses.end()) - ) { - - if ((_config)&&(_config->com())&&(!_config->isPublic())&&(peer->needsOurNetworkMembershipCertificate(_id,now,true))) { - Packet outp(peer->address(),RR->identity.address(),Packet::VERB_NETWORK_MEMBERSHIP_CERTIFICATE); - _config->com().serialize(outp); - outp.armor(peer->key(),true); - peer->send(RR,outp.data(),outp.size(),now); - } - - { - Packet outp(peer->address(),RR->identity.address(),Packet::VERB_MULTICAST_LIKE); - - for(std::vector<MulticastGroup>::const_iterator mg(allMulticastGroups.begin());mg!=allMulticastGroups.end();++mg) { - if ((outp.size() + 18) >= ZT_UDP_DEFAULT_PAYLOAD_MTU) { - outp.armor(peer->key(),true); - peer->send(RR,outp.data(),outp.size(),now); - 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()); - } - - if (outp.size() > ZT_PROTO_MIN_PACKET_LENGTH) { - outp.armor(peer->key(),true); - peer->send(RR,outp.data(),outp.size(),now); - } - } - - return true; - } - return false; -} - -class _AnnounceMulticastGroupsToAll +class _GetPeersThatNeedMulticastAnnouncement { public: - _AnnounceMulticastGroupsToAll(const RuntimeEnvironment *renv,Network *nw) : + _GetPeersThatNeedMulticastAnnouncement(const RuntimeEnvironment *renv,Network *nw) : _now(renv->node->now()), + _controller(nw->controller()), _network(nw), - _rootAddresses(renv->topology->rootAddresses()), - _allMulticastGroups(nw->_allMulticastGroups()) + _rootAddresses(renv->topology->rootAddresses()) {} - - inline void operator()(Topology &t,const SharedPtr<Peer> &p) { _network->_tryAnnounceMulticastGroupsTo(_rootAddresses,_allMulticastGroups,p,_now); } - + inline void operator()(Topology &t,const SharedPtr<Peer> &p) + { + if ( + (_network->_isAllowed(p)) || + (p->address() == _controller) || + (std::find(_rootAddresses.begin(),_rootAddresses.end(),p->address()) != _rootAddresses.end()) + ) { + peers.push_back(p->address()); + } + } + std::vector<Address> peers; private: uint64_t _now; + Address _controller; Network *_network; std::vector<Address> _rootAddresses; - std::vector<MulticastGroup> _allMulticastGroups; }; void Network::_announceMulticastGroups() { // Assumes _lock is locked - _AnnounceMulticastGroupsToAll afunc(RR,this); - RR->topology->eachPeer<_AnnounceMulticastGroupsToAll &>(afunc); + + _GetPeersThatNeedMulticastAnnouncement gpfunc(RR,this); + RR->topology->eachPeer<_GetPeersThatNeedMulticastAnnouncement &>(gpfunc); + + std::vector<MulticastGroup> allMulticastGroups(_allMulticastGroups()); + for(std::vector<Address>::const_iterator pa(gpfunc.peers.begin());pa!=gpfunc.peers.end();++pa) + _announceMulticastGroupsTo(*pa,allMulticastGroups); +} + +void Network::_announceMulticastGroupsTo(const Address &peerAddress,const std::vector<MulticastGroup> &allMulticastGroups) const +{ + // 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())) { + Packet outp(peerAddress,RR->identity.address(),Packet::VERB_NETWORK_MEMBERSHIP_CERTIFICATE); + _config->com().serialize(outp); + RR->sw->send(outp,true,0); + } + + { + Packet outp(peerAddress,RR->identity.address(),Packet::VERB_MULTICAST_LIKE); + + for(std::vector<MulticastGroup>::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(peerAddress,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()); + } + + if (outp.size() > ZT_PROTO_MIN_PACKET_LENGTH) + RR->sw->send(outp,true,0); + } } std::vector<MulticastGroup> Network::_allMulticastGroups() const { // Assumes _lock is locked + std::vector<MulticastGroup> mgs; mgs.reserve(_myMulticastGroups.size() + _multicastGroupsBehindMe.size() + 1); mgs.insert(mgs.end(),_myMulticastGroups.begin(),_myMulticastGroups.end()); @@ -479,6 +490,7 @@ std::vector<MulticastGroup> Network::_allMulticastGroups() const mgs.push_back(Network::BROADCAST); std::sort(mgs.begin(),mgs.end()); mgs.erase(std::unique(mgs.begin(),mgs.end()),mgs.end()); + return mgs; } |