diff options
| author | Adam Ierymenko <adam.ierymenko@gmail.com> | 2014-09-26 12:23:43 -0700 |
|---|---|---|
| committer | Adam Ierymenko <adam.ierymenko@gmail.com> | 2014-09-26 12:23:43 -0700 |
| commit | 2d41055bdce886722d1b6a355559862016ac964c (patch) | |
| tree | b7af7882c20515f0e8695c2adc8e2500f1d19e5a /node/Network.cpp | |
| parent | 027060dad15df2273dcb25616bea5446be335f55 (diff) | |
| download | infinitytier-2d41055bdce886722d1b6a355559862016ac964c.tar.gz infinitytier-2d41055bdce886722d1b6a355559862016ac964c.zip | |
Some Network code cleanup.
Diffstat (limited to 'node/Network.cpp')
| -rw-r--r-- | node/Network.cpp | 140 |
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"); |
