summaryrefslogtreecommitdiff
path: root/node/Network.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'node/Network.cpp')
-rw-r--r--node/Network.cpp128
1 files changed, 89 insertions, 39 deletions
diff --git a/node/Network.cpp b/node/Network.cpp
index 7b033181..fb31f87c 100644
--- a/node/Network.cpp
+++ b/node/Network.cpp
@@ -100,20 +100,25 @@ Network::Network(const RuntimeEnvironment *renv,uint64_t nwid) :
ZT1_VirtualNetworkConfig ctmp;
_externalConfig(&ctmp);
- _portError = RR->node->configureVirtualNetworkPort(_id,&ctmp);
+ _portError = RR->node->configureVirtualNetworkPort(_id,ZT1_VIRTUAL_NETWORK_CONFIG_OPERATION_UP,&ctmp);
}
Network::~Network()
{
- RR->node->configureVirtualNetworkPort(_id,(const ZT1_VirtualNetworkConfig *)0);
+ ZT1_VirtualNetworkConfig ctmp;
+ _externalConfig(&ctmp);
char n[128];
if (_destroyed) {
+ RR->node->configureVirtualNetworkPort(_id,ZT1_VIRTUAL_NETWORK_CONFIG_OPERATION_DESTROY,&ctmp);
+
Utils::snprintf(n,sizeof(n),"networks.d/%.16llx.conf",_id);
RR->node->dataStoreDelete(n);
Utils::snprintf(n,sizeof(n),"networks.d/%.16llx.mcerts",_id);
RR->node->dataStoreDelete(n);
} else {
+ RR->node->configureVirtualNetworkPort(_id,ZT1_VIRTUAL_NETWORK_CONFIG_OPERATION_DOWN,&ctmp);
+
clean();
std::string buf("ZTMCD0");
@@ -132,49 +137,35 @@ Network::~Network()
}
}
-// Function object used by rescanMulticastGroups()
-class AnnounceMulticastGroupsToPeersWithActiveDirectPaths
+void Network::multicastSubscribe(const MulticastGroup &mg)
{
-public:
- AnnounceMulticastGroupsToPeersWithActiveDirectPaths(const RuntimeEnvironment *renv,Network *nw) :
- RR(renv),
- _now(Utils::now()),
- _network(nw),
- _supernodeAddresses(renv->topology->supernodeAddresses())
- {}
+ Mutex::Lock _l(_lock);
+ if (std::find(_myMulticastGroups.begin(),_myMulticastGroups.end(),mg) != _myMulticastGroups.end())
+ return;
+ _myMulticastGroups.push_back(mg);
+ std::sort(_myMulticastGroups.begin(),_myMulticastGroups.end());
+}
- inline void operator()(Topology &t,const SharedPtr<Peer> &p)
+void Network::multicastUnsubscribe(const MulticastGroup &mg)
+{
+ bool needAnnounce = false;
{
- if ( ( (p->hasActiveDirectPath(_now)) && (_network->isAllowed(p->address())) ) || (std::find(_supernodeAddresses.begin(),_supernodeAddresses.end(),p->address()) != _supernodeAddresses.end()) ) {
- Packet outp(p->address(),RR->identity.address(),Packet::VERB_MULTICAST_LIKE);
-
- std::vector<MulticastGroup> mgs(_network->multicastGroups());
- for(std::vector<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);
- }
+ Mutex::Lock _l(_lock);
- // network ID, MAC, ADI
- outp.append((uint64_t)_network->id());
- mg->mac().appendTo(outp);
- outp.append((uint32_t)mg->adi());
- }
+ std::vector<MulticastGroup> nmg;
+ for(std::vector<MulticastGroup>::const_iterator i(_myMulticastGroups.begin());i!=_myMulticastGroups.end();++i) {
+ if (*i != mg)
+ nmg.push_back(*i);
+ }
- if (outp.size() > ZT_PROTO_MIN_PACKET_LENGTH) {
- outp.armor(p->key(),true);
- p->send(RR,outp.data(),outp.size(),_now);
- }
+ if (nmg.size() != _myMulticastGroups.size()) {
+ _myMulticastGroups.swap(nmg);
+ needAnnounce = true;
}
}
-
-private:
- const RuntimeEnvironment *RR;
- uint64_t _now;
- Network *_network;
- std::vector<Address> _supernodeAddresses;
-};
+ if (needAnnounce)
+ _announceMulticastGroups();
+}
bool Network::applyConfiguration(const SharedPtr<NetworkConfig> &conf)
{
@@ -189,7 +180,7 @@ bool Network::applyConfiguration(const SharedPtr<NetworkConfig> &conf)
ZT1_VirtualNetworkConfig ctmp;
_externalConfig(&ctmp);
- _portError = RR->node->configureVirtualNetworkPort(_id,&ctmp);
+ _portError = RR->node->configureVirtualNetworkPort(_id,ZT1_VIRTUAL_NETWORK_CONFIG_OPERATION_CONFIG_UPDATE,&ctmp);
return true;
} else {
@@ -405,6 +396,15 @@ void Network::learnBridgeRoute(const MAC &mac,const Address &addr)
}
}
+void Network::learnBridgedMulticastGroup(const MulticastGroup &mg,uint64_t now)
+{
+ Mutex::Lock _l(_lock);
+ unsigned long tmp = _multicastGroupsBehindMe.size();
+ _multicastGroupsBehindMe[mg] = now;
+ if (tmp != _multicastGroupsBehindMe.size())
+ _announceMulticastGroups();
+}
+
void Network::setEnabled(bool enabled)
{
Mutex::Lock _l(_lock);
@@ -467,4 +467,54 @@ void Network::_externalConfig(ZT1_VirtualNetworkConfig *ec) const
} else ec->assignedAddressCount = 0;
}
+// Used in Network::_announceMulticastGroups()
+class _AnnounceMulticastGroupsToPeersWithActiveDirectPaths
+{
+public:
+ _AnnounceMulticastGroupsToPeersWithActiveDirectPaths(const RuntimeEnvironment *renv,Network *nw) :
+ RR(renv),
+ _now(Utils::now()),
+ _network(nw),
+ _supernodeAddresses(renv->topology->supernodeAddresses())
+ {}
+
+ inline void operator()(Topology &t,const SharedPtr<Peer> &p)
+ {
+ if ( ( (p->hasActiveDirectPath(_now)) && (_network->isAllowed(p->address())) ) || (std::find(_supernodeAddresses.begin(),_supernodeAddresses.end(),p->address()) != _supernodeAddresses.end()) ) {
+ Packet outp(p->address(),RR->identity.address(),Packet::VERB_MULTICAST_LIKE);
+
+ std::vector<MulticastGroup> mgs(_network->allMulticastGroups());
+ for(std::vector<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);
+ }
+ }
+ }
+
+private:
+ const RuntimeEnvironment *RR;
+ uint64_t _now;
+ Network *_network;
+ std::vector<Address> _supernodeAddresses;
+};
+
+void Network::_announceMulticastGroups()
+{
+ _AnnounceMulticastGroupsToPeersWithActiveDirectPaths afunc(RR,this);
+ RR->topology->eachPeer<_AnnounceMulticastGroupsToPeersWithActiveDirectPaths &>(afunc);
+}
+
} // namespace ZeroTier