|
|
|
|
@ -111,33 +111,84 @@ SharedPtr<Network> Network::newInstance(const RuntimeEnvironment *renv,NodeConfi
|
|
|
|
|
return nw; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
bool Network::updateMulticastGroups() |
|
|
|
|
// Function object used by rescanMulticastGroups()
|
|
|
|
|
class AnnounceMulticastGroupsToPeersWithActiveDirectPaths |
|
|
|
|
{ |
|
|
|
|
Mutex::Lock _l(_lock); |
|
|
|
|
EthernetTap *t = _tap; |
|
|
|
|
if (t) { |
|
|
|
|
// Grab current groups from the local tap
|
|
|
|
|
bool updated = t->updateMulticastGroups(_myMulticastGroups); |
|
|
|
|
|
|
|
|
|
// Merge in learned groups from any hosts bridged in behind us
|
|
|
|
|
for(std::map<MulticastGroup,uint64_t>::const_iterator mg(_multicastGroupsBehindMe.begin());mg!=_multicastGroupsBehindMe.end();++mg) |
|
|
|
|
_myMulticastGroups.insert(mg->first); |
|
|
|
|
|
|
|
|
|
// Add or remove BROADCAST group based on broadcast enabled netconf flag
|
|
|
|
|
if ((_config)&&(_config->enableBroadcast())) { |
|
|
|
|
if (_myMulticastGroups.count(BROADCAST)) |
|
|
|
|
return updated; |
|
|
|
|
else { |
|
|
|
|
_myMulticastGroups.insert(BROADCAST); |
|
|
|
|
return true; |
|
|
|
|
public: |
|
|
|
|
AnnounceMulticastGroupsToPeersWithActiveDirectPaths(const RuntimeEnvironment *renv,Network *nw) : |
|
|
|
|
RR(renv), |
|
|
|
|
_now(Utils::now()), |
|
|
|
|
_network(nw) |
|
|
|
|
{} |
|
|
|
|
|
|
|
|
|
inline void operator()(Topology &t,const SharedPtr<Peer> &p) |
|
|
|
|
{ |
|
|
|
|
if ( ( (p->hasActiveDirectPath(_now)) && (_network->isAllowed(p->address())) ) || (_network->controller() == p->address()) || (t.isSupernode(p->address())) ) { |
|
|
|
|
Packet outp(p->address(),RR->identity.address(),Packet::VERB_MULTICAST_LIKE); |
|
|
|
|
|
|
|
|
|
std::set<MulticastGroup> mgs(_network->multicastGroups()); |
|
|
|
|
for(std::set<MulticastGroup>::iterator mg(mgs.begin());mg!=mgs.end();++mg) { |
|
|
|
|
if ((outp.size() + 18) > ZT_UDP_DEFAULT_PAYLOAD_MTU) { |
|
|
|
|
outp.armor(p->key(),true); |
|
|
|
|
p->send(RR,outp.data(),outp.size(),_now); |
|
|
|
|
outp.reset(p->address(),RR->identity.address(),Packet::VERB_MULTICAST_LIKE); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// network ID, MAC, ADI
|
|
|
|
|
outp.append((uint64_t)_network->id()); |
|
|
|
|
mg->mac().appendTo(outp); |
|
|
|
|
outp.append((uint32_t)mg->adi()); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (outp.size() > ZT_PROTO_MIN_PACKET_LENGTH) { |
|
|
|
|
outp.armor(p->key(),true); |
|
|
|
|
p->send(RR,outp.data(),outp.size(),_now); |
|
|
|
|
} |
|
|
|
|
} else { |
|
|
|
|
if (_myMulticastGroups.count(BROADCAST)) { |
|
|
|
|
_myMulticastGroups.erase(BROADCAST); |
|
|
|
|
return true; |
|
|
|
|
} else return updated; |
|
|
|
|
} |
|
|
|
|
} else return false; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
private: |
|
|
|
|
const RuntimeEnvironment *RR; |
|
|
|
|
uint64_t _now; |
|
|
|
|
Network *_network; |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
bool Network::rescanMulticastGroups() |
|
|
|
|
{ |
|
|
|
|
bool updated = false; |
|
|
|
|
|
|
|
|
|
{ |
|
|
|
|
Mutex::Lock _l(_lock); |
|
|
|
|
EthernetTap *t = _tap; |
|
|
|
|
if (t) { |
|
|
|
|
// Grab current groups from the local tap
|
|
|
|
|
updated = t->updateMulticastGroups(_myMulticastGroups); |
|
|
|
|
|
|
|
|
|
// Merge in learned groups from any hosts bridged in behind us
|
|
|
|
|
for(std::map<MulticastGroup,uint64_t>::const_iterator mg(_multicastGroupsBehindMe.begin());mg!=_multicastGroupsBehindMe.end();++mg) |
|
|
|
|
_myMulticastGroups.insert(mg->first); |
|
|
|
|
|
|
|
|
|
// Add or remove BROADCAST group based on broadcast enabled netconf flag
|
|
|
|
|
if ((_config)&&(_config->enableBroadcast())) { |
|
|
|
|
if (!_myMulticastGroups.count(BROADCAST)) { |
|
|
|
|
_myMulticastGroups.insert(BROADCAST); |
|
|
|
|
updated = true; |
|
|
|
|
} |
|
|
|
|
} else { |
|
|
|
|
if (_myMulticastGroups.count(BROADCAST)) { |
|
|
|
|
_myMulticastGroups.erase(BROADCAST); |
|
|
|
|
updated = true; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (updated) { |
|
|
|
|
AnnounceMulticastGroupsToPeersWithActiveDirectPaths afunc(RR,this); |
|
|
|
|
RR->topology->eachPeer<AnnounceMulticastGroupsToPeersWithActiveDirectPaths &>(afunc); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return updated; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
bool Network::applyConfiguration(const SharedPtr<NetworkConfig> &conf) |
|
|
|
|
@ -449,6 +500,8 @@ void Network::threadMain()
|
|
|
|
|
t->setEnabled(_enabled); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
rescanMulticastGroups(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void Network::_CBhandleTapData(void *arg,const MAC &from,const MAC &to,unsigned int etherType,const Buffer<4096> &data) |
|
|
|
|
|