mirror of
https://github.com/zerotier/ZeroTierOne.git
synced 2024-12-21 05:53:09 +00:00
Back out of RPC... blech. Have a better idea.
This commit is contained in:
parent
57d8730f1b
commit
b0a83093ce
@ -324,9 +324,4 @@ error_no_ZT_ARCH_defined;
|
|||||||
*/
|
*/
|
||||||
#define ZT_RENDEZVOUS_NAT_T_DELAY 500
|
#define ZT_RENDEZVOUS_NAT_T_DELAY 500
|
||||||
|
|
||||||
/**
|
|
||||||
* Timeout for remote RPC calls
|
|
||||||
*/
|
|
||||||
#define ZT_RPC_TIMEOUT 10000
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -50,14 +50,6 @@ class NodeConfig;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Local membership to a network
|
* Local membership to a network
|
||||||
*
|
|
||||||
* Networks configure themselves via RPC by accessing the function
|
|
||||||
* com.zerotier.one.Network.bootstrap at any supernode. This returns
|
|
||||||
* a series of key/value pairs that includes the IP address
|
|
||||||
* information for this node on the network and -- for closed
|
|
||||||
* networks -- a URL to retreive the network's membership list.
|
|
||||||
* A SHA-256 hash is also included to verify the return from this
|
|
||||||
* URL query.
|
|
||||||
*/
|
*/
|
||||||
class Network : NonCopyable
|
class Network : NonCopyable
|
||||||
{
|
{
|
||||||
|
@ -68,7 +68,6 @@
|
|||||||
#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"
|
||||||
|
|
||||||
@ -211,7 +210,6 @@ 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;
|
||||||
@ -317,7 +315,6 @@ 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;
|
||||||
@ -341,25 +338,6 @@ 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
|
||||||
|
@ -42,7 +42,6 @@ const char *Packet::verbString(Verb v)
|
|||||||
case VERB_FRAME: return "FRAME";
|
case VERB_FRAME: return "FRAME";
|
||||||
case VERB_MULTICAST_FRAME: return "MULTICAST_FRAME";
|
case VERB_MULTICAST_FRAME: return "MULTICAST_FRAME";
|
||||||
case VERB_MULTICAST_LIKE: return "MULTICAST_LIKE";
|
case VERB_MULTICAST_LIKE: return "MULTICAST_LIKE";
|
||||||
case VERB_RPC: return "RPC";
|
|
||||||
}
|
}
|
||||||
return "(unknown)";
|
return "(unknown)";
|
||||||
}
|
}
|
||||||
|
@ -463,26 +463,7 @@ public:
|
|||||||
*
|
*
|
||||||
* No OK or ERROR is generated.
|
* No OK or ERROR is generated.
|
||||||
*/
|
*/
|
||||||
VERB_MULTICAST_FRAME = 9,
|
VERB_MULTICAST_FRAME = 9
|
||||||
|
|
||||||
/* Call a plugin via RPC:
|
|
||||||
* <[2] length of function name>
|
|
||||||
* <[...] function name>
|
|
||||||
* [<[2] length of argument>]
|
|
||||||
* [<[...] argument>]
|
|
||||||
* [... additional length/argument pairs ...]
|
|
||||||
*
|
|
||||||
* This generates ERROR_NOT_FOUND if the specified function was not
|
|
||||||
* found. Otherwise it generates an OK message. The OK message has
|
|
||||||
* the same format as the request, except arguments are replaced
|
|
||||||
* by results.
|
|
||||||
*
|
|
||||||
* This can be used to implement simple RPC. No retransmission or
|
|
||||||
* other guarantees are made, so it behaves like UDP-based RPC
|
|
||||||
* protocols. Plugins are typically run by supernodes and are used
|
|
||||||
* to implement network lookup and other services.
|
|
||||||
*/
|
|
||||||
VERB_RPC = 10
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -102,8 +102,6 @@ bool PacketDecoder::tryDecode(const RuntimeEnvironment *_r)
|
|||||||
return _doMULTICAST_LIKE(_r,peer);
|
return _doMULTICAST_LIKE(_r,peer);
|
||||||
case Packet::VERB_MULTICAST_FRAME:
|
case Packet::VERB_MULTICAST_FRAME:
|
||||||
return _doMULTICAST_FRAME(_r,peer);
|
return _doMULTICAST_FRAME(_r,peer);
|
||||||
case Packet::VERB_RPC:
|
|
||||||
return _doRPC(_r,peer);
|
|
||||||
default:
|
default:
|
||||||
// This might be something from a new or old version of the protocol.
|
// This might be something from a new or old version of the protocol.
|
||||||
// Technically it passed HMAC so the packet is still valid, but we
|
// Technically it passed HMAC so the packet is still valid, but we
|
||||||
@ -540,8 +538,4 @@ bool PacketDecoder::_doMULTICAST_FRAME(const RuntimeEnvironment *_r,const Shared
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool PacketDecoder::_doRPC(const RuntimeEnvironment *_r,const SharedPtr<Peer> &peer)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace ZeroTier
|
} // namespace ZeroTier
|
||||||
|
@ -122,7 +122,6 @@ private:
|
|||||||
bool _doFRAME(const RuntimeEnvironment *_r,const SharedPtr<Peer> &peer);
|
bool _doFRAME(const RuntimeEnvironment *_r,const SharedPtr<Peer> &peer);
|
||||||
bool _doMULTICAST_LIKE(const RuntimeEnvironment *_r,const SharedPtr<Peer> &peer);
|
bool _doMULTICAST_LIKE(const RuntimeEnvironment *_r,const SharedPtr<Peer> &peer);
|
||||||
bool _doMULTICAST_FRAME(const RuntimeEnvironment *_r,const SharedPtr<Peer> &peer);
|
bool _doMULTICAST_FRAME(const RuntimeEnvironment *_r,const SharedPtr<Peer> &peer);
|
||||||
bool _doRPC(const RuntimeEnvironment *_r,const SharedPtr<Peer> &peer);
|
|
||||||
|
|
||||||
uint64_t _receiveTime;
|
uint64_t _receiveTime;
|
||||||
Demarc::Port _localPort;
|
Demarc::Port _localPort;
|
||||||
|
212
node/RPC.cpp
212
node/RPC.cpp
@ -1,212 +0,0 @@
|
|||||||
/*
|
|
||||||
* ZeroTier One - Global Peer to Peer Ethernet
|
|
||||||
* Copyright (C) 2012-2013 ZeroTier Networks LLC
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*
|
|
||||||
* --
|
|
||||||
*
|
|
||||||
* ZeroTier may be used and distributed under the terms of the GPLv3, which
|
|
||||||
* are available at: http://www.gnu.org/licenses/gpl-3.0.html
|
|
||||||
*
|
|
||||||
* If you would like to embed ZeroTier into a commercial application or
|
|
||||||
* redistribute it in a modified binary form, please contact ZeroTier Networks
|
|
||||||
* LLC. Start here: http://www.zerotier.com/
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef __WINDOWS__
|
|
||||||
#include <dlfcn.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "Utils.hpp"
|
|
||||||
#include "RuntimeEnvironment.hpp"
|
|
||||||
#include "RPC.hpp"
|
|
||||||
#include "Switch.hpp"
|
|
||||||
#include "Topology.hpp"
|
|
||||||
|
|
||||||
namespace ZeroTier {
|
|
||||||
|
|
||||||
#ifndef __WINDOWS__
|
|
||||||
|
|
||||||
RPC::LocalService::LocalService(const char *dllPath)
|
|
||||||
throw(std::invalid_argument) :
|
|
||||||
_handle((void *)0),
|
|
||||||
_init((void *)0),
|
|
||||||
_do((void *)0),
|
|
||||||
_free((void *)0),
|
|
||||||
_destroy((void *)0)
|
|
||||||
{
|
|
||||||
_handle = dlopen(dllPath,RTLD_LAZY|RTLD_LOCAL);
|
|
||||||
if (!_handle)
|
|
||||||
throw std::invalid_argument("Unable to load DLL: dlopen() failed");
|
|
||||||
|
|
||||||
_init = dlsym(_handle,"ZeroTierPluginInit");
|
|
||||||
if (!_init) {
|
|
||||||
dlclose(_handle);
|
|
||||||
throw std::invalid_argument("Unable to resolve symbol ZeroTierPluginInit in DLL");
|
|
||||||
}
|
|
||||||
_do = dlsym(_handle,"ZeroTierPluginDo");
|
|
||||||
if (!_do) {
|
|
||||||
dlclose(_handle);
|
|
||||||
throw std::invalid_argument("Unable to resolve symbol ZeroTierPluginDo in DLL");
|
|
||||||
}
|
|
||||||
_free = dlsym(_handle,"ZeroTierPluginFree");
|
|
||||||
if (!_free) {
|
|
||||||
dlclose(_handle);
|
|
||||||
throw std::invalid_argument("Unable to resolve symbol ZeroTierPluginFree in DLL");
|
|
||||||
}
|
|
||||||
_destroy = dlsym(_handle,"ZeroTierPluginDestroy");
|
|
||||||
if (!_destroy) {
|
|
||||||
dlclose(_handle);
|
|
||||||
throw std::invalid_argument("Unable to resolve symbol ZeroTierPluginDestroy in DLL");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (((int (*)())_init)() < 0) {
|
|
||||||
dlclose(_handle);
|
|
||||||
throw std::invalid_argument("ZeroTierPluginInit() returned error");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
RPC::LocalService::~LocalService()
|
|
||||||
{
|
|
||||||
if (_handle) {
|
|
||||||
if (_destroy)
|
|
||||||
((void (*)())_destroy)();
|
|
||||||
dlclose(_handle);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
std::pair< int,std::vector<std::string> > RPC::LocalService::operator()(const std::vector<std::string> &args)
|
|
||||||
{
|
|
||||||
unsigned int alengths[4096];
|
|
||||||
const void *argptrs[4096];
|
|
||||||
const unsigned int *rlengths = (const unsigned int *)0;
|
|
||||||
const void **resultptrs = (const void **)0;
|
|
||||||
std::vector<std::string> results;
|
|
||||||
|
|
||||||
if (args.size() > 4096)
|
|
||||||
throw std::runtime_error("args[] too long");
|
|
||||||
|
|
||||||
for(unsigned int i=0;i<args.size();++i) {
|
|
||||||
alengths[i] = args[i].length();
|
|
||||||
argptrs[i] = (const void *)args[i].data();
|
|
||||||
}
|
|
||||||
|
|
||||||
int rcount = ((int (*)(unsigned int,const unsigned int *,const void **,const unsigned int **,const void ***))_do)((unsigned int)args.size(),alengths,argptrs,&rlengths,&resultptrs);
|
|
||||||
|
|
||||||
for(int i=0;i<rcount;++i)
|
|
||||||
results.push_back(std::string((const char *)resultptrs[i],rlengths[i]));
|
|
||||||
|
|
||||||
((void (*)(int,const unsigned int *,const void **))_free)(rcount,rlengths,resultptrs);
|
|
||||||
|
|
||||||
return std::pair< int,std::vector<std::string> >(rcount,results);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // __WINDOWS__
|
|
||||||
|
|
||||||
RPC::RPC(const RuntimeEnvironment *renv) :
|
|
||||||
_r(renv)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
RPC::~RPC()
|
|
||||||
{
|
|
||||||
for(std::map<uint64_t,RemoteCallOutstanding>::iterator co(_remoteCallsOutstanding.begin());co!=_remoteCallsOutstanding.end();++co) {
|
|
||||||
if (co->second.handler)
|
|
||||||
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(
|
|
||||||
const Address &peer,
|
|
||||||
const std::string &name,
|
|
||||||
const std::vector<std::string> &args,
|
|
||||||
void (*handler)(void *,uint64_t,const Address &,int,const std::vector<std::string> &),
|
|
||||||
void *arg)
|
|
||||||
throw(std::invalid_argument,std::out_of_range)
|
|
||||||
{
|
|
||||||
Packet outp(peer,_r->identity.address(),Packet::VERB_RPC);
|
|
||||||
|
|
||||||
if (name.length() > 0xffff)
|
|
||||||
throw std::invalid_argument("function name too long");
|
|
||||||
outp.append((uint16_t)name.length());
|
|
||||||
outp.append(name);
|
|
||||||
for(std::vector<std::string>::const_iterator a(args.begin());a!=args.end();++a) {
|
|
||||||
if (a->length() > 0xffff)
|
|
||||||
throw std::invalid_argument("argument too long");
|
|
||||||
outp.append((uint16_t)a->length());
|
|
||||||
outp.append(*a);
|
|
||||||
}
|
|
||||||
outp.compress();
|
|
||||||
|
|
||||||
uint64_t id = outp.packetId();
|
|
||||||
|
|
||||||
{
|
|
||||||
Mutex::Lock _l(_remoteCallsOutstanding_m);
|
|
||||||
RemoteCallOutstanding &rc = _remoteCallsOutstanding[id];
|
|
||||||
rc.callTime = Utils::now();
|
|
||||||
rc.peer = peer;
|
|
||||||
rc.handler = handler;
|
|
||||||
rc.arg = arg;
|
|
||||||
}
|
|
||||||
|
|
||||||
_r->sw->send(outp,true);
|
|
||||||
|
|
||||||
return id;
|
|
||||||
}
|
|
||||||
|
|
||||||
void RPC::clean()
|
|
||||||
{
|
|
||||||
Mutex::Lock _l(_remoteCallsOutstanding_m);
|
|
||||||
uint64_t now = Utils::now();
|
|
||||||
for(std::map<uint64_t,RemoteCallOutstanding>::iterator co(_remoteCallsOutstanding.begin());co!=_remoteCallsOutstanding.end();) {
|
|
||||||
if ((now - co->second.callTime) >= ZT_RPC_TIMEOUT) {
|
|
||||||
if (co->second.handler)
|
|
||||||
co->second.handler(co->second.arg,co->first,co->second.peer,ZT_RPC_ERROR_EXPIRED_NO_RESPONSE,std::vector<std::string>());
|
|
||||||
_remoteCallsOutstanding.erase(co++);
|
|
||||||
} else ++co;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace ZeroTier
|
|
196
node/RPC.hpp
196
node/RPC.hpp
@ -1,196 +0,0 @@
|
|||||||
/*
|
|
||||||
* ZeroTier One - Global Peer to Peer Ethernet
|
|
||||||
* Copyright (C) 2012-2013 ZeroTier Networks LLC
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*
|
|
||||||
* --
|
|
||||||
*
|
|
||||||
* ZeroTier may be used and distributed under the terms of the GPLv3, which
|
|
||||||
* are available at: http://www.gnu.org/licenses/gpl-3.0.html
|
|
||||||
*
|
|
||||||
* If you would like to embed ZeroTier into a commercial application or
|
|
||||||
* redistribute it in a modified binary form, please contact ZeroTier Networks
|
|
||||||
* LLC. Start here: http://www.zerotier.com/
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef _ZT_RPC_HPP
|
|
||||||
#define _ZT_RPC_HPP
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
#include <stdexcept>
|
|
||||||
#include <map>
|
|
||||||
#include <vector>
|
|
||||||
#include <utility>
|
|
||||||
|
|
||||||
#include "Constants.hpp"
|
|
||||||
#include "NonCopyable.hpp"
|
|
||||||
#include "Mutex.hpp"
|
|
||||||
#include "Address.hpp"
|
|
||||||
|
|
||||||
namespace ZeroTier {
|
|
||||||
|
|
||||||
class RuntimeEnvironment;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Peer or method not found
|
|
||||||
*/
|
|
||||||
#define ZT_RPC_ERROR_NOT_FOUND -1
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A runtime error occurred
|
|
||||||
*/
|
|
||||||
#define ZT_RPC_ERROR_RUNTIME -2
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Call was expired without response from target
|
|
||||||
*/
|
|
||||||
#define ZT_RPC_ERROR_EXPIRED_NO_RESPONSE -3
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Call was cancelled (or RPC is shutting down)
|
|
||||||
*/
|
|
||||||
#define ZT_RPC_ERROR_CANCELLED -4
|
|
||||||
|
|
||||||
/**
|
|
||||||
* RPC request and result handler
|
|
||||||
*/
|
|
||||||
class RPC : NonCopyable
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
#ifndef __WINDOWS__
|
|
||||||
/**
|
|
||||||
* A local service accessible by RPC, non-Windows only for now
|
|
||||||
*
|
|
||||||
* Each service DLL must export these functions:
|
|
||||||
*
|
|
||||||
* int ZeroTierPluginInit();
|
|
||||||
* int ZeroTierPluginDo(unsigned int,const unsigned int *,const void **,const unsigned int **,const void ***);
|
|
||||||
* void ZeroTierPluginFree(int,const unsigned int *,const void **);
|
|
||||||
* void ZeroTierPluginDestroy();
|
|
||||||
*
|
|
||||||
* Init is called on library load, Destroy on unload. Do() may
|
|
||||||
* be called from multiple threads concurrently, so any locking
|
|
||||||
* is the responsibility of the library. These must have C
|
|
||||||
* function signatures (extern "C" in C++).
|
|
||||||
*
|
|
||||||
* Do's arguments are: the number of paramters, the size of each parameter in bytes,
|
|
||||||
* and each parameter's contents. The last two arguments are result parameters. The
|
|
||||||
* first result parameter must be set to an array of integers describing the size of
|
|
||||||
* each result. The second is set to an array of pointers to actual results. The number
|
|
||||||
* of results (size of both arrays) is returned. If Do() returns zero or negative,
|
|
||||||
* these result paremeters are not used by the caller and don't need to be set.
|
|
||||||
*
|
|
||||||
* After the caller is done with Do()'s results, it calls ZeroTierPluginFree() to
|
|
||||||
* free them. This may also be called concurrently. Free() takes the number of
|
|
||||||
* results, the array of result sizes, and the result array.
|
|
||||||
*/
|
|
||||||
class LocalService : NonCopyable
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
/**
|
|
||||||
* @param dllPath Path to DLL/shared object
|
|
||||||
* @throws std::invalid_argument Unable to properly load or resolve symbol(s) in DLL
|
|
||||||
*/
|
|
||||||
LocalService(const char *dllPath)
|
|
||||||
throw(std::invalid_argument);
|
|
||||||
|
|
||||||
~LocalService();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Call the DLL, return result
|
|
||||||
*
|
|
||||||
* @param args Input arguments
|
|
||||||
* @return Results from DLL
|
|
||||||
* @throws std::runtime_error Error calling DLL
|
|
||||||
*/
|
|
||||||
std::pair< int,std::vector<std::string> > operator()(const std::vector<std::string> &args);
|
|
||||||
|
|
||||||
private:
|
|
||||||
void *_handle;
|
|
||||||
void *_init;
|
|
||||||
void *_do;
|
|
||||||
void *_free;
|
|
||||||
void *_destroy;
|
|
||||||
};
|
|
||||||
#endif
|
|
||||||
|
|
||||||
RPC(const RuntimeEnvironment *renv);
|
|
||||||
~RPC();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Used by PacketDecoder to call local RPC methods
|
|
||||||
*
|
|
||||||
* @param name Name of locally loaded method to call
|
|
||||||
* @param args Arguments to method
|
|
||||||
* @return Return value of method, and results (negative first item and empty vector means error)
|
|
||||||
*/
|
|
||||||
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
|
|
||||||
*
|
|
||||||
* @param peer Peer to call on
|
|
||||||
* @param name Name of remote function
|
|
||||||
* @param args Arguments to remote function
|
|
||||||
* @param handler Handler to call on result
|
|
||||||
* @param arg First argument to handler
|
|
||||||
* @return Call ID (packet ID of sent packet)
|
|
||||||
*/
|
|
||||||
uint64_t callRemote(
|
|
||||||
const Address &peer,
|
|
||||||
const std::string &name,
|
|
||||||
const std::vector<std::string> &args,
|
|
||||||
void (*handler)(void *,uint64_t,const Address &,int,const std::vector<std::string> &),
|
|
||||||
void *arg)
|
|
||||||
throw(std::invalid_argument,std::out_of_range);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Periodically called to clean up, such as by expiring remote calls
|
|
||||||
*/
|
|
||||||
void clean();
|
|
||||||
|
|
||||||
private:
|
|
||||||
const RuntimeEnvironment *_r;
|
|
||||||
|
|
||||||
#ifndef __WINDOWS__
|
|
||||||
std::map<std::string,LocalService *> _rpcServices;
|
|
||||||
Mutex _rpcServices_m;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
struct RemoteCallOutstanding
|
|
||||||
{
|
|
||||||
uint64_t callTime;
|
|
||||||
Address peer;
|
|
||||||
void (*handler)(void *,uint64_t,const Address &,int,const std::vector<std::string> &);
|
|
||||||
void *arg;
|
|
||||||
};
|
|
||||||
std::map<uint64_t,RemoteCallOutstanding> _remoteCallsOutstanding;
|
|
||||||
Mutex _remoteCallsOutstanding_m;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace ZeroTier
|
|
||||||
|
|
||||||
#endif
|
|
@ -42,7 +42,6 @@ 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
|
||||||
@ -67,8 +66,7 @@ public:
|
|||||||
multicaster((Multicaster *)0),
|
multicaster((Multicaster *)0),
|
||||||
sw((Switch *)0),
|
sw((Switch *)0),
|
||||||
topology((Topology *)0),
|
topology((Topology *)0),
|
||||||
sysEnv((SysEnv *)0),
|
sysEnv((SysEnv *)0)
|
||||||
rpc((RPC *)0)
|
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -90,7 +88,6 @@ public:
|
|||||||
Switch *sw;
|
Switch *sw;
|
||||||
Topology *topology;
|
Topology *topology;
|
||||||
SysEnv *sysEnv;
|
SysEnv *sysEnv;
|
||||||
RPC *rpc;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace ZeroTier
|
} // namespace ZeroTier
|
||||||
|
@ -21,7 +21,6 @@ OBJS=\
|
|||||||
node/PacketDecoder.o \
|
node/PacketDecoder.o \
|
||||||
node/Pack.o \
|
node/Pack.o \
|
||||||
node/Peer.o \
|
node/Peer.o \
|
||||||
node/RPC.o \
|
|
||||||
node/Salsa20.o \
|
node/Salsa20.o \
|
||||||
node/Switch.o \
|
node/Switch.o \
|
||||||
node/SysEnv.o \
|
node/SysEnv.o \
|
||||||
|
Loading…
Reference in New Issue
Block a user