diff --git a/nonfree/controller/CV1.cpp b/nonfree/controller/CV1.cpp index 95d85a280..1d1fc8013 100644 --- a/nonfree/controller/CV1.cpp +++ b/nonfree/controller/CV1.cpp @@ -1,23 +1,14 @@ -/* - * Copyright (c)2019 ZeroTier, Inc. - * - * Use of this software is governed by the Business Source License included - * in the LICENSE.TXT file in the project's root directory. - * - * Change Date: 2026-01-01 - * - * On the date above, in accordance with the Business Source License, use - * of this software will be governed by version 2.0 of the Apache License. +/* (c) ZeroTier, Inc. + * See LICENSE.txt in nonfree/ */ -/****/ #include "CV1.hpp" #ifdef ZT_CONTROLLER_USE_LIBPQ -#include "../node/Constants.hpp" -#include "../node/SHA512.hpp" -#include "../version.h" +#include "../../node/Constants.hpp" +#include "../../node/SHA512.hpp" +#include "../../version.h" #include "CtlUtil.hpp" #include "EmbeddedNetworkController.hpp" #include "Redis.hpp" diff --git a/nonfree/controller/CV1.hpp b/nonfree/controller/CV1.hpp index b1a362798..4819cde37 100644 --- a/nonfree/controller/CV1.hpp +++ b/nonfree/controller/CV1.hpp @@ -1,15 +1,6 @@ -/* - * Copyright (c)2019 ZeroTier, Inc. - * - * Use of this software is governed by the Business Source License included - * in the LICENSE.TXT file in the project's root directory. - * - * Change Date: 2026-01-01 - * - * On the date above, in accordance with the Business Source License, use - * of this software will be governed by version 2.0 of the Apache License. +/* (c) ZeroTier, Inc. + * See LICENSE.txt in nonfree/ */ -/****/ #include "DB.hpp" diff --git a/nonfree/controller/CV2.cpp b/nonfree/controller/CV2.cpp index db9effb3c..8b8370772 100644 --- a/nonfree/controller/CV2.cpp +++ b/nonfree/controller/CV2.cpp @@ -1,23 +1,14 @@ -/* - * Copyright (c)2025 ZeroTier, Inc. - * - * Use of this software is governed by the Business Source License included - * in the LICENSE.TXT file in the project's root directory. - * - * Change Date: 2026-01-01 - * - * On the date above, in accordance with the Business Source License, use - * of this software will be governed by version 2.0 of the Apache License. +/* (c) ZeroTier, Inc. + * See LICENSE.txt in nonfree/ */ -/****/ - -#include "CV2.hpp" #ifdef ZT_CONTROLLER_USE_LIBPQ -#include "../node/Constants.hpp" -#include "../node/SHA512.hpp" -#include "../version.h" +#include "CV2.hpp" + +#include "../../node/Constants.hpp" +#include "../../node/SHA512.hpp" +#include "../../version.h" #include "CtlUtil.hpp" #include "EmbeddedNetworkController.hpp" #include "opentelemetry/trace/provider.h" @@ -1241,4 +1232,4 @@ void CV2::onlineNotificationThread() exit(6); } } -#endif // ZT_CONTROLLER_USE_LIBPQ \ No newline at end of file +#endif // ZT_CONTROLLER_USE_LIBPQ diff --git a/nonfree/controller/CV2.hpp b/nonfree/controller/CV2.hpp index 09501e021..c5679ae3d 100644 --- a/nonfree/controller/CV2.hpp +++ b/nonfree/controller/CV2.hpp @@ -1,17 +1,8 @@ -/* - * Copyright (c)2025 ZeroTier, Inc. - * - * Use of this software is governed by the Business Source License included - * in the LICENSE.TXT file in the project's root directory. - * - * Change Date: 2026-01-01 - * - * On the date above, in accordance with the Business Source License, use - * of this software will be governed by version 2.0 of the Apache License. +/* (c) ZeroTier, Inc. + * See LICENSE.txt in nonfree/ */ -/****/ -#include "DB.hpp" +include "DB.hpp" #ifdef ZT_CONTROLLER_USE_LIBPQ @@ -20,7 +11,7 @@ #define ZT_CENTRAL_CONTROLLER_COMMIT_THREADS 4 -#include "../node/Metrics.hpp" +#include "../../node/Metrics.hpp" #include "ConnectionPool.hpp" #include "PostgreSQL.hpp" @@ -28,82 +19,82 @@ #include #include -namespace ZeroTier { + namespace ZeroTier +{ + class CV2 : public DB { + friend class MemberNotificationReceiver; + friend class NetworkNotificationReceiver; -class CV2 : public DB { - friend class MemberNotificationReceiver; - friend class NetworkNotificationReceiver; + public: + CV2(const Identity& myId, const char* path, int listenPort); + virtual ~CV2(); - public: - CV2(const Identity& myId, const char* path, int listenPort); - virtual ~CV2(); + virtual bool waitForReady(); + virtual bool isReady(); + virtual bool save(nlohmann::json& record, bool notifyListeners); + virtual void eraseNetwork(const uint64_t networkId); + virtual void eraseMember(const uint64_t networkId, const uint64_t memberId); + virtual void nodeIsOnline(const uint64_t networkId, const uint64_t memberId, const InetAddress& physicalAddress); + virtual void nodeIsOnline(const uint64_t networkId, const uint64_t memberId, const InetAddress& physicalAddress, const char* osArch); + virtual AuthInfo getSSOAuthInfo(const nlohmann::json& member, const std::string& redirectURL); - virtual bool waitForReady(); - virtual bool isReady(); - virtual bool save(nlohmann::json& record, bool notifyListeners); - virtual void eraseNetwork(const uint64_t networkId); - virtual void eraseMember(const uint64_t networkId, const uint64_t memberId); - virtual void nodeIsOnline(const uint64_t networkId, const uint64_t memberId, const InetAddress& physicalAddress); - virtual void nodeIsOnline(const uint64_t networkId, const uint64_t memberId, const InetAddress& physicalAddress, const char* osArch); - virtual AuthInfo getSSOAuthInfo(const nlohmann::json& member, const std::string& redirectURL); - - virtual bool ready() - { - return _ready == 2; - } - - protected: - struct _PairHasher { - inline std::size_t operator()(const std::pair& p) const + virtual bool ready() { - return (std::size_t)(p.first ^ p.second); + return _ready == 2; } + + protected: + struct _PairHasher { + inline std::size_t operator()(const std::pair& p) const + { + return (std::size_t)(p.first ^ p.second); + } + }; + virtual void _memberChanged(nlohmann::json& old, nlohmann::json& memberConfig, bool notifyListeners); + + virtual void _networkChanged(nlohmann::json& old, nlohmann::json& networkConfig, bool notifyListeners); + + private: + void initializeNetworks(); + void initializeMembers(); + void heartbeat(); + void membersDbWatcher(); + void networksDbWatcher(); + + void commitThread(); + void onlineNotificationThread(); + + // void notifyNewMember(const std::string &networkID, const std::string &memberID); + + enum OverrideMode { ALLOW_PGBOUNCER_OVERRIDE = 0, NO_OVERRIDE = 1 }; + + std::shared_ptr > _pool; + + const Identity _myId; + const Address _myAddress; + std::string _myAddressStr; + std::string _connString; + + BlockingQueue > _commitQueue; + + std::thread _heartbeatThread; + std::thread _membersDbWatcher; + std::thread _networksDbWatcher; + std::thread _commitThread[ZT_CENTRAL_CONTROLLER_COMMIT_THREADS]; + std::thread _onlineNotificationThread; + + std::unordered_map, NodeOnlineRecord, _PairHasher> _lastOnline; + + mutable std::mutex _lastOnline_l; + mutable std::mutex _readyLock; + std::atomic _ready, _connected, _run; + mutable volatile bool _waitNoticePrinted; + + int _listenPort; + uint8_t _ssoPsk[48]; }; - virtual void _memberChanged(nlohmann::json& old, nlohmann::json& memberConfig, bool notifyListeners); - - virtual void _networkChanged(nlohmann::json& old, nlohmann::json& networkConfig, bool notifyListeners); - - private: - void initializeNetworks(); - void initializeMembers(); - void heartbeat(); - void membersDbWatcher(); - void networksDbWatcher(); - - void commitThread(); - void onlineNotificationThread(); - - // void notifyNewMember(const std::string &networkID, const std::string &memberID); - - enum OverrideMode { ALLOW_PGBOUNCER_OVERRIDE = 0, NO_OVERRIDE = 1 }; - - std::shared_ptr > _pool; - - const Identity _myId; - const Address _myAddress; - std::string _myAddressStr; - std::string _connString; - - BlockingQueue > _commitQueue; - - std::thread _heartbeatThread; - std::thread _membersDbWatcher; - std::thread _networksDbWatcher; - std::thread _commitThread[ZT_CENTRAL_CONTROLLER_COMMIT_THREADS]; - std::thread _onlineNotificationThread; - - std::unordered_map, NodeOnlineRecord, _PairHasher> _lastOnline; - - mutable std::mutex _lastOnline_l; - mutable std::mutex _readyLock; - std::atomic _ready, _connected, _run; - mutable volatile bool _waitNoticePrinted; - - int _listenPort; - uint8_t _ssoPsk[48]; -}; } // namespace ZeroTier #endif // ZT_CONTROLLER_CV2_HPP -#endif // ZT_CONTROLLER_USE_LIBPQ \ No newline at end of file +#endif // ZT_CONTROLLER_USE_LIBPQ diff --git a/nonfree/controller/ConnectionPool.hpp b/nonfree/controller/ConnectionPool.hpp index 75690fab4..2588ae3a9 100644 --- a/nonfree/controller/ConnectionPool.hpp +++ b/nonfree/controller/ConnectionPool.hpp @@ -1,15 +1,6 @@ -/* - * Copyright (c)2021 ZeroTier, Inc. - * - * Use of this software is governed by the Business Source License included - * in the LICENSE.TXT file in the project's root directory. - * - * Change Date: 2026-01-01 - * - * On the date above, in accordance with the Business Source License, use - * of this software will be governed by version 2.0 of the Apache License. +/* (c) ZeroTier, Inc. + * See LICENSE.txt in nonfree/ */ -/****/ #ifndef ZT_CONNECTION_POOL_H_ #define ZT_CONNECTION_POOL_H_ @@ -18,7 +9,7 @@ #define _DEBUG(x) #endif -#include "../node/Metrics.hpp" +#include "../../node/Metrics.hpp" #include "opentelemetry/trace/provider.h" #include @@ -26,7 +17,6 @@ #include #include #include -#include namespace ZeroTier { diff --git a/nonfree/controller/CtlUtil.cpp b/nonfree/controller/CtlUtil.cpp index e1e82f7a3..51a5535cf 100644 --- a/nonfree/controller/CtlUtil.cpp +++ b/nonfree/controller/CtlUtil.cpp @@ -1,3 +1,7 @@ +/* (c) ZeroTier, Inc. + * See LICENSE.txt in nonfree/ + */ + #include "CtlUtil.hpp" #ifdef ZT_CONTROLLER_USE_LIBPQ @@ -61,4 +65,4 @@ std::string url_encode(const std::string& value) } // namespace ZeroTier -#endif \ No newline at end of file +#endif diff --git a/nonfree/controller/CtlUtil.hpp b/nonfree/controller/CtlUtil.hpp index 0ba665af3..5347f9a4d 100644 --- a/nonfree/controller/CtlUtil.hpp +++ b/nonfree/controller/CtlUtil.hpp @@ -1,3 +1,7 @@ +/* (c) ZeroTier, Inc. + * See LICENSE.txt in nonfree/ + */ + #ifndef ZT_CTLUTIL_HPP #define ZT_CTLUTIL_HPP @@ -13,4 +17,4 @@ std::vector split(std::string str, char delim); std::string url_encode(const std::string& value); } // namespace ZeroTier -#endif // namespace ZeroTier \ No newline at end of file +#endif // namespace ZeroTier diff --git a/nonfree/controller/DB.cpp b/nonfree/controller/DB.cpp index 4cce312ed..e71fe6eee 100644 --- a/nonfree/controller/DB.cpp +++ b/nonfree/controller/DB.cpp @@ -1,19 +1,10 @@ -/* - * Copyright (c)2019 ZeroTier, Inc. - * - * Use of this software is governed by the Business Source License included - * in the LICENSE.TXT file in the project's root directory. - * - * Change Date: 2026-01-01 - * - * On the date above, in accordance with the Business Source License, use - * of this software will be governed by version 2.0 of the Apache License. +/* (c) ZeroTier, Inc. + * See LICENSE.txt in nonfree/ */ -/****/ #include "DB.hpp" -#include "../node/Metrics.hpp" +#include "../../node/Metrics.hpp" #include "EmbeddedNetworkController.hpp" #include "opentelemetry/trace/provider.h" diff --git a/nonfree/controller/DB.hpp b/nonfree/controller/DB.hpp index 01b6f1266..0d8026ab7 100644 --- a/nonfree/controller/DB.hpp +++ b/nonfree/controller/DB.hpp @@ -1,26 +1,17 @@ -/* - * Copyright (c)2019 ZeroTier, Inc. - * - * Use of this software is governed by the Business Source License included - * in the LICENSE.TXT file in the project's root directory. - * - * Change Date: 2026-01-01 - * - * On the date above, in accordance with the Business Source License, use - * of this software will be governed by version 2.0 of the Apache License. +/* (c) ZeroTier, Inc. + * See LICENSE.txt in nonfree/ */ -/****/ #ifndef ZT_CONTROLLER_DB_HPP #define ZT_CONTROLLER_DB_HPP // #define ZT_CONTROLLER_USE_LIBPQ -#include "../node/Constants.hpp" -#include "../node/Identity.hpp" -#include "../node/InetAddress.hpp" -#include "../osdep/BlockingQueue.hpp" -#include "../osdep/OSUtils.hpp" +#include "../../node/Constants.hpp" +#include "../../node/Identity.hpp" +#include "../../node/InetAddress.hpp" +#include "../../osdep/BlockingQueue.hpp" +#include "../../osdep/OSUtils.hpp" #include #include diff --git a/nonfree/controller/DBMirrorSet.cpp b/nonfree/controller/DBMirrorSet.cpp index f8c6f0366..404c494c5 100644 --- a/nonfree/controller/DBMirrorSet.cpp +++ b/nonfree/controller/DBMirrorSet.cpp @@ -1,15 +1,6 @@ -/* - * Copyright (c)2019 ZeroTier, Inc. - * - * Use of this software is governed by the Business Source License included - * in the LICENSE.TXT file in the project's root directory. - * - * Change Date: 2026-01-01 - * - * On the date above, in accordance with the Business Source License, use - * of this software will be governed by version 2.0 of the Apache License. +/* (c) ZeroTier, Inc. + * See LICENSE.txt in nonfree/ */ -/****/ #include "DBMirrorSet.hpp" diff --git a/nonfree/controller/DBMirrorSet.hpp b/nonfree/controller/DBMirrorSet.hpp index 50230c545..c839e440e 100644 --- a/nonfree/controller/DBMirrorSet.hpp +++ b/nonfree/controller/DBMirrorSet.hpp @@ -1,15 +1,6 @@ -/* - * Copyright (c)2019 ZeroTier, Inc. - * - * Use of this software is governed by the Business Source License included - * in the LICENSE.TXT file in the project's root directory. - * - * Change Date: 2026-01-01 - * - * On the date above, in accordance with the Business Source License, use - * of this software will be governed by version 2.0 of the Apache License. +/* (c) ZeroTier, Inc. + * See LICENSE.txt in nonfree/ */ -/****/ #ifndef ZT_DBMIRRORSET_HPP #define ZT_DBMIRRORSET_HPP diff --git a/nonfree/controller/EmbeddedNetworkController.cpp b/nonfree/controller/EmbeddedNetworkController.cpp index 7f825fd77..9011f5f5c 100644 --- a/nonfree/controller/EmbeddedNetworkController.cpp +++ b/nonfree/controller/EmbeddedNetworkController.cpp @@ -1,15 +1,6 @@ -/* - * Copyright (c)2019 ZeroTier, Inc. - * - * Use of this software is governed by the Business Source License included - * in the LICENSE.TXT file in the project's root directory. - * - * Change Date: 2026-01-01 - * - * On the date above, in accordance with the Business Source License, use - * of this software will be governed by version 2.0 of the Apache License. +/* (c) ZeroTier, Inc. + * See LICENSE.txt in nonfree/ */ -/****/ #include #include @@ -20,10 +11,9 @@ #ifndef _WIN32 #include #endif -#include "../include/ZeroTierOne.h" +#include "../../include/ZeroTierOne.h" #include "EmbeddedNetworkController.hpp" #include "FileDB.hpp" -#include "LFDB.hpp" #include #include @@ -621,36 +611,6 @@ void EmbeddedNetworkController::init(const Identity& signingId, Sender* sender) } #endif - std::string lfJSON; - OSUtils::readFile((_ztPath + ZT_PATH_SEPARATOR_S "local.conf").c_str(), lfJSON); - if (lfJSON.length() > 0) { - nlohmann::json lfConfig(OSUtils::jsonParse(lfJSON)); - nlohmann::json& settings = lfConfig["settings"]; - if (settings.is_object()) { - nlohmann::json& controllerDb = settings["controllerDb"]; - if (controllerDb.is_object()) { - std::string type = controllerDb["type"]; - if (type == "lf") { - std::string lfOwner = controllerDb["owner"]; - std::string lfHost = controllerDb["host"]; - int lfPort = controllerDb["port"]; - bool storeOnlineState = controllerDb["storeOnlineState"]; - if ((lfOwner.length()) && (lfHost.length()) && (lfPort > 0) && (lfPort < 65536)) { - std::size_t pubHdrLoc = lfOwner.find("Public: "); - if ((pubHdrLoc > 0) && ((pubHdrLoc + 8) < lfOwner.length())) { - std::string lfOwnerPublic = lfOwner.substr(pubHdrLoc + 8); - std::size_t pubHdrEnd = lfOwnerPublic.find_first_of("\n\r\t "); - if (pubHdrEnd != std::string::npos) { - lfOwnerPublic = lfOwnerPublic.substr(0, pubHdrEnd); - _db.addDB(std::shared_ptr(new LFDB(_signingId, _path.c_str(), lfOwner.c_str(), lfOwnerPublic.c_str(), lfHost.c_str(), lfPort, storeOnlineState))); - } - } - } - } - } - } - } - _db.waitForReady(); } diff --git a/nonfree/controller/EmbeddedNetworkController.hpp b/nonfree/controller/EmbeddedNetworkController.hpp index a4f93ae43..81f248ab4 100644 --- a/nonfree/controller/EmbeddedNetworkController.hpp +++ b/nonfree/controller/EmbeddedNetworkController.hpp @@ -1,23 +1,14 @@ -/* - * Copyright (c)2019 ZeroTier, Inc. - * - * Use of this software is governed by the Business Source License included - * in the LICENSE.TXT file in the project's root directory. - * - * Change Date: 2026-01-01 - * - * On the date above, in accordance with the Business Source License, use - * of this software will be governed by version 2.0 of the Apache License. +/* (c) ZeroTier, Inc. + * See LICENSE.txt in nonfree/ */ -/****/ #ifndef ZT_SQLITENETWORKCONTROLLER_HPP #define ZT_SQLITENETWORKCONTROLLER_HPP -#include "../node/Constants.hpp" -#include "../node/InetAddress.hpp" -#include "../node/NetworkController.hpp" -#include "../osdep/BlockingQueue.hpp" +#include "../../node/Constants.hpp" +#include "../../node/InetAddress.hpp" +#include "../../node/NetworkController.hpp" +#include "../../osdep/BlockingQueue.hpp" #include "DB.hpp" #include "DBMirrorSet.hpp" diff --git a/nonfree/controller/FileDB.cpp b/nonfree/controller/FileDB.cpp index 6472022e2..699195953 100644 --- a/nonfree/controller/FileDB.cpp +++ b/nonfree/controller/FileDB.cpp @@ -1,15 +1,6 @@ -/* - * Copyright (c)2019 ZeroTier, Inc. - * - * Use of this software is governed by the Business Source License included - * in the LICENSE.TXT file in the project's root directory. - * - * Change Date: 2026-01-01 - * - * On the date above, in accordance with the Business Source License, use - * of this software will be governed by version 2.0 of the Apache License. +/* (c) ZeroTier, Inc. + * See LICENSE.txt in nonfree/ */ -/****/ #include "FileDB.hpp" diff --git a/nonfree/controller/FileDB.hpp b/nonfree/controller/FileDB.hpp index e10753223..f5b62ad89 100644 --- a/nonfree/controller/FileDB.hpp +++ b/nonfree/controller/FileDB.hpp @@ -1,15 +1,6 @@ -/* - * Copyright (c)2019 ZeroTier, Inc. - * - * Use of this software is governed by the Business Source License included - * in the LICENSE.TXT file in the project's root directory. - * - * Change Date: 2026-01-01 - * - * On the date above, in accordance with the Business Source License, use - * of this software will be governed by version 2.0 of the Apache License. +/* (c) ZeroTier, Inc. + * See LICENSE.txt in nonfree/ */ -/****/ #ifndef ZT_CONTROLLER_FILEDB_HPP #define ZT_CONTROLLER_FILEDB_HPP diff --git a/nonfree/controller/LFDB.cpp b/nonfree/controller/LFDB.cpp deleted file mode 100644 index 77fa8ffe1..000000000 --- a/nonfree/controller/LFDB.cpp +++ /dev/null @@ -1,443 +0,0 @@ -/* - * Copyright (c)2019 ZeroTier, Inc. - * - * Use of this software is governed by the Business Source License included - * in the LICENSE.TXT file in the project's root directory. - * - * Change Date: 2026-01-01 - * - * On the date above, in accordance with the Business Source License, use - * of this software will be governed by version 2.0 of the Apache License. - */ -/****/ - -#include "LFDB.hpp" - -#include "../ext/cpp-httplib/httplib.h" -#include "../osdep/OSUtils.hpp" - -#include -#include -#include -#include - -namespace ZeroTier { - -LFDB::LFDB(const Identity& myId, const char* path, const char* lfOwnerPrivate, const char* lfOwnerPublic, const char* lfNodeHost, int lfNodePort, bool storeOnlineState) - : DB() - , _myId(myId) - , _lfOwnerPrivate((lfOwnerPrivate) ? lfOwnerPrivate : "") - , _lfOwnerPublic((lfOwnerPublic) ? lfOwnerPublic : "") - , _lfNodeHost((lfNodeHost) ? lfNodeHost : "127.0.0.1") - , _lfNodePort(((lfNodePort > 0) && (lfNodePort < 65536)) ? lfNodePort : 9980) - , _running(true) - , _ready(false) - , _storeOnlineState(storeOnlineState) -{ - _syncThread = std::thread([this]() { - char controllerAddress[24]; - const uint64_t controllerAddressInt = _myId.address().toInt(); - _myId.address().toString(controllerAddress); - std::string networksSelectorName("com.zerotier.controller.lfdb:"); - networksSelectorName.append(controllerAddress); - networksSelectorName.append("/network"); - - // LF record masking key is the first 32 bytes of SHA512(controller private key) in hex, - // hiding record values from anything but the controller or someone who has its key. - uint8_t sha512pk[64]; - _myId.sha512PrivateKey(sha512pk); - char maskingKey[128]; - Utils::hex(sha512pk, 32, maskingKey); - - httplib::Client htcli(_lfNodeHost.c_str(), _lfNodePort); - int64_t timeRangeStart = 0; - while (_running.load()) { - { - std::lock_guard sl(_state_l); - for (auto ns = _state.begin(); ns != _state.end(); ++ns) { - if (ns->second.dirty) { - nlohmann::json network; - if (get(ns->first, network)) { - nlohmann::json newrec, selector0; - selector0["Name"] = networksSelectorName; - selector0["Ordinal"] = ns->first; - newrec["Selectors"].push_back(selector0); - newrec["Value"] = network.dump(); - newrec["OwnerPrivate"] = _lfOwnerPrivate; - newrec["MaskingKey"] = maskingKey; - newrec["PulseIfUnchanged"] = true; - try { - auto resp = htcli.Post("/makerecord", newrec.dump(), "application/json"); - if (resp) { - if (resp->status == 200) { - ns->second.dirty = false; - // printf("SET network %.16llx %s\n",ns->first,resp->body.c_str()); - } - else { - fprintf(stderr, "ERROR: LFDB: %d from node (create/update network): %s" ZT_EOL_S, resp->status, resp->body.c_str()); - } - } - else { - fprintf(stderr, "ERROR: LFDB: node is offline" ZT_EOL_S); - } - } - catch (std::exception& e) { - fprintf(stderr, "ERROR: LFDB: unexpected exception querying node (create/update network): %s" ZT_EOL_S, e.what()); - } - catch (...) { - fprintf(stderr, "ERROR: LFDB: unexpected exception querying node (create/update network): unknown exception" ZT_EOL_S); - } - } - } - - for (auto ms = ns->second.members.begin(); ms != ns->second.members.end(); ++ms) { - if ((_storeOnlineState) && (ms->second.lastOnlineDirty) && (ms->second.lastOnlineAddress)) { - nlohmann::json newrec, selector0, selector1, selectors, ip; - char tmp[1024], tmp2[128]; - OSUtils::ztsnprintf(tmp, sizeof(tmp), "com.zerotier.controller.lfdb:%s/network/%.16llx/online", controllerAddress, (unsigned long long)ns->first); - ms->second.lastOnlineAddress.toIpString(tmp2); - selector0["Name"] = tmp; - selector0["Ordinal"] = ms->first; - selector1["Name"] = tmp2; - selector1["Ordinal"] = 0; - selectors.push_back(selector0); - selectors.push_back(selector1); - newrec["Selectors"] = selectors; - const uint8_t* const rawip = (const uint8_t*)ms->second.lastOnlineAddress.rawIpData(); - switch (ms->second.lastOnlineAddress.ss_family) { - case AF_INET: - for (int j = 0; j < 4; ++j) - ip.push_back((unsigned int)rawip[j]); - break; - case AF_INET6: - for (int j = 0; j < 16; ++j) - ip.push_back((unsigned int)rawip[j]); - break; - default: - ip = tmp2; // should never happen since only IP transport is currently supported - break; - } - newrec["Value"] = ip; - newrec["OwnerPrivate"] = _lfOwnerPrivate; - newrec["MaskingKey"] = maskingKey; - newrec["Timestamp"] = ms->second.lastOnlineTime; - newrec["PulseIfUnchanged"] = true; - try { - auto resp = htcli.Post("/makerecord", newrec.dump(), "application/json"); - if (resp) { - if (resp->status == 200) { - ms->second.lastOnlineDirty = false; - // printf("SET member online %.16llx %.10llx %s\n",ns->first,ms->first,resp->body.c_str()); - } - else { - fprintf(stderr, "ERROR: LFDB: %d from node (create/update member online status): %s" ZT_EOL_S, resp->status, resp->body.c_str()); - } - } - else { - fprintf(stderr, "ERROR: LFDB: node is offline" ZT_EOL_S); - } - } - catch (std::exception& e) { - fprintf(stderr, "ERROR: LFDB: unexpected exception querying node (create/update member online status): %s" ZT_EOL_S, e.what()); - } - catch (...) { - fprintf(stderr, "ERROR: LFDB: unexpected exception querying node (create/update member online status): unknown exception" ZT_EOL_S); - } - } - - if (ms->second.dirty) { - nlohmann::json network, member; - if (get(ns->first, network, ms->first, member)) { - nlohmann::json newrec, selector0, selector1, selectors; - selector0["Name"] = networksSelectorName; - selector0["Ordinal"] = ns->first; - selector1["Name"] = "member"; - selector1["Ordinal"] = ms->first; - selectors.push_back(selector0); - selectors.push_back(selector1); - newrec["Selectors"] = selectors; - newrec["Value"] = member.dump(); - newrec["OwnerPrivate"] = _lfOwnerPrivate; - newrec["MaskingKey"] = maskingKey; - newrec["PulseIfUnchanged"] = true; - try { - auto resp = htcli.Post("/makerecord", newrec.dump(), "application/json"); - if (resp) { - if (resp->status == 200) { - ms->second.dirty = false; - // printf("SET member %.16llx %.10llx %s\n",ns->first,ms->first,resp->body.c_str()); - } - else { - fprintf(stderr, "ERROR: LFDB: %d from node (create/update member): %s" ZT_EOL_S, resp->status, resp->body.c_str()); - } - } - else { - fprintf(stderr, "ERROR: LFDB: node is offline" ZT_EOL_S); - } - } - catch (std::exception& e) { - fprintf(stderr, "ERROR: LFDB: unexpected exception querying node (create/update member): %s" ZT_EOL_S, e.what()); - } - catch (...) { - fprintf(stderr, "ERROR: LFDB: unexpected exception querying node (create/update member): unknown exception" ZT_EOL_S); - } - } - } - } - } - } - - try { - std::ostringstream query; - query << "{" - "\"Ranges\":[{" - "\"Name\":\"" - << networksSelectorName - << "\"," - "\"Range\":[0,18446744073709551615]" - "}]," - "\"TimeRange\":[" - << timeRangeStart - << ",9223372036854775807]," - "\"MaskingKey\":\"" - << maskingKey - << "\"," - "\"Owners\":[\"" - << _lfOwnerPublic - << "\"]" - "}"; - auto resp = htcli.Post("/query", query.str(), "application/json"); - if (resp) { - if (resp->status == 200) { - nlohmann::json results(OSUtils::jsonParse(resp->body)); - if ((results.is_array()) && (! results.empty())) { - for (std::size_t ri = 0; ri < results.size(); ++ri) { - nlohmann::json& rset = results[ri]; - if ((rset.is_array()) && (! rset.empty())) { - nlohmann::json& result = rset[0]; - if (result.is_object()) { - nlohmann::json& record = result["Record"]; - if (record.is_object()) { - const std::string recordValue = result["Value"]; - // printf("GET network %s\n",recordValue.c_str()); - nlohmann::json network(OSUtils::jsonParse(recordValue)); - if (network.is_object()) { - const std::string idstr = network["id"]; - const uint64_t id = Utils::hexStrToU64(idstr.c_str()); - if ((id >> 24) == controllerAddressInt) { // sanity check - - nlohmann::json oldNetwork; - if ((timeRangeStart > 0) && (get(id, oldNetwork))) { - const uint64_t revision = network["revision"]; - const uint64_t prevRevision = oldNetwork["revision"]; - if (prevRevision < revision) { - _networkChanged(oldNetwork, network, timeRangeStart > 0); - } - } - else { - nlohmann::json nullJson; - _networkChanged(nullJson, network, timeRangeStart > 0); - } - } - } - } - } - } - } - } - } - else { - fprintf(stderr, "ERROR: LFDB: %d from node (check for network updates): %s" ZT_EOL_S, resp->status, resp->body.c_str()); - } - } - else { - fprintf(stderr, "ERROR: LFDB: node is offline" ZT_EOL_S); - } - } - catch (std::exception& e) { - fprintf(stderr, "ERROR: LFDB: unexpected exception querying node (check for network updates): %s" ZT_EOL_S, e.what()); - } - catch (...) { - fprintf(stderr, "ERROR: LFDB: unexpected exception querying node (check for network updates): unknown exception" ZT_EOL_S); - } - - try { - std::ostringstream query; - query << "{" - "\"Ranges\":[{" - "\"Name\":\"" - << networksSelectorName - << "\"," - "\"Range\":[0,18446744073709551615]" - "},{" - "\"Name\":\"member\"," - "\"Range\":[0,18446744073709551615]" - "}]," - "\"TimeRange\":[" - << timeRangeStart - << ",9223372036854775807]," - "\"MaskingKey\":\"" - << maskingKey - << "\"," - "\"Owners\":[\"" - << _lfOwnerPublic - << "\"]" - "}"; - auto resp = htcli.Post("/query", query.str(), "application/json"); - if (resp) { - if (resp->status == 200) { - nlohmann::json results(OSUtils::jsonParse(resp->body)); - if ((results.is_array()) && (! results.empty())) { - for (std::size_t ri = 0; ri < results.size(); ++ri) { - nlohmann::json& rset = results[ri]; - if ((rset.is_array()) && (! rset.empty())) { - nlohmann::json& result = rset[0]; - if (result.is_object()) { - nlohmann::json& record = result["Record"]; - if (record.is_object()) { - const std::string recordValue = result["Value"]; - // printf("GET member %s\n",recordValue.c_str()); - nlohmann::json member(OSUtils::jsonParse(recordValue)); - if (member.is_object()) { - const std::string nwidstr = member["nwid"]; - const std::string idstr = member["id"]; - const uint64_t nwid = Utils::hexStrToU64(nwidstr.c_str()); - const uint64_t id = Utils::hexStrToU64(idstr.c_str()); - if ((id) && ((nwid >> 24) == controllerAddressInt)) { // sanity check - - nlohmann::json network, oldMember; - if ((timeRangeStart > 0) && (get(nwid, network, id, oldMember))) { - const uint64_t revision = member["revision"]; - const uint64_t prevRevision = oldMember["revision"]; - if (prevRevision < revision) - _memberChanged(oldMember, member, timeRangeStart > 0); - } - else if (hasNetwork(nwid)) { - nlohmann::json nullJson; - _memberChanged(nullJson, member, timeRangeStart > 0); - } - } - } - } - } - } - } - } - } - else { - fprintf(stderr, "ERROR: LFDB: %d from node (check for member updates): %s" ZT_EOL_S, resp->status, resp->body.c_str()); - } - } - else { - fprintf(stderr, "ERROR: LFDB: node is offline" ZT_EOL_S); - } - } - catch (std::exception& e) { - fprintf(stderr, "ERROR: LFDB: unexpected exception querying node (check for member updates): %s" ZT_EOL_S, e.what()); - } - catch (...) { - fprintf(stderr, "ERROR: LFDB: unexpected exception querying node (check for member updates): unknown exception" ZT_EOL_S); - } - - timeRangeStart = time(nullptr) - 120; // start next query 2m before now to avoid losing updates - _ready.store(true); - - for (int k = 0; k < 4; ++k) { // 2s delay between queries for remotely modified networks or members - if (! _running.load()) - return; - std::this_thread::sleep_for(std::chrono::milliseconds(500)); - } - } - }); -} - -LFDB::~LFDB() -{ - _running.store(false); - _syncThread.join(); -} - -bool LFDB::waitForReady() -{ - while (! _ready.load()) { - std::this_thread::sleep_for(std::chrono::milliseconds(500)); - } - return true; -} - -bool LFDB::isReady() -{ - return (_ready.load()); -} - -bool LFDB::save(nlohmann::json& record, bool notifyListeners) -{ - bool modified = false; - const std::string objtype = record["objtype"]; - if (objtype == "network") { - const uint64_t nwid = OSUtils::jsonIntHex(record["id"], 0ULL); - if (nwid) { - nlohmann::json old; - get(nwid, old); - if ((! old.is_object()) || (! _compareRecords(old, record))) { - record["revision"] = OSUtils::jsonInt(record["revision"], 0ULL) + 1ULL; - _networkChanged(old, record, notifyListeners); - { - std::lock_guard l(_state_l); - _state[nwid].dirty = true; - } - modified = true; - } - } - } - else if (objtype == "member") { - const uint64_t nwid = OSUtils::jsonIntHex(record["nwid"], 0ULL); - const uint64_t id = OSUtils::jsonIntHex(record["id"], 0ULL); - if ((id) && (nwid)) { - nlohmann::json network, old; - get(nwid, network, id, old); - if ((! old.is_object()) || (! _compareRecords(old, record))) { - record["revision"] = OSUtils::jsonInt(record["revision"], 0ULL) + 1ULL; - _memberChanged(old, record, notifyListeners); - { - std::lock_guard l(_state_l); - _state[nwid].members[id].dirty = true; - } - modified = true; - } - } - } - return modified; -} - -void LFDB::eraseNetwork(const uint64_t networkId) -{ - // TODO -} - -void LFDB::eraseMember(const uint64_t networkId, const uint64_t memberId) -{ - // TODO -} - -void LFDB::nodeIsOnline(const uint64_t networkId, const uint64_t memberId, const InetAddress& physicalAddress, const char* osArch) -{ - std::lock_guard l(_state_l); - auto nw = _state.find(networkId); - if (nw != _state.end()) { - auto m = nw->second.members.find(memberId); - if (m != nw->second.members.end()) { - m->second.lastOnlineTime = OSUtils::now(); - if (physicalAddress) - m->second.lastOnlineAddress = physicalAddress; - m->second.lastOnlineDirty = true; - } - } -} - -void LFDB::nodeIsOnline(const uint64_t networkId, const uint64_t memberId, const InetAddress& physicalAddress) -{ - this->nodeIsOnline(networkId, memberId, physicalAddress, "unknown/unknown"); -} - -} // namespace ZeroTier diff --git a/nonfree/controller/LFDB.hpp b/nonfree/controller/LFDB.hpp deleted file mode 100644 index 3632e483f..000000000 --- a/nonfree/controller/LFDB.hpp +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Copyright (c)2019 ZeroTier, Inc. - * - * Use of this software is governed by the Business Source License included - * in the LICENSE.TXT file in the project's root directory. - * - * Change Date: 2026-01-01 - * - * On the date above, in accordance with the Business Source License, use - * of this software will be governed by version 2.0 of the Apache License. - */ -/****/ - -#ifndef ZT_CONTROLLER_LFDB_HPP -#define ZT_CONTROLLER_LFDB_HPP - -#include "DB.hpp" - -#include -#include -#include -#include - -namespace ZeroTier { - -/** - * DB implementation for controller that stores data in LF - */ -class LFDB : public DB { - public: - /** - * @param myId This controller's identity - * @param path Base path for ZeroTier node itself - * @param lfOwnerPrivate LF owner private in PEM format - * @param lfOwnerPublic LF owner public in @base62 format - * @param lfNodeHost LF node host - * @param lfNodePort LF node http (not https) port - * @param storeOnlineState If true, store online/offline state and IP info in LF (a lot of data, only for private networks!) - */ - LFDB(const Identity& myId, const char* path, const char* lfOwnerPrivate, const char* lfOwnerPublic, const char* lfNodeHost, int lfNodePort, bool storeOnlineState); - virtual ~LFDB(); - - virtual bool waitForReady(); - virtual bool isReady(); - virtual bool save(nlohmann::json& record, bool notifyListeners); - virtual void eraseNetwork(const uint64_t networkId); - virtual void eraseMember(const uint64_t networkId, const uint64_t memberId); - virtual void nodeIsOnline(const uint64_t networkId, const uint64_t memberId, const InetAddress& physicalAddress); - virtual void nodeIsOnline(const uint64_t networkId, const uint64_t memberId, const InetAddress& physicalAddress, const char* osArch); - - protected: - const Identity _myId; - - std::string _lfOwnerPrivate, _lfOwnerPublic; - std::string _lfNodeHost; - int _lfNodePort; - - struct _MemberState { - _MemberState() : lastOnlineAddress(), lastOnlineTime(0), dirty(false), lastOnlineDirty(false) - { - } - InetAddress lastOnlineAddress; - int64_t lastOnlineTime; - bool dirty; - bool lastOnlineDirty; - }; - struct _NetworkState { - _NetworkState() : members(), dirty(false) - { - } - std::unordered_map members; - bool dirty; - }; - std::unordered_map _state; - std::mutex _state_l; - - std::atomic_bool _running; - std::atomic_bool _ready; - std::thread _syncThread; - bool _storeOnlineState; -}; - -} // namespace ZeroTier - -#endif diff --git a/nonfree/controller/PostgreSQL.cpp b/nonfree/controller/PostgreSQL.cpp index 3bc864601..57dab6c7e 100644 --- a/nonfree/controller/PostgreSQL.cpp +++ b/nonfree/controller/PostgreSQL.cpp @@ -1,3 +1,7 @@ +/* (c) ZeroTier, Inc. + * See LICENSE.txt in nonfree/ + */ + #ifdef ZT_CONTROLLER_USE_LIBPQ #include "PostgreSQL.hpp" @@ -8,4 +12,4 @@ using namespace nlohmann; using namespace ZeroTier; -#endif \ No newline at end of file +#endif diff --git a/nonfree/controller/PostgreSQL.hpp b/nonfree/controller/PostgreSQL.hpp index 41f36e3c5..af40d6467 100644 --- a/nonfree/controller/PostgreSQL.hpp +++ b/nonfree/controller/PostgreSQL.hpp @@ -1,15 +1,6 @@ -/* - * Copyright (c)2025 ZeroTier, Inc. - * - * Use of this software is governed by the Business Source License included - * in the LICENSE.TXT file in the project's root directory. - * - * Change Date: 2026-01-01 - * - * On the date above, in accordance with the Business Source License, use - * of this software will be governed by version 2.0 of the Apache License. +/* (c) ZeroTier, Inc. + * See LICENSE.txt in nonfree/ */ -/****/ #ifdef ZT_CONTROLLER_USE_LIBPQ @@ -192,4 +183,4 @@ struct NodeOnlineRecord { #endif // ZT_CONTROLLER_POSTGRESQL_HPP -#endif // ZT_CONTROLLER_USE_LIBPQ \ No newline at end of file +#endif // ZT_CONTROLLER_USE_LIBPQ diff --git a/nonfree/controller/Redis.hpp b/nonfree/controller/Redis.hpp index c6845d517..cc02cb97d 100644 --- a/nonfree/controller/Redis.hpp +++ b/nonfree/controller/Redis.hpp @@ -1,3 +1,7 @@ +/* (c) ZeroTier, Inc. + * See LICENSE.txt in nonfree/ + */ + #ifndef ZT_CONTROLLER_REDIS_HPP #define ZT_CONTROLLER_REDIS_HPP @@ -12,4 +16,4 @@ struct RedisConfig { }; } // namespace ZeroTier -#endif \ No newline at end of file +#endif diff --git a/objects.mk b/objects.mk index d6e2ee308..5f6f636c7 100644 --- a/objects.mk +++ b/objects.mk @@ -38,7 +38,6 @@ ONE_OBJS=\ nonfree/controller/DBMirrorSet.o \ nonfree/controller/DB.o \ nonfree/controller/FileDB.o \ - nonfree/controller/LFDB.o \ nonfree/controller/CtlUtil.o \ nonfree/controller/CV1.o \ nonfree/controller/CV2.o \