mirror of
https://github.com/ZeroTier/ZeroTierOne
synced 2025-07-05 12:36:14 -07:00
Merge branch 'dev' into dev-extosdep
# Conflicts: # controller/DB.hpp # controller/DBMirrorSet.cpp # controller/DBMirrorSet.hpp # controller/EmbeddedNetworkController.cpp # controller/FileDB.cpp # controller/FileDB.hpp # controller/LFDB.cpp # controller/LFDB.hpp # controller/PostgreSQL.cpp # controller/PostgreSQL.hpp # node/Metrics.cpp # node/Metrics.hpp # osdep/EthernetTap.cpp # osdep/Http.hpp # osdep/ManagedRoute.cpp # service/OneService.cpp
This commit is contained in:
commit
69de477d0b
39 changed files with 3625 additions and 2184 deletions
5
.github/workflows/build.yml
vendored
5
.github/workflows/build.yml
vendored
|
@ -1,4 +1,7 @@
|
|||
on: [ push ]
|
||||
on:
|
||||
pull_request:
|
||||
push:
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
build_ubuntu:
|
||||
|
|
1
.github/workflows/validate.yml
vendored
1
.github/workflows/validate.yml
vendored
|
@ -1,4 +1,5 @@
|
|||
on:
|
||||
pull_request:
|
||||
push:
|
||||
workflow_dispatch:
|
||||
|
||||
|
|
3
Makefile
3
Makefile
|
@ -31,3 +31,6 @@ drone:
|
|||
@echo "rendering .drone.yaml from .drone.jsonnet"
|
||||
drone jsonnet --format --stream
|
||||
drone sign zerotier/ZeroTierOne --save
|
||||
|
||||
clang-format:
|
||||
find node osdep service tcp-proxy controller -iname '*.cpp' -o -iname '*.hpp' | xargs clang-format -i
|
||||
|
|
|
@ -64,6 +64,7 @@ You can control a few settings including the identity used and the authtoken use
|
|||
- `ZEROTIER_API_SECRET`: replaces the `authtoken.secret` before booting and allows you to manage the control socket's authentication key.
|
||||
- `ZEROTIER_IDENTITY_PUBLIC`: the `identity.public` file for zerotier-one. Use `zerotier-idtool` to generate one of these for you.
|
||||
- `ZEROTIER_IDENTITY_SECRET`: the `identity.secret` file for zerotier-one. Use `zerotier-idtool` to generate one of these for you.
|
||||
- `ZEROTIER_LOCAL_CONF`: Sets the the `local.conf` file content for zerotier-one
|
||||
|
||||
### Tips
|
||||
|
||||
|
|
1952
controller/CV1.cpp
Normal file
1952
controller/CV1.cpp
Normal file
File diff suppressed because it is too large
Load diff
141
controller/CV1.hpp
Normal file
141
controller/CV1.hpp
Normal file
|
@ -0,0 +1,141 @@
|
|||
/*
|
||||
* 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 "DB.hpp"
|
||||
|
||||
#ifdef ZT_CONTROLLER_USE_LIBPQ
|
||||
|
||||
#ifndef ZT_CONTROLLER_CV1_HPP
|
||||
#define ZT_CONTROLLER_CV1_HPP
|
||||
|
||||
#define ZT_CENTRAL_CONTROLLER_COMMIT_THREADS 4
|
||||
|
||||
#include "../node/Metrics.hpp"
|
||||
#include "ConnectionPool.hpp"
|
||||
#include "PostgreSQL.hpp"
|
||||
|
||||
#include <memory>
|
||||
#include <pqxx/pqxx>
|
||||
#include <redis++/redis++.h>
|
||||
|
||||
namespace smeeclient {
|
||||
struct SmeeClient;
|
||||
}
|
||||
|
||||
namespace ZeroTier {
|
||||
|
||||
struct RedisConfig;
|
||||
|
||||
/**
|
||||
* A controller database driver that talks to PostgreSQL
|
||||
*
|
||||
* This is for use with ZeroTier Central. Others are free to build and use it
|
||||
* but be aware that we might change it at any time.
|
||||
*/
|
||||
class CV1 : public DB {
|
||||
public:
|
||||
CV1(const Identity& myId, const char* path, int listenPort, RedisConfig* rc);
|
||||
virtual ~CV1();
|
||||
|
||||
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
|
||||
{
|
||||
return (std::size_t)(p.first ^ p.second);
|
||||
}
|
||||
};
|
||||
virtual void _memberChanged(nlohmann::json& old, nlohmann::json& memberConfig, bool notifyListeners)
|
||||
{
|
||||
DB::_memberChanged(old, memberConfig, notifyListeners);
|
||||
}
|
||||
|
||||
virtual void _networkChanged(nlohmann::json& old, nlohmann::json& networkConfig, bool notifyListeners)
|
||||
{
|
||||
DB::_networkChanged(old, networkConfig, notifyListeners);
|
||||
}
|
||||
|
||||
private:
|
||||
void initializeNetworks();
|
||||
void initializeMembers();
|
||||
void heartbeat();
|
||||
void membersDbWatcher();
|
||||
void _membersWatcher_Postgres();
|
||||
void networksDbWatcher();
|
||||
void _networksWatcher_Postgres();
|
||||
|
||||
void _membersWatcher_Redis();
|
||||
void _networksWatcher_Redis();
|
||||
|
||||
void commitThread();
|
||||
void onlineNotificationThread();
|
||||
void onlineNotification_Postgres();
|
||||
void onlineNotification_Redis();
|
||||
uint64_t _doRedisUpdate(sw::redis::Transaction& tx, std::string& controllerId, std::unordered_map<std::pair<uint64_t, uint64_t>, NodeOnlineRecord, _PairHasher>& lastOnline);
|
||||
|
||||
void configureSmee();
|
||||
void notifyNewMember(const std::string& networkID, const std::string& memberID);
|
||||
|
||||
enum OverrideMode { ALLOW_PGBOUNCER_OVERRIDE = 0, NO_OVERRIDE = 1 };
|
||||
|
||||
std::shared_ptr<ConnectionPool<PostgresConnection> > _pool;
|
||||
|
||||
const Identity _myId;
|
||||
const Address _myAddress;
|
||||
std::string _myAddressStr;
|
||||
std::string _connString;
|
||||
|
||||
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::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;
|
||||
|
||||
int _listenPort;
|
||||
uint8_t _ssoPsk[48];
|
||||
|
||||
RedisConfig* _rc;
|
||||
std::shared_ptr<sw::redis::Redis> _redis;
|
||||
std::shared_ptr<sw::redis::RedisCluster> _cluster;
|
||||
bool _redisMemberStatus;
|
||||
|
||||
smeeclient::SmeeClient* _smee;
|
||||
};
|
||||
|
||||
} // namespace ZeroTier
|
||||
|
||||
#endif // ZT_CONTROLLER_CV1_HPP
|
||||
|
||||
#endif // ZT_CONTROLLER_USE_LIBPQ
|
1104
controller/CV2.cpp
Normal file
1104
controller/CV2.cpp
Normal file
File diff suppressed because it is too large
Load diff
112
controller/CV2.hpp
Normal file
112
controller/CV2.hpp
Normal file
|
@ -0,0 +1,112 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
/****/
|
||||
|
||||
#include "DB.hpp"
|
||||
|
||||
#ifdef ZT_CONTROLLER_USE_LIBPQ
|
||||
|
||||
#ifndef ZT_CONTROLLER_CV2_HPP
|
||||
#define ZT_CONTROLLER_CV2_HPP
|
||||
|
||||
#define ZT_CENTRAL_CONTROLLER_COMMIT_THREADS 4
|
||||
|
||||
#include "../node/Metrics.hpp"
|
||||
#include "ConnectionPool.hpp"
|
||||
#include "PostgreSQL.hpp"
|
||||
|
||||
#include <memory>
|
||||
#include <pqxx/pqxx>
|
||||
#include <redis++/redis++.h>
|
||||
|
||||
namespace ZeroTier {
|
||||
|
||||
class CV2 : public DB {
|
||||
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
|
||||
{
|
||||
return (std::size_t)(p.first ^ p.second);
|
||||
}
|
||||
};
|
||||
virtual void _memberChanged(nlohmann::json& old, nlohmann::json& memberConfig, bool notifyListeners)
|
||||
{
|
||||
DB::_memberChanged(old, memberConfig, notifyListeners);
|
||||
}
|
||||
|
||||
virtual void _networkChanged(nlohmann::json& old, nlohmann::json& networkConfig, bool notifyListeners)
|
||||
{
|
||||
DB::_networkChanged(old, networkConfig, 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<ConnectionPool<PostgresConnection> > _pool;
|
||||
|
||||
const Identity _myId;
|
||||
const Address _myAddress;
|
||||
std::string _myAddressStr;
|
||||
std::string _connString;
|
||||
|
||||
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::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;
|
||||
|
||||
int _listenPort;
|
||||
uint8_t _ssoPsk[48];
|
||||
};
|
||||
|
||||
} // namespace ZeroTier
|
||||
|
||||
#endif // ZT_CONTROLLER_CV2_HPP
|
||||
#endif // ZT_CONTROLLER_USE_LIBPQ
|
64
controller/CtlUtil.cpp
Normal file
64
controller/CtlUtil.cpp
Normal file
|
@ -0,0 +1,64 @@
|
|||
#include "CtlUtil.hpp"
|
||||
|
||||
#ifdef ZT_CONTROLLER_USE_LIBPQ
|
||||
|
||||
#include <iomanip>
|
||||
#include <sstream>
|
||||
|
||||
namespace ZeroTier {
|
||||
|
||||
const char* _timestr()
|
||||
{
|
||||
time_t t = time(0);
|
||||
char* ts = ctime(&t);
|
||||
char* p = ts;
|
||||
if (! p)
|
||||
return "";
|
||||
while (*p) {
|
||||
if (*p == '\n') {
|
||||
*p = (char)0;
|
||||
break;
|
||||
}
|
||||
++p;
|
||||
}
|
||||
return ts;
|
||||
}
|
||||
|
||||
std::vector<std::string> split(std::string str, char delim)
|
||||
{
|
||||
std::istringstream iss(str);
|
||||
std::vector<std::string> tokens;
|
||||
std::string item;
|
||||
while (std::getline(iss, item, delim)) {
|
||||
tokens.push_back(item);
|
||||
}
|
||||
return tokens;
|
||||
}
|
||||
|
||||
std::string url_encode(const std::string& value)
|
||||
{
|
||||
std::ostringstream escaped;
|
||||
escaped.fill('0');
|
||||
escaped << std::hex;
|
||||
|
||||
for (std::string::const_iterator i = value.begin(), n = value.end(); i != n; ++i) {
|
||||
std::string::value_type c = (*i);
|
||||
|
||||
// Keep alphanumeric and other accepted characters intact
|
||||
if (isalnum(c) || c == '-' || c == '_' || c == '.' || c == '~') {
|
||||
escaped << c;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Any other characters are percent-encoded
|
||||
escaped << std::uppercase;
|
||||
escaped << '%' << std::setw(2) << int((unsigned char)c);
|
||||
escaped << std::nouppercase;
|
||||
}
|
||||
|
||||
return escaped.str();
|
||||
}
|
||||
|
||||
} // namespace ZeroTier
|
||||
|
||||
#endif
|
16
controller/CtlUtil.hpp
Normal file
16
controller/CtlUtil.hpp
Normal file
|
@ -0,0 +1,16 @@
|
|||
#ifndef ZT_CTLUTIL_HPP
|
||||
#define ZT_CTLUTIL_HPP
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace ZeroTier {
|
||||
|
||||
const char* _timestr();
|
||||
|
||||
std::vector<std::string> split(std::string str, char delim);
|
||||
|
||||
std::string url_encode(const std::string& value);
|
||||
} // namespace ZeroTier
|
||||
|
||||
#endif // namespace ZeroTier
|
|
@ -61,6 +61,10 @@ struct AuthInfo {
|
|||
* Base class with common infrastructure for all controller DB implementations
|
||||
*/
|
||||
class DB {
|
||||
#ifdef ZT_CONTROLLER_USE_LIBPQ
|
||||
friend class MemberNotificationReceiver;
|
||||
friend class NetworkNotificationReceiver;
|
||||
#endif
|
||||
public:
|
||||
class ChangeListener {
|
||||
public:
|
||||
|
@ -132,6 +136,7 @@ class DB {
|
|||
virtual void eraseNetwork(const uint64_t networkId) = 0;
|
||||
virtual void eraseMember(const uint64_t networkId, const uint64_t memberId) = 0;
|
||||
virtual void nodeIsOnline(const uint64_t networkId, const uint64_t memberId, const InetAddress& physicalAddress) = 0;
|
||||
virtual void nodeIsOnline(const uint64_t networkId, const uint64_t memberId, const InetAddress& physicalAddress, const char* osArch) = 0;
|
||||
|
||||
virtual AuthInfo getSSOAuthInfo(const nlohmann::json& member, const std::string& redirectURL)
|
||||
{
|
||||
|
|
|
@ -205,14 +205,19 @@ void DBMirrorSet::eraseMember(const uint64_t networkId, const uint64_t memberId)
|
|||
}
|
||||
}
|
||||
|
||||
void DBMirrorSet::nodeIsOnline(const uint64_t networkId, const uint64_t memberId, const InetAddress& physicalAddress)
|
||||
void DBMirrorSet::nodeIsOnline(const uint64_t networkId, const uint64_t memberId, const InetAddress& physicalAddress, const char* osArch)
|
||||
{
|
||||
std::shared_lock<std::shared_mutex> l(_dbs_l);
|
||||
for (auto d = _dbs.begin(); d != _dbs.end(); ++d) {
|
||||
(*d)->nodeIsOnline(networkId, memberId, physicalAddress);
|
||||
(*d)->nodeIsOnline(networkId, memberId, physicalAddress, osArch);
|
||||
}
|
||||
}
|
||||
|
||||
void DBMirrorSet::nodeIsOnline(const uint64_t networkId, const uint64_t memberId, const InetAddress& physicalAddress)
|
||||
{
|
||||
this->nodeIsOnline(networkId, memberId, physicalAddress, "unknown/unknown");
|
||||
}
|
||||
|
||||
void DBMirrorSet::onNetworkUpdate(const void* db, uint64_t networkId, const nlohmann::json& network)
|
||||
{
|
||||
nlohmann::json record(network);
|
||||
|
|
|
@ -43,7 +43,8 @@ class DBMirrorSet : public DB::ChangeListener {
|
|||
bool save(nlohmann::json& record, bool notifyListeners);
|
||||
void eraseNetwork(const uint64_t networkId);
|
||||
void eraseMember(const uint64_t networkId, const uint64_t memberId);
|
||||
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);
|
||||
virtual void nodeIsOnline(const uint64_t networkId, const uint64_t memberId, const InetAddress& physicalAddress, const char* osArch);
|
||||
|
||||
// These are called by various DB instances when changes occur.
|
||||
virtual void onNetworkUpdate(const void* db, uint64_t networkId, const nlohmann::json& network);
|
||||
|
|
|
@ -38,7 +38,8 @@
|
|||
#include <thread>
|
||||
#include <utility>
|
||||
#ifdef ZT_CONTROLLER_USE_LIBPQ
|
||||
#include "PostgreSQL.hpp"
|
||||
#include "CV1.hpp"
|
||||
#include "CV2.hpp"
|
||||
#endif
|
||||
|
||||
#include "../node/CertificateOfMembership.hpp"
|
||||
|
@ -594,9 +595,15 @@ void EmbeddedNetworkController::init(const Identity& signingId, Sender* sender)
|
|||
|
||||
#ifdef ZT_CONTROLLER_USE_LIBPQ
|
||||
if ((_path.length() > 9) && (_path.substr(0, 9) == "postgres:")) {
|
||||
_db.addDB(std::shared_ptr<DB>(new PostgreSQL(_signingId, _path.substr(9).c_str(), _listenPort, _rc)));
|
||||
fprintf(stderr, "CV1\n");
|
||||
_db.addDB(std::shared_ptr<DB>(new CV1(_signingId, _path.substr(9).c_str(), _listenPort, _rc)));
|
||||
}
|
||||
else if ((_path.length() > 4) && (_path.substr(0, 4) == "cv2:")) {
|
||||
fprintf(stderr, "CV2\n");
|
||||
_db.addDB(std::shared_ptr<DB>(new CV2(_signingId, _path.substr(4).c_str(), _listenPort)));
|
||||
}
|
||||
else {
|
||||
fprintf(stderr, "FileDB\n");
|
||||
#endif
|
||||
_db.addDB(std::shared_ptr<DB>(new FileDB(_path.c_str())));
|
||||
#ifdef ZT_CONTROLLER_USE_LIBPQ
|
||||
|
@ -1496,7 +1503,11 @@ void EmbeddedNetworkController::_request(uint64_t nwid, const InetAddress& fromA
|
|||
c2++;
|
||||
b2.start();
|
||||
#endif
|
||||
_db.nodeIsOnline(nwid, identity.address().toInt(), fromAddr);
|
||||
char osArch[256];
|
||||
metaData.get(ZT_NETWORKCONFIG_REQUEST_METADATA_KEY_OS_ARCH, osArch, sizeof(osArch));
|
||||
// fprintf(stderr, "Network Config Request: nwid=%.16llx, nodeid=%.10llx, osArch=%s\n",
|
||||
// nwid, identity.address().toInt(), osArch);
|
||||
_db.nodeIsOnline(nwid, identity.address().toInt(), fromAddr, osArch);
|
||||
#ifdef CENTRAL_CONTROLLER_REQUEST_BENCHMARK
|
||||
b2.stop();
|
||||
|
||||
|
@ -1650,6 +1661,7 @@ void EmbeddedNetworkController::_request(uint64_t nwid, const InetAddress& fromA
|
|||
authInfo.add(ZT_AUTHINFO_DICT_KEY_NONCE, info.ssoNonce.c_str());
|
||||
authInfo.add(ZT_AUTHINFO_DICT_KEY_STATE, info.ssoState.c_str());
|
||||
authInfo.add(ZT_AUTHINFO_DICT_KEY_CLIENT_ID, info.ssoClientID.c_str());
|
||||
authInfo.add(ZT_AUTHINFO_DICT_KEY_SSO_PROVIDER, info.ssoProvider.c_str());
|
||||
_sender->ncSendError(nwid, requestPacketId, identity.address(), NetworkController::NC_ERROR_AUTHENTICATION_REQUIRED, authInfo.data(), authInfo.sizeBytes());
|
||||
}
|
||||
DB::cleanMember(member);
|
||||
|
|
|
@ -160,7 +160,7 @@ void FileDB::eraseMember(const uint64_t networkId, const uint64_t memberId)
|
|||
this->_online[networkId].erase(memberId);
|
||||
}
|
||||
|
||||
void FileDB::nodeIsOnline(const uint64_t networkId, const uint64_t memberId, const InetAddress& physicalAddress)
|
||||
void FileDB::nodeIsOnline(const uint64_t networkId, const uint64_t memberId, const InetAddress& physicalAddress, const char* osArch)
|
||||
{
|
||||
char mid[32], atmp[64];
|
||||
OSUtils::ztsnprintf(mid, sizeof(mid), "%.10llx", (unsigned long long)memberId);
|
||||
|
@ -169,4 +169,9 @@ void FileDB::nodeIsOnline(const uint64_t networkId, const uint64_t memberId, con
|
|||
this->_online[networkId][memberId][OSUtils::now()] = physicalAddress;
|
||||
}
|
||||
|
||||
void FileDB::nodeIsOnline(const uint64_t networkId, const uint64_t memberId, const InetAddress& physicalAddress)
|
||||
{
|
||||
this->nodeIsOnline(networkId, memberId, physicalAddress, "unknown/unknown");
|
||||
}
|
||||
|
||||
} // namespace ZeroTier
|
||||
|
|
|
@ -29,6 +29,7 @@ class FileDB : public DB {
|
|||
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:
|
||||
std::string _path;
|
||||
|
|
|
@ -420,7 +420,7 @@ 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)
|
||||
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);
|
||||
|
@ -435,4 +435,9 @@ void LFDB::nodeIsOnline(const uint64_t networkId, const uint64_t memberId, const
|
|||
}
|
||||
}
|
||||
|
||||
void LFDB::nodeIsOnline(const uint64_t networkId, const uint64_t memberId, const InetAddress& physicalAddress)
|
||||
{
|
||||
this->nodeIsOnline(networkId, memberId, physicalAddress, "unknown/unknown");
|
||||
}
|
||||
|
||||
} // namespace ZeroTier
|
||||
|
|
|
@ -46,6 +46,7 @@ class LFDB : public DB {
|
|||
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;
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c)2019 ZeroTier, Inc.
|
||||
* 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.
|
||||
|
@ -11,34 +11,23 @@
|
|||
*/
|
||||
/****/
|
||||
|
||||
#include "DB.hpp"
|
||||
|
||||
#ifdef ZT_CONTROLLER_USE_LIBPQ
|
||||
|
||||
#ifndef ZT_CONTROLLER_LIBPQ_HPP
|
||||
#define ZT_CONTROLLER_LIBPQ_HPP
|
||||
#ifndef ZT_CONTROLLER_POSTGRESQL_HPP
|
||||
#define ZT_CONTROLLER_POSTGRESQL_HPP
|
||||
|
||||
#define ZT_CENTRAL_CONTROLLER_COMMIT_THREADS 4
|
||||
|
||||
#include "../node/Metrics.hpp"
|
||||
#include "ConnectionPool.hpp"
|
||||
#include "DB.hpp"
|
||||
|
||||
#include <memory>
|
||||
#include <pqxx/pqxx>
|
||||
#include <redis++/redis++.h>
|
||||
|
||||
namespace ZeroTier {
|
||||
|
||||
extern "C" {
|
||||
typedef struct pg_conn PGconn;
|
||||
}
|
||||
|
||||
namespace smeeclient {
|
||||
struct SmeeClient;
|
||||
}
|
||||
|
||||
namespace ZeroTier {
|
||||
|
||||
struct RedisConfig;
|
||||
|
||||
class PostgresConnection : public Connection {
|
||||
public:
|
||||
virtual ~PostgresConnection()
|
||||
|
@ -67,11 +56,9 @@ class PostgresConnFactory : public ConnectionFactory {
|
|||
std::string m_connString;
|
||||
};
|
||||
|
||||
class PostgreSQL;
|
||||
|
||||
class MemberNotificationReceiver : public pqxx::notification_receiver {
|
||||
public:
|
||||
MemberNotificationReceiver(PostgreSQL* p, pqxx::connection& c, const std::string& channel);
|
||||
MemberNotificationReceiver(DB* p, pqxx::connection& c, const std::string& channel);
|
||||
virtual ~MemberNotificationReceiver()
|
||||
{
|
||||
fprintf(stderr, "MemberNotificationReceiver destroyed\n");
|
||||
|
@ -80,12 +67,12 @@ class MemberNotificationReceiver : public pqxx::notification_receiver {
|
|||
virtual void operator()(const std::string& payload, int backendPid);
|
||||
|
||||
private:
|
||||
PostgreSQL* _psql;
|
||||
DB* _psql;
|
||||
};
|
||||
|
||||
class NetworkNotificationReceiver : public pqxx::notification_receiver {
|
||||
public:
|
||||
NetworkNotificationReceiver(PostgreSQL* p, pqxx::connection& c, const std::string& channel);
|
||||
NetworkNotificationReceiver(DB* p, pqxx::connection& c, const std::string& channel);
|
||||
virtual ~NetworkNotificationReceiver()
|
||||
{
|
||||
fprintf(stderr, "NetworkNotificationReceiver destroyed\n");
|
||||
|
@ -94,106 +81,17 @@ class NetworkNotificationReceiver : public pqxx::notification_receiver {
|
|||
virtual void operator()(const std::string& payload, int packend_pid);
|
||||
|
||||
private:
|
||||
PostgreSQL* _psql;
|
||||
DB* _psql;
|
||||
};
|
||||
|
||||
/**
|
||||
* A controller database driver that talks to PostgreSQL
|
||||
*
|
||||
* This is for use with ZeroTier Central. Others are free to build and use it
|
||||
* but be aware that we might change it at any time.
|
||||
*/
|
||||
class PostgreSQL : public DB {
|
||||
friend class MemberNotificationReceiver;
|
||||
friend class NetworkNotificationReceiver;
|
||||
|
||||
public:
|
||||
PostgreSQL(const Identity& myId, const char* path, int listenPort, RedisConfig* rc);
|
||||
virtual ~PostgreSQL();
|
||||
|
||||
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 AuthInfo getSSOAuthInfo(const nlohmann::json& member, const std::string& redirectURL);
|
||||
|
||||
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)
|
||||
{
|
||||
DB::_memberChanged(old, memberConfig, notifyListeners);
|
||||
}
|
||||
|
||||
virtual void _networkChanged(nlohmann::json& old, nlohmann::json& networkConfig, bool notifyListeners)
|
||||
{
|
||||
DB::_networkChanged(old, networkConfig, notifyListeners);
|
||||
}
|
||||
|
||||
private:
|
||||
void initializeNetworks();
|
||||
void initializeMembers();
|
||||
void heartbeat();
|
||||
void membersDbWatcher();
|
||||
void _membersWatcher_Postgres();
|
||||
void networksDbWatcher();
|
||||
void _networksWatcher_Postgres();
|
||||
|
||||
void _membersWatcher_Redis();
|
||||
void _networksWatcher_Redis();
|
||||
|
||||
void commitThread();
|
||||
void onlineNotificationThread();
|
||||
void onlineNotification_Postgres();
|
||||
void onlineNotification_Redis();
|
||||
uint64_t _doRedisUpdate(sw::redis::Transaction& tx, std::string& controllerId, std::unordered_map<std::pair<uint64_t, uint64_t>, std::pair<int64_t, InetAddress>, _PairHasher>& lastOnline);
|
||||
|
||||
void configureSmee();
|
||||
void notifyNewMember(const std::string& networkID, const std::string& memberID);
|
||||
|
||||
enum OverrideMode { ALLOW_PGBOUNCER_OVERRIDE = 0, NO_OVERRIDE = 1 };
|
||||
|
||||
std::shared_ptr<ConnectionPool<PostgresConnection> > _pool;
|
||||
|
||||
const Identity _myId;
|
||||
const Address _myAddress;
|
||||
std::string _myAddressStr;
|
||||
std::string _connString;
|
||||
|
||||
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::unordered_map<std::pair<uint64_t, uint64_t>, std::pair<int64_t, InetAddress>, _PairHasher> _lastOnline;
|
||||
|
||||
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];
|
||||
|
||||
RedisConfig* _rc;
|
||||
std::shared_ptr<sw::redis::Redis> _redis;
|
||||
std::shared_ptr<sw::redis::RedisCluster> _cluster;
|
||||
bool _redisMemberStatus;
|
||||
|
||||
smeeclient::SmeeClient* _smee;
|
||||
struct NodeOnlineRecord {
|
||||
uint64_t lastSeen;
|
||||
InetAddress physicalAddress;
|
||||
std::string osArch;
|
||||
};
|
||||
|
||||
} // namespace ZeroTier
|
||||
|
||||
#endif // ZT_CONTROLLER_LIBPQ_HPP
|
||||
#endif // ZT_CONTROLLER_POSTGRESQL_HPP
|
||||
|
||||
#endif // ZT_CONTROLLER_USE_LIBPQ
|
||||
#endif // ZT_CONTROLLER_USE_LIBPQ
|
|
@ -9,15 +9,16 @@ mkztfile() {
|
|||
file=$1
|
||||
mode=$2
|
||||
content=$3
|
||||
|
||||
echo "creating $file"
|
||||
mkdir -p /var/lib/zerotier-one
|
||||
echo "$content" > "/var/lib/zerotier-one/$file"
|
||||
echo -n "$content" > "/var/lib/zerotier-one/$file"
|
||||
chmod "$mode" "/var/lib/zerotier-one/$file"
|
||||
}
|
||||
|
||||
if [ "x$ZEROTIER_API_SECRET" != "x" ]
|
||||
then
|
||||
mkztfile authtoken.secret 0600 "$ZEROTIER_API_SECRET"
|
||||
mkztfile metricstoken.secret 0600 "$ZEROTIER_API_SECRET"
|
||||
fi
|
||||
|
||||
if [ "x$ZEROTIER_IDENTITY_PUBLIC" != "x" ]
|
||||
|
@ -30,6 +31,11 @@ then
|
|||
mkztfile identity.secret 0600 "$ZEROTIER_IDENTITY_SECRET"
|
||||
fi
|
||||
|
||||
if [ "x$ZEROTIER_LOCAL_CONF" != "x" ]
|
||||
then
|
||||
mkztfile local.conf 0644 "$ZEROTIER_LOCAL_CONF"
|
||||
fi
|
||||
|
||||
mkztfile zerotier-one.port 0600 "9993"
|
||||
|
||||
killzerotier() {
|
||||
|
|
|
@ -1,11 +1,16 @@
|
|||
# Dockerfile for ZeroTier Central Controllers
|
||||
FROM registry.zerotier.com/zerotier/ctlbuild:latest as builder
|
||||
MAINTAINER Adam Ierymekno <adam.ierymenko@zerotier.com>, Grant Limberg <grant.limberg@zerotier.com>
|
||||
FROM registry.zerotier.com/zerotier/ctlbuild:2025-05-13-01 AS builder
|
||||
ADD . /ZeroTierOne
|
||||
RUN export PATH=$PATH:~/.cargo/bin && cd ZeroTierOne && make clean && make central-controller -j8
|
||||
|
||||
FROM registry.zerotier.com/zerotier/ctlrun:latest
|
||||
FROM golang:bookworm AS go_base
|
||||
RUN go install -tags 'postgres' github.com/golang-migrate/migrate/v4/cmd/migrate@latest
|
||||
|
||||
FROM registry.zerotier.com/zerotier/ctlrun:2025-05-13-01
|
||||
COPY --from=builder /ZeroTierOne/zerotier-one /usr/local/bin/zerotier-one
|
||||
COPY --from=go_base /go/bin/migrate /usr/local/bin/migrate
|
||||
COPY ext/central-controller-docker/migrations /migrations
|
||||
|
||||
RUN chmod a+x /usr/local/bin/zerotier-one
|
||||
RUN echo "/usr/local/lib64" > /etc/ld.so.conf.d/usr-local-lib64.conf && ldconfig
|
||||
|
||||
|
|
|
@ -1,8 +1,5 @@
|
|||
# Dockerfile for building ZeroTier Central Controllers
|
||||
FROM ubuntu:jammy as builder
|
||||
MAINTAINER Adam Ierymekno <adam.ierymenko@zerotier.com>, Grant Limberg <grant.limberg@zerotier.com>
|
||||
|
||||
ARG git_branch=master
|
||||
FROM debian:bookworm
|
||||
|
||||
RUN apt update && apt upgrade -y
|
||||
RUN apt -y install \
|
||||
|
|
|
@ -1,15 +1,17 @@
|
|||
FROM ubuntu:jammy
|
||||
FROM debian:bookworm
|
||||
|
||||
|
||||
|
||||
RUN apt update && apt upgrade -y
|
||||
|
||||
RUN apt -y install \
|
||||
netcat \
|
||||
netcat-traditional \
|
||||
postgresql-client \
|
||||
postgresql-client-common \
|
||||
libjemalloc2 \
|
||||
libpq5 \
|
||||
curl \
|
||||
binutils \
|
||||
linux-tools-gke \
|
||||
perf-tools-unstable \
|
||||
google-perftools
|
||||
google-perftools \
|
||||
gnupg
|
||||
|
||||
|
|
|
@ -1,9 +1,5 @@
|
|||
#!/bin/bash
|
||||
|
||||
if [ -z "$ZT_IDENTITY_PATH" ]; then
|
||||
echo '*** FAILED: ZT_IDENTITY_PATH environment variable is not defined'
|
||||
exit 1
|
||||
fi
|
||||
if [ -z "$ZT_DB_HOST" ]; then
|
||||
echo '*** FAILED: ZT_DB_HOST environment variable not defined'
|
||||
exit 1
|
||||
|
@ -24,6 +20,9 @@ if [ -z "$ZT_DB_PASSWORD" ]; then
|
|||
echo '*** FAILED: ZT_DB_PASSWORD environment variable not defined'
|
||||
exit 1
|
||||
fi
|
||||
if [ -z "$ZT_DB_TYPE" ]; then
|
||||
ZT_DB_TYPE="postgres"
|
||||
fi
|
||||
|
||||
REDIS=""
|
||||
if [ "$ZT_USE_REDIS" == "true" ]; then
|
||||
|
@ -56,10 +55,14 @@ fi
|
|||
mkdir -p /var/lib/zerotier-one
|
||||
|
||||
pushd /var/lib/zerotier-one
|
||||
ln -s $ZT_IDENTITY_PATH/identity.public identity.public
|
||||
ln -s $ZT_IDENTITY_PATH/identity.secret identity.secret
|
||||
if [ -f "$ZT_IDENTITY_PATH/authtoken.secret" ]; then
|
||||
ln -s $ZT_IDENTITY_PATH/authtoken.secret authtoken.secret
|
||||
if [ -d "$ZT_IDENTITY_PATH" ]; then
|
||||
echo '*** Using existing ZT identity from path $ZT_IDENTITY_PATH'
|
||||
|
||||
ln -s $ZT_IDENTITY_PATH/identity.public identity.public
|
||||
ln -s $ZT_IDENTITY_PATH/identity.secret identity.secret
|
||||
if [ -f "$ZT_IDENTITY_PATH/authtoken.secret" ]; then
|
||||
ln -s $ZT_IDENTITY_PATH/authtoken.secret authtoken.secret
|
||||
fi
|
||||
fi
|
||||
popd
|
||||
|
||||
|
@ -70,7 +73,7 @@ APP_NAME="controller-$(cat /var/lib/zerotier-one/identity.public | cut -d ':' -f
|
|||
|
||||
echo "{
|
||||
\"settings\": {
|
||||
\"controllerDbPath\": \"postgres:host=${ZT_DB_HOST} port=${ZT_DB_PORT} dbname=${ZT_DB_NAME} user=${ZT_DB_USER} password=${ZT_DB_PASSWORD} application_name=${APP_NAME} sslmode=prefer sslcert=${DB_CLIENT_CERT} sslkey=${DB_CLIENT_KEY} sslrootcert=${DB_SERVER_CA}\",
|
||||
\"controllerDbPath\": \"${ZT_DB_TYPE}:host=${ZT_DB_HOST} port=${ZT_DB_PORT} dbname=${ZT_DB_NAME} user=${ZT_DB_USER} password=${ZT_DB_PASSWORD} application_name=${APP_NAME} sslmode=prefer sslcert=${DB_CLIENT_CERT} sslkey=${DB_CLIENT_KEY} sslrootcert=${DB_SERVER_CA}\",
|
||||
\"portMappingEnabled\": true,
|
||||
\"softwareUpdate\": \"disable\",
|
||||
\"interfacePrefixBlacklist\": [
|
||||
|
@ -100,6 +103,15 @@ else
|
|||
done
|
||||
fi
|
||||
|
||||
if [ "$ZT_DB_TYPE" == "cv2" ]; then
|
||||
echo "Migrating database (if needed)..."
|
||||
if [ -n "$DB_SERVER_CA" ]; then
|
||||
/usr/local/bin/migrate -source file:///migrations -database "postgres://$ZT_DB_USER:$ZT_DB_PASSWORD@$ZT_DB_HOST:$ZT_DB_PORT/$ZT_DB_NAME?x-migrations-table=controller_migrations&sslmode=verify-full&sslrootcert=$DB_SERVER_CA&sslcert=$DB_CLIENT_CERT&sslkey=$DB_CLIENT_KEY" up
|
||||
else
|
||||
/usr/local/bin/migrate -source file:///migrations -database "postgres://$ZT_DB_USER:$ZT_DB_PASSWORD@$ZT_DB_HOST:$ZT_DB_PORT/$ZT_DB_NAME?x-migrations-table=controller_migrations&sslmode=disable" up
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ -n "$ZT_TEMPORAL_HOST" ] && [ -n "$ZT_TEMPORAL_PORT" ]; then
|
||||
echo "waiting for temporal..."
|
||||
while ! nc -z ${ZT_TEMPORAL_HOST} ${ZT_TEMPORAL_PORT}; do
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
DROP TABLE IF EXISTS network_memberships_ctl;
|
||||
DROP TABLE IF EXISTS networks_ctl;
|
||||
DROP TABLE IF EXISTS controllers_ctl;
|
47
ext/central-controller-docker/migrations/0001_init.up.sql
Normal file
47
ext/central-controller-docker/migrations/0001_init.up.sql
Normal file
|
@ -0,0 +1,47 @@
|
|||
-- inits controller db schema
|
||||
|
||||
CREATE TABLE IF NOT EXISTS controllers_ctl (
|
||||
id text NOT NULL PRIMARY KEY,
|
||||
hostname text,
|
||||
last_heartbeat timestamp with time zone,
|
||||
public_identity text NOT NULL,
|
||||
version text
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS networks_ctl (
|
||||
id character varying(22) NOT NULL PRIMARY KEY,
|
||||
name text NOT NULL,
|
||||
configuration jsonb DEFAULT '{}'::jsonb NOT NULL,
|
||||
controller_id text REFERENCES controllers_ctl(id),
|
||||
revision integer DEFAULT 0 NOT NULL,
|
||||
last_modified timestamp with time zone DEFAULT now(),
|
||||
creation_time timestamp with time zone DEFAULT now()
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS network_memberships_ctl (
|
||||
device_id character varying(22) NOT NULL,
|
||||
network_id character varying(22) NOT NULL REFERENCES networks_ctl(id),
|
||||
authorized boolean,
|
||||
active_bridge boolean,
|
||||
ip_assignments text[],
|
||||
no_auto_assign_ips boolean,
|
||||
sso_exempt boolean,
|
||||
authentication_expiry_time timestamp with time zone,
|
||||
capabilities jsonb,
|
||||
creation_time timestamp with time zone DEFAULT now(),
|
||||
last_modified timestamp with time zone DEFAULT now(),
|
||||
identity text DEFAULT ''::text,
|
||||
last_authorized_credential text,
|
||||
last_authorized_time timestamp with time zone,
|
||||
last_deauthorized_time timestamp with time zone,
|
||||
last_seen jsonb DEFAULT '{}'::jsonb NOT NULL, -- in the context of the network
|
||||
remote_trace_level integer DEFAULT 0 NOT NULL,
|
||||
remote_trace_target text DEFAULT ''::text NOT NULL,
|
||||
revision integer DEFAULT 0 NOT NULL,
|
||||
tags jsonb,
|
||||
version_major integer DEFAULT 0 NOT NULL,
|
||||
version_minor integer DEFAULT 0 NOT NULL,
|
||||
version_revision integer DEFAULT 0 NOT NULL,
|
||||
version_protocol integer DEFAULT 0 NOT NULL,
|
||||
PRIMARY KEY (device_id, network_id)
|
||||
);
|
|
@ -0,0 +1,3 @@
|
|||
ALTER TABLE network_memberships_ctl
|
||||
DROP COLUMN os,
|
||||
DROP COLUMN arch;
|
|
@ -0,0 +1,3 @@
|
|||
ALTER TABLE network_memberships_ctl
|
||||
ADD COLUMN os TEXT NOT NULL DEFAULT 'unknown',
|
||||
ADD COLUMN arch TEXT NOT NULL DEFAULT 'unknown';
|
|
@ -444,6 +444,10 @@ central-controller-docker: _buildx FORCE
|
|||
docker buildx build --platform linux/amd64,linux/arm64 --no-cache -t registry.zerotier.com/zerotier-central/ztcentral-controller:${TIMESTAMP} -f ext/central-controller-docker/Dockerfile --build-arg git_branch=`git name-rev --name-only HEAD` . --push
|
||||
@echo Image: registry.zerotier.com/zerotier-central/ztcentral-controller:${TIMESTAMP}
|
||||
|
||||
centralv2-controller-docker: _buildx FORCE
|
||||
docker buildx build --platform linux/amd64,linux/arm64 --no-cache -t us-central1-docker.pkg.dev/zerotier-421eb9/docker-images/ztcentral-controller:$(shell git rev-parse --short HEAD) -f ext/central-controller-docker/Dockerfile --build-arg git_branch=`git name-rev --name-only HEAD` . --push
|
||||
@echo Image: us-central1-docker.pkg.dev/zerotier-421eb9/docker-images/ztcentral-controller:$(shell git rev-parse --short HEAD)
|
||||
|
||||
debug: FORCE
|
||||
make ZT_DEBUG=1 one
|
||||
make ZT_DEBUG=1 selftest
|
||||
|
|
21
make-mac.mk
21
make-mac.mk
|
@ -57,9 +57,9 @@ ONE_OBJS+=ext/libnatpmp/natpmp.o ext/libnatpmp/getgateway.o ext/miniupnpc/connec
|
|||
ifeq ($(ZT_CONTROLLER),1)
|
||||
MACOS_VERSION_MIN=10.15
|
||||
override CXXFLAGS=$(CFLAGS) -std=c++17 -stdlib=libc++
|
||||
LIBS+=-L/usr/local/opt/libpqxx/lib -L/usr/local/opt/libpq/lib -L/usr/local/opt/openssl/lib/ -lpqxx -lpq -lssl -lcrypto -lgssapi_krb5 ext/redis-plus-plus-1.1.1/install/macos/lib/libredis++.a ext/hiredis-0.14.1/lib/macos/libhiredis.a
|
||||
LIBS+=-L/opt/homebrew/lib -L/usr/local/opt/libpqxx/lib -L/usr/local/opt/libpq/lib -L/usr/local/opt/openssl/lib/ -lpqxx -lpq -lssl -lcrypto -lgssapi_krb5 ext/redis-plus-plus-1.1.1/install/macos/lib/libredis++.a ext/hiredis-0.14.1/lib/macos/libhiredis.a rustybits/target/libsmeeclient.a
|
||||
DEFS+=-DZT_CONTROLLER_USE_LIBPQ -DZT_CONTROLLER_USE_REDIS -DZT_CONTROLLER
|
||||
INCLUDES+=-I/usr/local/opt/libpq/include -I/usr/local/opt/libpqxx/include -Iext/hiredis-0.14.1/include/ -Iext/redis-plus-plus-1.1.1/install/macos/include/sw/
|
||||
INCLUDES+=-I/opt/homebrew/include -I/opt/homebrew/opt/libpq/include -I/usr/local/opt/libpq/include -I/usr/local/opt/libpqxx/include -Iext/hiredis-0.14.1/include/ -Iext/redis-plus-plus-1.1.1/install/macos/include/sw/ -Irustybits/target/
|
||||
else
|
||||
MACOS_VERSION_MIN=10.13
|
||||
endif
|
||||
|
@ -115,7 +115,11 @@ mac-agent: FORCE
|
|||
osdep/MacDNSHelper.o: osdep/MacDNSHelper.mm
|
||||
$(CXX) $(CXXFLAGS) -c osdep/MacDNSHelper.mm -o osdep/MacDNSHelper.o
|
||||
|
||||
ifeq ($(ZT_CONTROLLER),1)
|
||||
one: zeroidc smeeclient $(CORE_OBJS) $(ONE_OBJS) one.o mac-agent
|
||||
else
|
||||
one: zeroidc $(CORE_OBJS) $(ONE_OBJS) one.o mac-agent
|
||||
endif
|
||||
$(CXX) $(CXXFLAGS) -o zerotier-one $(CORE_OBJS) $(ONE_OBJS) one.o $(LIBS) rustybits/target/libzeroidc.a
|
||||
# $(STRIP) zerotier-one
|
||||
ln -sf zerotier-one zerotier-idtool
|
||||
|
@ -126,6 +130,15 @@ zerotier-one: one
|
|||
|
||||
zeroidc: rustybits/target/libzeroidc.a
|
||||
|
||||
ifeq ($(ZT_CONTROLLER),1)
|
||||
smeeclient: rustybits/target/libsmeeclient.a
|
||||
|
||||
rustybits/target/libsmeeclient.a: FORCE
|
||||
cd rustybits && MACOSX_DEPLOYMENT_TARGET=$(MACOS_VERSION_MIN) cargo build -p smeeclient --target=x86_64-apple-darwin $(EXTRA_CARGO_FLAGS)
|
||||
cd rustybits && MACOSX_DEPLOYMENT_TARGET=$(MACOS_VERSION_MIN) cargo build -p smeeclient --target=aarch64-apple-darwin $(EXTRA_CARGO_FLAGS)
|
||||
cd rustybits && lipo -create target/x86_64-apple-darwin/$(RUST_VARIANT)/libsmeeclient.a target/aarch64-apple-darwin/$(RUST_VARIANT)/libsmeeclient.a -output target/libsmeeclient.a
|
||||
endif
|
||||
|
||||
rustybits/target/libzeroidc.a: FORCE
|
||||
cd rustybits && MACOSX_DEPLOYMENT_TARGET=$(MACOS_VERSION_MIN) cargo build -p zeroidc --target=x86_64-apple-darwin $(EXTRA_CARGO_FLAGS)
|
||||
cd rustybits && MACOSX_DEPLOYMENT_TARGET=$(MACOS_VERSION_MIN) cargo build -p zeroidc --target=aarch64-apple-darwin $(EXTRA_CARGO_FLAGS)
|
||||
|
@ -195,6 +208,10 @@ central-controller-docker: _buildx FORCE
|
|||
docker buildx build --platform linux/arm64,linux/amd64 --no-cache -t registry.zerotier.com/zerotier-central/ztcentral-controller:${TIMESTAMP} -f ext/central-controller-docker/Dockerfile --build-arg git_branch=$(shell git name-rev --name-only HEAD) . --push
|
||||
@echo Image: registry.zerotier.com/zerotier-central/ztcentral-controller:${TIMESTAMP}
|
||||
|
||||
centralv2-controller-docker: _buildx FORCE
|
||||
docker buildx build --platform linux/amd64,linux/arm64 --no-cache -t us-central1-docker.pkg.dev/zerotier-d648c7/central-v2/ztcentral-controller:${TIMESTAMP} -f ext/central-controller-docker/Dockerfile --build-arg git_branch=`git name-rev --name-only HEAD` . --push
|
||||
@echo Image: us-central1-docker.pkg.dev/zerotier-d648c7/central-v2/ztcentral-controller:${TIMESTAMP}
|
||||
|
||||
docker-release: _buildx
|
||||
docker buildx build --platform linux/386,linux/amd64,linux/arm/v7,linux/arm64,linux/mips64le,linux/ppc64le,linux/s390x -t zerotier/zerotier:${RELEASE_DOCKER_TAG} -t zerotier/zerotier:latest --build-arg VERSION=${RELEASE_VERSION} -f Dockerfile.release . --push
|
||||
|
||||
|
|
|
@ -10,8 +10,10 @@
|
|||
* of this software will be governed by version 2.0 of the Apache License.
|
||||
*/
|
||||
|
||||
#include <prometheus/histogram.h>
|
||||
// clang-format off
|
||||
#include <prometheus/simpleapi.h>
|
||||
#include <prometheus/histogram.h>
|
||||
// clang-format on
|
||||
|
||||
namespace prometheus {
|
||||
namespace simpleapi {
|
||||
|
|
|
@ -12,8 +12,10 @@
|
|||
#ifndef METRICS_H_
|
||||
#define METRICS_H_
|
||||
|
||||
#include <prometheus/histogram.h>
|
||||
// clang-format off
|
||||
#include <prometheus/simpleapi.h>
|
||||
#include <prometheus/histogram.h>
|
||||
// clang-format on
|
||||
|
||||
namespace prometheus {
|
||||
namespace simpleapi {
|
||||
|
|
|
@ -39,7 +39,10 @@ ONE_OBJS=\
|
|||
controller/DB.o \
|
||||
controller/FileDB.o \
|
||||
controller/LFDB.o \
|
||||
controller/CtlUtil.o \
|
||||
controller/PostgreSQL.o \
|
||||
controller/CV1.o \
|
||||
controller/CV2.o \
|
||||
osdep/EthernetTap.o \
|
||||
osdep/ManagedRoute.o \
|
||||
osdep/Http.o \
|
||||
|
|
|
@ -19,9 +19,11 @@
|
|||
#include <string>
|
||||
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
#include <windows.h>
|
||||
// clang-format off
|
||||
#include <winsock2.h>
|
||||
#include <ws2tcpip.h>
|
||||
#include <windows.h>
|
||||
// clang-format on
|
||||
#else
|
||||
#include <arpa/inet.h>
|
||||
#include <netinet/in.h>
|
||||
|
|
35
rustybits/Cargo.lock
generated
35
rustybits/Cargo.lock
generated
|
@ -1,6 +1,6 @@
|
|||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
version = 3
|
||||
version = 4
|
||||
|
||||
[[package]]
|
||||
name = "addr2line"
|
||||
|
@ -287,9 +287,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "cc"
|
||||
version = "1.2.2"
|
||||
version = "1.2.16"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f34d93e62b03caf570cccc334cbc6c2fceca82f39211051345108adcba3eebdc"
|
||||
checksum = "be714c154be609ec7f5dad223a33bf1482fff90472de28f7362806e6d4832b8c"
|
||||
dependencies = [
|
||||
"shlex",
|
||||
]
|
||||
|
@ -373,9 +373,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "crossbeam-channel"
|
||||
version = "0.5.13"
|
||||
version = "0.5.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "33480d6946193aa8033910124896ca395333cae7e2d1113d1fef6c3272217df2"
|
||||
checksum = "82b8f8f868b36967f9606790d1903570de9ceaf870a7bf9fbbd3016d636a2cb2"
|
||||
dependencies = [
|
||||
"crossbeam-utils",
|
||||
]
|
||||
|
@ -1508,9 +1508,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.167"
|
||||
version = "0.2.171"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "09d6582e104315a817dff97f75133544b2e094ee22447d2acf4a74e189ba06fc"
|
||||
checksum = "c19937216e9d3aa9956d9bb8dfc0b0c8beb6058fc4f7a4dc4d850edf86a237d6"
|
||||
|
||||
[[package]]
|
||||
name = "libm"
|
||||
|
@ -1804,9 +1804,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "openssl"
|
||||
version = "0.10.70"
|
||||
version = "0.10.72"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "61cfb4e166a8bb8c9b55c500bc2308550148ece889be90f609377e58140f42c6"
|
||||
checksum = "fedfea7d58a1f73118430a55da6a286e7b044961736ce96a16a17068ea25e5da"
|
||||
dependencies = [
|
||||
"bitflags 2.6.0",
|
||||
"cfg-if",
|
||||
|
@ -1836,9 +1836,9 @@ checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf"
|
|||
|
||||
[[package]]
|
||||
name = "openssl-sys"
|
||||
version = "0.9.105"
|
||||
version = "0.9.107"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8b22d5b84be05a8d6947c7cb71f7c849aa0f112acd4bf51c2a7c1c988ac0a9dc"
|
||||
checksum = "8288979acd84749c744a9014b4382d42b8f7b2592847b5afb2ed29e5d16ede07"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"libc",
|
||||
|
@ -2378,15 +2378,14 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "ring"
|
||||
version = "0.17.8"
|
||||
version = "0.17.13"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c17fa4cb658e3583423e915b9f3acc01cceaee1860e33d59ebae66adc3a2dc0d"
|
||||
checksum = "70ac5d832aa16abd7d1def883a8545280c20a60f523a370aa3a9617c2b8550ee"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"cfg-if",
|
||||
"getrandom",
|
||||
"libc",
|
||||
"spin",
|
||||
"untrusted",
|
||||
"windows-sys 0.52.0",
|
||||
]
|
||||
|
@ -3218,9 +3217,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "tokio"
|
||||
version = "1.42.0"
|
||||
version = "1.43.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5cec9b21b0450273377fc97bd4c33a8acffc8c996c987a7c5b319a0083707551"
|
||||
checksum = "492a604e2fd7f814268a378409e6c92b5525d747d10db9a229723f55a417958c"
|
||||
dependencies = [
|
||||
"backtrace",
|
||||
"bytes",
|
||||
|
@ -3236,9 +3235,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "tokio-macros"
|
||||
version = "2.4.0"
|
||||
version = "2.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "693d596312e88961bc67d7f1f97af8a70227d9f90c31bba5806eec004978d752"
|
||||
checksum = "6e06d43f1345a3bcd39f6a56dbb7dcab2ba47e68e8ac134855e7e2bdbaf8cab8"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
|
|
|
@ -13,7 +13,7 @@ serde = { version = "1", features = ["derive"] }
|
|||
temporal-sdk = { git = "https://github.com/temporalio/sdk-core", branch = "master" }
|
||||
temporal-client = { git = "https://github.com/temporalio/sdk-core", branch = "master", features = ["telemetry"] }
|
||||
temporal-sdk-core-protos = { git = "https://github.com/temporalio/sdk-core", branch = "master" }
|
||||
tokio = { version = "1.29", features = ["full"] }
|
||||
tokio = { version = "1.43", features = ["full"] }
|
||||
url = { version = "2" }
|
||||
uuid = { version = "1.4", features = ["v4"] }
|
||||
|
||||
|
|
|
@ -16,7 +16,10 @@ use serde::{Deserialize, Serialize};
|
|||
use std::str::FromStr;
|
||||
use std::time::Duration;
|
||||
use temporal_client::{Client, ClientOptionsBuilder, RetryClient, WorkflowClientTrait, WorkflowOptions};
|
||||
use temporal_sdk_core_protos::{coresdk::AsJsonPayloadExt, temporal::api::enums::v1::WorkflowIdReusePolicy};
|
||||
use temporal_sdk_core_protos::{
|
||||
coresdk::AsJsonPayloadExt,
|
||||
temporal::api::enums::v1::{WorkflowIdConflictPolicy, WorkflowIdReusePolicy},
|
||||
};
|
||||
use url::Url;
|
||||
use uuid::Uuid;
|
||||
|
||||
|
@ -72,6 +75,7 @@ impl SmeeClient {
|
|||
println!("notifying network joined");
|
||||
let options = WorkflowOptions {
|
||||
id_reuse_policy: WorkflowIdReusePolicy::RejectDuplicate,
|
||||
id_conflict_policy: WorkflowIdConflictPolicy::Fail,
|
||||
execution_timeout: None,
|
||||
run_timeout: None,
|
||||
task_timeout: None,
|
||||
|
|
|
@ -2217,6 +2217,7 @@ class OneServiceImpl : public OneService {
|
|||
auto statusGet = [&, setContent](const httplib::Request& req, httplib::Response& res) {
|
||||
ZT_NodeStatus status;
|
||||
_node->status(&status);
|
||||
|
||||
auto out = json::object();
|
||||
char tmp[256] = {};
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue