Browse Source

Remove ancient unused LFDB code and change license notice in controller files.

Adam Ierymenko 1 month ago
parent
commit
c668990b4d

+ 5 - 14
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"

+ 2 - 11
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"
 

+ 8 - 17
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
+#endif	 // ZT_CONTROLLER_USE_LIBPQ

+ 65 - 74
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 <pqxx/pqxx>
 #include <redis++/redis++.h>
 
-namespace ZeroTier {
-
-class CV2 : public DB {
-	friend class MemberNotificationReceiver<CV2>;
-	friend class NetworkNotificationReceiver<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 ready()
-	{
-		return _ready == 2;
-	}
-
-  protected:
-	struct _PairHasher {
-		inline std::size_t operator()(const std::pair<uint64_t, uint64_t>& p) const
+	namespace ZeroTier
+{
+	class CV2 : public DB {
+		friend class MemberNotificationReceiver<CV2>;
+		friend class NetworkNotificationReceiver<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 ready()
 		{
-			return (std::size_t)(p.first ^ p.second);
+			return _ready == 2;
 		}
-	};
-	virtual void _memberChanged(nlohmann::json& old, nlohmann::json& memberConfig, bool notifyListeners);
 
-	virtual void _networkChanged(nlohmann::json& old, nlohmann::json& networkConfig, bool notifyListeners);
+	  protected:
+		struct _PairHasher {
+			inline std::size_t operator()(const std::pair<uint64_t, uint64_t>& 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();
+	  private:
+		void initializeNetworks();
+		void initializeMembers();
+		void heartbeat();
+		void membersDbWatcher();
+		void networksDbWatcher();
 
-	void commitThread();
-	void onlineNotificationThread();
+		void commitThread();
+		void onlineNotificationThread();
 
-	// void notifyNewMember(const std::string &networkID, const std::string &memberID);
+		// void notifyNewMember(const std::string &networkID, const std::string &memberID);
 
-	enum OverrideMode { ALLOW_PGBOUNCER_OVERRIDE = 0, NO_OVERRIDE = 1 };
+		enum OverrideMode { ALLOW_PGBOUNCER_OVERRIDE = 0, NO_OVERRIDE = 1 };
 
-	std::shared_ptr<ConnectionPool<PostgresConnection> > _pool;
+		std::shared_ptr<ConnectionPool<PostgresConnection> > _pool;
 
-	const Identity _myId;
-	const Address _myAddress;
-	std::string _myAddressStr;
-	std::string _connString;
+		const Identity _myId;
+		const Address _myAddress;
+		std::string _myAddressStr;
+		std::string _connString;
 
-	BlockingQueue<std::pair<nlohmann::json, bool> > _commitQueue;
+		BlockingQueue<std::pair<nlohmann::json, bool> > _commitQueue;
 
-	std::thread _heartbeatThread;
-	std::thread _membersDbWatcher;
-	std::thread _networksDbWatcher;
-	std::thread _commitThread[ZT_CENTRAL_CONTROLLER_COMMIT_THREADS];
-	std::thread _onlineNotificationThread;
+		std::thread _heartbeatThread;
+		std::thread _membersDbWatcher;
+		std::thread _networksDbWatcher;
+		std::thread _commitThread[ZT_CENTRAL_CONTROLLER_COMMIT_THREADS];
+		std::thread _onlineNotificationThread;
 
-	std::unordered_map<std::pair<uint64_t, uint64_t>, NodeOnlineRecord, _PairHasher> _lastOnline;
+		std::unordered_map<std::pair<uint64_t, uint64_t>, NodeOnlineRecord, _PairHasher> _lastOnline;
 
-	mutable std::mutex _lastOnline_l;
-	mutable std::mutex _readyLock;
-	std::atomic<int> _ready, _connected, _run;
-	mutable volatile bool _waitNoticePrinted;
+		mutable std::mutex _lastOnline_l;
+		mutable std::mutex _readyLock;
+		std::atomic<int> _ready, _connected, _run;
+		mutable volatile bool _waitNoticePrinted;
 
-	int _listenPort;
-	uint8_t _ssoPsk[48];
-};
+		int _listenPort;
+		uint8_t _ssoPsk[48];
+	};
 
 }	// namespace ZeroTier
 
 #endif	 // ZT_CONTROLLER_CV2_HPP
-#endif	 // ZT_CONTROLLER_USE_LIBPQ
+#endif	 // ZT_CONTROLLER_USE_LIBPQ

+ 3 - 13
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 <deque>
@@ -26,7 +17,6 @@
 #include <memory>
 #include <mutex>
 #include <set>
-#include <string>
 
 namespace ZeroTier {
 

+ 5 - 1
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
+#endif

+ 5 - 1
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<std::string> split(std::string str, char delim);
 std::string url_encode(const std::string& value);
 }	// namespace ZeroTier
 
-#endif	 // namespace ZeroTier
+#endif	 // namespace ZeroTier

+ 3 - 12
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"
 

+ 7 - 16
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 <atomic>
 #include <map>

+ 2 - 11
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"
 

+ 2 - 11
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

+ 3 - 43
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 <stdint.h>
 #include <stdio.h>
@@ -20,10 +11,9 @@
 #ifndef _WIN32
 #include <sys/time.h>
 #endif
-#include "../include/ZeroTierOne.h"
+#include "../../include/ZeroTierOne.h"
 #include "EmbeddedNetworkController.hpp"
 #include "FileDB.hpp"
-#include "LFDB.hpp"
 
 #include <algorithm>
 #include <cctype>
@@ -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<DB>(new LFDB(_signingId, _path.c_str(), lfOwner.c_str(), lfOwnerPublic.c_str(), lfHost.c_str(), lfPort, storeOnlineState)));
-							}
-						}
-					}
-				}
-			}
-		}
-	}
-
 	_db.waitForReady();
 }
 

+ 6 - 15
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"
 

+ 2 - 11
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"
 

+ 2 - 11
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

+ 0 - 443
nonfree/controller/LFDB.cpp

@@ -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 <chrono>
-#include <iostream>
-#include <sstream>
-#include <thread>
-
-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<std::mutex> 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<std::mutex> 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<std::mutex> 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<std::mutex> 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

+ 0 - 85
nonfree/controller/LFDB.hpp

@@ -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 <atomic>
-#include <mutex>
-#include <string>
-#include <unordered_map>
-
-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<uint64_t, _MemberState> members;
-		bool dirty;
-	};
-	std::unordered_map<uint64_t, _NetworkState> _state;
-	std::mutex _state_l;
-
-	std::atomic_bool _running;
-	std::atomic_bool _ready;
-	std::thread _syncThread;
-	bool _storeOnlineState;
-};
-
-}	// namespace ZeroTier
-
-#endif

+ 5 - 1
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
+#endif

+ 3 - 12
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
+#endif	 // ZT_CONTROLLER_USE_LIBPQ

+ 5 - 1
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
+#endif

+ 0 - 1
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 \