Browse Source

Work in progress on RPC.

Adam Ierymenko 12 years ago
parent
commit
083ae2d097
3 changed files with 223 additions and 1 deletions
  1. 9 1
      node/Network.hpp
  2. 31 0
      node/RPC.cpp
  3. 183 0
      node/RPC.hpp

+ 9 - 1
node/Network.hpp

@@ -49,7 +49,15 @@ namespace ZeroTier {
 class NodeConfig;
 
 /**
- * Local network endpoint
+ * 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
 {

+ 31 - 0
node/RPC.cpp

@@ -0,0 +1,31 @@
+/*
+ * 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/
+ */
+
+#include "RuntimeEnvironment.hpp"
+#include "RPC.hpp"
+#include "Switch.hpp"
+#include "Topology.hpp"

+ 183 - 0
node/RPC.hpp

@@ -0,0 +1,183 @@
+/*
+ * 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 "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 _WIN32
+	/**
+	 * A local service accessible by RPC, non-Windows only for now
+	 *
+	 * Each service DLL must export these functions:
+	 *
+	 * void 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::vector<std::string> operator()(const std::vector<std::string> &args)
+			throw(std::runtime_error);
+
+	private:
+		void *_dlhandle;
+	};
+#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)
+		throw();
+
+	/**
+	 * 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);
+
+	/**
+	 * Periodically called to clean up, such as by expiring remote calls
+	 */
+	void clean();
+
+private:
+	const RuntimeEnvironment *_r;
+
+	std::map<std::string,LocalService *> _rpcServices;
+	Mutex _rpcServices_m;
+
+	struct RemoteCallOutstanding
+	{
+		uint64_t callTime;
+		Address peer;
+		std::string name;
+		std::vector<std::string> &args;
+		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