mirror of
https://github.com/zerotier/ZeroTierOne.git
synced 2025-01-29 15:43:52 +00:00
Netconf build fixes, schema, etc.
This commit is contained in:
parent
fab951e98a
commit
31bf0a4ea6
1
.gitignore
vendored
1
.gitignore
vendored
@ -43,3 +43,4 @@
|
||||
/testnet/local-testnet/*/root-topology
|
||||
/testnet/local-testnet/*/local.conf
|
||||
/testnet/local-testnet/*/networks.d
|
||||
/netconf/netconf.db
|
||||
|
@ -6,8 +6,8 @@ DEFS=
|
||||
LIBS=
|
||||
|
||||
include objects.mk
|
||||
OBJS+=osnet/BSDEthernetTapFactory.o osnet/BSDEthernetTap.o osnet/BSDRoutingTable.o
|
||||
TESTNET_OBJS=testnet/SimNet.o testnet/SimNetSocketManager.o testnet/TestEthernetTap.o testnet/TestEthernetTapFactory.o testnet/TestRoutingTable.o
|
||||
OBJS+=osnet/BSDEthernetTapFactory.o osnet/BSDEthernetTap.o osnet/BSDRoutingTable.o
|
||||
TESTNET_OBJS=testnet/SimNet.o testnet/SimNetSocketManager.o testnet/TestEthernetTap.o testnet/TestEthernetTapFactory.o testnet/TestRoutingTable.o
|
||||
|
||||
# Enable SSE-optimized Salsa20 on x86 and x86_64 machines
|
||||
MACHINE=$(shell uname -m)
|
||||
@ -30,6 +30,13 @@ ifeq ($(MACHINE),x86)
|
||||
DEFS+=-DZT_SALSA20_SSE
|
||||
endif
|
||||
|
||||
# Build with ZT_ENABLE_NETCONF_MASTER=1 to build with NetworkConfigMaster enabled
|
||||
ifeq ($(ZT_ENABLE_NETCONF_MASTER),1)
|
||||
DEFS+=-DZT_ENABLE_NETCONF_MASTER
|
||||
LIBS+=-lsqlite3
|
||||
OBJS+=netconf/SqliteNetworkConfigMaster.o
|
||||
endif
|
||||
|
||||
# "make official" is a shortcut for this
|
||||
ifeq ($(ZT_OFFICIAL_RELEASE),1)
|
||||
ZT_AUTO_UPDATE=1
|
||||
|
@ -7,8 +7,8 @@ DEFS=
|
||||
LIBS=
|
||||
|
||||
include objects.mk
|
||||
OBJS+=osnet/LinuxRoutingTable.o osnet/LinuxEthernetTap.o osnet/LinuxEthernetTapFactory.o
|
||||
TESTNET_OBJS=testnet/SimNet.o testnet/SimNetSocketManager.o testnet/TestEthernetTap.o testnet/TestEthernetTapFactory.o testnet/TestRoutingTable.o
|
||||
OBJS+=osnet/LinuxRoutingTable.o osnet/LinuxEthernetTap.o osnet/LinuxEthernetTapFactory.o
|
||||
TESTNET_OBJS=testnet/SimNet.o testnet/SimNetSocketManager.o testnet/TestEthernetTap.o testnet/TestEthernetTapFactory.o testnet/TestRoutingTable.o
|
||||
|
||||
# Enable SSE-optimized Salsa20 on x86 and x86_64 machines
|
||||
MACHINE=$(shell uname -m)
|
||||
@ -34,7 +34,8 @@ endif
|
||||
# Build with ZT_ENABLE_NETCONF_MASTER=1 to build with NetworkConfigMaster enabled
|
||||
ifeq ($(ZT_ENABLE_NETCONF_MASTER),1)
|
||||
DEFS+=-DZT_ENABLE_NETCONF_MASTER
|
||||
LIBS+=-lhiredis
|
||||
LIBS+=-lsqlite3
|
||||
OBJS+=netconf/SqliteNetworkConfigMaster.o
|
||||
endif
|
||||
|
||||
# "make official" is a shortcut for this
|
||||
|
@ -29,8 +29,9 @@ endif
|
||||
# Build with ZT_ENABLE_NETCONF_MASTER=1 to build with NetworkConfigMaster enabled
|
||||
ifeq ($(ZT_ENABLE_NETCONF_MASTER),1)
|
||||
DEFS+=-DZT_ENABLE_NETCONF_MASTER
|
||||
LIBS+=-L/usr/local/lib -lhiredis
|
||||
LIBS+=-L/usr/local/lib -lsqlite3
|
||||
ARCH_FLAGS=-arch x86_64
|
||||
OBJS+=netconf/SqliteNetworkConfigMaster.o
|
||||
endif
|
||||
|
||||
# Enable SSE-optimized Salsa20 -- all Intel macs support SSE2
|
||||
|
@ -11,9 +11,13 @@ By default this code is not built or included in the client. To build on Linux,
|
||||
|
||||
### Running
|
||||
|
||||
When you run a node with netconf support, a SQLite3 database will be created in the ZeroTier One working directory. On Linux this is /var/lib/zerotier-one by default unless you run the service with a command line to specify something else.
|
||||
To enable netconf functionality, place a properly initialized SQLite3 database called **netconf.db** into the ZeroTier working directory of the node you wish to serve network configurations and restart it. If that file is present it will be opened and the network configuration master function will be enabled. You will see this in the log file.
|
||||
|
||||
This database can be attached to and modified while the service is running as per SQLite3's rather awesome sharing capabilities. For now you're on your own in that department too, but in the future we might ship some code for this.
|
||||
To initialize a database run:
|
||||
|
||||
sqlite3 -init netconf-schema.sql netconf.db
|
||||
|
||||
Then type '.quit' to exit the SQLite3 command shell.
|
||||
|
||||
### Reliability
|
||||
|
||||
|
@ -37,40 +37,37 @@
|
||||
#include <utility>
|
||||
#include <stdexcept>
|
||||
|
||||
#include "RedisNetworkConfigMaster.hpp"
|
||||
#include "SqliteNetworkConfigMaster.hpp"
|
||||
#include "../node/Utils.hpp"
|
||||
#include "../node/CertificateOfMembership.hpp"
|
||||
#include "../node/NetworkConfig.hpp"
|
||||
|
||||
namespace ZeroTier {
|
||||
|
||||
RedisNetworkConfigMaster::RedisNetworkConfigMaster(
|
||||
const Identity &signingId,
|
||||
const char *redisHost,
|
||||
unsigned int redisPort,
|
||||
const char *redisPassword,
|
||||
unsigned int redisDatabaseNumber) :
|
||||
_lock(),
|
||||
SqliteNetworkConfigMaster::SqliteNetworkConfigMaster(const Identity &signingId,const char *dbPath) :
|
||||
_signingId(signingId),
|
||||
_redisHost(redisHost),
|
||||
_redisPassword((redisPassword) ? redisPassword : ""),
|
||||
_redisPort(redisPort),
|
||||
_redisDatabaseNumber(redisDatabaseNumber),
|
||||
_rc((redisContext *)0)
|
||||
_dbPath(dbPath),
|
||||
_db((sqlite3 *)0)
|
||||
_lock()
|
||||
{
|
||||
if (!_signingId.hasPrivate())
|
||||
throw std::runtime_error("RedisNetworkConfigMaster signing identity must have a private key");
|
||||
throw std::runtime_error("SqliteNetworkConfigMaster signing identity must have a private key");
|
||||
|
||||
if (sqlite3_open_v2(dbPath,&_db,SQLITE_OPEN_READWRITE,(const char *)0) != SQLITE_OK)
|
||||
throw std::runtime_error("SqliteNetworkConfigMaster cannot open database file");
|
||||
sqlite3_busy_timeout(_db,10000);
|
||||
}
|
||||
|
||||
RedisNetworkConfigMaster::~RedisNetworkConfigMaster()
|
||||
SqliteNetworkConfigMaster::~SqliteNetworkConfigMaster()
|
||||
{
|
||||
Mutex::Lock _l(_lock);
|
||||
if (_rc)
|
||||
redisFree(_rc);
|
||||
if (_db)
|
||||
sqlite3_close(_db);
|
||||
}
|
||||
|
||||
NetworkConfigMaster::ResultCode RedisNetworkConfigMaster::doNetworkConfigRequest(const InetAddress &fromAddr,uint64_t packetId,const Identity &member,uint64_t nwid,const Dictionary &metaData,uint64_t haveTimestamp,Dictionary &netconf)
|
||||
NetworkConfigMaster::ResultCode SqliteNetworkConfigMaster::doNetworkConfigRequest(const InetAddress &fromAddr,uint64_t packetId,const Identity &member,uint64_t nwid,const Dictionary &metaData,uint64_t haveTimestamp,Dictionary &netconf)
|
||||
{
|
||||
#if 0
|
||||
char memberKey[128],nwids[24],addrs[16],nwKey[128],revKey[128];
|
||||
Dictionary memberRecord;
|
||||
std::string revision,tmps2;
|
||||
@ -87,7 +84,7 @@ NetworkConfigMaster::ResultCode RedisNetworkConfigMaster::doNetworkConfigRequest
|
||||
|
||||
// Check to make sure network itself exists and is valid
|
||||
if (!_hget(nwKey,"id",tmps2)) {
|
||||
netconf["error"] = "Redis error retrieving network record ID field";
|
||||
netconf["error"] = "Sqlite error retrieving network record ID field";
|
||||
return NetworkConfigMaster::NETCONF_QUERY_INTERNAL_SERVER_ERROR;
|
||||
}
|
||||
if (tmps2 != nwids)
|
||||
@ -95,7 +92,7 @@ NetworkConfigMaster::ResultCode RedisNetworkConfigMaster::doNetworkConfigRequest
|
||||
|
||||
// Get network revision
|
||||
if (!_get(revKey,revision)) {
|
||||
netconf["error"] = "Redis error retrieving network revision";
|
||||
netconf["error"] = "Sqlite error retrieving network revision";
|
||||
return NetworkConfigMaster::NETCONF_QUERY_INTERNAL_SERVER_ERROR;
|
||||
}
|
||||
if (!revision.length())
|
||||
@ -103,7 +100,7 @@ NetworkConfigMaster::ResultCode RedisNetworkConfigMaster::doNetworkConfigRequest
|
||||
|
||||
// Get network member record for this peer
|
||||
if (!_hgetall(memberKey,memberRecord)) {
|
||||
netconf["error"] = "Redis error retrieving member record";
|
||||
netconf["error"] = "Sqlite error retrieving member record";
|
||||
return NetworkConfigMaster::NETCONF_QUERY_INTERNAL_SERVER_ERROR;
|
||||
}
|
||||
|
||||
@ -147,227 +144,12 @@ NetworkConfigMaster::ResultCode RedisNetworkConfigMaster::doNetworkConfigRequest
|
||||
} else {
|
||||
return NetworkConfigMaster::NETCONF_QUERY_ACCESS_DENIED;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
bool RedisNetworkConfigMaster::_reconnect()
|
||||
{
|
||||
struct timeval tv;
|
||||
|
||||
if (_rc)
|
||||
redisFree(_rc);
|
||||
|
||||
tv.tv_sec = ZT_NETCONF_REDIS_TIMEOUT;
|
||||
tv.tv_usec = 0;
|
||||
_rc = redisConnectWithTimeout(_redisHost.c_str(),_redisPort,tv);
|
||||
if (!_rc)
|
||||
return false;
|
||||
if (_rc->err) {
|
||||
redisFree(_rc);
|
||||
_rc = (redisContext *)0;
|
||||
return false;
|
||||
}
|
||||
redisSetTimeout(_rc,tv); // necessary???
|
||||
|
||||
// TODO: support AUTH and SELECT !!!
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool RedisNetworkConfigMaster::_hgetall(const char *key,Dictionary &hdata)
|
||||
{
|
||||
if (!_rc) {
|
||||
if (!_reconnect())
|
||||
return false;
|
||||
}
|
||||
|
||||
redisReply *reply = (redisReply *)redisCommand(_rc,"HGETALL %s",key);
|
||||
if (!reply) {
|
||||
if (_reconnect())
|
||||
return _hgetall(key,hdata);
|
||||
return false;
|
||||
}
|
||||
|
||||
hdata.clear();
|
||||
if (reply->type == REDIS_REPLY_ARRAY) {
|
||||
for(long i=0;i<reply->elements;) {
|
||||
try {
|
||||
const char *k = reply->element[i]->str;
|
||||
if (++i >= reply->elements)
|
||||
break;
|
||||
if ((k)&&(reply->element[i]->str))
|
||||
hdata[k] = reply->element[i]->str;
|
||||
++i;
|
||||
} catch ( ... ) {
|
||||
break; // memory safety
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
freeReplyObject(reply);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool RedisNetworkConfigMaster::_hmset(const char *key,const Dictionary &hdata)
|
||||
{
|
||||
const char *hargv[1024];
|
||||
|
||||
if (!hdata.size())
|
||||
return true;
|
||||
|
||||
if (!_rc) {
|
||||
if (!_reconnect())
|
||||
return false;
|
||||
}
|
||||
|
||||
hargv[0] = "HMSET";
|
||||
hargv[1] = key;
|
||||
int hargc = 2;
|
||||
for(Dictionary::const_iterator i(hdata.begin());i!=hdata.end();++i) {
|
||||
if (hargc >= 1024)
|
||||
break;
|
||||
hargv[hargc++] = i->first.c_str();
|
||||
hargv[hargc++] = i->second.c_str();
|
||||
}
|
||||
|
||||
redisReply *reply = (redisReply *)redisCommandArgv(_rc,hargc,hargv,(const size_t *)0);
|
||||
if (!reply) {
|
||||
if (_reconnect())
|
||||
return _hmset(key,hdata);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (reply->type == REDIS_REPLY_ERROR) {
|
||||
freeReplyObject(reply);
|
||||
return false;
|
||||
}
|
||||
|
||||
freeReplyObject(reply);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool RedisNetworkConfigMaster::_hget(const char *key,const char *hashKey,std::string &value)
|
||||
{
|
||||
if (!_rc) {
|
||||
if (!_reconnect())
|
||||
return false;
|
||||
}
|
||||
|
||||
redisReply *reply = (redisReply *)redisCommand(_rc,"HGET %s %s",key,hashKey);
|
||||
if (!reply) {
|
||||
if (_reconnect())
|
||||
return _hget(key,hashKey,value);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (reply->type == REDIS_REPLY_STRING)
|
||||
value = reply->str;
|
||||
else value = "";
|
||||
|
||||
freeReplyObject(reply);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool RedisNetworkConfigMaster::_hset(const char *key,const char *hashKey,const char *value)
|
||||
{
|
||||
if (!_rc) {
|
||||
if (!_reconnect())
|
||||
return false;
|
||||
}
|
||||
|
||||
redisReply *reply = (redisReply *)redisCommand(_rc,"HSET %s %s %s",key,hashKey,value);
|
||||
if (!reply) {
|
||||
if (_reconnect())
|
||||
return _hset(key,hashKey,value);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (reply->type == REDIS_REPLY_ERROR) {
|
||||
freeReplyObject(reply);
|
||||
return false;
|
||||
}
|
||||
|
||||
freeReplyObject(reply);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool RedisNetworkConfigMaster::_get(const char *key,std::string &value)
|
||||
{
|
||||
if (!_rc) {
|
||||
if (!_reconnect())
|
||||
return false;
|
||||
}
|
||||
|
||||
redisReply *reply = (redisReply *)redisCommand(_rc,"GET %s",key);
|
||||
if (!reply) {
|
||||
if (_reconnect())
|
||||
return _get(key,value);
|
||||
return false;
|
||||
}
|
||||
|
||||
if ((reply->type == REDIS_REPLY_STRING)&&(reply->str))
|
||||
value = reply->str;
|
||||
else value = "";
|
||||
|
||||
freeReplyObject(reply);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool RedisNetworkConfigMaster::_sadd(const char *key,const char *value)
|
||||
{
|
||||
if (!_rc) {
|
||||
if (!_reconnect())
|
||||
return false;
|
||||
}
|
||||
|
||||
redisReply *reply = (redisReply *)redisCommand(_rc,"SADD %s %s",key,value);
|
||||
if (!reply) {
|
||||
if (_reconnect())
|
||||
return _sadd(key,value);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (reply->type == REDIS_REPLY_ERROR) {
|
||||
freeReplyObject(reply);
|
||||
return false;
|
||||
}
|
||||
|
||||
freeReplyObject(reply);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool RedisNetworkConfigMaster::_smembers(const char *key,std::vector<std::string> &sdata)
|
||||
{
|
||||
if (!_rc) {
|
||||
if (!_reconnect())
|
||||
return false;
|
||||
}
|
||||
|
||||
redisReply *reply = (redisReply *)redisCommand(_rc,"SMEMBERS %s",key);
|
||||
if (!reply) {
|
||||
if (_reconnect())
|
||||
return _smembers(key,sdata);
|
||||
return false;
|
||||
}
|
||||
|
||||
sdata.clear();
|
||||
if (reply->type == REDIS_REPLY_ARRAY) {
|
||||
for(long i=0;i<reply->elements;++i) {
|
||||
if (reply->element[i]->str)
|
||||
sdata.push_back(reply->element[i]->str);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool RedisNetworkConfigMaster::_initNewMember(uint64_t nwid,const Identity &member,const Dictionary &metaData,Dictionary &memberRecord)
|
||||
bool SqliteNetworkConfigMaster::_initNewMember(uint64_t nwid,const Identity &member,const Dictionary &metaData,Dictionary &memberRecord)
|
||||
{
|
||||
#if 0
|
||||
char memberKey[128],nwids[24],addrs[16],nwKey[128],membersKey[128];
|
||||
Dictionary networkRecord;
|
||||
|
||||
@ -378,7 +160,7 @@ bool RedisNetworkConfigMaster::_initNewMember(uint64_t nwid,const Identity &memb
|
||||
Utils::snprintf(membersKey,sizeof(membersKey),"zt1:network:%s:members",nwids);
|
||||
|
||||
if (!_hgetall(nwKey,networkRecord)) {
|
||||
//LOG("netconf: Redis error retrieving %s",nwKey);
|
||||
//LOG("netconf: Sqlite error retrieving %s",nwKey);
|
||||
return false;
|
||||
}
|
||||
if (networkRecord.get("id","") != nwids) {
|
||||
@ -399,10 +181,12 @@ bool RedisNetworkConfigMaster::_initNewMember(uint64_t nwid,const Identity &memb
|
||||
return false;
|
||||
|
||||
return true;
|
||||
#endif
|
||||
}
|
||||
|
||||
bool RedisNetworkConfigMaster::_generateNetconf(uint64_t nwid,const Identity &member,const Dictionary &metaData,Dictionary &netconf,uint64_t &ts,std::string &errorMessage)
|
||||
bool SqliteNetworkConfigMaster::_generateNetconf(uint64_t nwid,const Identity &member,const Dictionary &metaData,Dictionary &netconf,uint64_t &ts,std::string &errorMessage)
|
||||
{
|
||||
#if 0
|
||||
char memberKey[256],nwids[24],addrs[16],tss[24],nwKey[256],revKey[128],abKey[128],ipaKey[128];
|
||||
Dictionary networkRecord,memberRecord;
|
||||
std::string revision;
|
||||
@ -416,7 +200,7 @@ bool RedisNetworkConfigMaster::_generateNetconf(uint64_t nwid,const Identity &me
|
||||
Utils::snprintf(ipaKey,sizeof(revKey),"zt1:network:%s:ipAssignments",nwids);
|
||||
|
||||
if (!_hgetall(nwKey,networkRecord)) {
|
||||
errorMessage = "Redis error retrieving network record";
|
||||
errorMessage = "Sqlite error retrieving network record";
|
||||
return false;
|
||||
}
|
||||
if (networkRecord.get("id","") != nwids) {
|
||||
@ -425,12 +209,12 @@ bool RedisNetworkConfigMaster::_generateNetconf(uint64_t nwid,const Identity &me
|
||||
}
|
||||
|
||||
if (!_hgetall(memberKey,memberRecord)) {
|
||||
errorMessage = "Redis error retrieving member record";
|
||||
errorMessage = "Sqlite error retrieving member record";
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!_get(revKey,revision)) {
|
||||
errorMessage = "Redis error retrieving network revision";
|
||||
errorMessage = "Sqlite error retrieving network revision";
|
||||
return false;
|
||||
}
|
||||
if (!revision.length())
|
||||
@ -462,7 +246,7 @@ bool RedisNetworkConfigMaster::_generateNetconf(uint64_t nwid,const Identity &me
|
||||
std::string activeBridgeList;
|
||||
std::vector<std::string> activeBridgeSet;
|
||||
if (!_smembers(abKey,activeBridgeSet)) {
|
||||
errorMessage = "Redis error retrieving active bridge set";
|
||||
errorMessage = "Sqlite error retrieving active bridge set";
|
||||
return false;
|
||||
}
|
||||
std::sort(activeBridgeSet.begin(),activeBridgeSet.end());
|
||||
@ -531,7 +315,7 @@ bool RedisNetworkConfigMaster::_generateNetconf(uint64_t nwid,const Identity &me
|
||||
// Is 'ip' already assigned to another node?
|
||||
std::string assignment;
|
||||
if (!_hget(ipaKey,ip.toString().c_str(),assignment)) {
|
||||
errorMessage = "Redis error while checking IP allocation";
|
||||
errorMessage = "Sqlite error while checking IP allocation";
|
||||
return false;
|
||||
}
|
||||
if ((assignment.length() != 10)||(assignment == member.address().toString())) {
|
||||
@ -620,12 +404,13 @@ bool RedisNetworkConfigMaster::_generateNetconf(uint64_t nwid,const Identity &me
|
||||
upd.set("netconfTimestamp",ts);
|
||||
upd["netconfRevision"] = revision;
|
||||
if (!_hmset(memberKey,upd)) {
|
||||
errorMessage = "Redis error updating network record with new netconf dictionary";
|
||||
errorMessage = "Sqlite error updating network record with new netconf dictionary";
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
#endif
|
||||
}
|
||||
|
||||
} // namespace ZeroTier
|
||||
|
@ -25,10 +25,13 @@
|
||||
* LLC. Start here: http://www.zerotier.com/
|
||||
*/
|
||||
|
||||
#ifndef ZT_REDISNETWORKCONFIGMASTER_HPP
|
||||
#define ZT_REDISNETWORKCONFIGMASTER_HPP
|
||||
#ifndef ZT_SQLITENETWORKCONFIGMASTER_HPP
|
||||
#define ZT_SQLITENETWORKCONFIGMASTER_HPP
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include <sqlite3.h>
|
||||
|
||||
#include <string>
|
||||
#include <map>
|
||||
#include <vector>
|
||||
@ -37,25 +40,13 @@
|
||||
#include "../node/NetworkConfigMaster.hpp"
|
||||
#include "../node/Mutex.hpp"
|
||||
|
||||
#include <hiredis/hiredis.h>
|
||||
|
||||
// Redis timeout in seconds
|
||||
#define ZT_NETCONF_REDIS_TIMEOUT 10
|
||||
|
||||
namespace ZeroTier {
|
||||
|
||||
class RedisNetworkConfigMaster : public NetworkConfigMaster
|
||||
class SqliteNetworkConfigMaster : public NetworkConfigMaster
|
||||
{
|
||||
public:
|
||||
RedisNetworkConfigMaster(
|
||||
const Identity &signingId,
|
||||
const char *redisHost,
|
||||
unsigned int redisPort,
|
||||
const char *redisPassword,
|
||||
unsigned int redisDatabaseNumber);
|
||||
|
||||
virtual ~RedisNetworkConfigMaster();
|
||||
|
||||
SqliteNetworkConfigMaster(const Identity &signingId,const char *dbPath);
|
||||
virtual ~SqliteNetworkConfigMaster();
|
||||
virtual NetworkConfigMaster::ResultCode doNetworkConfigRequest(
|
||||
const InetAddress &fromAddr,
|
||||
uint64_t packetId,
|
||||
@ -66,29 +57,14 @@ public:
|
||||
Dictionary &netconf);
|
||||
|
||||
private:
|
||||
// These assume _lock is locked
|
||||
bool _reconnect();
|
||||
bool _hgetall(const char *key,Dictionary &hdata);
|
||||
bool _hmset(const char *key,const Dictionary &hdata);
|
||||
bool _hget(const char *key,const char *hashKey,std::string &value);
|
||||
bool _hset(const char *key,const char *hashKey,const char *value);
|
||||
bool _get(const char *key,std::string &value);
|
||||
bool _sadd(const char *key,const char *value);
|
||||
bool _smembers(const char *key,std::vector<std::string> &sdata);
|
||||
|
||||
bool _initNewMember(uint64_t nwid,const Identity &member,const Dictionary &metaData,Dictionary &memberRecord);
|
||||
bool _generateNetconf(uint64_t nwid,const Identity &member,const Dictionary &metaData,Dictionary &netconf,uint64_t &ts,std::string &errorMessage);
|
||||
|
||||
Mutex _lock;
|
||||
|
||||
Identity _signingId;
|
||||
std::string _dbPath;
|
||||
sqlite3 *_db;
|
||||
|
||||
std::string _redisHost;
|
||||
std::string _redisPassword;
|
||||
unsigned int _redisPort;
|
||||
unsigned int _redisDatabaseNumber;
|
||||
|
||||
redisContext *_rc;
|
||||
Mutex _lock;
|
||||
};
|
||||
|
||||
} // namespace ZeroTier
|
||||
|
81
netconf/netconf-schema.sql
Normal file
81
netconf/netconf-schema.sql
Normal file
@ -0,0 +1,81 @@
|
||||
CREATE TABLE Config (
|
||||
k varchar(16) PRIMARY KEY NOT NULL,
|
||||
v varchar(1024) NOT NULL
|
||||
) WITHOUT ROWID;
|
||||
|
||||
CREATE TABLE IpAssignment (
|
||||
networkId char(16) NOT NULL,
|
||||
nodeId char(10) NOT NULL,
|
||||
ip varchar(64) NOT NULL,
|
||||
ipNetmaskBits integer(4) NOT NULL DEFAULT(0)
|
||||
);
|
||||
|
||||
CREATE INDEX IpAssignment_networkId ON IpAssignment (networkId);
|
||||
|
||||
CREATE INDEX IpAssignment_networkId_nodeId ON IpAssignment (networkId, nodeId);
|
||||
|
||||
CREATE UNIQUE INDEX IpAssignment_networkId_ip ON IpAssignment (networkId, ip);
|
||||
|
||||
CREATE TABLE IpAssignmentPool (
|
||||
networkId char(16) NOT NULL,
|
||||
ipNetwork varchar(64) NOT NULL,
|
||||
ipNetmaskBits integer(4) NOT NULL,
|
||||
active integer(1) NOT NULL DEFAULT(1)
|
||||
);
|
||||
|
||||
CREATE INDEX IpAssignmentPool_networkId ON IpAssignmentPool (networkId);
|
||||
|
||||
CREATE TABLE Member (
|
||||
networkId char(16) NOT NULL,
|
||||
nodeId char(10) NOT NULL,
|
||||
cachedNetconf blob(4096),
|
||||
cachedNetconfRevision integer(32),
|
||||
cachedNetconfTimestamp integer(32),
|
||||
clientReportedTimestamp integer(32),
|
||||
authorized integer(1) NOT NULL DEFAULT(0),
|
||||
activeBridge integer(1) NOT NULL DEFAULT(0)
|
||||
);
|
||||
|
||||
CREATE UNIQUE INDEX Member_networkId_nodeId ON Member (networkId, nodeId);
|
||||
|
||||
CREATE INDEX Member_networkId ON Member (networkId ASC);
|
||||
|
||||
CREATE TABLE Network (
|
||||
id char(16) PRIMARY KEY NOT NULL,
|
||||
name varchar(128) NOT NULL,
|
||||
private integer(1) NOT NULL DEFAULT(1),
|
||||
enableBroadcast integer(1) NOT NULL DEFAULT(1),
|
||||
allowPassiveBridging integer(1) NOT NULL DEFAULT(0),
|
||||
v4AssignMode varchar(8) NOT NULL DEFAULT('none'),
|
||||
v6AssignMode varchar(8) NOT NULL DEFAULT('none'),
|
||||
multicastLimit integer(8) NOT NULL DEFAULT(32),
|
||||
creationTime integer(32) NOT NULL DEFAULT(0),
|
||||
revision integer(32) NOT NULL DEFAULT(0)
|
||||
) WITHOUT ROWID;
|
||||
|
||||
CREATE TABLE Node (
|
||||
id char(10) PRIMARY KEY NOT NULL,
|
||||
identity varchar(4096) NOT NULL,
|
||||
lastAt varchar(64),
|
||||
lastSeen integer(32) NOT NULL DEFAULT(0),
|
||||
firstSeen integer(32) NOT NULL DEFAULT(0)
|
||||
) WITHOUT ROWID;
|
||||
|
||||
CREATE TABLE Rule (
|
||||
networkId char(16) NOT NULL,
|
||||
nodeId char(10),
|
||||
vlanId integer(4),
|
||||
vlanPcp integer(4),
|
||||
etherType integer(8),
|
||||
macSource char(12),
|
||||
macDest char(12),
|
||||
ipSource varchar(64),
|
||||
ipDest varchar(64),
|
||||
ipTos integer(4),
|
||||
ipProtocol integer(4),
|
||||
ipSourcePort integer(8),
|
||||
ipDestPort integer(8),
|
||||
"action" varchar(4096) NOT NULL DEFAULT('accept')
|
||||
);
|
||||
|
||||
CREATE INDEX Rule_networkId ON Rule (networkId);
|
Binary file not shown.
Loading…
x
Reference in New Issue
Block a user