Always announce multicast groups, not just to peers with direct links, and push network COMs to any MULTICAST_LIKE recipient for future use.

This commit is contained in:
Adam Ierymenko 2015-10-01 12:50:19 -07:00
parent a7409850d6
commit d6676a9d6c
2 changed files with 49 additions and 36 deletions

View File

@ -400,31 +400,23 @@ bool Network::_isAllowed(const SharedPtr<Peer> &peer) const
return false; // default position on any failure
}
// Used in Network::_announceMulticastGroups()
class _AnnounceMulticastGroupsToPeersWithActiveDirectPaths
{
public:
_AnnounceMulticastGroupsToPeersWithActiveDirectPaths(const RuntimeEnvironment *renv,Network *nw) :
_now(renv->node->now()),
RR(renv),
_network(nw),
_rootAddresses(renv->topology->rootAddresses()),
_allMulticastGroups(nw->_allMulticastGroups())
{}
inline void operator()(Topology &t,const SharedPtr<Peer> &p) { _network->_tryAnnounceMulticastGroupsTo(_rootAddresses,_allMulticastGroups,p,_now); }
private:
uint64_t _now;
const RuntimeEnvironment *RR;
Network *_network;
std::vector<Address> _rootAddresses;
std::vector<MulticastGroup> _allMulticastGroups;
};
bool Network::_tryAnnounceMulticastGroupsTo(const std::vector<Address> &alwaysAddresses,const std::vector<MulticastGroup> &allMulticastGroups,const SharedPtr<Peer> &peer,uint64_t now) const
{
if ( ( (peer->hasActiveDirectPath(now)) && ( _isAllowed(peer) || (peer->address() == this->controller()) ) ) || (std::find(alwaysAddresses.begin(),alwaysAddresses.end(),peer->address()) != alwaysAddresses.end()) ) {
// 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) {
@ -444,17 +436,38 @@ bool Network::_tryAnnounceMulticastGroupsTo(const std::vector<Address> &alwaysAd
outp.armor(peer->key(),true);
peer->send(RR,outp.data(),outp.size(),now);
}
}
return true;
}
return false;
}
class _AnnounceMulticastGroupsToAll
{
public:
_AnnounceMulticastGroupsToAll(const RuntimeEnvironment *renv,Network *nw) :
_now(renv->node->now()),
RR(renv),
_network(nw),
_rootAddresses(renv->topology->rootAddresses()),
_allMulticastGroups(nw->_allMulticastGroups())
{}
inline void operator()(Topology &t,const SharedPtr<Peer> &p) { _network->_tryAnnounceMulticastGroupsTo(_rootAddresses,_allMulticastGroups,p,_now); }
private:
uint64_t _now;
const RuntimeEnvironment *RR;
Network *_network;
std::vector<Address> _rootAddresses;
std::vector<MulticastGroup> _allMulticastGroups;
};
void Network::_announceMulticastGroups()
{
// Assumes _lock is locked
_AnnounceMulticastGroupsToPeersWithActiveDirectPaths afunc(RR,this);
RR->topology->eachPeer<_AnnounceMulticastGroupsToPeersWithActiveDirectPaths &>(afunc);
_AnnounceMulticastGroupsToAll afunc(RR,this);
RR->topology->eachPeer<_AnnounceMulticastGroupsToAll &>(afunc);
}
std::vector<MulticastGroup> Network::_allMulticastGroups() const

View File

@ -55,8 +55,8 @@
namespace ZeroTier {
class RuntimeEnvironment;
class _AnnounceMulticastGroupsToPeersWithActiveDirectPaths;
class Peer;
class _AnnounceMulticastGroupsToAll; // internal function object in Network.cpp
/**
* A virtual LAN
@ -64,7 +64,7 @@ class Peer;
class Network : NonCopyable
{
friend class SharedPtr<Network>;
friend class _AnnounceMulticastGroupsToPeersWithActiveDirectPaths;
friend class _AnnounceMulticastGroupsToAll;
public:
/**