diff --git a/node/Constants.hpp b/node/Constants.hpp index b8dc9ebfd..36973b380 100644 --- a/node/Constants.hpp +++ b/node/Constants.hpp @@ -183,9 +183,9 @@ error_no_ZT_ARCH_defined; #define ZT_MAC_FIRST_OCTET 0x32 /** - * How often Topology::clean() is called in ms + * How often Topology::clean() and Network::clean() are called in ms */ -#define ZT_TOPOLOGY_CLEAN_PERIOD 300000 +#define ZT_DB_CLEAN_PERIOD 300000 /** * Delay between WHOIS retries in ms diff --git a/node/Network.cpp b/node/Network.cpp index 5878a2817..a50d56dca 100644 --- a/node/Network.cpp +++ b/node/Network.cpp @@ -34,6 +34,7 @@ #include "NodeConfig.hpp" #include "Network.hpp" #include "Switch.hpp" +#include "Packet.hpp" namespace ZeroTier { @@ -103,6 +104,7 @@ Network::Network(const RuntimeEnvironment *renv,uint64_t id) throw(std::runtime_error) : _r(renv), _tap(renv,renv->identity.address().toMAC(),ZT_IF_MTU,&_CBhandleTapData,this), + _lastConfigUpdate(0), _id(id) { } @@ -114,16 +116,23 @@ Network::~Network() void Network::setConfiguration(const Network::Config &conf) { Mutex::Lock _l(_lock); - _configuration = conf; - _myCertificate = conf.certificateOfMembership(); + if ((conf.networkId() == _id)&&(conf.peerAddress() == _r->identity.address())) { // sanity check + _configuration = conf; + _myCertificate = conf.certificateOfMembership(); + _lastConfigUpdate = Utils::now(); + } } void Network::requestConfiguration() { + Packet outp(controller(),_r->identity.address(),Packet::VERB_NETWORK_CONFIG_REQUEST); + outp.append((uint64_t)_id); + _r->sw->send(outp,true); } bool Network::isAllowed(const Address &peer) const { + // Exceptions can occur if we do not yet have *our* configuration. try { Mutex::Lock _l(_lock); if (_configuration.isOpen()) diff --git a/node/Network.hpp b/node/Network.hpp index e553cd3ac..62c0e978a 100644 --- a/node/Network.hpp +++ b/node/Network.hpp @@ -392,6 +392,15 @@ public: */ void clean(); + /** + * @return Time of last updated configuration or 0 if none + */ + inline uint64_t lastConfigUpdate() const + throw() + { + return _lastConfigUpdate; + } + private: static void _CBhandleTapData(void *arg,const MAC &from,const MAC &to,unsigned int etherType,const Buffer<4096> &data); @@ -402,7 +411,7 @@ private: std::map _membershipCertificates; Config _configuration; Certificate _myCertificate; - uint64_t _lastCertificateUpdate; + uint64_t _lastConfigUpdate; uint64_t _id; Mutex _lock; diff --git a/node/Node.cpp b/node/Node.cpp index 827af23be..9c748b4a1 100644 --- a/node/Node.cpp +++ b/node/Node.cpp @@ -339,7 +339,7 @@ Node::ReasonForTermination Node::run() try { uint64_t lastPingCheck = 0; - uint64_t lastTopologyClean = Utils::now(); // don't need to do this immediately + uint64_t lastClean = Utils::now(); // don't need to do this immediately uint64_t lastNetworkFingerprintCheck = 0; uint64_t lastAutoconfigureCheck = 0; uint64_t networkConfigurationFingerprint = _r->sysEnv->getNetworkConfigurationFingerprint(); @@ -459,9 +459,10 @@ Node::ReasonForTermination Node::run() } } - if ((now - lastTopologyClean) >= ZT_TOPOLOGY_CLEAN_PERIOD) { - lastTopologyClean = now; - _r->topology->clean(); // happens in background + if ((now - lastClean) >= ZT_DB_CLEAN_PERIOD) { + lastClean = now; + _r->topology->clean(); + _r->nc->cleanAllNetworks(); } try { diff --git a/node/NodeConfig.cpp b/node/NodeConfig.cpp index 214c06b7d..4a1745358 100644 --- a/node/NodeConfig.cpp +++ b/node/NodeConfig.cpp @@ -72,6 +72,13 @@ void NodeConfig::whackAllTaps() n->second->tap().whack(); } +void NodeConfig::cleanAllNetworks() +{ + Mutex::Lock _l(_networks_m); + for(std::map< uint64_t,SharedPtr >::const_iterator n(_networks.begin());n!=_networks.end();++n) + n->second->clean(); +} + // Macro used in execute() #undef _P #define _P(f,...) { r.push_back(std::string()); Utils::stdsprintf(r.back(),(f),##__VA_ARGS__); } diff --git a/node/NodeConfig.hpp b/node/NodeConfig.hpp index 98678944a..62b23609a 100644 --- a/node/NodeConfig.hpp +++ b/node/NodeConfig.hpp @@ -107,6 +107,11 @@ public: */ void whackAllTaps(); + /** + * Call clean() on all networks + */ + void cleanAllNetworks(); + /** * @param nwid Network ID * @return True if this network exists