mirror of
https://github.com/ZeroTier/ZeroTierOne
synced 2025-08-14 02:27:38 -07:00
Revert "Backport guts of 1.8 to 1.6 tree so we can point release without waiting for UI quirks to be fixed."
This reverts commit 48ce7632fa
.
This commit is contained in:
parent
452b1e806b
commit
75a45eeb27
42 changed files with 4153 additions and 3754 deletions
|
@ -1,161 +0,0 @@
|
|||
/*
|
||||
* 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: 2025-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_CONNECTION_POOL_H_
|
||||
#define ZT_CONNECTION_POOL_H_
|
||||
|
||||
|
||||
#ifndef _DEBUG
|
||||
#define _DEBUG(x)
|
||||
#endif
|
||||
|
||||
#include <deque>
|
||||
#include <set>
|
||||
#include <memory>
|
||||
#include <mutex>
|
||||
#include <exception>
|
||||
#include <string>
|
||||
|
||||
namespace ZeroTier {
|
||||
|
||||
struct ConnectionUnavailable : std::exception {
|
||||
char const* what() const throw() {
|
||||
return "Unable to allocate connection";
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
class Connection {
|
||||
public:
|
||||
virtual ~Connection() {};
|
||||
};
|
||||
|
||||
class ConnectionFactory {
|
||||
public:
|
||||
virtual ~ConnectionFactory() {};
|
||||
virtual std::shared_ptr<Connection> create()=0;
|
||||
};
|
||||
|
||||
struct ConnectionPoolStats {
|
||||
size_t pool_size;
|
||||
size_t borrowed_size;
|
||||
};
|
||||
|
||||
template<class T>
|
||||
class ConnectionPool {
|
||||
public:
|
||||
ConnectionPool(size_t max_pool_size, size_t min_pool_size, std::shared_ptr<ConnectionFactory> factory)
|
||||
: m_maxPoolSize(max_pool_size)
|
||||
, m_minPoolSize(min_pool_size)
|
||||
, m_factory(factory)
|
||||
{
|
||||
while(m_pool.size() < m_minPoolSize){
|
||||
m_pool.push_back(m_factory->create());
|
||||
}
|
||||
};
|
||||
|
||||
ConnectionPoolStats get_stats() {
|
||||
std::unique_lock<std::mutex> lock(m_poolMutex);
|
||||
|
||||
ConnectionPoolStats stats;
|
||||
stats.pool_size = m_pool.size();
|
||||
stats.borrowed_size = m_borrowed.size();
|
||||
|
||||
return stats;
|
||||
};
|
||||
|
||||
~ConnectionPool() {
|
||||
};
|
||||
|
||||
/**
|
||||
* Borrow
|
||||
*
|
||||
* Borrow a connection for temporary use
|
||||
*
|
||||
* When done, either (a) call unborrow() to return it, or (b) (if it's bad) just let it go out of scope. This will cause it to automatically be replaced.
|
||||
* @retval a shared_ptr to the connection object
|
||||
*/
|
||||
std::shared_ptr<T> borrow() {
|
||||
std::unique_lock<std::mutex> l(m_poolMutex);
|
||||
|
||||
while((m_pool.size() + m_borrowed.size()) < m_minPoolSize) {
|
||||
std::shared_ptr<Connection> conn = m_factory->create();
|
||||
m_pool.push_back(conn);
|
||||
}
|
||||
|
||||
if(m_pool.size()==0){
|
||||
|
||||
if ((m_pool.size() + m_borrowed.size()) <= m_maxPoolSize) {
|
||||
try {
|
||||
std::shared_ptr<Connection> conn = m_factory->create();
|
||||
m_borrowed.insert(conn);
|
||||
return std::static_pointer_cast<T>(conn);
|
||||
} catch (std::exception &e) {
|
||||
throw ConnectionUnavailable();
|
||||
}
|
||||
} else {
|
||||
for(auto it = m_borrowed.begin(); it != m_borrowed.end(); ++it){
|
||||
if((*it).unique()) {
|
||||
// This connection has been abandoned! Destroy it and create a new connection
|
||||
try {
|
||||
// If we are able to create a new connection, return it
|
||||
_DEBUG("Creating new connection to replace discarded connection");
|
||||
std::shared_ptr<Connection> conn = m_factory->create();
|
||||
m_borrowed.erase(it);
|
||||
m_borrowed.insert(conn);
|
||||
return std::static_pointer_cast<T>(conn);
|
||||
} catch(std::exception& e) {
|
||||
// Error creating a replacement connection
|
||||
throw ConnectionUnavailable();
|
||||
}
|
||||
}
|
||||
}
|
||||
// Nothing available
|
||||
throw ConnectionUnavailable();
|
||||
}
|
||||
}
|
||||
|
||||
// Take one off the front
|
||||
std::shared_ptr<Connection> conn = m_pool.front();
|
||||
m_pool.pop_front();
|
||||
// Add it to the borrowed list
|
||||
m_borrowed.insert(conn);
|
||||
return std::static_pointer_cast<T>(conn);
|
||||
};
|
||||
|
||||
/**
|
||||
* Unborrow a connection
|
||||
*
|
||||
* Only call this if you are returning a working connection. If the connection was bad, just let it go out of scope (so the connection manager can replace it).
|
||||
* @param the connection
|
||||
*/
|
||||
void unborrow(std::shared_ptr<T> conn) {
|
||||
// Lock
|
||||
std::unique_lock<std::mutex> lock(m_poolMutex);
|
||||
m_borrowed.erase(conn);
|
||||
if ((m_pool.size() + m_borrowed.size()) < m_maxPoolSize) {
|
||||
m_pool.push_back(conn);
|
||||
}
|
||||
};
|
||||
protected:
|
||||
size_t m_maxPoolSize;
|
||||
size_t m_minPoolSize;
|
||||
std::shared_ptr<ConnectionFactory> m_factory;
|
||||
std::deque<std::shared_ptr<Connection> > m_pool;
|
||||
std::set<std::shared_ptr<Connection> > m_borrowed;
|
||||
std::mutex m_poolMutex;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
|
@ -49,9 +49,6 @@ void DB::initNetwork(nlohmann::json &network)
|
|||
}};
|
||||
}
|
||||
if (!network.count("dns")) network["dns"] = nlohmann::json::array();
|
||||
if (!network.count("ssoEnabled")) network["ssoEnabled"] = false;
|
||||
if (!network.count("clientId")) network["clientId"] = "";
|
||||
if (!network.count("authorizationEndpoint")) network["authorizationEndpoint"] = "";
|
||||
|
||||
network["objtype"] = "network";
|
||||
}
|
||||
|
@ -59,7 +56,6 @@ void DB::initNetwork(nlohmann::json &network)
|
|||
void DB::initMember(nlohmann::json &member)
|
||||
{
|
||||
if (!member.count("authorized")) member["authorized"] = false;
|
||||
if (!member.count("ssoExempt")) member["ssoExempt"] = false;
|
||||
if (!member.count("ipAssignments")) member["ipAssignments"] = nlohmann::json::array();
|
||||
if (!member.count("activeBridge")) member["activeBridge"] = false;
|
||||
if (!member.count("tags")) member["tags"] = nlohmann::json::array();
|
||||
|
@ -71,7 +67,6 @@ void DB::initMember(nlohmann::json &member)
|
|||
if (!member.count("lastAuthorizedTime")) member["lastAuthorizedTime"] = 0ULL;
|
||||
if (!member.count("lastAuthorizedCredentialType")) member["lastAuthorizedCredentialType"] = nlohmann::json();
|
||||
if (!member.count("lastAuthorizedCredential")) member["lastAuthorizedCredential"] = nlohmann::json();
|
||||
if (!member.count("authenticationExpiryTime")) member["authenticationExpiryTime"] = 0LL;
|
||||
if (!member.count("vMajor")) member["vMajor"] = -1;
|
||||
if (!member.count("vMinor")) member["vMinor"] = -1;
|
||||
if (!member.count("vRev")) member["vRev"] = -1;
|
||||
|
@ -97,8 +92,6 @@ void DB::cleanMember(nlohmann::json &member)
|
|||
member.erase("recentLog");
|
||||
member.erase("lastModified");
|
||||
member.erase("lastRequestMetaData");
|
||||
member.erase("authenticationURL"); // computed
|
||||
member.erase("authenticationClientID"); // computed
|
||||
}
|
||||
|
||||
DB::DB() {}
|
||||
|
@ -181,9 +174,8 @@ bool DB::get(const uint64_t networkId,nlohmann::json &network,std::vector<nlohma
|
|||
{
|
||||
std::lock_guard<std::mutex> l2(nw->lock);
|
||||
network = nw->config;
|
||||
for(auto m=nw->members.begin();m!=nw->members.end();++m) {
|
||||
for(auto m=nw->members.begin();m!=nw->members.end();++m)
|
||||
members.push_back(m->second);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
@ -196,14 +188,6 @@ void DB::networks(std::set<uint64_t> &networks)
|
|||
networks.insert(n->first);
|
||||
}
|
||||
|
||||
void DB::networkMemberSSOHasExpired(uint64_t nwid, int64_t now) {
|
||||
std::lock_guard<std::mutex> l(_networks_l);
|
||||
auto nw = _networks.find(nwid);
|
||||
if (nw != _networks.end()) {
|
||||
nw->second->mostRecentDeauthTime = now;
|
||||
}
|
||||
}
|
||||
|
||||
void DB::_memberChanged(nlohmann::json &old,nlohmann::json &memberConfig,bool notifyListeners)
|
||||
{
|
||||
uint64_t memberId = 0;
|
||||
|
|
|
@ -31,12 +31,9 @@
|
|||
#include <atomic>
|
||||
#include <mutex>
|
||||
#include <set>
|
||||
#include <map>
|
||||
|
||||
#include "../ext/json/json.hpp"
|
||||
|
||||
#define ZT_MEMBER_AUTH_TIMEOUT_NOTIFY_BEFORE 25000
|
||||
|
||||
namespace ZeroTier
|
||||
{
|
||||
|
||||
|
@ -104,12 +101,11 @@ public:
|
|||
}
|
||||
|
||||
virtual bool save(nlohmann::json &record,bool notifyListeners) = 0;
|
||||
|
||||
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 std::string getSSOAuthURL(const nlohmann::json &member, const std::string &redirectURL) { return ""; }
|
||||
virtual void networkMemberSSOHasExpired(uint64_t nwid, int64_t ts);
|
||||
virtual void nodeIsOnline(const uint64_t networkId,const uint64_t memberId,const InetAddress &physicalAddress) = 0;
|
||||
|
||||
inline void addListener(DB::ChangeListener *const listener)
|
||||
{
|
||||
|
@ -152,8 +148,8 @@ protected:
|
|||
std::mutex lock;
|
||||
};
|
||||
|
||||
virtual void _memberChanged(nlohmann::json &old,nlohmann::json &memberConfig,bool notifyListeners);
|
||||
virtual void _networkChanged(nlohmann::json &old,nlohmann::json &networkConfig,bool notifyListeners);
|
||||
void _memberChanged(nlohmann::json &old,nlohmann::json &memberConfig,bool notifyListeners);
|
||||
void _networkChanged(nlohmann::json &old,nlohmann::json &networkConfig,bool notifyListeners);
|
||||
void _fillSummaryInfo(const std::shared_ptr<_Network> &nw,NetworkSummaryInfo &info);
|
||||
|
||||
std::vector<DB::ChangeListener *> _changeListeners;
|
||||
|
|
|
@ -36,7 +36,7 @@ DBMirrorSet::DBMirrorSet(DB::ChangeListener *listener) :
|
|||
}
|
||||
|
||||
for(auto db=dbs.begin();db!=dbs.end();++db) {
|
||||
(*db)->each([&dbs,&db](uint64_t networkId,const nlohmann::json &network,uint64_t memberId,const nlohmann::json &member) {
|
||||
(*db)->each([this,&dbs,&db](uint64_t networkId,const nlohmann::json &network,uint64_t memberId,const nlohmann::json &member) {
|
||||
try {
|
||||
if (network.is_object()) {
|
||||
if (memberId == 0) {
|
||||
|
@ -125,26 +125,6 @@ bool DBMirrorSet::get(const uint64_t networkId,nlohmann::json &network,std::vect
|
|||
return false;
|
||||
}
|
||||
|
||||
std::string DBMirrorSet::getSSOAuthURL(const nlohmann::json &member, const std::string &redirectURL)
|
||||
{
|
||||
std::lock_guard<std::mutex> l(_dbs_l);
|
||||
for(auto d=_dbs.begin();d!=_dbs.end();++d) {
|
||||
std::string url = (*d)->getSSOAuthURL(member, redirectURL);
|
||||
if (!url.empty()) {
|
||||
return url;
|
||||
}
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
void DBMirrorSet::networkMemberSSOHasExpired(uint64_t nwid, int64_t ts)
|
||||
{
|
||||
std::lock_guard<std::mutex> l(_dbs_l);
|
||||
for(auto d=_dbs.begin();d!=_dbs.end();++d) {
|
||||
(*d)->networkMemberSSOHasExpired(nwid, ts);
|
||||
}
|
||||
}
|
||||
|
||||
void DBMirrorSet::networks(std::set<uint64_t> &networks)
|
||||
{
|
||||
std::lock_guard<std::mutex> l(_dbs_l);
|
||||
|
@ -248,47 +228,4 @@ void DBMirrorSet::onNetworkMemberDeauthorize(const void *db,uint64_t networkId,u
|
|||
_listener->onNetworkMemberDeauthorize(this,networkId,memberId);
|
||||
}
|
||||
|
||||
void DBMirrorSet::membersExpiring(std::set< std::pair<uint64_t, uint64_t> > &soon, std::set< std::pair<uint64_t, uint64_t> > &expired)
|
||||
{
|
||||
std::unique_lock<std::mutex> l(_membersExpiringSoon_l);
|
||||
int64_t now = OSUtils::now();
|
||||
for(auto next=_membersExpiringSoon.begin();next!=_membersExpiringSoon.end();) {
|
||||
if (next->first > now) {
|
||||
const uint64_t nwid = next->second.first;
|
||||
const uint64_t memberId = next->second.second;
|
||||
nlohmann::json network, member;
|
||||
if (this->get(nwid, network, memberId, member)) {
|
||||
try {
|
||||
const bool authorized = member["authorized"];
|
||||
const bool ssoExempt = member["ssoExempt"];
|
||||
const int64_t authenticationExpiryTime = member["authenticationExpiryTime"];
|
||||
if ((authenticationExpiryTime == next->first)&&(authorized)&&(!ssoExempt)) {
|
||||
if ((authenticationExpiryTime - now) > ZT_MEMBER_AUTH_TIMEOUT_NOTIFY_BEFORE) {
|
||||
// Stop when we get to entries too far in the future.
|
||||
break;
|
||||
} else {
|
||||
const bool ssoEnabled = network["ssoEnabled"];
|
||||
if (ssoEnabled)
|
||||
soon.insert(std::pair<uint64_t, uint64_t>(nwid, memberId));
|
||||
}
|
||||
} else {
|
||||
// Obsolete entry, no longer authorized, or SSO exempt.
|
||||
}
|
||||
} catch ( ... ) {
|
||||
// Invalid member object, erase.
|
||||
}
|
||||
} else {
|
||||
// Not found.
|
||||
}
|
||||
}
|
||||
_membersExpiringSoon.erase(next++);
|
||||
}
|
||||
}
|
||||
|
||||
void DBMirrorSet::memberWillExpire(int64_t expTime, uint64_t nwid, uint64_t memberId)
|
||||
{
|
||||
std::unique_lock<std::mutex> l(_membersExpiringSoon_l);
|
||||
_membersExpiringSoon.insert(std::pair< int64_t, std::pair< uint64_t, uint64_t > >(expTime, std::pair< uint64_t, uint64_t >(nwid, memberId)));
|
||||
}
|
||||
|
||||
} // namespace ZeroTier
|
||||
|
|
|
@ -51,9 +51,6 @@ public:
|
|||
virtual void onNetworkMemberUpdate(const void *db,uint64_t networkId,uint64_t memberId,const nlohmann::json &member);
|
||||
virtual void onNetworkMemberDeauthorize(const void *db,uint64_t networkId,uint64_t memberId);
|
||||
|
||||
std::string getSSOAuthURL(const nlohmann::json &member, const std::string &redirectURL);
|
||||
void networkMemberSSOHasExpired(uint64_t nwid, int64_t ts);
|
||||
|
||||
inline void addDB(const std::shared_ptr<DB> &db)
|
||||
{
|
||||
db->addListener(this);
|
||||
|
@ -61,17 +58,12 @@ public:
|
|||
_dbs.push_back(db);
|
||||
}
|
||||
|
||||
void membersExpiring(std::set< std::pair<uint64_t, uint64_t> > &soon, std::set< std::pair<uint64_t, uint64_t> > &expired);
|
||||
void memberWillExpire(int64_t expTime, uint64_t nwid, uint64_t memberId);
|
||||
|
||||
private:
|
||||
DB::ChangeListener *const _listener;
|
||||
std::atomic_bool _running;
|
||||
std::thread _syncCheckerThread;
|
||||
std::vector< std::shared_ptr< DB > > _dbs;
|
||||
mutable std::mutex _dbs_l;
|
||||
std::set< std::pair< int64_t, std::pair<uint64_t, uint64_t> > > _membersExpiringSoon;
|
||||
mutable std::mutex _membersExpiringSoon_l;
|
||||
};
|
||||
|
||||
} // namespace ZeroTier
|
||||
|
|
|
@ -28,9 +28,6 @@
|
|||
#include <map>
|
||||
#include <thread>
|
||||
#include <memory>
|
||||
#include <iomanip>
|
||||
#include <sstream>
|
||||
#include <cctype>
|
||||
|
||||
#include "../include/ZeroTierOne.h"
|
||||
#include "../version.h"
|
||||
|
@ -63,29 +60,6 @@ namespace ZeroTier {
|
|||
|
||||
namespace {
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
static json _renderRule(ZT_VirtualNetworkRule &rule)
|
||||
{
|
||||
char tmp[128];
|
||||
|
@ -502,10 +476,6 @@ EmbeddedNetworkController::~EmbeddedNetworkController()
|
|||
t->join();
|
||||
}
|
||||
|
||||
void EmbeddedNetworkController::setSSORedirectURL(const std::string &url) {
|
||||
_ssoRedirectURL = url_encode(url);
|
||||
}
|
||||
|
||||
void EmbeddedNetworkController::init(const Identity &signingId,Sender *sender)
|
||||
{
|
||||
char tmp[64];
|
||||
|
@ -718,10 +688,8 @@ unsigned int EmbeddedNetworkController::handleControlPlaneHttpPOST(
|
|||
DB::initMember(member);
|
||||
|
||||
try {
|
||||
if (b.count("activeBridge")) member["activeBridge"] = OSUtils::jsonBool(b["activeBridge"], false);
|
||||
if (b.count("noAutoAssignIps")) member["noAutoAssignIps"] = OSUtils::jsonBool(b["noAutoAssignIps"], false);
|
||||
if (b.count("authenticationExpiryTime")) member["authenticationExpiryTime"] = (uint64_t)OSUtils::jsonInt(b["authenticationExpiryTime"], 0ULL);
|
||||
if (b.count("authenticationURL")) member["authenticationURL"] = OSUtils::jsonString(b["authenticationURL"], "");
|
||||
if (b.count("activeBridge")) member["activeBridge"] = OSUtils::jsonBool(b["activeBridge"],false);
|
||||
if (b.count("noAutoAssignIps")) member["noAutoAssignIps"] = OSUtils::jsonBool(b["noAutoAssignIps"],false);
|
||||
|
||||
if (b.count("remoteTraceTarget")) {
|
||||
const std::string rtt(OSUtils::jsonString(b["remoteTraceTarget"],""));
|
||||
|
@ -1280,7 +1248,7 @@ void EmbeddedNetworkController::_request(
|
|||
Utils::hex(nwid,nwids);
|
||||
_db.get(nwid,network,identity.address().toInt(),member,ns);
|
||||
if ((!network.is_object())||(network.empty())) {
|
||||
_sender->ncSendError(nwid,requestPacketId,identity.address(),NetworkController::NC_ERROR_OBJECT_NOT_FOUND, nullptr, 0);
|
||||
_sender->ncSendError(nwid,requestPacketId,identity.address(),NetworkController::NC_ERROR_OBJECT_NOT_FOUND);
|
||||
return;
|
||||
}
|
||||
const bool newMember = ((!member.is_object())||(member.empty()));
|
||||
|
@ -1294,11 +1262,11 @@ void EmbeddedNetworkController::_request(
|
|||
// known member.
|
||||
try {
|
||||
if (Identity(haveIdStr.c_str()) != identity) {
|
||||
_sender->ncSendError(nwid,requestPacketId,identity.address(),NetworkController::NC_ERROR_ACCESS_DENIED, nullptr, 0);
|
||||
_sender->ncSendError(nwid,requestPacketId,identity.address(),NetworkController::NC_ERROR_ACCESS_DENIED);
|
||||
return;
|
||||
}
|
||||
} catch ( ... ) {
|
||||
_sender->ncSendError(nwid,requestPacketId,identity.address(),NetworkController::NC_ERROR_ACCESS_DENIED, nullptr, 0);
|
||||
_sender->ncSendError(nwid,requestPacketId,identity.address(),NetworkController::NC_ERROR_ACCESS_DENIED);
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
|
@ -1355,38 +1323,6 @@ void EmbeddedNetworkController::_request(
|
|||
member["lastAuthorizedCredential"] = autoAuthCredential;
|
||||
}
|
||||
|
||||
// Should we check SSO Stuff?
|
||||
// If network is configured with SSO, and the member is not marked exempt: yes
|
||||
// Otherwise no, we use standard auth logic.
|
||||
bool networkSSOEnabled = OSUtils::jsonBool(network["ssoEnabled"], false);
|
||||
bool memberSSOExempt = OSUtils::jsonBool(member["ssoExempt"], false);
|
||||
std::string authenticationURL;
|
||||
if (networkSSOEnabled && !memberSSOExempt) {
|
||||
authenticationURL = _db.getSSOAuthURL(member, _ssoRedirectURL);
|
||||
std::string memberId = member["id"];
|
||||
//fprintf(stderr, "ssoEnabled && !ssoExempt %s-%s\n", nwids, memberId.c_str());
|
||||
uint64_t authenticationExpiryTime = (int64_t)OSUtils::jsonInt(member["authenticationExpiryTime"], 0);
|
||||
//fprintf(stderr, "authExpiryTime: %lld\n", authenticationExpiryTime);
|
||||
if (authenticationExpiryTime < now) {
|
||||
if (!authenticationURL.empty()) {
|
||||
_db.networkMemberSSOHasExpired(nwid, now);
|
||||
onNetworkMemberDeauthorize(&_db, nwid, identity.address().toInt());
|
||||
|
||||
Dictionary<3072> authInfo;
|
||||
authInfo.add("aU", authenticationURL.c_str());
|
||||
//fprintf(stderr, "sending auth URL: %s\n", authenticationURL.c_str());
|
||||
|
||||
DB::cleanMember(member);
|
||||
_db.save(member,true);
|
||||
|
||||
_sender->ncSendError(nwid,requestPacketId,identity.address(),NetworkController::NC_ERROR_AUTHENTICATION_REQUIRED, authInfo.data(), authInfo.sizeBytes());
|
||||
return;
|
||||
}
|
||||
} else if (authorized) {
|
||||
_db.memberWillExpire(authenticationExpiryTime, nwid, identity.address().toInt());
|
||||
}
|
||||
}
|
||||
|
||||
if (authorized) {
|
||||
// Update version info and meta-data if authorized and if this is a genuine request
|
||||
if (requestPacketId) {
|
||||
|
@ -1411,18 +1347,17 @@ void EmbeddedNetworkController::_request(
|
|||
ms.lastRequestMetaData = metaData;
|
||||
ms.identity = identity;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
||||
// If they are not authorized, STOP!
|
||||
DB::cleanMember(member);
|
||||
_db.save(member,true);
|
||||
_sender->ncSendError(nwid,requestPacketId,identity.address(),NetworkController::NC_ERROR_ACCESS_DENIED, nullptr, 0);
|
||||
_sender->ncSendError(nwid,requestPacketId,identity.address(),NetworkController::NC_ERROR_ACCESS_DENIED);
|
||||
return;
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// If we made it this far, they are authorized (and authenticated).
|
||||
// If we made it this far, they are authorized.
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
int64_t credentialtmd = ZT_NETWORKCONFIG_DEFAULT_CREDENTIAL_TIME_MAX_MAX_DELTA;
|
||||
|
@ -1451,11 +1386,7 @@ void EmbeddedNetworkController::_request(
|
|||
nc->mtu = std::max(std::min((unsigned int)OSUtils::jsonInt(network["mtu"],ZT_DEFAULT_MTU),(unsigned int)ZT_MAX_MTU),(unsigned int)ZT_MIN_MTU);
|
||||
nc->multicastLimit = (unsigned int)OSUtils::jsonInt(network["multicastLimit"],32ULL);
|
||||
|
||||
nc->ssoEnabled = OSUtils::jsonBool(network["ssoEnabled"], false);
|
||||
nc->authenticationExpiryTime = OSUtils::jsonInt(member["authenticationExpiryTime"], 0LL);
|
||||
if (!authenticationURL.empty())
|
||||
Utils::scopy(nc->authenticationURL, sizeof(nc->authenticationURL), authenticationURL.c_str());
|
||||
|
||||
|
||||
std::string rtt(OSUtils::jsonString(member["remoteTraceTarget"],""));
|
||||
if (rtt.length() == 10) {
|
||||
nc->remoteTraceTarget = Address(Utils::hexStrToU64(rtt.c_str()));
|
||||
|
@ -1484,8 +1415,6 @@ void EmbeddedNetworkController::_request(
|
|||
json &memberTags = member["tags"];
|
||||
json &dns = network["dns"];
|
||||
|
||||
//fprintf(stderr, "IP Assignment Pools for Network %s: %s\n", nwids, OSUtils::jsonDump(ipAssignmentPools, 2).c_str());
|
||||
|
||||
if (metaData.getUI(ZT_NETWORKCONFIG_REQUEST_METADATA_KEY_RULES_ENGINE_REV,0) <= 0) {
|
||||
// Old versions with no rules engine support get an allow everything rule.
|
||||
// Since rules are enforced bidirectionally, newer versions *will* still
|
||||
|
@ -1801,11 +1730,11 @@ void EmbeddedNetworkController::_request(
|
|||
nc->certificateOfOwnershipCount = 1;
|
||||
}
|
||||
|
||||
CertificateOfMembership com(now,credentialtmd,nwid,identity);
|
||||
CertificateOfMembership com(now,credentialtmd,nwid,identity.address());
|
||||
if (com.sign(_signingId)) {
|
||||
nc->com = com;
|
||||
} else {
|
||||
_sender->ncSendError(nwid,requestPacketId,identity.address(),NetworkController::NC_ERROR_INTERNAL_SERVER_ERROR, nullptr, 0);
|
||||
_sender->ncSendError(nwid,requestPacketId,identity.address(),NetworkController::NC_ERROR_INTERNAL_SERVER_ERROR);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1824,44 +1753,17 @@ void EmbeddedNetworkController::_startThreads()
|
|||
_threads.emplace_back([this]() {
|
||||
for(;;) {
|
||||
_RQEntry *qe = (_RQEntry *)0;
|
||||
auto timedWaitResult = _queue.get(qe, 1000);
|
||||
if (timedWaitResult == BlockingQueue<_RQEntry *>::STOP) {
|
||||
if (!_queue.get(qe))
|
||||
break;
|
||||
} else if (timedWaitResult == BlockingQueue<_RQEntry *>::OK) {
|
||||
try {
|
||||
if (qe) {
|
||||
try {
|
||||
_request(qe->nwid,qe->fromAddr,qe->requestPacketId,qe->identity,qe->metaData);
|
||||
} catch (std::exception &e) {
|
||||
fprintf(stderr,"ERROR: exception in controller request handling thread: %s" ZT_EOL_S,e.what());
|
||||
} catch ( ... ) {
|
||||
fprintf(stderr,"ERROR: exception in controller request handling thread: unknown exception" ZT_EOL_S);
|
||||
}
|
||||
_request(qe->nwid,qe->fromAddr,qe->requestPacketId,qe->identity,qe->metaData);
|
||||
delete qe;
|
||||
}
|
||||
}
|
||||
|
||||
std::set< std::pair<uint64_t, uint64_t> > soon;
|
||||
std::set< std::pair<uint64_t, uint64_t> > expired;
|
||||
_db.membersExpiring(soon, expired);
|
||||
|
||||
for(auto s=soon.begin();s!=soon.end();++s) {
|
||||
Identity identity;
|
||||
Dictionary<ZT_NETWORKCONFIG_METADATA_DICT_CAPACITY> lastMetaData;
|
||||
{
|
||||
std::unique_lock<std::mutex> ll(_memberStatus_l);
|
||||
auto ms = _memberStatus.find(_MemberStatusKey(s->first, s->second));
|
||||
if (ms != _memberStatus.end()) {
|
||||
lastMetaData = ms->second.lastRequestMetaData;
|
||||
identity = ms->second.identity;
|
||||
}
|
||||
}
|
||||
if (identity) {
|
||||
request(s->first,InetAddress(),0,identity,lastMetaData);
|
||||
}
|
||||
}
|
||||
|
||||
for(auto e=expired.begin();e!=expired.end();++e) {
|
||||
onNetworkMemberDeauthorize(nullptr, e->first, e->second);
|
||||
} catch (std::exception &e) {
|
||||
fprintf(stderr,"ERROR: exception in controller request handling thread: %s" ZT_EOL_S,e.what());
|
||||
} catch ( ... ) {
|
||||
fprintf(stderr,"ERROR: exception in controller request handling thread: unknown exception" ZT_EOL_S);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
|
|
@ -57,8 +57,6 @@ public:
|
|||
|
||||
virtual void init(const Identity &signingId,Sender *sender);
|
||||
|
||||
void setSSORedirectURL(const std::string &url);
|
||||
|
||||
virtual void request(
|
||||
uint64_t nwid,
|
||||
const InetAddress &fromAddr,
|
||||
|
@ -153,7 +151,6 @@ private:
|
|||
std::mutex _memberStatus_l;
|
||||
|
||||
RedisConfig *_rc;
|
||||
std::string _ssoRedirectURL;
|
||||
};
|
||||
|
||||
} // namespace ZeroTier
|
||||
|
|
|
@ -140,7 +140,8 @@ void FileDB::eraseNetwork(const uint64_t networkId)
|
|||
void FileDB::eraseMember(const uint64_t networkId,const uint64_t memberId)
|
||||
{
|
||||
nlohmann::json network,member,nullJson;
|
||||
get(networkId,network,memberId,member);
|
||||
get(networkId,network);
|
||||
get(memberId,member);
|
||||
char p[4096];
|
||||
OSUtils::ztsnprintf(p,sizeof(p),"%s" ZT_PATH_SEPARATOR_S "%.16llx" ZT_PATH_SEPARATOR_S "member" ZT_PATH_SEPARATOR_S "%.10llx.json",_networksPath.c_str(),networkId,memberId);
|
||||
OSUtils::rm(p);
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -20,9 +20,6 @@
|
|||
|
||||
#define ZT_CENTRAL_CONTROLLER_COMMIT_THREADS 4
|
||||
|
||||
#include "ConnectionPool.hpp"
|
||||
#include <pqxx/pqxx>
|
||||
|
||||
#include <memory>
|
||||
#include <redis++/redis++.h>
|
||||
|
||||
|
@ -34,69 +31,14 @@ namespace ZeroTier {
|
|||
|
||||
struct RedisConfig;
|
||||
|
||||
|
||||
class PostgresConnection : public Connection {
|
||||
public:
|
||||
virtual ~PostgresConnection() {
|
||||
}
|
||||
|
||||
std::shared_ptr<pqxx::connection> c;
|
||||
int a;
|
||||
};
|
||||
|
||||
|
||||
class PostgresConnFactory : public ConnectionFactory {
|
||||
public:
|
||||
PostgresConnFactory(std::string &connString)
|
||||
: m_connString(connString)
|
||||
{
|
||||
}
|
||||
|
||||
virtual std::shared_ptr<Connection> create() {
|
||||
auto c = std::shared_ptr<PostgresConnection>(new PostgresConnection());
|
||||
c->c = std::make_shared<pqxx::connection>(m_connString);
|
||||
return std::static_pointer_cast<Connection>(c);
|
||||
}
|
||||
private:
|
||||
std::string m_connString;
|
||||
};
|
||||
|
||||
class PostgreSQL;
|
||||
|
||||
class MemberNotificationReceiver : public pqxx::notification_receiver {
|
||||
public:
|
||||
MemberNotificationReceiver(PostgreSQL *p, pqxx::connection &c, const std::string &channel);
|
||||
virtual ~MemberNotificationReceiver() {
|
||||
fprintf(stderr, "MemberNotificationReceiver destroyed\n");
|
||||
}
|
||||
|
||||
virtual void operator() (const std::string &payload, int backendPid);
|
||||
private:
|
||||
PostgreSQL *_psql;
|
||||
};
|
||||
|
||||
class NetworkNotificationReceiver : public pqxx::notification_receiver {
|
||||
public:
|
||||
NetworkNotificationReceiver(PostgreSQL *p, pqxx::connection &c, const std::string &channel);
|
||||
virtual ~NetworkNotificationReceiver() {
|
||||
fprintf(stderr, "NetworkNotificationReceiver destroyed\n");
|
||||
};
|
||||
|
||||
virtual void operator() (const std::string &payload, int packend_pid);
|
||||
private:
|
||||
PostgreSQL *_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.
|
||||
* but be aware taht 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();
|
||||
|
@ -107,29 +49,21 @@ public:
|
|||
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 std::string getSSOAuthURL(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 initializeNetworks(PGconn *conn);
|
||||
void initializeMembers(PGconn *conn);
|
||||
void heartbeat();
|
||||
void membersDbWatcher();
|
||||
void _membersWatcher_Postgres();
|
||||
void _membersWatcher_Postgres(PGconn *conn);
|
||||
void networksDbWatcher();
|
||||
void _networksWatcher_Postgres();
|
||||
void _networksWatcher_Postgres(PGconn *conn);
|
||||
|
||||
void _membersWatcher_Redis();
|
||||
void _networksWatcher_Redis();
|
||||
|
@ -146,7 +80,7 @@ private:
|
|||
NO_OVERRIDE = 1
|
||||
};
|
||||
|
||||
std::shared_ptr<ConnectionPool<PostgresConnection> > _pool;
|
||||
PGconn * getPgConn( OverrideMode m = ALLOW_PGBOUNCER_OVERRIDE );
|
||||
|
||||
const Identity _myId;
|
||||
const Address _myAddress;
|
||||
|
@ -169,7 +103,6 @@ private:
|
|||
mutable volatile bool _waitNoticePrinted;
|
||||
|
||||
int _listenPort;
|
||||
uint8_t _ssoPsk[48];
|
||||
|
||||
RedisConfig *_rc;
|
||||
std::shared_ptr<sw::redis::Redis> _redis;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue