mirror of
https://github.com/zerotier/ZeroTierOne.git
synced 2025-01-18 02:40:13 +00:00
Wire up RPC plugin loading to Node.
This commit is contained in:
parent
af8fcac0fc
commit
57d8730f1b
@ -68,6 +68,7 @@
|
||||
#include "Mutex.hpp"
|
||||
#include "Multicaster.hpp"
|
||||
#include "CMWC4096.hpp"
|
||||
#include "RPC.hpp"
|
||||
|
||||
#include "../version.h"
|
||||
|
||||
@ -210,6 +211,7 @@ Node::~Node()
|
||||
{
|
||||
_NodeImpl *impl = (_NodeImpl *)_impl;
|
||||
|
||||
delete impl->renv.rpc;
|
||||
delete impl->renv.sysEnv;
|
||||
delete impl->renv.topology;
|
||||
delete impl->renv.sw;
|
||||
@ -315,6 +317,7 @@ Node::ReasonForTermination Node::run()
|
||||
_r->sw = new Switch(_r);
|
||||
_r->topology = new Topology(_r,(_r->homePath + ZT_PATH_SEPARATOR_S + "peer.db").c_str());
|
||||
_r->sysEnv = new SysEnv(_r);
|
||||
_r->rpc = new RPC(_r);
|
||||
|
||||
// TODO: make configurable
|
||||
bool boundPort = false;
|
||||
@ -338,6 +341,25 @@ Node::ReasonForTermination Node::run()
|
||||
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 {
|
||||
uint64_t lastPingCheck = 0;
|
||||
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 {
|
||||
|
||||
#ifndef __WINDOWS__
|
||||
|
||||
RPC::LocalService::LocalService(const char *dllPath)
|
||||
throw(std::invalid_argument) :
|
||||
_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);
|
||||
}
|
||||
|
||||
#endif // __WINDOWS__
|
||||
|
||||
RPC::RPC(const RuntimeEnvironment *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>());
|
||||
}
|
||||
|
||||
#ifndef __WINDOWS__
|
||||
for(std::map<std::string,LocalService *>::iterator s(_rpcServices.begin());s!=_rpcServices.end();++s)
|
||||
delete s->second;
|
||||
#endif
|
||||
}
|
||||
|
||||
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);
|
||||
std::map<std::string,LocalService *>::iterator s(_rpcServices.find(name));
|
||||
if (s == _rpcServices.end())
|
||||
return std::pair< int,std::vector<std::string> >(ZT_RPC_ERROR_NOT_FOUND,std::vector<std::string>());
|
||||
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(
|
||||
|
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);
|
||||
|
||||
/**
|
||||
* 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
|
||||
*
|
||||
@ -165,8 +175,10 @@ public:
|
||||
private:
|
||||
const RuntimeEnvironment *_r;
|
||||
|
||||
#ifndef __WINDOWS__
|
||||
std::map<std::string,LocalService *> _rpcServices;
|
||||
Mutex _rpcServices_m;
|
||||
#endif
|
||||
|
||||
struct RemoteCallOutstanding
|
||||
{
|
||||
|
@ -42,6 +42,7 @@ class Topology;
|
||||
class SysEnv;
|
||||
class Multicaster;
|
||||
class CMWC4096;
|
||||
class RPC;
|
||||
|
||||
/**
|
||||
* Holds global state for an instance of ZeroTier::Node
|
||||
@ -65,7 +66,9 @@ public:
|
||||
demarc((Demarc *)0),
|
||||
multicaster((Multicaster *)0),
|
||||
sw((Switch *)0),
|
||||
topology((Topology *)0)
|
||||
topology((Topology *)0),
|
||||
sysEnv((SysEnv *)0),
|
||||
rpc((RPC *)0)
|
||||
{
|
||||
}
|
||||
|
||||
@ -76,6 +79,9 @@ public:
|
||||
|
||||
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
|
||||
CMWC4096 *prng;
|
||||
NodeConfig *nc;
|
||||
@ -84,6 +90,7 @@ public:
|
||||
Switch *sw;
|
||||
Topology *topology;
|
||||
SysEnv *sysEnv;
|
||||
RPC *rpc;
|
||||
};
|
||||
|
||||
} // namespace ZeroTier
|
||||
|
@ -29,14 +29,13 @@
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
#include "Utils.hpp"
|
||||
#include "Mutex.hpp"
|
||||
|
||||
#if defined(__APPLE__) || defined(__linux__) || defined(linux) || defined(__LINUX__) || defined(__linux)
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <dirent.h>
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
@ -46,6 +45,9 @@
|
||||
#include <sys/stat.h>
|
||||
#include <openssl/rand.h>
|
||||
|
||||
#include "Utils.hpp"
|
||||
#include "Mutex.hpp"
|
||||
|
||||
namespace ZeroTier {
|
||||
|
||||
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 *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)
|
||||
{
|
||||
if (!len)
|
||||
|
@ -38,6 +38,7 @@
|
||||
#include <string>
|
||||
#include <stdexcept>
|
||||
#include <vector>
|
||||
#include <map>
|
||||
|
||||
#include "../ext/lz4/lz4.h"
|
||||
#include "../ext/lz4/lz4hc.h"
|
||||
@ -58,6 +59,16 @@ namespace ZeroTier {
|
||||
class Utils
|
||||
{
|
||||
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 len Length of data
|
||||
|
Loading…
Reference in New Issue
Block a user