From 2e85cf18c19ce86363de636ff30827fe232aa80b Mon Sep 17 00:00:00 2001 From: Adam Ierymenko Date: Wed, 17 Jul 2013 14:39:34 -0400 Subject: Cleanup and build fixes. --- node/RuntimeEnvironment.hpp | 6 ------ 1 file changed, 6 deletions(-) (limited to 'node/RuntimeEnvironment.hpp') diff --git a/node/RuntimeEnvironment.hpp b/node/RuntimeEnvironment.hpp index 5f76c8ac..bc63543a 100644 --- a/node/RuntimeEnvironment.hpp +++ b/node/RuntimeEnvironment.hpp @@ -59,7 +59,6 @@ class RuntimeEnvironment { public: RuntimeEnvironment() : - identity(), log((Logger *)0), prng((CMWC4096 *)0), nc((NodeConfig *)0), @@ -71,15 +70,10 @@ public: } 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 Condition mainLoopWaitCondition; - Identity configAuthority; Identity identity; Logger *log; // may be null -- cgit v1.2.3 From 57d8730f1b3da3f9fe23a9fa02c8557b80bf6716 Mon Sep 17 00:00:00 2001 From: Adam Ierymenko Date: Thu, 25 Jul 2013 17:53:57 -0400 Subject: Wire up RPC plugin loading to Node. --- node/Node.cpp | 22 ++++++++++++++++++++++ node/RPC.cpp | 22 ++++++++++++++++++++++ node/RPC.hpp | 12 ++++++++++++ node/RuntimeEnvironment.hpp | 9 ++++++++- node/Utils.cpp | 29 +++++++++++++++++++++++++++-- node/Utils.hpp | 11 +++++++++++ 6 files changed, 102 insertions(+), 3 deletions(-) (limited to 'node/RuntimeEnvironment.hpp') diff --git a/node/Node.cpp b/node/Node.cpp index 08b08fc1..b5c23ed9 100644 --- a/node/Node.cpp +++ b/node/Node.cpp @@ -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 pluginsd(Utils::listDirectory((_r->homePath + ZT_PATH_SEPARATOR_S + "plugins.d").c_str())); + for(std::map::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 diff --git a/node/RPC.cpp b/node/RPC.cpp index e6591d7d..5a9cd719 100644 --- a/node/RPC.cpp +++ b/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 > RPC::LocalService::operator()(const st return std::pair< int,std::vector >(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()); } +#ifndef __WINDOWS__ for(std::map::iterator s(_rpcServices.begin());s!=_rpcServices.end();++s) delete s->second; +#endif } std::pair< int,std::vector > RPC::callLocal(const std::string &name,const std::vector &args) { +#ifdef __WINDOWS__ + return std::pair< int,std::vector >(ZT_RPC_ERROR_NOT_FOUND,std::vector()); +#else Mutex::Lock _l(_rpcServices_m); std::map::iterator s(_rpcServices.find(name)); if (s == _rpcServices.end()) return std::pair< int,std::vector >(ZT_RPC_ERROR_NOT_FOUND,std::vector()); 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( diff --git a/node/RPC.hpp b/node/RPC.hpp index e31b5f6d..669bf5ae 100644 --- a/node/RPC.hpp +++ b/node/RPC.hpp @@ -139,6 +139,16 @@ public: */ std::pair< int,std::vector > callLocal(const std::string &name,const std::vector &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 _rpcServices; Mutex _rpcServices_m; +#endif struct RemoteCallOutstanding { diff --git a/node/RuntimeEnvironment.hpp b/node/RuntimeEnvironment.hpp index bc63543a..35c2de3f 100644 --- a/node/RuntimeEnvironment.hpp +++ b/node/RuntimeEnvironment.hpp @@ -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 diff --git a/node/Utils.cpp b/node/Utils.cpp index 7b2a17af..7a4d51ba 100644 --- a/node/Utils.cpp +++ b/node/Utils.cpp @@ -29,14 +29,13 @@ #include #include #include -#include "Utils.hpp" -#include "Mutex.hpp" #if defined(__APPLE__) || defined(__linux__) || defined(linux) || defined(__LINUX__) || defined(__linux) #include #include #include #include +#include #endif #ifdef _WIN32 @@ -46,6 +45,9 @@ #include #include +#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 Utils::listDirectory(const char *path) +{ + struct dirent de; + struct dirent *dptr; + std::map 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) diff --git a/node/Utils.hpp b/node/Utils.hpp index b1917b27..fbabe3d7 100644 --- a/node/Utils.hpp +++ b/node/Utils.hpp @@ -38,6 +38,7 @@ #include #include #include +#include #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 listDirectory(const char *path); + /** * @param data Data to convert to hex * @param len Length of data -- cgit v1.2.3 From b0a83093ce698390a4e2d266ba1c63ee241cd7ad Mon Sep 17 00:00:00 2001 From: Adam Ierymenko Date: Sat, 27 Jul 2013 13:36:27 -0400 Subject: Back out of RPC... blech. Have a better idea. --- node/Constants.hpp | 5 -- node/Network.hpp | 8 -- node/Node.cpp | 22 ----- node/Packet.cpp | 1 - node/Packet.hpp | 21 +---- node/PacketDecoder.cpp | 6 -- node/PacketDecoder.hpp | 1 - node/RPC.cpp | 212 -------------------------------------------- node/RPC.hpp | 196 ---------------------------------------- node/RuntimeEnvironment.hpp | 5 +- objects.mk | 1 - 11 files changed, 2 insertions(+), 476 deletions(-) delete mode 100644 node/RPC.cpp delete mode 100644 node/RPC.hpp (limited to 'node/RuntimeEnvironment.hpp') diff --git a/node/Constants.hpp b/node/Constants.hpp index 9f856948..b8dc9ebf 100644 --- a/node/Constants.hpp +++ b/node/Constants.hpp @@ -324,9 +324,4 @@ error_no_ZT_ARCH_defined; */ #define ZT_RENDEZVOUS_NAT_T_DELAY 500 -/** - * Timeout for remote RPC calls - */ -#define ZT_RPC_TIMEOUT 10000 - #endif diff --git a/node/Network.hpp b/node/Network.hpp index 8429cf84..a95ae869 100644 --- a/node/Network.hpp +++ b/node/Network.hpp @@ -50,14 +50,6 @@ class NodeConfig; /** * 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 { diff --git a/node/Node.cpp b/node/Node.cpp index b5c23ed9..08b08fc1 100644 --- a/node/Node.cpp +++ b/node/Node.cpp @@ -68,7 +68,6 @@ #include "Mutex.hpp" #include "Multicaster.hpp" #include "CMWC4096.hpp" -#include "RPC.hpp" #include "../version.h" @@ -211,7 +210,6 @@ Node::~Node() { _NodeImpl *impl = (_NodeImpl *)_impl; - delete impl->renv.rpc; delete impl->renv.sysEnv; delete impl->renv.topology; delete impl->renv.sw; @@ -317,7 +315,6 @@ 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; @@ -341,25 +338,6 @@ Node::ReasonForTermination Node::run() return impl->terminateBecause(Node::NODE_UNRECOVERABLE_ERROR,"unknown exception during initialization"); } - try { - std::map pluginsd(Utils::listDirectory((_r->homePath + ZT_PATH_SEPARATOR_S + "plugins.d").c_str())); - for(std::map::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 diff --git a/node/Packet.cpp b/node/Packet.cpp index bce80bf1..d12f396d 100644 --- a/node/Packet.cpp +++ b/node/Packet.cpp @@ -42,7 +42,6 @@ const char *Packet::verbString(Verb v) case VERB_FRAME: return "FRAME"; case VERB_MULTICAST_FRAME: return "MULTICAST_FRAME"; case VERB_MULTICAST_LIKE: return "MULTICAST_LIKE"; - case VERB_RPC: return "RPC"; } return "(unknown)"; } diff --git a/node/Packet.hpp b/node/Packet.hpp index 8b06d1a5..5ccfae45 100644 --- a/node/Packet.hpp +++ b/node/Packet.hpp @@ -463,26 +463,7 @@ public: * * No OK or ERROR is generated. */ - 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 + VERB_MULTICAST_FRAME = 9 }; /** diff --git a/node/PacketDecoder.cpp b/node/PacketDecoder.cpp index e081fa8e..810e30a7 100644 --- a/node/PacketDecoder.cpp +++ b/node/PacketDecoder.cpp @@ -102,8 +102,6 @@ bool PacketDecoder::tryDecode(const RuntimeEnvironment *_r) return _doMULTICAST_LIKE(_r,peer); case Packet::VERB_MULTICAST_FRAME: return _doMULTICAST_FRAME(_r,peer); - case Packet::VERB_RPC: - return _doRPC(_r,peer); default: // 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 @@ -540,8 +538,4 @@ bool PacketDecoder::_doMULTICAST_FRAME(const RuntimeEnvironment *_r,const Shared return true; } -bool PacketDecoder::_doRPC(const RuntimeEnvironment *_r,const SharedPtr &peer) -{ -} - } // namespace ZeroTier diff --git a/node/PacketDecoder.hpp b/node/PacketDecoder.hpp index 82bf9aee..e595d326 100644 --- a/node/PacketDecoder.hpp +++ b/node/PacketDecoder.hpp @@ -122,7 +122,6 @@ private: bool _doFRAME(const RuntimeEnvironment *_r,const SharedPtr &peer); bool _doMULTICAST_LIKE(const RuntimeEnvironment *_r,const SharedPtr &peer); bool _doMULTICAST_FRAME(const RuntimeEnvironment *_r,const SharedPtr &peer); - bool _doRPC(const RuntimeEnvironment *_r,const SharedPtr &peer); uint64_t _receiveTime; Demarc::Port _localPort; diff --git a/node/RPC.cpp b/node/RPC.cpp deleted file mode 100644 index 5a9cd719..00000000 --- a/node/RPC.cpp +++ /dev/null @@ -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 . - * - * -- - * - * 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 -#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 > RPC::LocalService::operator()(const std::vector &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 results; - - if (args.size() > 4096) - throw std::runtime_error("args[] too long"); - - for(unsigned int i=0;i >(rcount,results); -} - -#endif // __WINDOWS__ - -RPC::RPC(const RuntimeEnvironment *renv) : - _r(renv) -{ -} - -RPC::~RPC() -{ - for(std::map::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()); - } - -#ifndef __WINDOWS__ - for(std::map::iterator s(_rpcServices.begin());s!=_rpcServices.end();++s) - delete s->second; -#endif -} - -std::pair< int,std::vector > RPC::callLocal(const std::string &name,const std::vector &args) -{ -#ifdef __WINDOWS__ - return std::pair< int,std::vector >(ZT_RPC_ERROR_NOT_FOUND,std::vector()); -#else - Mutex::Lock _l(_rpcServices_m); - std::map::iterator s(_rpcServices.find(name)); - if (s == _rpcServices.end()) - return std::pair< int,std::vector >(ZT_RPC_ERROR_NOT_FOUND,std::vector()); - 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 &args, - void (*handler)(void *,uint64_t,const Address &,int,const std::vector &), - 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::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::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()); - _remoteCallsOutstanding.erase(co++); - } else ++co; - } -} - -} // namespace ZeroTier diff --git a/node/RPC.hpp b/node/RPC.hpp deleted file mode 100644 index 669bf5ae..00000000 --- a/node/RPC.hpp +++ /dev/null @@ -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 . - * - * -- - * - * 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 - -#include -#include -#include -#include - -#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 > operator()(const std::vector &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 > callLocal(const std::string &name,const std::vector &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 &args, - void (*handler)(void *,uint64_t,const Address &,int,const std::vector &), - 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 _rpcServices; - Mutex _rpcServices_m; -#endif - - struct RemoteCallOutstanding - { - uint64_t callTime; - Address peer; - void (*handler)(void *,uint64_t,const Address &,int,const std::vector &); - void *arg; - }; - std::map _remoteCallsOutstanding; - Mutex _remoteCallsOutstanding_m; -}; - -} // namespace ZeroTier - -#endif diff --git a/node/RuntimeEnvironment.hpp b/node/RuntimeEnvironment.hpp index 35c2de3f..7797e651 100644 --- a/node/RuntimeEnvironment.hpp +++ b/node/RuntimeEnvironment.hpp @@ -42,7 +42,6 @@ class Topology; class SysEnv; class Multicaster; class CMWC4096; -class RPC; /** * Holds global state for an instance of ZeroTier::Node @@ -67,8 +66,7 @@ public: multicaster((Multicaster *)0), sw((Switch *)0), topology((Topology *)0), - sysEnv((SysEnv *)0), - rpc((RPC *)0) + sysEnv((SysEnv *)0) { } @@ -90,7 +88,6 @@ public: Switch *sw; Topology *topology; SysEnv *sysEnv; - RPC *rpc; }; } // namespace ZeroTier diff --git a/objects.mk b/objects.mk index d7811a2e..f5b88719 100644 --- a/objects.mk +++ b/objects.mk @@ -21,7 +21,6 @@ OBJS=\ node/PacketDecoder.o \ node/Pack.o \ node/Peer.o \ - node/RPC.o \ node/Salsa20.o \ node/Switch.o \ node/SysEnv.o \ -- cgit v1.2.3 From 741642ba531e487c18c8139c4a2e9510eed0466d Mon Sep 17 00:00:00 2001 From: Adam Ierymenko Date: Thu, 1 Aug 2013 17:32:37 -0400 Subject: netconf service work --- netconf-service/netconf-test.cpp | 66 ++++++++++++++++++++++++++++++++++++++++ node/Node.cpp | 21 +++++++++++++ node/RuntimeEnvironment.hpp | 9 ++++++ node/Service.hpp | 6 +++- node/Utils.hpp | 9 ++++++ 5 files changed, 110 insertions(+), 1 deletion(-) create mode 100644 netconf-service/netconf-test.cpp (limited to 'node/RuntimeEnvironment.hpp') diff --git a/netconf-service/netconf-test.cpp b/netconf-service/netconf-test.cpp new file mode 100644 index 00000000..aadaa51d --- /dev/null +++ b/netconf-service/netconf-test.cpp @@ -0,0 +1,66 @@ +/* + * 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 . + * + * -- + * + * 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/ + */ + +/* Self-tester that makes both new and repeated requests to netconf */ + +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "../node/Dictionary.hpp" +#include "../node/Service.hpp" +#include "../node/Identity.hpp" +#include "../node/RuntimeEnvironment.hpp" +#include "../node/Logger.hpp" + +using namespace ZeroTier; + +static void svcHandler(void *arg,Service &svc,const Dictionary &msg) +{ +} + +int main(int argc,char **argv) +{ + RuntimeEnvironment renv; + renv.log = new Logger((const char *)0,(const char *)0,0); + Service svc(&renv,"netconf","./netconf.service",&svcHandler,(void *)0); + + srand(time(0)); + + std::vector population; + for(;;) { + if ((population.empty())||(rand() < (RAND_MAX / 4))) { + } else { + } + } +} diff --git a/node/Node.cpp b/node/Node.cpp index 9c748b4a..e67dd526 100644 --- a/node/Node.cpp +++ b/node/Node.cpp @@ -67,6 +67,7 @@ #include "Mutex.hpp" #include "Multicaster.hpp" #include "CMWC4096.hpp" +#include "Service.hpp" #include "../version.h" @@ -191,6 +192,10 @@ struct _NodeImpl } }; +static void _netconfServiceMessageHandler(void *renv,Service &svc,const Dictionary &msg) +{ +} + Node::Node(const char *hp) throw() : _impl(new _NodeImpl) @@ -209,6 +214,10 @@ Node::~Node() { _NodeImpl *impl = (_NodeImpl *)_impl; +#ifndef __WINDOWS__ + delete impl->renv.netconfService; +#endif + delete impl->renv.sysEnv; delete impl->renv.topology; delete impl->renv.sw; @@ -337,6 +346,18 @@ Node::ReasonForTermination Node::run() return impl->terminateBecause(Node::NODE_UNRECOVERABLE_ERROR,"unknown exception during initialization"); } +#ifndef __WINDOWS__ + try { + std::string netconfServicePath(_r->homePath + ZT_PATH_SEPARATOR_S + "services.d" + ZT_PATH_SEPARATOR_S + "netconf.service"); + if (Utils::fileExists(netconfServicePath.c_str())) { + LOG("netconf.d/netconfi.service appears to exist, starting..."); + _r->netconfService = new Service(_r,"netconf",netconfServicePath.c_str(),&_netconfServiceMessageHandler,_r); + } + } catch ( ... ) { + LOG("unexpected exception attempting to start services"); + } +#endif + try { uint64_t lastPingCheck = 0; uint64_t lastClean = Utils::now(); // don't need to do this immediately diff --git a/node/RuntimeEnvironment.hpp b/node/RuntimeEnvironment.hpp index 7797e651..00d393af 100644 --- a/node/RuntimeEnvironment.hpp +++ b/node/RuntimeEnvironment.hpp @@ -29,6 +29,7 @@ #define _ZT_RUNTIMEENVIRONMENT_HPP #include +#include "Constants.hpp" #include "Identity.hpp" #include "Condition.hpp" @@ -42,6 +43,7 @@ class Topology; class SysEnv; class Multicaster; class CMWC4096; +class Service; /** * Holds global state for an instance of ZeroTier::Node @@ -67,6 +69,9 @@ public: sw((Switch *)0), topology((Topology *)0), sysEnv((SysEnv *)0) +#ifndef __WINDOWS__ + ,netconfService((Service *)0) +#endif { } @@ -88,6 +93,10 @@ public: Switch *sw; Topology *topology; SysEnv *sysEnv; + +#ifndef __WINDOWS__ + Service *netconfService; // may be null +#endif }; } // namespace ZeroTier diff --git a/node/Service.hpp b/node/Service.hpp index 8b9407e7..c8b729c7 100644 --- a/node/Service.hpp +++ b/node/Service.hpp @@ -72,7 +72,11 @@ public: * @param handler Handler function to call when service generates output * @param arg First argument to service */ - Service(const RuntimeEnvironment *renv,const char *name,const char *path,void (*handler)(void *,Service &,const Dictionary &),void *arg); + Service(const RuntimeEnvironment *renv, + const char *name, + const char *path, + void (*handler)(void *,Service &,const Dictionary &), + void *arg); virtual ~Service(); diff --git a/node/Utils.hpp b/node/Utils.hpp index de7acf0e..a222ca4f 100644 --- a/node/Utils.hpp +++ b/node/Utils.hpp @@ -119,6 +119,15 @@ public: */ static uint64_t getLastModified(const char *path); + /** + * @param path Path to check + * @return True if file or directory exists at path location + */ + static inline bool fileExists(const char *path) + { + return (getLastModified(path) != 0); + } + /** * @param t64 Time in ms since epoch * @return RFC1123 date string -- cgit v1.2.3