summaryrefslogtreecommitdiff
path: root/node/Network.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'node/Network.cpp')
-rw-r--r--node/Network.cpp140
1 files changed, 73 insertions, 67 deletions
diff --git a/node/Network.cpp b/node/Network.cpp
index 6968fb0d..18fbb624 100644
--- a/node/Network.cpp
+++ b/node/Network.cpp
@@ -81,7 +81,7 @@ Network::~Network()
Utils::rm(std::string(RR->homePath + ZT_PATH_SEPARATOR_S + "networks.d" + ZT_PATH_SEPARATOR_S + idString() + ".mcerts"));
} else {
clean();
- _dumpMulticastCerts();
+ _dumpMembershipCerts();
}
}
@@ -338,45 +338,58 @@ Network::Status Network::status() const
}
}
-void Network::_CBhandleTapData(void *arg,const MAC &from,const MAC &to,unsigned int etherType,const Buffer<4096> &data)
+void Network::learnBridgeRoute(const MAC &mac,const Address &addr)
{
- if ((!((Network *)arg)->_enabled)||(((Network *)arg)->status() != NETWORK_OK))
- return;
-
- const RuntimeEnvironment *RR = ((Network *)arg)->RR;
- if (RR->shutdownInProgress)
- return;
+ Mutex::Lock _l(_lock);
+ _remoteBridgeRoutes[mac] = addr;
- try {
- RR->sw->onLocalEthernet(SharedPtr<Network>((Network *)arg),from,to,etherType,data);
- } catch (std::exception &exc) {
- TRACE("unexpected exception handling local packet: %s",exc.what());
- } catch ( ... ) {
- TRACE("unexpected exception handling local packet");
+ // If _remoteBridgeRoutes exceeds sanity limit, trim worst offenders until below -- denial of service circuit breaker
+ while (_remoteBridgeRoutes.size() > ZT_MAX_BRIDGE_ROUTES) {
+ std::map<Address,unsigned long> counts;
+ Address maxAddr;
+ unsigned long maxCount = 0;
+ for(std::map<MAC,Address>::iterator br(_remoteBridgeRoutes.begin());br!=_remoteBridgeRoutes.end();++br) {
+ unsigned long c = ++counts[br->second];
+ if (c > maxCount) {
+ maxCount = c;
+ maxAddr = br->second;
+ }
+ }
+ for(std::map<MAC,Address>::iterator br(_remoteBridgeRoutes.begin());br!=_remoteBridgeRoutes.end();) {
+ if (br->second == maxAddr)
+ _remoteBridgeRoutes.erase(br++);
+ else ++br;
+ }
}
}
-void Network::_pushMembershipCertificate(const Address &peer,bool force,uint64_t now)
+void Network::setEnabled(bool enabled)
{
- uint64_t pushTimeout = _config->com().timestampMaxDelta() / 2;
- if (!pushTimeout)
- return; // still waiting on my own cert
- if (pushTimeout > 1000)
- pushTimeout -= 1000;
+ Mutex::Lock _l(_lock);
+ _enabled = enabled;
+ if (_tap)
+ _tap->setEnabled(enabled);
+}
- uint64_t &lastPushed = _lastPushedMembershipCertificate[peer];
- if ((force)||((now - lastPushed) > pushTimeout)) {
- lastPushed = now;
- TRACE("pushing membership cert for %.16llx to %s",(unsigned long long)_id,peer.toString().c_str());
+void Network::destroy()
+{
+ Mutex::Lock _l(_lock);
- Packet outp(peer,RR->identity.address(),Packet::VERB_NETWORK_MEMBERSHIP_CERTIFICATE);
- _config->com().serialize(outp);
- RR->sw->send(outp,true);
- }
+ _enabled = false;
+ _destroyed = true;
+
+ if (_setupThread)
+ Thread::join(_setupThread);
+ _setupThread = Thread();
+
+ if (_tap)
+ RR->tapFactory->close(_tap,true);
+ _tap = (EthernetTap *)0;
}
// Ethernet tap creation thread -- required on some platforms where tap
-// creation may be time consuming (e.g. Windows).
+// creation may be time consuming (e.g. Windows). Thread exits after tap
+// device setup.
void Network::threadMain()
throw()
{
@@ -420,53 +433,46 @@ void Network::threadMain()
}
}
-void Network::learnBridgeRoute(const MAC &mac,const Address &addr)
+void Network::_CBhandleTapData(void *arg,const MAC &from,const MAC &to,unsigned int etherType,const Buffer<4096> &data)
{
- Mutex::Lock _l(_lock);
- _remoteBridgeRoutes[mac] = addr;
+ if ((!((Network *)arg)->_enabled)||(((Network *)arg)->status() != NETWORK_OK))
+ return;
- // If _remoteBridgeRoutes exceeds sanity limit, trim worst offenders until below -- denial of service circuit breaker
- while (_remoteBridgeRoutes.size() > ZT_MAX_BRIDGE_ROUTES) {
- std::map<Address,unsigned long> counts;
- Address maxAddr;
- unsigned long maxCount = 0;
- for(std::map<MAC,Address>::iterator br(_remoteBridgeRoutes.begin());br!=_remoteBridgeRoutes.end();++br) {
- unsigned long c = ++counts[br->second];
- if (c > maxCount) {
- maxCount = c;
- maxAddr = br->second;
- }
- }
- for(std::map<MAC,Address>::iterator br(_remoteBridgeRoutes.begin());br!=_remoteBridgeRoutes.end();) {
- if (br->second == maxAddr)
- _remoteBridgeRoutes.erase(br++);
- else ++br;
- }
+ const RuntimeEnvironment *RR = ((Network *)arg)->RR;
+ if (RR->shutdownInProgress)
+ return;
+
+ try {
+ RR->sw->onLocalEthernet(SharedPtr<Network>((Network *)arg),from,to,etherType,data);
+ } catch (std::exception &exc) {
+ TRACE("unexpected exception handling local packet: %s",exc.what());
+ } catch ( ... ) {
+ TRACE("unexpected exception handling local packet");
}
}
-void Network::setEnabled(bool enabled)
+void Network::_pushMembershipCertificate(const Address &peer,bool force,uint64_t now)
{
- Mutex::Lock _l(_lock);
- _enabled = enabled;
- if (_tap)
- _tap->setEnabled(enabled);
-}
+ // assumes _lock is locked
+ uint64_t pushTimeout = _config->com().timestampMaxDelta() / 2;
-void Network::destroy()
-{
- Mutex::Lock _l(_lock);
+ // Zero means we're still waiting on our own cert
+ if (!pushTimeout)
+ return;
- _enabled = false;
- _destroyed = true;
+ // Give a 1s margin around +/- 1/2 max delta to account for latency
+ if (pushTimeout > 1000)
+ pushTimeout -= 1000;
- if (_setupThread)
- Thread::join(_setupThread);
- _setupThread = Thread();
+ uint64_t &lastPushed = _lastPushedMembershipCertificate[peer];
+ if ((force)||((now - lastPushed) > pushTimeout)) {
+ lastPushed = now;
+ TRACE("pushing membership cert for %.16llx to %s",(unsigned long long)_id,peer.toString().c_str());
- if (_tap)
- RR->tapFactory->close(_tap,true);
- _tap = (EthernetTap *)0;
+ Packet outp(peer,RR->identity.address(),Packet::VERB_NETWORK_MEMBERSHIP_CERTIFICATE);
+ _config->com().serialize(outp);
+ RR->sw->send(outp,true);
+ }
}
void Network::_restoreState()
@@ -537,7 +543,7 @@ void Network::_restoreState()
}
}
-void Network::_dumpMulticastCerts()
+void Network::_dumpMembershipCerts()
{
Buffer<ZT_NETWORK_CERT_WRITE_BUF_SIZE> buf;
std::string mcdbPath(RR->homePath + ZT_PATH_SEPARATOR_S + "networks.d" + ZT_PATH_SEPARATOR_S + idString() + ".mcerts");