diff options
Diffstat (limited to 'controller/EmbeddedNetworkController.hpp')
-rw-r--r-- | controller/EmbeddedNetworkController.hpp | 138 |
1 files changed, 65 insertions, 73 deletions
diff --git a/controller/EmbeddedNetworkController.hpp b/controller/EmbeddedNetworkController.hpp index bce8890c..bca0956e 100644 --- a/controller/EmbeddedNetworkController.hpp +++ b/controller/EmbeddedNetworkController.hpp @@ -37,9 +37,18 @@ #include "../osdep/OSUtils.hpp" #include "../osdep/Thread.hpp" +#include "../osdep/BlockingQueue.hpp" #include "../ext/json/json.hpp" +#include "JSONDB.hpp" + +// Number of background threads to start -- not actually started until needed +#define ZT_EMBEDDEDNETWORKCONTROLLER_BACKGROUND_THREAD_COUNT 2 + +// TTL for circuit tests +#define ZT_EMBEDDEDNETWORKCONTROLLER_CIRCUIT_TEST_EXPIRATION 120000 + namespace ZeroTier { class Node; @@ -47,20 +56,21 @@ class Node; class EmbeddedNetworkController : public NetworkController { public: + /** + * @param node Parent node + * @param dbPath Path to store data + */ EmbeddedNetworkController(Node *node,const char *dbPath); virtual ~EmbeddedNetworkController(); - // Thread main method -- do not call directly - void threadMain() - throw(); + virtual void init(const Identity &signingId,Sender *sender); - virtual NetworkController::ResultCode doNetworkConfigRequest( + virtual void request( + uint64_t nwid, const InetAddress &fromAddr, - const Identity &signingId, + uint64_t requestPacketId, const Identity &identity, - uint64_t nwid, - const Dictionary<ZT_NETWORKCONFIG_METADATA_DICT_CAPACITY> &metaData, - NetworkConfig &nc); + const Dictionary<ZT_NETWORKCONFIG_METADATA_DICT_CAPACITY> &metaData); unsigned int handleControlPlaneHttpGET( const std::vector<std::string> &path, @@ -84,49 +94,33 @@ public: std::string &responseBody, std::string &responseContentType); + void threadMain() + throw(); + private: static void _circuitTestCallback(ZT_Node *node,ZT_CircuitTest *test,const ZT_CircuitTestReport *report); + void _request( + uint64_t nwid, + const InetAddress &fromAddr, + uint64_t requestPacketId, + const Identity &identity, + const Dictionary<ZT_NETWORKCONFIG_METADATA_DICT_CAPACITY> &metaData); - // Network base path and network JSON path - inline std::string _networkBP(const uint64_t nwid,bool create) - { - char tmp[64]; - std::string p(_path + ZT_PATH_SEPARATOR_S + "network"); - if (create) OSUtils::mkdir(p.c_str()); - p.push_back(ZT_PATH_SEPARATOR); - Utils::snprintf(tmp,sizeof(tmp),"%.16llx",nwid); - p.append(tmp); - if (create) OSUtils::mkdir(p.c_str()); - return p; - } - inline std::string _networkJP(const uint64_t nwid,bool create) - { - return (_networkBP(nwid,create) + ZT_PATH_SEPARATOR + "config.json"); - } - - // Member base path and member JSON path - inline std::string _memberBP(const uint64_t nwid,const Address &member,bool create) + struct _RQEntry { - std::string p(_networkBP(nwid,create)); - p.push_back(ZT_PATH_SEPARATOR); - p.append("member"); - if (create) OSUtils::mkdir(p.c_str()); - p.push_back(ZT_PATH_SEPARATOR); - p.append(member.toString()); - if (create) OSUtils::mkdir(p.c_str()); - return p; - } - inline std::string _memberJP(const uint64_t nwid,const Address &member,bool create) - { - return (_memberBP(nwid,member,create) + ZT_PATH_SEPARATOR + "config.json"); - } + uint64_t nwid; + uint64_t requestPacketId; + InetAddress fromAddr; + Identity identity; + Dictionary<ZT_NETWORKCONFIG_METADATA_DICT_CAPACITY> metaData; + }; + BlockingQueue<_RQEntry *> _queue; - // In-memory cache of network members - std::map< uint64_t,std::map< Address,nlohmann::json > > _networkMemberCache; - Mutex _networkMemberCache_m; + Thread _threads[ZT_EMBEDDEDNETWORKCONTROLLER_BACKGROUND_THREAD_COUNT]; + bool _threadsStarted; + Mutex _threads_m; // Gathers a bunch of statistics about members of a network, IP assignments, etc. that we need in various places - // This does lock _networkMemberCache_m struct _NetworkMemberInfo { _NetworkMemberInfo() : authorizedMemberCount(0),activeMemberCount(0),totalMemberCount(0),mostRecentDeauthTime(0) {} @@ -136,8 +130,18 @@ private: unsigned long activeMemberCount; unsigned long totalMemberCount; uint64_t mostRecentDeauthTime; + uint64_t nmiTimestamp; // time this NMI structure was computed }; + std::map<uint64_t,_NetworkMemberInfo> _nmiCache; + Mutex _nmiCache_m; void _getNetworkMemberInfo(uint64_t now,uint64_t nwid,_NetworkMemberInfo &nmi); + inline void _clearNetworkMemberInfoCache(const uint64_t nwid) + { + Mutex::Lock _l(_nmiCache_m); + _nmiCache.erase(nwid); + } + + void _pushMemberUpdate(uint64_t now,uint64_t nwid,const nlohmann::json &member); // These init objects with default and static/informational fields inline void _initMember(nlohmann::json &member) @@ -152,7 +156,8 @@ private: if (!member.count("creationTime")) member["creationTime"] = OSUtils::now(); if (!member.count("noAutoAssignIps")) member["noAutoAssignIps"] = false; if (!member.count("revision")) member["revision"] = 0ULL; - if (!member.count("enableBroadcast")) member["enableBroadcast"] = true; + if (!member.count("lastDeauthorizedTime")) member["lastDeauthorizedTime"] = 0ULL; + if (!member.count("lastAuthorizedTime")) member["lastAuthorizedTime"] = 0ULL; member["objtype"] = "member"; } inline void _initNetwork(nlohmann::json &network) @@ -161,17 +166,21 @@ private: if (!network.count("creationTime")) network["creationTime"] = OSUtils::now(); if (!network.count("name")) network["name"] = ""; if (!network.count("multicastLimit")) network["multicastLimit"] = (uint64_t)32; + if (!network.count("enableBroadcast")) network["enableBroadcast"] = true; if (!network.count("v4AssignMode")) network["v4AssignMode"] = {{"zt",false}}; if (!network.count("v6AssignMode")) network["v6AssignMode"] = {{"rfc4193",false},{"zt",false},{"6plane",false}}; if (!network.count("authTokens")) network["authTokens"] = nlohmann::json::array(); if (!network.count("capabilities")) network["capabilities"] = nlohmann::json::array(); + if (!network.count("tags")) network["tags"] = nlohmann::json::array(); + if (!network.count("routes")) network["routes"] = nlohmann::json::array(); if (!network.count("ipAssignmentPools")) network["ipAssignmentPools"] = nlohmann::json::array(); if (!network.count("rules")) { // If unspecified, rules are set to allow anything and behave like a flat L2 segment - network["rules"] = { + network["rules"] = {{ { "not",false }, + { "or", false }, { "type","ACTION_ACCEPT" } - }; + }}; } network["objtype"] = "network"; } @@ -187,37 +196,20 @@ private: member["clock"] = now; } - // These are const after construction + JSONDB _db; + Mutex _db_m; + Node *const _node; std::string _path; - // Circuit tests outstanding - struct _CircuitTestEntry - { - ZT_CircuitTest *test; - std::string jsonResults; - }; - std::map< uint64_t,_CircuitTestEntry > _circuitTests; - Mutex _circuitTests_m; - - // Last request time by address, for rate limitation - std::map< std::pair<uint64_t,uint64_t>,uint64_t > _lastRequestTime; - Mutex _lastRequestTime_m; + NetworkController::Sender *_sender; + Identity _signingId; - // Queue of network member refreshes to be pushed - struct _Refresh - { - Address dest; - uint64_t nwid; - uint64_t blacklistAddresses[64]; - uint64_t blacklistThresholds[64]; - unsigned int numBlacklistEntries; - }; - std::list< _Refresh > _refreshQueue; - Mutex _refreshQueue_m; + std::list< ZT_CircuitTest > _tests; + Mutex _tests_m; - Thread _daemon; - volatile bool _daemonRun; + std::map< std::pair<uint64_t,uint64_t>,uint64_t > _lastRequestTime; // last request time by <address,networkId> + Mutex _lastRequestTime_m; }; } // namespace ZeroTier |