Merge branch 'dev'

This commit is contained in:
Adam Ierymenko 2020-10-08 18:08:24 -04:00
commit 24769219b5
393 changed files with 74602 additions and 12278 deletions

View file

@ -4,7 +4,7 @@
* 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: 2023-01-01
* 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.
@ -48,6 +48,8 @@ void DB::initNetwork(nlohmann::json &network)
{ "type","ACTION_ACCEPT" }
}};
}
if (!network.count("dns")) network["dns"] = nlohmann::json::array();
network["objtype"] = "network";
}

View file

@ -4,7 +4,7 @@
* 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: 2023-01-01
* 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.

View file

@ -4,7 +4,7 @@
* 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: 2023-01-01
* 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.

View file

@ -4,7 +4,7 @@
* 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: 2023-01-01
* 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.

View file

@ -4,7 +4,7 @@
* 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: 2023-01-01
* 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.
@ -456,7 +456,7 @@ static bool _parseRule(json &r,ZT_VirtualNetworkRule &rule)
} // anonymous namespace
EmbeddedNetworkController::EmbeddedNetworkController(Node *node,const char *ztPath,const char *dbPath, int listenPort, MQConfig *mqc) :
EmbeddedNetworkController::EmbeddedNetworkController(Node *node,const char *ztPath,const char *dbPath, int listenPort, RedisConfig *rc) :
_startTime(OSUtils::now()),
_listenPort(listenPort),
_node(node),
@ -464,7 +464,7 @@ EmbeddedNetworkController::EmbeddedNetworkController(Node *node,const char *ztPa
_path(dbPath),
_sender((NetworkController::Sender *)0),
_db(this),
_mqc(mqc)
_rc(rc)
{
}
@ -485,7 +485,7 @@ 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, _mqc)));
_db.addDB(std::shared_ptr<DB>(new PostgreSQL(_signingId,_path.substr(9).c_str(), _listenPort, _rc)));
} else {
#endif
_db.addDB(std::shared_ptr<DB>(new FileDB(_path.c_str())));
@ -585,7 +585,7 @@ unsigned int EmbeddedNetworkController::handleControlPlaneHttpGET(
responseBody.reserve((members.size() + 2) * 32);
std::string mid;
for(auto member=members.begin();member!=members.end();++member) {
mid = (*member)["id"];
mid = OSUtils::jsonString((*member)["id"], "");
char tmp[128];
OSUtils::ztsnprintf(tmp,sizeof(tmp),"%s\"%s\":%llu",(responseBody.length() > 1) ? "," : "",mid.c_str(),(unsigned long long)OSUtils::jsonInt((*member)["revision"],0));
responseBody.append(tmp);
@ -1029,6 +1029,26 @@ unsigned int EmbeddedNetworkController::handleControlPlaneHttpPOST(
}
}
if (b.count("dns")) {
json &dns = b["dns"];
if (dns.is_object()) {
json nd;
nd["domain"] = dns["domain"];
json &srv = dns["servers"];
if (srv.is_array()) {
json ns = json::array();
for(unsigned int i=0;i<srv.size();++i) {
ns.push_back(srv[i]);
}
nd["servers"] = ns;
}
network["dns"] = nd;
}
}
} catch ( ... ) {
responseBody = "{ \"message\": \"exception occurred while parsing body variables\" }";
responseContentType = "application/json";
@ -1366,6 +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);
std::string rtt(OSUtils::jsonString(member["remoteTraceTarget"],""));
if (rtt.length() == 10) {
nc->remoteTraceTarget = Address(Utils::hexStrToU64(rtt.c_str()));
@ -1392,6 +1413,7 @@ void EmbeddedNetworkController::_request(
json &tags = network["tags"];
json &memberCapabilities = member["capabilities"];
json &memberTags = member["tags"];
json &dns = network["dns"];
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.
@ -1684,6 +1706,20 @@ void EmbeddedNetworkController::_request(
}
}
}
if(dns.is_object()) {
std::string domain = OSUtils::jsonString(dns["domain"],"");
memcpy(nc->dns.domain, domain.c_str(), domain.size());
json &addrArray = dns["servers"];
if (addrArray.is_array()) {
for(unsigned int j = 0; j < addrArray.size() && j < ZT_MAX_DNS_SERVERS; ++j) {
json &addr = addrArray[j];
nc->dns.server_addr[j] = InetAddress(OSUtils::jsonString(addr,"").c_str());
}
}
} else {
dns = json::object();
}
// Issue a certificate of ownership for all static IPs
if (nc->staticIpCount) {

View file

@ -4,7 +4,7 @@
* 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: 2023-01-01
* 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.
@ -43,8 +43,7 @@
namespace ZeroTier {
class Node;
struct MQConfig;
struct RedisConfig;
class EmbeddedNetworkController : public NetworkController,public DB::ChangeListener
{
@ -53,7 +52,7 @@ public:
* @param node Parent node
* @param dbPath Database path (file path or database credentials)
*/
EmbeddedNetworkController(Node *node,const char *ztPath,const char *dbPath, int listenPort, MQConfig *mqc = NULL);
EmbeddedNetworkController(Node *node,const char *ztPath,const char *dbPath, int listenPort, RedisConfig *rc);
virtual ~EmbeddedNetworkController();
virtual void init(const Identity &signingId,Sender *sender);
@ -151,7 +150,7 @@ private:
std::unordered_map< _MemberStatusKey,_MemberStatus,_MemberStatusHash > _memberStatus;
std::mutex _memberStatus_l;
MQConfig *_mqc;
RedisConfig *_rc;
};
} // namespace ZeroTier

View file

@ -4,7 +4,7 @@
* 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: 2023-01-01
* 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.

View file

@ -4,7 +4,7 @@
* 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: 2023-01-01
* 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.

View file

@ -4,7 +4,7 @@
* 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: 2023-01-01
* 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.
@ -48,7 +48,7 @@ LFDB::LFDB(const Identity &myId,const char *path,const char *lfOwnerPrivate,cons
char maskingKey [128];
Utils::hex(sha512pk,32,maskingKey);
httplib::Client htcli(_lfNodeHost.c_str(),_lfNodePort,600);
httplib::Client htcli(_lfNodeHost.c_str(),_lfNodePort);
int64_t timeRangeStart = 0;
while (_running.load()) {
{

View file

@ -4,7 +4,7 @@
* 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: 2023-01-01
* 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.

File diff suppressed because it is too large Load diff

View file

@ -4,7 +4,7 @@
* 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: 2023-01-01
* 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.
@ -20,13 +20,16 @@
#define ZT_CENTRAL_CONTROLLER_COMMIT_THREADS 4
#include <memory>
#include <redis++/redis++.h>
extern "C" {
typedef struct pg_conn PGconn;
}
namespace ZeroTier {
struct MQConfig;
struct RedisConfig;
/**
* A controller database driver that talks to PostgreSQL
@ -37,7 +40,7 @@ struct MQConfig;
class PostgreSQL : public DB
{
public:
PostgreSQL(const Identity &myId, const char *path, int listenPort, MQConfig *mqc = NULL);
PostgreSQL(const Identity &myId, const char *path, int listenPort, RedisConfig *rc);
virtual ~PostgreSQL();
virtual bool waitForReady();
@ -59,13 +62,18 @@ private:
void heartbeat();
void membersDbWatcher();
void _membersWatcher_Postgres(PGconn *conn);
void _membersWatcher_RabbitMQ();
void networksDbWatcher();
void _networksWatcher_Postgres(PGconn *conn);
void _networksWatcher_RabbitMQ();
void _membersWatcher_Redis();
void _networksWatcher_Redis();
void commitThread();
void onlineNotificationThread();
void onlineNotification_Postgres();
void onlineNotification_Redis();
void _doRedisUpdate(sw::redis::Transaction &tx, std::string &controllerId,
std::unordered_map< std::pair<uint64_t,uint64_t>,std::pair<int64_t,InetAddress>,_PairHasher > &lastOnline);
enum OverrideMode {
ALLOW_PGBOUNCER_OVERRIDE = 0,
@ -96,7 +104,9 @@ private:
int _listenPort;
MQConfig *_mqc;
RedisConfig *_rc;
std::shared_ptr<sw::redis::Redis> _redis;
std::shared_ptr<sw::redis::RedisCluster> _cluster;
};
} // namespace ZeroTier

View file

@ -1,120 +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: 2023-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 "RabbitMQ.hpp"
#ifdef ZT_CONTROLLER_USE_LIBPQ
#include <amqp.h>
#include <amqp_tcp_socket.h>
#include <stdexcept>
#include <cstring>
namespace ZeroTier
{
RabbitMQ::RabbitMQ(MQConfig *cfg, const char *queueName)
: _mqc(cfg)
, _qName(queueName)
, _socket(NULL)
, _status(0)
{
}
RabbitMQ::~RabbitMQ()
{
amqp_channel_close(_conn, _channel, AMQP_REPLY_SUCCESS);
amqp_connection_close(_conn, AMQP_REPLY_SUCCESS);
amqp_destroy_connection(_conn);
}
void RabbitMQ::init()
{
struct timeval tval;
memset(&tval, 0, sizeof(struct timeval));
tval.tv_sec = 5;
fprintf(stderr, "Initializing RabbitMQ %s\n", _qName);
_conn = amqp_new_connection();
_socket = amqp_tcp_socket_new(_conn);
if (!_socket) {
throw std::runtime_error("Can't create socket for RabbitMQ");
}
_status = amqp_socket_open_noblock(_socket, _mqc->host.c_str(), _mqc->port, &tval);
if (_status) {
throw std::runtime_error("Can't connect to RabbitMQ");
}
amqp_rpc_reply_t r = amqp_login(_conn, "/", 0, 131072, 0, AMQP_SASL_METHOD_PLAIN,
_mqc->username.c_str(), _mqc->password.c_str());
if (r.reply_type != AMQP_RESPONSE_NORMAL) {
throw std::runtime_error("RabbitMQ Login Error");
}
static int chan = 0;
{
Mutex::Lock l(_chan_m);
_channel = ++chan;
}
amqp_channel_open(_conn, _channel);
r = amqp_get_rpc_reply(_conn);
if(r.reply_type != AMQP_RESPONSE_NORMAL) {
throw std::runtime_error("Error opening communication channel");
}
_q = amqp_queue_declare(_conn, _channel, amqp_cstring_bytes(_qName), 0, 0, 0, 0, amqp_empty_table);
r = amqp_get_rpc_reply(_conn);
if (r.reply_type != AMQP_RESPONSE_NORMAL) {
throw std::runtime_error("Error declaring queue " + std::string(_qName));
}
amqp_basic_consume(_conn, _channel, amqp_cstring_bytes(_qName), amqp_empty_bytes, 0, 1, 0, amqp_empty_table);
r = amqp_get_rpc_reply(_conn);
if (r.reply_type != AMQP_RESPONSE_NORMAL) {
throw std::runtime_error("Error consuming queue " + std::string(_qName));
}
fprintf(stderr, "RabbitMQ Init OK %s\n", _qName);
}
std::string RabbitMQ::consume()
{
amqp_rpc_reply_t res;
amqp_envelope_t envelope;
amqp_maybe_release_buffers(_conn);
struct timeval timeout;
timeout.tv_sec = 1;
timeout.tv_usec = 0;
res = amqp_consume_message(_conn, &envelope, &timeout, 0);
if (res.reply_type != AMQP_RESPONSE_NORMAL) {
if (res.reply_type == AMQP_RESPONSE_LIBRARY_EXCEPTION && res.library_error == AMQP_STATUS_TIMEOUT) {
// timeout waiting for message. Return empty string
return "";
} else {
throw std::runtime_error("Error getting message");
}
}
std::string msg(
(const char*)envelope.message.body.bytes,
envelope.message.body.len
);
amqp_destroy_envelope(&envelope);
return msg;
}
}
#endif // ZT_CONTROLLER_USE_LIBPQ

View file

@ -1,69 +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: 2023-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_RABBITMQ_HPP
#define ZT_CONTROLLER_RABBITMQ_HPP
#include "DB.hpp"
#include <string>
namespace ZeroTier
{
struct MQConfig {
std::string host;
int port;
std::string username;
std::string password;
};
}
#ifdef ZT_CONTROLLER_USE_LIBPQ
#include "../node/Mutex.hpp"
#include <amqp.h>
#include <amqp_tcp_socket.h>
namespace ZeroTier
{
class RabbitMQ {
public:
RabbitMQ(MQConfig *cfg, const char *queueName);
~RabbitMQ();
void init();
std::string consume();
private:
MQConfig *_mqc;
const char *_qName;
amqp_socket_t *_socket;
amqp_connection_state_t _conn;
amqp_queue_declare_ok_t *_q;
int _status;
int _channel;
Mutex _chan_m;
};
}
#endif // ZT_CONTROLLER_USE_LIBPQ
#endif // ZT_CONTROLLER_RABBITMQ_HPP

15
controller/Redis.hpp Normal file
View file

@ -0,0 +1,15 @@
#ifndef ZT_CONTROLLER_REDIS_HPP
#define ZT_CONTROLLER_REDIS_HPP
#include <string>
namespace ZeroTier {
struct RedisConfig {
std::string hostname;
int port;
std::string password;
bool clusterMode;
};
}
#endif