2
0
Эх сурвалжийг харах

Fixes to control plane, API, eliminate problematic inheritance pattern, and start on a NodeJS class for talking to the network controller.

Adam Ierymenko 10 жил өмнө
parent
commit
a187d290f1

+ 1 - 0
.gitignore

@@ -43,3 +43,4 @@
 /ui/.module-cache
 /ui/.module-cache
 /windows/WebUIWrapper/bin
 /windows/WebUIWrapper/bin
 /windows/WebUIWrapper/obj
 /windows/WebUIWrapper/obj
+node_modules

+ 47 - 50
controller/SqliteNetworkController.cpp

@@ -560,12 +560,9 @@ unsigned int SqliteNetworkController::handleControlPlaneHttpGET(
 	std::string &responseContentType)
 	std::string &responseContentType)
 {
 {
 	char json[16384];
 	char json[16384];
-
-	if (path.empty())
-		return 404;
 	Mutex::Lock _l(_lock);
 	Mutex::Lock _l(_lock);
 
 
-	if (path[0] == "network") {
+	if ((path.size() > 0)&&(path[0] == "network")) {
 
 
 		if ((path.size() >= 2)&&(path[1].length() == 16)) {
 		if ((path.size() >= 2)&&(path[1].length() == 16)) {
 			uint64_t nwid = Utils::hexStrToU64(path[1].c_str());
 			uint64_t nwid = Utils::hexStrToU64(path[1].c_str());
@@ -584,15 +581,15 @@ unsigned int SqliteNetworkController::handleControlPlaneHttpGET(
 					if (sqlite3_step(_sGetMember2) == SQLITE_ROW) {
 					if (sqlite3_step(_sGetMember2) == SQLITE_ROW) {
 						Utils::snprintf(json,sizeof(json),
 						Utils::snprintf(json,sizeof(json),
 							"{\n"
 							"{\n"
-							"\tnwid: \"%s\",\n"
-							"\taddress: \"%s\",\n"
-							"\tauthorized: %s,\n"
-							"\tactiveBridge: %s,\n"
-							"\tlastAt: \"%s\",\n"
-							"\tlastSeen: %llu,\n"
-							"\tfirstSeen: %llu,\n"
-							"\tidentity: \"%s\",\n"
-							"\tipAssignments: [",
+							"\t\"nwid\": \"%s\",\n"
+							"\t\"address\": \"%s\",\n"
+							"\t\"authorized\": %s,\n"
+							"\t\"activeBridge\": %s,\n"
+							"\t\"lastAt\": \"%s\",\n"
+							"\t\"lastSeen\": %llu,\n"
+							"\t\"firstSeen\": %llu,\n"
+							"\t\"identity\": \"%s\",\n"
+							"\t\"ipAssignments\": [",
 							nwids,
 							nwids,
 							addrs,
 							addrs,
 							(sqlite3_column_int(_sGetMember2,0) > 0) ? "true" : "false",
 							(sqlite3_column_int(_sGetMember2,0) > 0) ? "true" : "false",
@@ -651,18 +648,18 @@ unsigned int SqliteNetworkController::handleControlPlaneHttpGET(
 										case NetworkController::NETCONF_QUERY_INTERNAL_SERVER_ERROR: result = "INTERNAL_SERVER_ERROR"; break;
 										case NetworkController::NETCONF_QUERY_INTERNAL_SERVER_ERROR: result = "INTERNAL_SERVER_ERROR"; break;
 										default: result = "(unrecognized result code)"; break;
 										default: result = "(unrecognized result code)"; break;
 									}
 									}
-									responseBody.append(",\n\tnetconf: \"");
+									responseBody.append(",\n\t\"netconf\": \"");
 									responseBody.append(_jsonEscape(netconf.toString().c_str()));
 									responseBody.append(_jsonEscape(netconf.toString().c_str()));
-									responseBody.append("\",\n\tnetconfResult: \"");
+									responseBody.append("\",\n\t\"netconfResult\": \"");
 									responseBody.append(result);
 									responseBody.append(result);
-									responseBody.append("\",\n\tnetconfResultMessage: \"");
+									responseBody.append("\",\n\t\"netconfResultMessage\": \"");
 									responseBody.append(_jsonEscape(netconf["error"].c_str()));
 									responseBody.append(_jsonEscape(netconf["error"].c_str()));
 									responseBody.append("\"");
 									responseBody.append("\"");
 								} else {
 								} else {
-									responseBody.append(",\n\tnetconf: \"\",\n\tnetconfResult: \"INTERNAL_SERVER_ERROR\",\n\tnetconfResultMessage: \"invalid member or signing identity\"");
+									responseBody.append(",\n\t\"netconf\": \"\",\n\t\"netconfResult\": \"INTERNAL_SERVER_ERROR\",\n\t\"netconfResultMessage\": \"invalid member or signing identity\"");
 								}
 								}
 							} catch ( ... ) {
 							} catch ( ... ) {
-								responseBody.append(",\n\tnetconf: \"\",\n\tnetconfResult: \"INTERNAL_SERVER_ERROR\",\n\tnetconfResultMessage: \"unexpected exception\"");
+								responseBody.append(",\n\t\"netconf\": \"\",\n\t\"netconfResult\": \"INTERNAL_SERVER_ERROR\",\n\t\"netconfResultMessage\": \"unexpected exception\"");
 							}
 							}
 						}
 						}
 
 
@@ -679,17 +676,17 @@ unsigned int SqliteNetworkController::handleControlPlaneHttpGET(
 				if (sqlite3_step(_sGetNetworkById) == SQLITE_ROW) {
 				if (sqlite3_step(_sGetNetworkById) == SQLITE_ROW) {
 					Utils::snprintf(json,sizeof(json),
 					Utils::snprintf(json,sizeof(json),
 						"{\n"
 						"{\n"
-						"\tnwid: \"%s\",\n"
-						"\tname: \"%s\",\n"
-						"\tprivate: %s,\n"
-						"\tenableBroadcast: %s,\n"
-						"\tallowPassiveBridging: %s,\n"
-						"\tv4AssignMode: \"%s\",\n"
-						"\tv6AssignMode: \"%s\",\n"
-						"\tmulticastLimit: %d,\n"
-						"\tcreationTime: %llu,\n",
-						"\trevision: %llu,\n"
-						"\amembers: [",
+						"\t\"nwid\": \"%s\",\n"
+						"\t\"name\": \"%s\",\n"
+						"\t\"private\": %s,\n"
+						"\t\"enableBroadcast\": %s,\n"
+						"\t\"allowPassiveBridging\": %s,\n"
+						"\t\"v4AssignMode\": \"%s\",\n"
+						"\t\"v6AssignMode\": \"%s\",\n"
+						"\t\"multicastLimit\": %d,\n"
+						"\t\"creationTime\": %llu,\n",
+						"\t\"revision\": %llu,\n"
+						"\a\"members\": [",
 						nwids,
 						nwids,
 						_jsonEscape((const char *)sqlite3_column_text(_sGetNetworkById,0)).c_str(),
 						_jsonEscape((const char *)sqlite3_column_text(_sGetNetworkById,0)).c_str(),
 						(sqlite3_column_int(_sGetNetworkById,1) > 0) ? "true" : "false",
 						(sqlite3_column_int(_sGetNetworkById,1) > 0) ? "true" : "false",
@@ -713,7 +710,7 @@ unsigned int SqliteNetworkController::handleControlPlaneHttpGET(
 						responseBody.push_back('"');
 						responseBody.push_back('"');
 						firstMember = false;
 						firstMember = false;
 					}
 					}
-					responseBody.append("],\n\trelays: [");
+					responseBody.append("],\n\t\"relays\": [");
 
 
 					sqlite3_reset(_sGetRelays);
 					sqlite3_reset(_sGetRelays);
 					sqlite3_bind_text(_sGetRelays,1,nwids,16,SQLITE_STATIC);
 					sqlite3_bind_text(_sGetRelays,1,nwids,16,SQLITE_STATIC);
@@ -721,13 +718,13 @@ unsigned int SqliteNetworkController::handleControlPlaneHttpGET(
 					while (sqlite3_step(_sGetRelays) == SQLITE_ROW) {
 					while (sqlite3_step(_sGetRelays) == SQLITE_ROW) {
 						responseBody.append(firstRelay ? "\n\t\t" : ",\n\t\t");
 						responseBody.append(firstRelay ? "\n\t\t" : ",\n\t\t");
 						firstRelay = false;
 						firstRelay = false;
-						responseBody.append("{address:\"");
+						responseBody.append("{\"address\":\"");
 						responseBody.append((const char *)sqlite3_column_text(_sGetRelays,0));
 						responseBody.append((const char *)sqlite3_column_text(_sGetRelays,0));
-						responseBody.append("\",phyAddress:\"");
+						responseBody.append("\",\"phyAddress\":\"");
 						responseBody.append(_jsonEscape((const char *)sqlite3_column_text(_sGetRelays,1)));
 						responseBody.append(_jsonEscape((const char *)sqlite3_column_text(_sGetRelays,1)));
 						responseBody.append("\"}");
 						responseBody.append("\"}");
 					}
 					}
-					responseBody.append("],\n\tipAssignmentPools: [");
+					responseBody.append("],\n\t\"ipAssignmentPools\": [");
 
 
 					sqlite3_reset(_sGetIpAssignmentPools2);
 					sqlite3_reset(_sGetIpAssignmentPools2);
 					sqlite3_bind_text(_sGetIpAssignmentPools2,1,nwids,16,SQLITE_STATIC);
 					sqlite3_bind_text(_sGetIpAssignmentPools2,1,nwids,16,SQLITE_STATIC);
@@ -736,69 +733,69 @@ unsigned int SqliteNetworkController::handleControlPlaneHttpGET(
 						responseBody.append(firstIpAssignmentPool ? "\n\t\t" : ",\n\t\t");
 						responseBody.append(firstIpAssignmentPool ? "\n\t\t" : ",\n\t\t");
 						firstIpAssignmentPool = false;
 						firstIpAssignmentPool = false;
 						InetAddress ipp((const void *)sqlite3_column_blob(_sGetIpAssignmentPools2,0),(sqlite3_column_int(_sGetIpAssignmentPools2,2) == 6) ? 16 : 4,(unsigned int)sqlite3_column_int(_sGetIpAssignmentPools2,1));
 						InetAddress ipp((const void *)sqlite3_column_blob(_sGetIpAssignmentPools2,0),(sqlite3_column_int(_sGetIpAssignmentPools2,2) == 6) ? 16 : 4,(unsigned int)sqlite3_column_int(_sGetIpAssignmentPools2,1));
-						Utils::snprintf(json,sizeof(json),"{network:\"%s\",netmaskBits:%u}",
+						Utils::snprintf(json,sizeof(json),"{\"network\":\"%s\",\"netmaskBits\":%u}",
 							_jsonEscape(ipp.toIpString()).c_str(),
 							_jsonEscape(ipp.toIpString()).c_str(),
 							ipp.netmaskBits());
 							ipp.netmaskBits());
 						responseBody.append(json);
 						responseBody.append(json);
 					}
 					}
-					responseBody.append("],\n\trules: [");
+					responseBody.append("],\n\t\"rules\": [");
 
 
 					sqlite3_reset(_sListRules);
 					sqlite3_reset(_sListRules);
 					sqlite3_bind_text(_sListRules,1,nwids,16,SQLITE_STATIC);
 					sqlite3_bind_text(_sListRules,1,nwids,16,SQLITE_STATIC);
 					bool firstRule = true;
 					bool firstRule = true;
 					while (sqlite3_step(_sListRules) == SQLITE_ROW) {
 					while (sqlite3_step(_sListRules) == SQLITE_ROW) {
 						responseBody.append(firstRule ? "\n\t{\n" : ",{\n");
 						responseBody.append(firstRule ? "\n\t{\n" : ",{\n");
-						Utils::snprintf(json,sizeof(json),"\t\truleId: %lld,\n",sqlite3_column_int64(_sListRules,0));
+						Utils::snprintf(json,sizeof(json),"\t\t\"ruleId\": %lld,\n",sqlite3_column_int64(_sListRules,0));
 						responseBody.append(json);
 						responseBody.append(json);
 						if (sqlite3_column_type(_sListRules,1) != SQLITE_NULL) {
 						if (sqlite3_column_type(_sListRules,1) != SQLITE_NULL) {
-							Utils::snprintf(json,sizeof(json),"\t\tnodeId: \"%s\",\n",(const char *)sqlite3_column_text(_sListRules,1));
+							Utils::snprintf(json,sizeof(json),"\t\t\"nodeId\": \"%s\",\n",(const char *)sqlite3_column_text(_sListRules,1));
 							responseBody.append(json);
 							responseBody.append(json);
 						}
 						}
 						if (sqlite3_column_type(_sListRules,2) != SQLITE_NULL) {
 						if (sqlite3_column_type(_sListRules,2) != SQLITE_NULL) {
-							Utils::snprintf(json,sizeof(json),"\t\tvlanId: %d,\n",sqlite3_column_int(_sListRules,2));
+							Utils::snprintf(json,sizeof(json),"\t\t\"vlanId\": %d,\n",sqlite3_column_int(_sListRules,2));
 							responseBody.append(json);
 							responseBody.append(json);
 						}
 						}
 						if (sqlite3_column_type(_sListRules,3) != SQLITE_NULL) {
 						if (sqlite3_column_type(_sListRules,3) != SQLITE_NULL) {
-							Utils::snprintf(json,sizeof(json),"\t\tvlanPcp: %d,\n",sqlite3_column_int(_sListRules,3));
+							Utils::snprintf(json,sizeof(json),"\t\t\"vlanPcp\": %d,\n",sqlite3_column_int(_sListRules,3));
 							responseBody.append(json);
 							responseBody.append(json);
 						}
 						}
 						if (sqlite3_column_type(_sListRules,4) != SQLITE_NULL) {
 						if (sqlite3_column_type(_sListRules,4) != SQLITE_NULL) {
-							Utils::snprintf(json,sizeof(json),"\t\tetherType: %d,\n",sqlite3_column_int(_sListRules,4));
+							Utils::snprintf(json,sizeof(json),"\t\t\"etherType\": %d,\n",sqlite3_column_int(_sListRules,4));
 							responseBody.append(json);
 							responseBody.append(json);
 						}
 						}
 						if (sqlite3_column_type(_sListRules,5) != SQLITE_NULL) {
 						if (sqlite3_column_type(_sListRules,5) != SQLITE_NULL) {
-							Utils::snprintf(json,sizeof(json),"\t\tmacSource: \"%s\",\n",MAC((const char *)sqlite3_column_text(_sListRules,5)).toString().c_str());
+							Utils::snprintf(json,sizeof(json),"\t\t\"macSource\": \"%s\",\n",MAC((const char *)sqlite3_column_text(_sListRules,5)).toString().c_str());
 							responseBody.append(json);
 							responseBody.append(json);
 						}
 						}
 						if (sqlite3_column_type(_sListRules,6) != SQLITE_NULL) {
 						if (sqlite3_column_type(_sListRules,6) != SQLITE_NULL) {
-							Utils::snprintf(json,sizeof(json),"\t\tmacDest: \"%s\",\n",MAC((const char *)sqlite3_column_text(_sListRules,6)).toString().c_str());
+							Utils::snprintf(json,sizeof(json),"\t\t\"macDest\": \"%s\",\n",MAC((const char *)sqlite3_column_text(_sListRules,6)).toString().c_str());
 							responseBody.append(json);
 							responseBody.append(json);
 						}
 						}
 						if (sqlite3_column_type(_sListRules,7) != SQLITE_NULL) {
 						if (sqlite3_column_type(_sListRules,7) != SQLITE_NULL) {
-							Utils::snprintf(json,sizeof(json),"\t\tipSource: \"%s\",\n",_jsonEscape((const char *)sqlite3_column_text(_sListRules,7)).c_str());
+							Utils::snprintf(json,sizeof(json),"\t\t\"ipSource\": \"%s\",\n",_jsonEscape((const char *)sqlite3_column_text(_sListRules,7)).c_str());
 							responseBody.append(json);
 							responseBody.append(json);
 						}
 						}
 						if (sqlite3_column_type(_sListRules,8) != SQLITE_NULL) {
 						if (sqlite3_column_type(_sListRules,8) != SQLITE_NULL) {
-							Utils::snprintf(json,sizeof(json),"\t\tipDest: \"%s\",\n",_jsonEscape((const char *)sqlite3_column_text(_sListRules,8)).c_str());
+							Utils::snprintf(json,sizeof(json),"\t\t\"ipDest\": \"%s\",\n",_jsonEscape((const char *)sqlite3_column_text(_sListRules,8)).c_str());
 							responseBody.append(json);
 							responseBody.append(json);
 						}
 						}
 						if (sqlite3_column_type(_sListRules,9) != SQLITE_NULL) {
 						if (sqlite3_column_type(_sListRules,9) != SQLITE_NULL) {
-							Utils::snprintf(json,sizeof(json),"\t\tipTos: %d,\n",sqlite3_column_int(_sListRules,9));
+							Utils::snprintf(json,sizeof(json),"\t\t\"ipTos\": %d,\n",sqlite3_column_int(_sListRules,9));
 							responseBody.append(json);
 							responseBody.append(json);
 						}
 						}
 						if (sqlite3_column_type(_sListRules,10) != SQLITE_NULL) {
 						if (sqlite3_column_type(_sListRules,10) != SQLITE_NULL) {
-							Utils::snprintf(json,sizeof(json),"\t\tipProtocol: %d,\n",sqlite3_column_int(_sListRules,10));
+							Utils::snprintf(json,sizeof(json),"\t\t\"ipProtocol\": %d,\n",sqlite3_column_int(_sListRules,10));
 							responseBody.append(json);
 							responseBody.append(json);
 						}
 						}
 						if (sqlite3_column_type(_sListRules,11) != SQLITE_NULL) {
 						if (sqlite3_column_type(_sListRules,11) != SQLITE_NULL) {
-							Utils::snprintf(json,sizeof(json),"\t\tipSourcePort: %d,\n",sqlite3_column_int(_sListRules,11));
+							Utils::snprintf(json,sizeof(json),"\t\t\"ipSourcePort\": %d,\n",sqlite3_column_int(_sListRules,11));
 							responseBody.append(json);
 							responseBody.append(json);
 						}
 						}
 						if (sqlite3_column_type(_sListRules,12) != SQLITE_NULL) {
 						if (sqlite3_column_type(_sListRules,12) != SQLITE_NULL) {
-							Utils::snprintf(json,sizeof(json),"\t\tipDestPort: %d,\n",sqlite3_column_int(_sListRules,12));
+							Utils::snprintf(json,sizeof(json),"\t\t\"ipDestPort\": %d,\n",sqlite3_column_int(_sListRules,12));
 							responseBody.append(json);
 							responseBody.append(json);
 						}
 						}
-						responseBody.append("\t\taction: \"");
+						responseBody.append("\t\t\"action\": \"");
 						responseBody.append(_jsonEscape((const char *)sqlite3_column_text(_sListRules,13)));
 						responseBody.append(_jsonEscape((const char *)sqlite3_column_text(_sListRules,13)));
 						responseBody.append("\"\n\t}");
 						responseBody.append("\"\n\t}");
 					}
 					}
@@ -828,7 +825,7 @@ unsigned int SqliteNetworkController::handleControlPlaneHttpGET(
 
 
 	} else {
 	} else {
 		// GET /controller returns status and API version if controller is supported
 		// GET /controller returns status and API version if controller is supported
-		Utils::snprintf(json,sizeof(json),"{\n\tcontroller: true,\n\tapiVersion: %d\n\tclock: %llu\n}",ZT_NETCONF_CONTROLLER_API_VERSION,(unsigned long long)OSUtils::now());
+		Utils::snprintf(json,sizeof(json),"{\n\t\"controller\": true,\n\t\"apiVersion\": %d,\n\t\"clock\": %llu\n}",ZT_NETCONF_CONTROLLER_API_VERSION,(unsigned long long)OSUtils::now());
 		responseBody = json;
 		responseBody = json;
 		responseContentType = "applicaiton/json";
 		responseContentType = "applicaiton/json";
 		return 200;
 		return 200;

+ 4 - 8
controller/SqliteNetworkController.hpp

@@ -40,17 +40,14 @@
 #include "../node/NetworkController.hpp"
 #include "../node/NetworkController.hpp"
 #include "../node/Mutex.hpp"
 #include "../node/Mutex.hpp"
 
 
-#include "../service/ControlPlaneSubsystem.hpp"
-
 namespace ZeroTier {
 namespace ZeroTier {
 
 
-class SqliteNetworkController : public NetworkController,public ControlPlaneSubsystem
+class SqliteNetworkController : public NetworkController
 {
 {
 public:
 public:
 	SqliteNetworkController(const char *dbPath);
 	SqliteNetworkController(const char *dbPath);
 	virtual ~SqliteNetworkController();
 	virtual ~SqliteNetworkController();
 
 
-	// NetworkController
 	virtual NetworkController::ResultCode doNetworkConfigRequest(
 	virtual NetworkController::ResultCode doNetworkConfigRequest(
 		const InetAddress &fromAddr,
 		const InetAddress &fromAddr,
 		const Identity &signingId,
 		const Identity &signingId,
@@ -60,22 +57,21 @@ public:
 		uint64_t haveRevision,
 		uint64_t haveRevision,
 		Dictionary &netconf);
 		Dictionary &netconf);
 
 
-	// ControlPlaneSubsystem
-	virtual unsigned int handleControlPlaneHttpGET(
+	unsigned int handleControlPlaneHttpGET(
 		const std::vector<std::string> &path,
 		const std::vector<std::string> &path,
 		const std::map<std::string,std::string> &urlArgs,
 		const std::map<std::string,std::string> &urlArgs,
 		const std::map<std::string,std::string> &headers,
 		const std::map<std::string,std::string> &headers,
 		const std::string &body,
 		const std::string &body,
 		std::string &responseBody,
 		std::string &responseBody,
 		std::string &responseContentType);
 		std::string &responseContentType);
-	virtual unsigned int handleControlPlaneHttpPOST(
+	unsigned int handleControlPlaneHttpPOST(
 		const std::vector<std::string> &path,
 		const std::vector<std::string> &path,
 		const std::map<std::string,std::string> &urlArgs,
 		const std::map<std::string,std::string> &urlArgs,
 		const std::map<std::string,std::string> &headers,
 		const std::map<std::string,std::string> &headers,
 		const std::string &body,
 		const std::string &body,
 		std::string &responseBody,
 		std::string &responseBody,
 		std::string &responseContentType);
 		std::string &responseContentType);
-	virtual unsigned int handleControlPlaneHttpDELETE(
+	unsigned int handleControlPlaneHttpDELETE(
 		const std::vector<std::string> &path,
 		const std::vector<std::string> &path,
 		const std::map<std::string,std::string> &urlArgs,
 		const std::map<std::string,std::string> &urlArgs,
 		const std::map<std::string,std::string> &headers,
 		const std::map<std::string,std::string> &headers,

+ 26 - 0
controller/zt1-controller-client/index.js

@@ -0,0 +1,26 @@
+'use strict'
+
+var request = require('request');
+
+function ZT1ControllerClient(url,authToken)
+{
+	this.url = url;
+	this.authToken = authToken;
+}
+
+ZT1ControllerClient.prototype.status = function(callback)
+{
+	request({
+		url: this.url + 'controller',
+		method: 'GET',
+		headers: {
+			'X-ZT1-Auth': this.authToken
+		}
+	},function(error,response,body) {
+		if ((error)||(response.statusCode !== 200))
+			return callback(error,{});
+		return callback(null,JSON.parse(body));
+	});
+};
+
+exports.ZT1ControllerClient = ZT1ControllerClient;

+ 14 - 0
controller/zt1-controller-client/package.json

@@ -0,0 +1,14 @@
+{
+  "name": "zt1-controller-client",
+  "version": "1.0.0",
+  "description": "ZeroTier One network controller client for NodeJS",
+  "main": "index.js",
+  "scripts": {
+    "test": "echo \"Error: no test specified\" && exit 1"
+  },
+  "author": "ZeroTier, Inc.",
+  "license": "BSD",
+  "dependencies": {
+    "request": "^2.55.0"
+  }
+}

+ 7 - 0
controller/zt1-controller-client/test-controller.js

@@ -0,0 +1,7 @@
+var ZT1ControllerClient = require('./index.js').ZT1ControllerClient;
+
+var zt1c = new ZT1ControllerClient('http://127.0.0.1:9993/','5d6181b71fae2684f9cc64ed');
+
+zt1c.status(function(err,status) {
+	console.log(status);
+});

+ 5 - 4
service/ControlPlane.cpp

@@ -26,7 +26,6 @@
  */
  */
 
 
 #include "ControlPlane.hpp"
 #include "ControlPlane.hpp"
-#include "ControlPlaneSubsystem.hpp"
 #include "OneService.hpp"
 #include "OneService.hpp"
 
 
 #include "../version.h"
 #include "../version.h"
@@ -34,6 +33,8 @@
 
 
 #include "../ext/http-parser/http_parser.h"
 #include "../ext/http-parser/http_parser.h"
 
 
+#include "../controller/SqliteNetworkController.hpp"
+
 #include "../node/InetAddress.hpp"
 #include "../node/InetAddress.hpp"
 #include "../node/Node.hpp"
 #include "../node/Node.hpp"
 #include "../node/Utils.hpp"
 #include "../node/Utils.hpp"
@@ -444,7 +445,7 @@ unsigned int ControlPlane::handleRequest(
 				responseContentType = "text/plain";
 				responseContentType = "text/plain";
 				scode = 200;
 				scode = 200;
 			} else {
 			} else {
-				std::map<std::string,ControlPlaneSubsystem *>::const_iterator ss(_subsystems.find(ps[0]));
+				std::map<std::string,SqliteNetworkController *>::const_iterator ss(_subsystems.find(ps[0]));
 				if (ss != _subsystems.end())
 				if (ss != _subsystems.end())
 					scode = ss->second->handleControlPlaneHttpGET(std::vector<std::string>(ps.begin()+1,ps.end()),urlArgs,headers,body,responseBody,responseContentType);
 					scode = ss->second->handleControlPlaneHttpGET(std::vector<std::string>(ps.begin()+1,ps.end()),urlArgs,headers,body,responseBody,responseContentType);
 				else scode = 404;
 				else scode = 404;
@@ -477,7 +478,7 @@ unsigned int ControlPlane::handleRequest(
 					} else scode = 500;
 					} else scode = 500;
 				}
 				}
 			} else {
 			} else {
-				std::map<std::string,ControlPlaneSubsystem *>::const_iterator ss(_subsystems.find(ps[0]));
+				std::map<std::string,SqliteNetworkController *>::const_iterator ss(_subsystems.find(ps[0]));
 				if (ss != _subsystems.end())
 				if (ss != _subsystems.end())
 					scode = ss->second->handleControlPlaneHttpPOST(std::vector<std::string>(ps.begin()+1,ps.end()),urlArgs,headers,body,responseBody,responseContentType);
 					scode = ss->second->handleControlPlaneHttpPOST(std::vector<std::string>(ps.begin()+1,ps.end()),urlArgs,headers,body,responseBody,responseContentType);
 				else scode = 404;
 				else scode = 404;
@@ -509,7 +510,7 @@ unsigned int ControlPlane::handleRequest(
 					_node->freeQueryResult((void *)nws);
 					_node->freeQueryResult((void *)nws);
 				} else scode = 500;
 				} else scode = 500;
 			} else {
 			} else {
-				std::map<std::string,ControlPlaneSubsystem *>::const_iterator ss(_subsystems.find(ps[0]));
+				std::map<std::string,SqliteNetworkController *>::const_iterator ss(_subsystems.find(ps[0]));
 				if (ss != _subsystems.end())
 				if (ss != _subsystems.end())
 					scode = ss->second->handleControlPlaneHttpDELETE(std::vector<std::string>(ps.begin()+1,ps.end()),urlArgs,headers,body,responseBody,responseContentType);
 					scode = ss->second->handleControlPlaneHttpDELETE(std::vector<std::string>(ps.begin()+1,ps.end()),urlArgs,headers,body,responseBody,responseContentType);
 				else scode = 404;
 				else scode = 404;

+ 3 - 3
service/ControlPlane.hpp

@@ -40,7 +40,7 @@ namespace ZeroTier {
 
 
 class OneService;
 class OneService;
 class Node;
 class Node;
-class ControlPlaneSubsystem;
+class SqliteNetworkController;
 struct InetAddress;
 struct InetAddress;
 
 
 /**
 /**
@@ -72,7 +72,7 @@ public:
 	 * @param prefix First element in URI path
 	 * @param prefix First element in URI path
 	 * @param subsys Object to call for results of GET and POST/PUT operations
 	 * @param subsys Object to call for results of GET and POST/PUT operations
 	 */
 	 */
-	inline void mount(const char *prefix,ControlPlaneSubsystem *subsys)
+	inline void mount(const char *prefix,SqliteNetworkController *subsys)
 	{
 	{
 		Mutex::Lock _l(_lock);
 		Mutex::Lock _l(_lock);
 		_subsystems[std::string(prefix)] = subsys;
 		_subsystems[std::string(prefix)] = subsys;
@@ -104,7 +104,7 @@ private:
 	Node *const _node;
 	Node *const _node;
 	std::string _uiStaticPath;
 	std::string _uiStaticPath;
 	std::set<std::string> _authTokens;
 	std::set<std::string> _authTokens;
-	std::map<std::string,ControlPlaneSubsystem *> _subsystems;
+	std::map<std::string,SqliteNetworkController *> _subsystems;
 	Mutex _lock;
 	Mutex _lock;
 };
 };
 
 

+ 0 - 76
service/ControlPlaneSubsystem.hpp

@@ -1,76 +0,0 @@
-/*
- * ZeroTier One - Network Virtualization Everywhere
- * Copyright (C) 2011-2015  ZeroTier, Inc.
- *
- * 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_CONTROLPLANESUBSYSTEM_HPP
-#define ZT_CONTROLPLANESUBSYSTEM_HPP
-
-#include <map>
-#include <vector>
-#include <string>
-
-namespace ZeroTier {
-
-/**
- * Base class for subsystems that can be mounted under the HTTP control plane
- *
- * Handlers should fill in responseBody and responseContentType and return
- * a HTTP status code or 0 on other errors.
- */
-class ControlPlaneSubsystem
-{
-public:
-	ControlPlaneSubsystem() {}
-	virtual ~ControlPlaneSubsystem() {}
-
-	virtual unsigned int handleControlPlaneHttpGET(
-		const std::vector<std::string> &path,
-		const std::map<std::string,std::string> &urlArgs,
-		const std::map<std::string,std::string> &headers,
-		const std::string &body,
-		std::string &responseBody,
-		std::string &responseContentType) = 0;
-
-	virtual unsigned int handleControlPlaneHttpPOST(
-		const std::vector<std::string> &path,
-		const std::map<std::string,std::string> &urlArgs,
-		const std::map<std::string,std::string> &headers,
-		const std::string &body,
-		std::string &responseBody,
-		std::string &responseContentType) = 0;
-
-	virtual unsigned int handleControlPlaneHttpDELETE(
-		const std::vector<std::string> &path,
-		const std::map<std::string,std::string> &urlArgs,
-		const std::map<std::string,std::string> &headers,
-		const std::string &body,
-		std::string &responseBody,
-		std::string &responseContentType) = 0;
-};
-
-} // namespace ZeroTier
-
-#endif

+ 1 - 1
service/OneService.cpp

@@ -233,7 +233,7 @@ public:
 			_controlPlane = new ControlPlane(this,_node,(_homePath + ZT_PATH_SEPARATOR_S + "ui").c_str());
 			_controlPlane = new ControlPlane(this,_node,(_homePath + ZT_PATH_SEPARATOR_S + "ui").c_str());
 			_controlPlane->addAuthToken(authToken.c_str());
 			_controlPlane->addAuthToken(authToken.c_str());
 			if (_master)
 			if (_master)
-				_controlPlane->mount("controller",reinterpret_cast<ControlPlaneSubsystem *>(_master));
+				_controlPlane->mount("controller",reinterpret_cast<SqliteNetworkController *>(_master));
 
 
 			{	// Remember networks from previous session
 			{	// Remember networks from previous session
 				std::vector<std::string> networksDotD(OSUtils::listDirectory((_homePath + ZT_PATH_SEPARATOR_S + "networks.d").c_str()));
 				std::vector<std::string> networksDotD(OSUtils::listDirectory((_homePath + ZT_PATH_SEPARATOR_S + "networks.d").c_str()));

+ 1 - 1
service/README.md

@@ -11,7 +11,7 @@ The JSON API supports GET, POST/PUT, and DELETE. PUT is treated as a synonym for
 
 
 Values POSTed to the JSON API are *extremely* type sensitive. Things *must* be of the indicated type, otherwise they will be ignored or will generate an error. Anything quoted is a string so booleans and integers must lack quotes. Booleans must be *true* or *false* and nothing else. Integers cannot contain decimal points or they are floats (and vice versa). If something seems to be getting ignored or set to a strange value, or if you receive errors, check the type of all JSON fields you are submitting against the types listed below. Unrecognized fields in JSON objects are also ignored.
 Values POSTed to the JSON API are *extremely* type sensitive. Things *must* be of the indicated type, otherwise they will be ignored or will generate an error. Anything quoted is a string so booleans and integers must lack quotes. Booleans must be *true* or *false* and nothing else. Integers cannot contain decimal points or they are floats (and vice versa). If something seems to be getting ignored or set to a strange value, or if you receive errors, check the type of all JSON fields you are submitting against the types listed below. Unrecognized fields in JSON objects are also ignored.
 
 
-API requests must be authenticated via an authentication token. ZeroTier One saves this token in the *authtoken.secret* file in its working directory. This token may be supplied via the *authToken* URL parameter (e.g. '?authToken=...') or via the *X-ZT1-Auth* HTTP request header. Static UI pages are the only thing the server will allow without authentication.
+API requests must be authenticated via an authentication token. ZeroTier One saves this token in the *authtoken.secret* file in its working directory. This token may be supplied via the *auth* URL parameter (e.g. '?auth=...') or via the *X-ZT1-Auth* HTTP request header. Static UI pages are the only thing the server will allow without authentication.
 
 
 A *jsonp* URL argument may be supplied to request JSONP encapsulation. A JSONP response is sent as a script with its JSON response payload wrapped in a call to the function name supplied as the argument to *jsonp*.
 A *jsonp* URL argument may be supplied to request JSONP encapsulation. A JSONP response is sent as a script with its JSON response payload wrapped in a call to the function name supplied as the argument to *jsonp*.