Browse Source

Basic control plane queries working.

Adam Ierymenko 10 years ago
parent
commit
a2605561af
4 changed files with 97 additions and 24 deletions
  1. 1 1
      node/Node.cpp
  2. 1 1
      node/Node.hpp
  3. 83 11
      service/ControlPlane.cpp
  4. 12 11
      service/One.cpp

+ 1 - 1
node/Node.cpp

@@ -373,7 +373,7 @@ ZT1_PeerList *Node::peers() const
 ZT1_VirtualNetworkConfig *Node::networkConfig(uint64_t nwid) const
 ZT1_VirtualNetworkConfig *Node::networkConfig(uint64_t nwid) const
 {
 {
 	Mutex::Lock _l(_networks_m);
 	Mutex::Lock _l(_networks_m);
-	std::map< uint64_t,SharedPtr<Network> >::iterator nw(_networks.find(nwid));
+	std::map< uint64_t,SharedPtr<Network> >::const_iterator nw(_networks.find(nwid));
 	if (nw != _networks.end()) {
 	if (nw != _networks.end()) {
 		ZT1_VirtualNetworkConfig *nc = (ZT1_VirtualNetworkConfig *)::malloc(sizeof(ZT1_VirtualNetworkConfig));
 		ZT1_VirtualNetworkConfig *nc = (ZT1_VirtualNetworkConfig *)::malloc(sizeof(ZT1_VirtualNetworkConfig));
 		nw->second->externalConfig(nc);
 		nw->second->externalConfig(nc);

+ 1 - 1
node/Node.hpp

@@ -99,7 +99,7 @@ public:
 	ZT1_ResultCode leave(uint64_t nwid);
 	ZT1_ResultCode leave(uint64_t nwid);
 	ZT1_ResultCode multicastSubscribe(uint64_t nwid,uint64_t multicastGroup,unsigned long multicastAdi);
 	ZT1_ResultCode multicastSubscribe(uint64_t nwid,uint64_t multicastGroup,unsigned long multicastAdi);
 	ZT1_ResultCode multicastUnsubscribe(uint64_t nwid,uint64_t multicastGroup,unsigned long multicastAdi);
 	ZT1_ResultCode multicastUnsubscribe(uint64_t nwid,uint64_t multicastGroup,unsigned long multicastAdi);
-	uint64_t address(ZT1_Node *node) const;
+	uint64_t address() const;
 	void status(ZT1_NodeStatus *status) const;
 	void status(ZT1_NodeStatus *status) const;
 	ZT1_PeerList *peers() const;
 	ZT1_PeerList *peers() const;
 	ZT1_VirtualNetworkConfig *networkConfig(uint64_t nwid) const;
 	ZT1_VirtualNetworkConfig *networkConfig(uint64_t nwid) const;

+ 83 - 11
service/ControlPlane.cpp

@@ -51,7 +51,7 @@ static std::string _jsonEscape(const char *s)
 			case '"':  buf.append("\\\""); break;
 			case '"':  buf.append("\\\""); break;
 			case '\\': buf.append("\\\\"); break;
 			case '\\': buf.append("\\\\"); break;
 			case '/':  buf.append("\\/");  break;
 			case '/':  buf.append("\\/");  break;
-			default:   buf.push_back(*s);  break;
+			default:   buf.push_back(*p);  break;
 		}
 		}
 	}
 	}
 	return buf;
 	return buf;
@@ -92,6 +92,22 @@ static std::string _jsonEnumerate(const struct sockaddr_storage *ss,unsigned int
 	buf.push_back(']');
 	buf.push_back(']');
 	return buf;
 	return buf;
 }
 }
+static std::string _jsonEnumerate(const ZT1_PeerPhysicalPath *pp,unsigned int count)
+{
+	char tmp[1024];
+	std::string buf;
+	buf.push_back('[');
+	for(unsigned int i=0;i<count;++i) {
+		if (i > 0)
+			buf.push_back(',');
+		buf.append("{\"address\":\"");
+		buf.append(_jsonEscape(reinterpret_cast<const InetAddress *>(&(pp[i].address))->toString()));
+		Utils::snprintf(tmp,sizeof(tmp),"\",\"lastSend\":%llu,\"lastReceive\":%llu,\"fixed\":%s}",pp[i].lastSend,pp[i].lastReceive,(pp[i].fixed == 0) ? "falase" : "true");
+		buf.append(tmp);
+	}
+	buf.push_back(']');
+	return buf;
+}
 static void _jsonAppend(std::string &buf,const ZT1_VirtualNetworkConfig *nc)
 static void _jsonAppend(std::string &buf,const ZT1_VirtualNetworkConfig *nc)
 {
 {
 	char json[65536];
 	char json[65536];
@@ -141,6 +157,33 @@ static void _jsonAppend(std::string &buf,const ZT1_VirtualNetworkConfig *nc)
 }
 }
 static void _jsonAppend(std::string &buf,const ZT1_Peer *peer)
 static void _jsonAppend(std::string &buf,const ZT1_Peer *peer)
 {
 {
+	char json[65536];
+	const char *prole = "";
+	switch(peer->role) {
+		case ZT1_PEER_ROLE_LEAF:      prole = "LEAF"; break;
+		case ZT1_PEER_ROLE_HUB:       prole = "HUB"; break;
+		case ZT1_PEER_ROLE_SUPERNODE: prole = "SUPERNODE"; break;
+	}
+	Utils::snprintf(json,sizeof(json),
+		"{"
+		"\"address\": \"%.10llx\","
+		"\"versionMajor\": %d,"
+		"\"versionMinor\": %d,"
+		"\"versionRev\": %d,"
+		"\"version\": \"%d.%d.%d\","
+		"\"latency\": %u,"
+		"\"role\": \"%s\","
+		"\"paths\": %s"
+		"}",
+		peer->address,
+		peer->versionMajor,
+		peer->versionMinor,
+		peer->versionRev,
+		peer->versionMajor,peer->versionMinor,peer->versionRev,
+		peer->latency,
+		prole,
+		_jsonEnumerate(peer->paths,peer->pathCount).c_str());
+	buf.append(json);
 }
 }
 
 
 ControlPlane::ControlPlane(Node *n,const std::set<std::string> atoks) :
 ControlPlane::ControlPlane(Node *n,const std::set<std::string> atoks) :
@@ -192,6 +235,7 @@ unsigned int ControlPlane::handleRequest(
 		if (ps[0] == "index") {
 		if (ps[0] == "index") {
 			responseContentType = "text/html";
 			responseContentType = "text/html";
 			responseBody = "<html><body>Hello World!</body></html>";
 			responseBody = "<html><body>Hello World!</body></html>";
+			scode = 200;
 		} else if (ps[0] == "status") {
 		} else if (ps[0] == "status") {
 			responseContentType = "application/json";
 			responseContentType = "application/json";
 			ZT1_NodeStatus status;
 			ZT1_NodeStatus status;
@@ -203,7 +247,7 @@ unsigned int ControlPlane::handleRequest(
 				"\"online\":%s,"
 				"\"online\":%s,"
 				"\"versionMajor\":%d,"
 				"\"versionMajor\":%d,"
 				"\"versionMinor\":%d,"
 				"\"versionMinor\":%d,"
-				"\"versionRevision\":%d,"
+				"\"versionRev\":%d,"
 				"\"version\":\"%d.%d.%d\""
 				"\"version\":\"%d.%d.%d\""
 				"}",
 				"}",
 				status.address,
 				status.address,
@@ -214,9 +258,11 @@ unsigned int ControlPlane::handleRequest(
 				ZEROTIER_ONE_VERSION_REVISION,
 				ZEROTIER_ONE_VERSION_REVISION,
 				ZEROTIER_ONE_VERSION_MAJOR,ZEROTIER_ONE_VERSION_MINOR,ZEROTIER_ONE_VERSION_REVISION);
 				ZEROTIER_ONE_VERSION_MAJOR,ZEROTIER_ONE_VERSION_MINOR,ZEROTIER_ONE_VERSION_REVISION);
 			responseBody = json;
 			responseBody = json;
+			scode = 200;
 		} else if (ps[0] == "config") {
 		} else if (ps[0] == "config") {
 			responseContentType = "application/json";
 			responseContentType = "application/json";
 			responseBody = "{}"; // TODO
 			responseBody = "{}"; // TODO
+			scode = 200;
 		} else if (ps[0] == "network") {
 		} else if (ps[0] == "network") {
 			ZT1_VirtualNetworkList *nws = _node->networks();
 			ZT1_VirtualNetworkList *nws = _node->networks();
 			if (nws) {
 			if (nws) {
@@ -230,27 +276,53 @@ unsigned int ControlPlane::handleRequest(
 						_jsonAppend(responseBody,&(nws->networks[i]));
 						_jsonAppend(responseBody,&(nws->networks[i]));
 					}
 					}
 					responseBody.push_back(']');
 					responseBody.push_back(']');
+					scode = 200;
 				} else if (ps.size() == 2) {
 				} else if (ps.size() == 2) {
 					// Return a single network by ID or 404 if not found
 					// Return a single network by ID or 404 if not found
 					uint64_t wantnw = Utils::hexStrToU64(ps[1].c_str());
 					uint64_t wantnw = Utils::hexStrToU64(ps[1].c_str());
-					bool got = false;
 					for(unsigned long i=0;i<nws->networkCount;++i) {
 					for(unsigned long i=0;i<nws->networkCount;++i) {
 						if (nws->networks[i].nwid == wantnw) {
 						if (nws->networks[i].nwid == wantnw) {
-							got = true;
 							responseContentType = "application/json";
 							responseContentType = "application/json";
 							_jsonAppend(responseBody,&(nws->networks[i]));
 							_jsonAppend(responseBody,&(nws->networks[i]));
+							scode = 200;
 							break;
 							break;
 						}
 						}
 					}
 					}
-					if (!got)
-						scode = 404;
-				} else {
-					// Not sure what they want here, 404
-					scode = 404;
-				}
+				} // else 404
 				_node->freeQueryResult((void *)nws);
 				_node->freeQueryResult((void *)nws);
-			} else scode = 500;
+			} else {
+				scode = 500;
+			}
 		} else if (ps[0] == "peer") {
 		} else if (ps[0] == "peer") {
+			ZT1_PeerList *pl = _node->peers();
+			if (pl) {
+				if (ps.size() == 1) {
+					// Return [array] of all peers
+					responseContentType = "application/json";
+					responseBody = "[";
+					for(unsigned long i=0;i<pl->peerCount;++i) {
+						if (i > 0)
+							responseBody.push_back(',');
+						_jsonAppend(responseBody,&(pl->peers[i]));
+					}
+					responseBody.push_back(']');
+					scode = 200;
+				} else if (ps.size() == 2) {
+					// Return a single peer by ID or 404 if not found
+					uint64_t wantp = Utils::hexStrToU64(ps[1].c_str());
+					for(unsigned long i=0;i<pl->peerCount;++i) {
+						if (pl->peers[i].address == wantp) {
+							responseContentType = "application/json";
+							_jsonAppend(responseBody,&(pl->peers[i]));
+							scode = 200;
+							break;
+						}
+					}
+				} // else 404
+				_node->freeQueryResult((void *)pl);
+			} else {
+				scode = 500;
+			}
 		}
 		}
 	} else if ((httpMethod == HTTP_POST)||(httpMethod == HTTP_PUT)) { // PUT is weird in REST but we'll take it anyway
 	} else if ((httpMethod == HTTP_POST)||(httpMethod == HTTP_PUT)) { // PUT is weird in REST but we'll take it anyway
 	} else if (httpMethod == HTTP_DELETE) {
 	} else if (httpMethod == HTTP_DELETE) {

+ 12 - 11
service/One.cpp

@@ -31,6 +31,7 @@
 
 
 #include <string>
 #include <string>
 #include <map>
 #include <map>
+#include <set>
 #include <vector>
 #include <vector>
 #include <algorithm>
 #include <algorithm>
 
 
@@ -188,7 +189,7 @@ public:
 			if (_master)
 			if (_master)
 				_node->setNetconfMaster((void *)_master);
 				_node->setNetconfMaster((void *)_master);
 
 
-			_controlPlane = new ControlPlane(_node);
+			_controlPlane = new ControlPlane(_node,std::set<std::string>());
 
 
 			_nextBackgroundTaskDeadline = 0;
 			_nextBackgroundTaskDeadline = 0;
 			for(;;) {
 			for(;;) {
@@ -453,7 +454,7 @@ public:
 		std::string contentType("text/plain"); // default if not changed in handleRequest()
 		std::string contentType("text/plain"); // default if not changed in handleRequest()
 		unsigned int scode = 404;
 		unsigned int scode = 404;
 
 
-		if ((htc->from == InetAddress::LO4)||(htc->from == InetAddress::LO6)) {
+		if ((htc->from.ipsEqual(InetAddress::LO4))||(htc->from.ipsEqual(InetAddress::LO6))) {
 			try {
 			try {
 				if (_controlPlane)
 				if (_controlPlane)
 					scode = _controlPlane->handleRequest(htc->parser.method,htc->url,htc->headers,htc->body,data,contentType);
 					scode = _controlPlane->handleRequest(htc->parser.method,htc->url,htc->headers,htc->body,data,contentType);
@@ -467,15 +468,15 @@ public:
 
 
 		const char *scodestr;
 		const char *scodestr;
 		switch(scode) {
 		switch(scode) {
-			case 200: scodestr = "OK";
-			case 400: scodestr = "Bad Request";
-			case 401: scodestr = "Unauthorized";
-			case 403: scodestr = "Forbidden";
-			case 404: scodestr = "Not Found";
-			case 500: scodestr = "Internal Server Error";
-			case 501: scodestr = "Not Implemented";
-			case 503: scodestr = "Service Unavailable";
-			default: scodestr = "Error";
+			case 200: scodestr = "OK"; break;
+			case 400: scodestr = "Bad Request"; break;
+			case 401: scodestr = "Unauthorized"; break;
+			case 403: scodestr = "Forbidden"; break;
+			case 404: scodestr = "Not Found"; break;
+			case 500: scodestr = "Internal Server Error"; break;
+			case 501: scodestr = "Not Implemented"; break;
+			case 503: scodestr = "Service Unavailable"; break;
+			default: scodestr = "Error"; break;
 		}
 		}
 
 
 		Utils::snprintf(tmpn,sizeof(tmpn),"HTTP/1.1 %.3u %s\r\nCache-Control: no-cache\r\nPragma: no-cache\r\n",scode,scodestr);
 		Utils::snprintf(tmpn,sizeof(tmpn),"HTTP/1.1 %.3u %s\r\nCache-Control: no-cache\r\nPragma: no-cache\r\n",scode,scodestr);