mirror of
https://github.com/zerotier/ZeroTierOne.git
synced 2025-06-06 12:33:44 +02:00
Wire up RPC plugin loading to Node.
This commit is contained in:
parent
af8fcac0fc
commit
57d8730f1b
6 changed files with 102 additions and 3 deletions
|
@ -68,6 +68,7 @@
|
||||||
#include "Mutex.hpp"
|
#include "Mutex.hpp"
|
||||||
#include "Multicaster.hpp"
|
#include "Multicaster.hpp"
|
||||||
#include "CMWC4096.hpp"
|
#include "CMWC4096.hpp"
|
||||||
|
#include "RPC.hpp"
|
||||||
|
|
||||||
#include "../version.h"
|
#include "../version.h"
|
||||||
|
|
||||||
|
@ -210,6 +211,7 @@ Node::~Node()
|
||||||
{
|
{
|
||||||
_NodeImpl *impl = (_NodeImpl *)_impl;
|
_NodeImpl *impl = (_NodeImpl *)_impl;
|
||||||
|
|
||||||
|
delete impl->renv.rpc;
|
||||||
delete impl->renv.sysEnv;
|
delete impl->renv.sysEnv;
|
||||||
delete impl->renv.topology;
|
delete impl->renv.topology;
|
||||||
delete impl->renv.sw;
|
delete impl->renv.sw;
|
||||||
|
@ -315,6 +317,7 @@ Node::ReasonForTermination Node::run()
|
||||||
_r->sw = new Switch(_r);
|
_r->sw = new Switch(_r);
|
||||||
_r->topology = new Topology(_r,(_r->homePath + ZT_PATH_SEPARATOR_S + "peer.db").c_str());
|
_r->topology = new Topology(_r,(_r->homePath + ZT_PATH_SEPARATOR_S + "peer.db").c_str());
|
||||||
_r->sysEnv = new SysEnv(_r);
|
_r->sysEnv = new SysEnv(_r);
|
||||||
|
_r->rpc = new RPC(_r);
|
||||||
|
|
||||||
// TODO: make configurable
|
// TODO: make configurable
|
||||||
bool boundPort = false;
|
bool boundPort = false;
|
||||||
|
@ -338,6 +341,25 @@ Node::ReasonForTermination Node::run()
|
||||||
return impl->terminateBecause(Node::NODE_UNRECOVERABLE_ERROR,"unknown exception during initialization");
|
return impl->terminateBecause(Node::NODE_UNRECOVERABLE_ERROR,"unknown exception during initialization");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
std::map<std::string,bool> pluginsd(Utils::listDirectory((_r->homePath + ZT_PATH_SEPARATOR_S + "plugins.d").c_str()));
|
||||||
|
for(std::map<std::string,bool>::iterator ppath(pluginsd.begin());ppath!=pluginsd.end();++ppath) {
|
||||||
|
if (!ppath->second) {
|
||||||
|
try {
|
||||||
|
std::string funcName(ppath->first.substr(0,ppath->first.rfind('.')));
|
||||||
|
LOG("loading plugins.d/%s as RPC function %s",ppath->first.c_str(),funcName.c_str());
|
||||||
|
_r->rpc->loadLocal(funcName.c_str(),(_r->homePath + ZT_PATH_SEPARATOR_S + "plugins.d" + ZT_PATH_SEPARATOR_S + ppath->first).c_str());
|
||||||
|
} catch (std::exception &exc) {
|
||||||
|
LOG("failed to load plugin plugins.d/%s: %s",ppath->first.c_str(),exc.what());
|
||||||
|
} catch ( ... ) {
|
||||||
|
LOG("failed to load plugin plugins.d/%s: (unknown exception)",ppath->first.c_str());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch ( ... ) {
|
||||||
|
TRACE("unknown exception attempting to enumerate and load plugins");
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
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
|
||||||
|
|
22
node/RPC.cpp
22
node/RPC.cpp
|
@ -37,6 +37,8 @@
|
||||||
|
|
||||||
namespace ZeroTier {
|
namespace ZeroTier {
|
||||||
|
|
||||||
|
#ifndef __WINDOWS__
|
||||||
|
|
||||||
RPC::LocalService::LocalService(const char *dllPath)
|
RPC::LocalService::LocalService(const char *dllPath)
|
||||||
throw(std::invalid_argument) :
|
throw(std::invalid_argument) :
|
||||||
_handle((void *)0),
|
_handle((void *)0),
|
||||||
|
@ -111,6 +113,8 @@ std::pair< int,std::vector<std::string> > RPC::LocalService::operator()(const st
|
||||||
return std::pair< int,std::vector<std::string> >(rcount,results);
|
return std::pair< int,std::vector<std::string> >(rcount,results);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif // __WINDOWS__
|
||||||
|
|
||||||
RPC::RPC(const RuntimeEnvironment *renv) :
|
RPC::RPC(const RuntimeEnvironment *renv) :
|
||||||
_r(renv)
|
_r(renv)
|
||||||
{
|
{
|
||||||
|
@ -123,17 +127,35 @@ RPC::~RPC()
|
||||||
co->second.handler(co->second.arg,co->first,co->second.peer,ZT_RPC_ERROR_CANCELLED,std::vector<std::string>());
|
co->second.handler(co->second.arg,co->first,co->second.peer,ZT_RPC_ERROR_CANCELLED,std::vector<std::string>());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef __WINDOWS__
|
||||||
for(std::map<std::string,LocalService *>::iterator s(_rpcServices.begin());s!=_rpcServices.end();++s)
|
for(std::map<std::string,LocalService *>::iterator s(_rpcServices.begin());s!=_rpcServices.end();++s)
|
||||||
delete s->second;
|
delete s->second;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
std::pair< int,std::vector<std::string> > RPC::callLocal(const std::string &name,const std::vector<std::string> &args)
|
std::pair< int,std::vector<std::string> > RPC::callLocal(const std::string &name,const std::vector<std::string> &args)
|
||||||
{
|
{
|
||||||
|
#ifdef __WINDOWS__
|
||||||
|
return std::pair< int,std::vector<std::string> >(ZT_RPC_ERROR_NOT_FOUND,std::vector<std::string>());
|
||||||
|
#else
|
||||||
Mutex::Lock _l(_rpcServices_m);
|
Mutex::Lock _l(_rpcServices_m);
|
||||||
std::map<std::string,LocalService *>::iterator s(_rpcServices.find(name));
|
std::map<std::string,LocalService *>::iterator s(_rpcServices.find(name));
|
||||||
if (s == _rpcServices.end())
|
if (s == _rpcServices.end())
|
||||||
return std::pair< int,std::vector<std::string> >(ZT_RPC_ERROR_NOT_FOUND,std::vector<std::string>());
|
return std::pair< int,std::vector<std::string> >(ZT_RPC_ERROR_NOT_FOUND,std::vector<std::string>());
|
||||||
return ((*(s->second))(args));
|
return ((*(s->second))(args));
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void RPC::loadLocal(const char *name,const char *path)
|
||||||
|
throw(std::invalid_argument)
|
||||||
|
{
|
||||||
|
#ifdef __WINDOWS__
|
||||||
|
throw std::invalid_argument("RPC plugins not supported on Windows (yet?)");
|
||||||
|
#else
|
||||||
|
LocalService *s = new LocalService(path);
|
||||||
|
Mutex::Lock _l(_rpcServices_m);
|
||||||
|
_rpcServices[std::string(name)] = s;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64_t RPC::callRemote(
|
uint64_t RPC::callRemote(
|
||||||
|
|
12
node/RPC.hpp
12
node/RPC.hpp
|
@ -139,6 +139,16 @@ public:
|
||||||
*/
|
*/
|
||||||
std::pair< int,std::vector<std::string> > callLocal(const std::string &name,const std::vector<std::string> &args);
|
std::pair< int,std::vector<std::string> > callLocal(const std::string &name,const std::vector<std::string> &args);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Load a plugin
|
||||||
|
*
|
||||||
|
* @param name Name of RPC function
|
||||||
|
* @param path Path to plugin DLL
|
||||||
|
* @throws std::invalid_argument Unable to properly load or resolve symbol(s) in DLL
|
||||||
|
*/
|
||||||
|
void loadLocal(const char *name,const char *path)
|
||||||
|
throw(std::invalid_argument);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Call a remote service
|
* Call a remote service
|
||||||
*
|
*
|
||||||
|
@ -165,8 +175,10 @@ public:
|
||||||
private:
|
private:
|
||||||
const RuntimeEnvironment *_r;
|
const RuntimeEnvironment *_r;
|
||||||
|
|
||||||
|
#ifndef __WINDOWS__
|
||||||
std::map<std::string,LocalService *> _rpcServices;
|
std::map<std::string,LocalService *> _rpcServices;
|
||||||
Mutex _rpcServices_m;
|
Mutex _rpcServices_m;
|
||||||
|
#endif
|
||||||
|
|
||||||
struct RemoteCallOutstanding
|
struct RemoteCallOutstanding
|
||||||
{
|
{
|
||||||
|
|
|
@ -42,6 +42,7 @@ class Topology;
|
||||||
class SysEnv;
|
class SysEnv;
|
||||||
class Multicaster;
|
class Multicaster;
|
||||||
class CMWC4096;
|
class CMWC4096;
|
||||||
|
class RPC;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Holds global state for an instance of ZeroTier::Node
|
* Holds global state for an instance of ZeroTier::Node
|
||||||
|
@ -65,7 +66,9 @@ public:
|
||||||
demarc((Demarc *)0),
|
demarc((Demarc *)0),
|
||||||
multicaster((Multicaster *)0),
|
multicaster((Multicaster *)0),
|
||||||
sw((Switch *)0),
|
sw((Switch *)0),
|
||||||
topology((Topology *)0)
|
topology((Topology *)0),
|
||||||
|
sysEnv((SysEnv *)0),
|
||||||
|
rpc((RPC *)0)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -76,6 +79,9 @@ public:
|
||||||
|
|
||||||
Identity identity;
|
Identity identity;
|
||||||
|
|
||||||
|
// Order matters a bit here. These are constructed in this order
|
||||||
|
// and then deleted in the opposite order on Node exit.
|
||||||
|
|
||||||
Logger *log; // may be null
|
Logger *log; // may be null
|
||||||
CMWC4096 *prng;
|
CMWC4096 *prng;
|
||||||
NodeConfig *nc;
|
NodeConfig *nc;
|
||||||
|
@ -84,6 +90,7 @@ public:
|
||||||
Switch *sw;
|
Switch *sw;
|
||||||
Topology *topology;
|
Topology *topology;
|
||||||
SysEnv *sysEnv;
|
SysEnv *sysEnv;
|
||||||
|
RPC *rpc;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace ZeroTier
|
} // namespace ZeroTier
|
||||||
|
|
|
@ -29,14 +29,13 @@
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include "Utils.hpp"
|
|
||||||
#include "Mutex.hpp"
|
|
||||||
|
|
||||||
#if defined(__APPLE__) || defined(__linux__) || defined(linux) || defined(__LINUX__) || defined(__linux)
|
#if defined(__APPLE__) || defined(__linux__) || defined(linux) || defined(__LINUX__) || defined(__linux)
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
|
#include <dirent.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
|
@ -46,6 +45,9 @@
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <openssl/rand.h>
|
#include <openssl/rand.h>
|
||||||
|
|
||||||
|
#include "Utils.hpp"
|
||||||
|
#include "Mutex.hpp"
|
||||||
|
|
||||||
namespace ZeroTier {
|
namespace ZeroTier {
|
||||||
|
|
||||||
const char Utils::HEXCHARS[16] = { '0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f' };
|
const char Utils::HEXCHARS[16] = { '0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f' };
|
||||||
|
@ -214,6 +216,29 @@ const char Utils::base64DecMap[128] = {
|
||||||
static const char *DAY_NAMES[7] = { "Sun","Mon","Tue","Wed","Thu","Fri","Sat" };
|
static const char *DAY_NAMES[7] = { "Sun","Mon","Tue","Wed","Thu","Fri","Sat" };
|
||||||
static const char *MONTH_NAMES[12] = { "Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec" };
|
static const char *MONTH_NAMES[12] = { "Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec" };
|
||||||
|
|
||||||
|
std::map<std::string,bool> Utils::listDirectory(const char *path)
|
||||||
|
{
|
||||||
|
struct dirent de;
|
||||||
|
struct dirent *dptr;
|
||||||
|
std::map<std::string,bool> r;
|
||||||
|
|
||||||
|
DIR *d = opendir(path);
|
||||||
|
if (!d)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
dptr = (struct dirent *)0;
|
||||||
|
for(;;) {
|
||||||
|
if (readdir_r(d,&de,&dptr))
|
||||||
|
break;
|
||||||
|
if (dptr) {
|
||||||
|
if ((!strcmp(dptr->d_name,"."))&&(!strcmp(dptr->d_name,"..")))
|
||||||
|
r[std::string(dptr->d_name)] = (dptr->d_type == DT_DIR);
|
||||||
|
} else break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
std::string Utils::base64Encode(const void *data,unsigned int len)
|
std::string Utils::base64Encode(const void *data,unsigned int len)
|
||||||
{
|
{
|
||||||
if (!len)
|
if (!len)
|
||||||
|
|
|
@ -38,6 +38,7 @@
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
#include <map>
|
||||||
|
|
||||||
#include "../ext/lz4/lz4.h"
|
#include "../ext/lz4/lz4.h"
|
||||||
#include "../ext/lz4/lz4hc.h"
|
#include "../ext/lz4/lz4hc.h"
|
||||||
|
@ -58,6 +59,16 @@ namespace ZeroTier {
|
||||||
class Utils
|
class Utils
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
/**
|
||||||
|
* List a directory's contents
|
||||||
|
*
|
||||||
|
* @param path Path to list
|
||||||
|
* @param files Set to fill with files
|
||||||
|
* @param directories Set to fill with directories
|
||||||
|
* @return Map of entries and whether or not they are also directories (empty on failure)
|
||||||
|
*/
|
||||||
|
static std::map<std::string,bool> listDirectory(const char *path);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param data Data to convert to hex
|
* @param data Data to convert to hex
|
||||||
* @param len Length of data
|
* @param len Length of data
|
||||||
|
|
Loading…
Add table
Reference in a new issue