Basic control plane queries working.

This commit is contained in:
Adam Ierymenko 2015-04-13 18:43:33 -07:00
parent b888e033c0
commit a2605561af
4 changed files with 97 additions and 24 deletions

View file

@ -51,7 +51,7 @@ static std::string _jsonEscape(const char *s)
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;
@ -92,6 +92,22 @@ static std::string _jsonEnumerate(const struct sockaddr_storage *ss,unsigned int
buf.push_back(']');
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)
{
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)
{
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) :
@ -192,6 +235,7 @@ unsigned int ControlPlane::handleRequest(
if (ps[0] == "index") {
responseContentType = "text/html";
responseBody = "<html><body>Hello World!</body></html>";
scode = 200;
} else if (ps[0] == "status") {
responseContentType = "application/json";
ZT1_NodeStatus status;
@ -203,7 +247,7 @@ unsigned int ControlPlane::handleRequest(
"\"online\":%s,"
"\"versionMajor\":%d,"
"\"versionMinor\":%d,"
"\"versionRevision\":%d,"
"\"versionRev\":%d,"
"\"version\":\"%d.%d.%d\""
"}",
status.address,
@ -214,9 +258,11 @@ unsigned int ControlPlane::handleRequest(
ZEROTIER_ONE_VERSION_REVISION,
ZEROTIER_ONE_VERSION_MAJOR,ZEROTIER_ONE_VERSION_MINOR,ZEROTIER_ONE_VERSION_REVISION);
responseBody = json;
scode = 200;
} else if (ps[0] == "config") {
responseContentType = "application/json";
responseBody = "{}"; // TODO
scode = 200;
} else if (ps[0] == "network") {
ZT1_VirtualNetworkList *nws = _node->networks();
if (nws) {
@ -230,27 +276,53 @@ unsigned int ControlPlane::handleRequest(
_jsonAppend(responseBody,&(nws->networks[i]));
}
responseBody.push_back(']');
scode = 200;
} else if (ps.size() == 2) {
// Return a single network by ID or 404 if not found
uint64_t wantnw = Utils::hexStrToU64(ps[1].c_str());
bool got = false;
for(unsigned long i=0;i<nws->networkCount;++i) {
if (nws->networks[i].nwid == wantnw) {
got = true;
responseContentType = "application/json";
_jsonAppend(responseBody,&(nws->networks[i]));
scode = 200;
break;
}
}
if (!got)
scode = 404;
} else {
// Not sure what they want here, 404
scode = 404;
}
} // else 404
_node->freeQueryResult((void *)nws);
} else scode = 500;
} else {
scode = 500;
}
} 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_DELETE) {