mirror of
https://github.com/zerotier/ZeroTierOne.git
synced 2025-06-06 12:33:44 +02:00
Cleanup and build fixes.
This commit is contained in:
parent
76bc9968ff
commit
2e85cf18c1
5 changed files with 37 additions and 101 deletions
21
main.cpp
21
main.cpp
|
@ -46,7 +46,6 @@
|
||||||
|
|
||||||
#include "node/Node.hpp"
|
#include "node/Node.hpp"
|
||||||
#include "node/Utils.hpp"
|
#include "node/Utils.hpp"
|
||||||
#include "node/Defaults.hpp"
|
|
||||||
|
|
||||||
#include "launcher.h"
|
#include "launcher.h"
|
||||||
|
|
||||||
|
@ -67,24 +66,15 @@ static void sighandlerQuit(int sig)
|
||||||
n->terminate();
|
n->terminate();
|
||||||
else exit(0);
|
else exit(0);
|
||||||
}
|
}
|
||||||
static void sighandlerUsr(int sig)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
static void sighandlerHup(int sig)
|
|
||||||
{
|
|
||||||
Node *n = node;
|
|
||||||
if (n)
|
|
||||||
n->updateStatusNow();
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
int main(int argc,char **argv)
|
int main(int argc,char **argv)
|
||||||
{
|
{
|
||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
signal(SIGHUP,&sighandlerHup);
|
signal(SIGHUP,SIG_IGN);
|
||||||
signal(SIGPIPE,SIG_IGN);
|
signal(SIGPIPE,SIG_IGN);
|
||||||
signal(SIGUSR1,&sighandlerUsr);
|
signal(SIGUSR1,SIG_IGN);
|
||||||
signal(SIGUSR2,&sighandlerUsr);
|
signal(SIGUSR2,SIG_IGN);
|
||||||
signal(SIGALRM,SIG_IGN);
|
signal(SIGALRM,SIG_IGN);
|
||||||
signal(SIGINT,&sighandlerQuit);
|
signal(SIGINT,&sighandlerQuit);
|
||||||
signal(SIGTERM,&sighandlerQuit);
|
signal(SIGTERM,&sighandlerQuit);
|
||||||
|
@ -124,13 +114,16 @@ int main(int argc,char **argv)
|
||||||
|
|
||||||
int exitCode = ZT_EXEC_RETURN_VALUE_NORMAL_TERMINATION;
|
int exitCode = ZT_EXEC_RETURN_VALUE_NORMAL_TERMINATION;
|
||||||
|
|
||||||
node = new Node(homeDir,ZT_DEFAULTS.configUrlPrefix.c_str(),ZT_DEFAULTS.configAuthority.c_str());
|
node = new Node(homeDir);
|
||||||
|
const char *termReason = (char *)0;
|
||||||
switch(node->run()) {
|
switch(node->run()) {
|
||||||
case Node::NODE_RESTART_FOR_RECONFIGURATION:
|
case Node::NODE_RESTART_FOR_RECONFIGURATION:
|
||||||
exitCode = ZT_EXEC_RETURN_VALUE_PLEASE_RESTART;
|
exitCode = ZT_EXEC_RETURN_VALUE_PLEASE_RESTART;
|
||||||
break;
|
break;
|
||||||
case Node::NODE_UNRECOVERABLE_ERROR:
|
case Node::NODE_UNRECOVERABLE_ERROR:
|
||||||
exitCode = ZT_EXEC_RETURN_VALUE_UNRECOVERABLE_ERROR;
|
exitCode = ZT_EXEC_RETURN_VALUE_UNRECOVERABLE_ERROR;
|
||||||
|
termReason = node->reasonForTermination();
|
||||||
|
fprintf(stderr,"%s: abnormal termination: %s\n",argv[0],(termReason) ? termReason : "(unknown reason)");
|
||||||
break;
|
break;
|
||||||
case Node::NODE_NEW_VERSION_AVAILABLE:
|
case Node::NODE_NEW_VERSION_AVAILABLE:
|
||||||
exitCode = ZT_EXEC_RETURN_VALUE_TERMINATED_FOR_UPGRADE;
|
exitCode = ZT_EXEC_RETURN_VALUE_TERMINATED_FOR_UPGRADE;
|
||||||
|
|
|
@ -37,15 +37,15 @@
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#ifndef _WIN32
|
#ifdef _WIN32
|
||||||
|
#include <Windows.h>
|
||||||
|
#else
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
#include <sys/file.h>
|
#include <sys/file.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <openssl/sha.h>
|
|
||||||
|
|
||||||
#include "Condition.hpp"
|
#include "Condition.hpp"
|
||||||
#include "Node.hpp"
|
#include "Node.hpp"
|
||||||
#include "Topology.hpp"
|
#include "Topology.hpp"
|
||||||
|
@ -78,7 +78,6 @@ struct _NodeImpl
|
||||||
Node::ReasonForTermination reasonForTermination;
|
Node::ReasonForTermination reasonForTermination;
|
||||||
volatile bool started;
|
volatile bool started;
|
||||||
volatile bool running;
|
volatile bool running;
|
||||||
volatile bool updateStatusNow;
|
|
||||||
volatile bool terminateNow;
|
volatile bool terminateNow;
|
||||||
|
|
||||||
// Helper used to rapidly terminate from run()
|
// Helper used to rapidly terminate from run()
|
||||||
|
@ -94,20 +93,17 @@ struct _NodeImpl
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
Node::Node(const char *hp,const char *urlPrefix,const char *configAuthorityIdentity)
|
Node::Node(const char *hp)
|
||||||
throw() :
|
throw() :
|
||||||
_impl(new _NodeImpl)
|
_impl(new _NodeImpl)
|
||||||
{
|
{
|
||||||
_NodeImpl *impl = (_NodeImpl *)_impl;
|
_NodeImpl *impl = (_NodeImpl *)_impl;
|
||||||
|
|
||||||
impl->renv.homePath = hp;
|
impl->renv.homePath = hp;
|
||||||
impl->renv.autoconfUrlPrefix = urlPrefix;
|
|
||||||
impl->renv.configAuthorityIdentityStr = configAuthorityIdentity;
|
|
||||||
|
|
||||||
impl->reasonForTermination = Node::NODE_RUNNING;
|
impl->reasonForTermination = Node::NODE_RUNNING;
|
||||||
impl->started = false;
|
impl->started = false;
|
||||||
impl->running = false;
|
impl->running = false;
|
||||||
impl->updateStatusNow = false;
|
|
||||||
impl->terminateNow = false;
|
impl->terminateNow = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -155,11 +151,9 @@ Node::ReasonForTermination Node::run()
|
||||||
|
|
||||||
TRACE("initializing...");
|
TRACE("initializing...");
|
||||||
|
|
||||||
|
// Create non-crypto PRNG right away in case other code in init wants to use it
|
||||||
_r->prng = new CMWC4096();
|
_r->prng = new CMWC4096();
|
||||||
|
|
||||||
if (!_r->configAuthority.fromString(_r->configAuthorityIdentityStr))
|
|
||||||
return impl->terminateBecause(Node::NODE_UNRECOVERABLE_ERROR,"configuration authority identity is not valid");
|
|
||||||
|
|
||||||
bool gotId = false;
|
bool gotId = false;
|
||||||
std::string identitySecretPath(_r->homePath + ZT_PATH_SEPARATOR_S + "identity.secret");
|
std::string identitySecretPath(_r->homePath + ZT_PATH_SEPARATOR_S + "identity.secret");
|
||||||
std::string identityPublicPath(_r->homePath + ZT_PATH_SEPARATOR_S + "identity.public");
|
std::string identityPublicPath(_r->homePath + ZT_PATH_SEPARATOR_S + "identity.public");
|
||||||
|
@ -188,37 +182,35 @@ Node::ReasonForTermination Node::run()
|
||||||
}
|
}
|
||||||
Utils::lockDownFile(identitySecretPath.c_str(),false);
|
Utils::lockDownFile(identitySecretPath.c_str(),false);
|
||||||
|
|
||||||
// Generate ownership verification secret, which can be presented to
|
// Clean up some obsolete files if present -- this will be removed later
|
||||||
// a controlling web site (like ours) to prove ownership of a node and
|
unlink((_r->homePath + ZT_PATH_SEPARATOR_S + "status").c_str());
|
||||||
// permit its configuration to be centrally modified. When ZeroTier One
|
unlink((_r->homePath + ZT_PATH_SEPARATOR_S + "thisdeviceismine").c_str());
|
||||||
// requests its config it sends a hash of this secret, and so the
|
|
||||||
// config server can verify this hash to determine if the secret the
|
// Load or generate config authentication secret
|
||||||
// user presents is correct.
|
std::string configAuthTokenPath(_r->homePath + ZT_PATH_SEPARATOR_S + "authtoken.secret");
|
||||||
std::string ovsPath(_r->homePath + ZT_PATH_SEPARATOR_S + "thisdeviceismine");
|
std::string configAuthToken;
|
||||||
if (((Utils::now() - Utils::getLastModified(ovsPath.c_str())) >= ZT_OVS_GENERATE_NEW_IF_OLDER_THAN)||(!Utils::readFile(ovsPath.c_str(),_r->ownershipVerificationSecret))) {
|
if (!Utils::readFile(configAuthTokenPath.c_str(),configAuthToken)) {
|
||||||
_r->ownershipVerificationSecret = "";
|
configAuthToken = "";
|
||||||
unsigned int securern = 0;
|
unsigned int sr = 0;
|
||||||
for(unsigned int i=0;i<24;++i) {
|
for(unsigned int i=0;i<24;++i) {
|
||||||
Utils::getSecureRandom(&securern,sizeof(securern));
|
Utils::getSecureRandom(&sr,sizeof(sr));
|
||||||
_r->ownershipVerificationSecret.push_back("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"[securern % 62]);
|
configAuthToken.push_back("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"[sr % 62]);
|
||||||
}
|
}
|
||||||
_r->ownershipVerificationSecret.append(ZT_EOL_S);
|
if (!Utils::writeFile(configAuthTokenPath.c_str(),configAuthToken))
|
||||||
if (!Utils::writeFile(ovsPath.c_str(),_r->ownershipVerificationSecret))
|
return impl->terminateBecause(Node::NODE_UNRECOVERABLE_ERROR,"could not write authtoken.secret (home path not writable?)");
|
||||||
return impl->terminateBecause(Node::NODE_UNRECOVERABLE_ERROR,"could not write 'thisdeviceismine' (home path not writable?)");
|
|
||||||
}
|
}
|
||||||
Utils::lockDownFile(ovsPath.c_str(),false);
|
Utils::lockDownFile(configAuthTokenPath.c_str(),false);
|
||||||
_r->ownershipVerificationSecret = Utils::trim(_r->ownershipVerificationSecret); // trim off CR file is saved with
|
|
||||||
unsigned char ovsDig[32];
|
|
||||||
SHA256_CTX sha;
|
|
||||||
SHA256_Init(&sha);
|
|
||||||
SHA256_Update(&sha,_r->ownershipVerificationSecret.data(),_r->ownershipVerificationSecret.length());
|
|
||||||
SHA256_Final(ovsDig,&sha);
|
|
||||||
_r->ownershipVerificationSecretHash = Utils::base64Encode(ovsDig,32);
|
|
||||||
|
|
||||||
// Create the core objects in RuntimeEnvironment: node config, demarcation
|
// Create the core objects in RuntimeEnvironment: node config, demarcation
|
||||||
// point, switch, network topology database, and system environment
|
// point, switch, network topology database, and system environment
|
||||||
// watcher.
|
// watcher.
|
||||||
_r->nc = new NodeConfig(_r,_r->autoconfUrlPrefix + _r->identity.address().toString());
|
try {
|
||||||
|
_r->nc = new NodeConfig(_r,configAuthToken.c_str());
|
||||||
|
} catch ( ... ) {
|
||||||
|
// An exception here currently means that another instance of ZeroTier
|
||||||
|
// One is running.
|
||||||
|
return impl->terminateBecause(Node::NODE_UNRECOVERABLE_ERROR,"another instance of ZeroTier One appears to be running, or local control UDP port cannot be bound");
|
||||||
|
}
|
||||||
_r->demarc = new Demarc(_r);
|
_r->demarc = new Demarc(_r);
|
||||||
_r->multicaster = new Multicaster();
|
_r->multicaster = new Multicaster();
|
||||||
_r->sw = new Switch(_r);
|
_r->sw = new Switch(_r);
|
||||||
|
@ -248,8 +240,6 @@ Node::ReasonForTermination Node::run()
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
std::string statusPath(_r->homePath + ZT_PATH_SEPARATOR_S + "status");
|
|
||||||
|
|
||||||
uint64_t lastPingCheck = 0;
|
uint64_t lastPingCheck = 0;
|
||||||
uint64_t lastTopologyClean = Utils::now(); // don't need to do this immediately
|
uint64_t lastTopologyClean = Utils::now(); // don't need to do this immediately
|
||||||
uint64_t lastNetworkFingerprintCheck = 0;
|
uint64_t lastNetworkFingerprintCheck = 0;
|
||||||
|
@ -257,7 +247,6 @@ Node::ReasonForTermination Node::run()
|
||||||
uint64_t networkConfigurationFingerprint = _r->sysEnv->getNetworkConfigurationFingerprint();
|
uint64_t networkConfigurationFingerprint = _r->sysEnv->getNetworkConfigurationFingerprint();
|
||||||
uint64_t lastMulticastCheck = 0;
|
uint64_t lastMulticastCheck = 0;
|
||||||
uint64_t lastMulticastAnnounceAll = 0;
|
uint64_t lastMulticastAnnounceAll = 0;
|
||||||
uint64_t lastStatusUpdate = 0;
|
|
||||||
long lastDelayDelta = 0;
|
long lastDelayDelta = 0;
|
||||||
|
|
||||||
LOG("%s starting version %s",_r->identity.address().toString().c_str(),versionString());
|
LOG("%s starting version %s",_r->identity.address().toString().c_str(),versionString());
|
||||||
|
@ -292,16 +281,6 @@ Node::ReasonForTermination Node::run()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((now - lastAutoconfigureCheck) >= ZT_AUTOCONFIGURE_CHECK_DELAY) {
|
|
||||||
// It seems odd to only do this simple check every so often, but the purpose is to
|
|
||||||
// delay between calls to refreshConfiguration() enough that the previous attempt
|
|
||||||
// has time to either succeed or fail. Otherwise we'll block the whole loop, since
|
|
||||||
// config update is guarded by a Mutex.
|
|
||||||
lastAutoconfigureCheck = now;
|
|
||||||
if ((now - _r->nc->lastAutoconfigure()) >= ZT_AUTOCONFIGURE_INTERVAL)
|
|
||||||
_r->nc->refreshConfiguration(); // happens in background
|
|
||||||
}
|
|
||||||
|
|
||||||
// Periodically check for changes in our local multicast subscriptions and broadcast
|
// Periodically check for changes in our local multicast subscriptions and broadcast
|
||||||
// those changes to peers.
|
// those changes to peers.
|
||||||
if ((now - lastMulticastCheck) >= ZT_MULTICAST_LOCAL_POLL_PERIOD) {
|
if ((now - lastMulticastCheck) >= ZT_MULTICAST_LOCAL_POLL_PERIOD) {
|
||||||
|
@ -389,20 +368,6 @@ Node::ReasonForTermination Node::run()
|
||||||
_r->topology->clean(); // happens in background
|
_r->topology->clean(); // happens in background
|
||||||
}
|
}
|
||||||
|
|
||||||
if (((now - lastStatusUpdate) >= ZT_STATUS_OUTPUT_PERIOD)||(impl->updateStatusNow)) {
|
|
||||||
lastStatusUpdate = now;
|
|
||||||
impl->updateStatusNow = false;
|
|
||||||
FILE *statusf = ::fopen(statusPath.c_str(),"w");
|
|
||||||
if (statusf) {
|
|
||||||
try {
|
|
||||||
_r->topology->eachPeer(Topology::DumpPeerStatistics(statusf));
|
|
||||||
} catch ( ... ) {
|
|
||||||
TRACE("unexpected exception updating status dump");
|
|
||||||
}
|
|
||||||
::fclose(statusf);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
unsigned long delay = std::min((unsigned long)ZT_MIN_SERVICE_LOOP_INTERVAL,_r->sw->doTimerTasks());
|
unsigned long delay = std::min((unsigned long)ZT_MIN_SERVICE_LOOP_INTERVAL,_r->sw->doTimerTasks());
|
||||||
uint64_t start = Utils::now();
|
uint64_t start = Utils::now();
|
||||||
|
@ -436,13 +401,6 @@ void Node::terminate()
|
||||||
((_NodeImpl *)_impl)->renv.mainLoopWaitCondition.signal();
|
((_NodeImpl *)_impl)->renv.mainLoopWaitCondition.signal();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Node::updateStatusNow()
|
|
||||||
throw()
|
|
||||||
{
|
|
||||||
((_NodeImpl *)_impl)->updateStatusNow = true;
|
|
||||||
((_NodeImpl *)_impl)->renv.mainLoopWaitCondition.signal();
|
|
||||||
}
|
|
||||||
|
|
||||||
class _VersionStringMaker
|
class _VersionStringMaker
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
|
@ -58,11 +58,8 @@ public:
|
||||||
* The node is not executed until run() is called.
|
* The node is not executed until run() is called.
|
||||||
*
|
*
|
||||||
* @param hp Home directory path
|
* @param hp Home directory path
|
||||||
* @param url URL prefix for autoconfiguration (http and file permitted)
|
|
||||||
* @param configAuthorityIdentity Public identity used to encrypt/authenticate configuration from this URL (ASCII string format)
|
|
||||||
* @throws std::invalid_argument Invalid argument supplied to constructor
|
|
||||||
*/
|
*/
|
||||||
Node(const char *hp,const char *urlPrefix,const char *configAuthorityIdentity)
|
Node(const char *hp)
|
||||||
throw();
|
throw();
|
||||||
|
|
||||||
~Node();
|
~Node();
|
||||||
|
@ -98,12 +95,6 @@ public:
|
||||||
void terminate()
|
void terminate()
|
||||||
throw();
|
throw();
|
||||||
|
|
||||||
/**
|
|
||||||
* Update the status file in the home directory on next service loop
|
|
||||||
*/
|
|
||||||
void updateStatusNow()
|
|
||||||
throw();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the ZeroTier version in major.minor.revision string format
|
* Get the ZeroTier version in major.minor.revision string format
|
||||||
*
|
*
|
||||||
|
|
|
@ -59,7 +59,6 @@ class RuntimeEnvironment
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
RuntimeEnvironment() :
|
RuntimeEnvironment() :
|
||||||
identity(),
|
|
||||||
log((Logger *)0),
|
log((Logger *)0),
|
||||||
prng((CMWC4096 *)0),
|
prng((CMWC4096 *)0),
|
||||||
nc((NodeConfig *)0),
|
nc((NodeConfig *)0),
|
||||||
|
@ -71,15 +70,10 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string homePath;
|
std::string homePath;
|
||||||
std::string autoconfUrlPrefix;
|
|
||||||
std::string configAuthorityIdentityStr;
|
|
||||||
std::string ownershipVerificationSecret;
|
|
||||||
std::string ownershipVerificationSecretHash; // base64 of SHA-256 X16 rounds
|
|
||||||
|
|
||||||
// signal() to prematurely interrupt main loop wait
|
// signal() to prematurely interrupt main loop wait
|
||||||
Condition mainLoopWaitCondition;
|
Condition mainLoopWaitCondition;
|
||||||
|
|
||||||
Identity configAuthority;
|
|
||||||
Identity identity;
|
Identity identity;
|
||||||
|
|
||||||
Logger *log; // may be null
|
Logger *log; // may be null
|
||||||
|
|
|
@ -89,7 +89,7 @@ UdpSocket::UdpSocket(
|
||||||
sin6.sin6_family = AF_INET6;
|
sin6.sin6_family = AF_INET6;
|
||||||
sin6.sin6_port = htons(localPort);
|
sin6.sin6_port = htons(localPort);
|
||||||
if (localOnly)
|
if (localOnly)
|
||||||
memcpy(&(sin6.sin6_addr.s6_addr),InetAddress::LO6.rawIpBytes(),16);
|
memcpy(&(sin6.sin6_addr.s6_addr),InetAddress::LO6.rawIpData(),16);
|
||||||
else memcpy(&(sin6.sin6_addr),&in6addr_any,sizeof(struct in6_addr));
|
else memcpy(&(sin6.sin6_addr),&in6addr_any,sizeof(struct in6_addr));
|
||||||
if (::bind(_sock,(const struct sockaddr *)&sin6,sizeof(sin6))) {
|
if (::bind(_sock,(const struct sockaddr *)&sin6,sizeof(sin6))) {
|
||||||
::close(_sock);
|
::close(_sock);
|
||||||
|
@ -113,7 +113,7 @@ UdpSocket::UdpSocket(
|
||||||
sin.sin_family = AF_INET;
|
sin.sin_family = AF_INET;
|
||||||
sin.sin_port = htons(localPort);
|
sin.sin_port = htons(localPort);
|
||||||
if (localOnly)
|
if (localOnly)
|
||||||
memcpy(&(sin.sin_addr.s_addr),InetAddress::LO4.rawIpBytes(),4);
|
memcpy(&(sin.sin_addr.s_addr),InetAddress::LO4.rawIpData(),4);
|
||||||
else sin.sin_addr.s_addr = INADDR_ANY;
|
else sin.sin_addr.s_addr = INADDR_ANY;
|
||||||
if (::bind(_sock,(const struct sockaddr *)&sin,sizeof(sin))) {
|
if (::bind(_sock,(const struct sockaddr *)&sin,sizeof(sin))) {
|
||||||
::close(_sock);
|
::close(_sock);
|
||||||
|
|
Loading…
Add table
Reference in a new issue