|
|
|
@ -57,14 +57,20 @@ |
|
|
|
|
|
|
|
|
|
|
|
#include "version.h" |
|
|
|
#include "version.h" |
|
|
|
#include "include/ZeroTierOne.h" |
|
|
|
#include "include/ZeroTierOne.h" |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#include "ext/json-parser/json.h" |
|
|
|
|
|
|
|
|
|
|
|
#include "node/Constants.hpp" |
|
|
|
#include "node/Constants.hpp" |
|
|
|
#include "node/Identity.hpp" |
|
|
|
#include "node/Identity.hpp" |
|
|
|
#include "node/CertificateOfMembership.hpp" |
|
|
|
#include "node/CertificateOfMembership.hpp" |
|
|
|
#include "node/Utils.hpp" |
|
|
|
#include "node/Utils.hpp" |
|
|
|
#include "node/NetworkController.hpp" |
|
|
|
#include "node/NetworkController.hpp" |
|
|
|
|
|
|
|
|
|
|
|
#include "osdep/OSUtils.hpp" |
|
|
|
#include "osdep/OSUtils.hpp" |
|
|
|
#include "osdep/Http.hpp" |
|
|
|
#include "osdep/Http.hpp" |
|
|
|
|
|
|
|
|
|
|
|
#include "service/OneService.hpp" |
|
|
|
#include "service/OneService.hpp" |
|
|
|
|
|
|
|
|
|
|
|
#ifdef ZT_ENABLE_NETWORK_CONTROLLER |
|
|
|
#ifdef ZT_ENABLE_NETWORK_CONTROLLER |
|
|
|
#include "controller/SqliteNetworkController.hpp" |
|
|
|
#include "controller/SqliteNetworkController.hpp" |
|
|
|
#endif |
|
|
|
#endif |
|
|
|
@ -92,7 +98,7 @@ static void cliPrintHelp(const char *pn,FILE *out) |
|
|
|
fprintf(out," -D<path> - ZeroTier home path for parameter auto-detect"ZT_EOL_S); |
|
|
|
fprintf(out," -D<path> - ZeroTier home path for parameter auto-detect"ZT_EOL_S); |
|
|
|
fprintf(out," -p<port> - HTTP port (default: auto)"ZT_EOL_S); |
|
|
|
fprintf(out," -p<port> - HTTP port (default: auto)"ZT_EOL_S); |
|
|
|
fprintf(out," -T<token> - Authentication token (default: auto)"ZT_EOL_S); |
|
|
|
fprintf(out," -T<token> - Authentication token (default: auto)"ZT_EOL_S); |
|
|
|
fprintf(out," -H<ip> - HTTP IP address (default: 127.0.0.1)"ZT_EOL_S""ZT_EOL_S); |
|
|
|
//fprintf(out," -H<ip> - HTTP IP address (default: 127.0.0.1)"ZT_EOL_S""ZT_EOL_S);
|
|
|
|
fprintf(out,"Available commands:"ZT_EOL_S); |
|
|
|
fprintf(out,"Available commands:"ZT_EOL_S); |
|
|
|
fprintf(out," info - Display status info"ZT_EOL_S); |
|
|
|
fprintf(out," info - Display status info"ZT_EOL_S); |
|
|
|
fprintf(out," listpeers - List all peers"ZT_EOL_S); |
|
|
|
fprintf(out," listpeers - List all peers"ZT_EOL_S); |
|
|
|
@ -254,6 +260,34 @@ static int cli(int argc,char **argv) |
|
|
|
printf("%s",cliFixJsonCRs(responseBody).c_str()); |
|
|
|
printf("%s",cliFixJsonCRs(responseBody).c_str()); |
|
|
|
return 0; |
|
|
|
return 0; |
|
|
|
} else { |
|
|
|
} else { |
|
|
|
|
|
|
|
json_value *j = json_parse(responseBody.c_str(),responseBody.length()); |
|
|
|
|
|
|
|
bool good = false; |
|
|
|
|
|
|
|
if (j) { |
|
|
|
|
|
|
|
if (j->type == json_object) { |
|
|
|
|
|
|
|
const char *address = (const char *)0; |
|
|
|
|
|
|
|
bool online = false; |
|
|
|
|
|
|
|
const char *version = (const char *)0; |
|
|
|
|
|
|
|
for(unsigned int k=0;k<j->u.object.length;++k) { |
|
|
|
|
|
|
|
if ((!strcmp(j->u.object.values[k].name,"address"))&&(j->u.object.values[k].value->type == json_string)) |
|
|
|
|
|
|
|
address = j->u.object.values[k].value->u.string.ptr; |
|
|
|
|
|
|
|
else if ((!strcmp(j->u.object.values[k].name,"version"))&&(j->u.object.values[k].value->type == json_string)) |
|
|
|
|
|
|
|
version = j->u.object.values[k].value->u.string.ptr; |
|
|
|
|
|
|
|
else if ((!strcmp(j->u.object.values[k].name,"online"))&&(j->u.object.values[k].value->type == json_boolean)) |
|
|
|
|
|
|
|
online = (j->u.object.values[k].value->u.boolean != 0); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
if ((address)&&(version)) { |
|
|
|
|
|
|
|
printf("200 info %s %s %s"ZT_EOL_S,address,(online ? "ONLINE" : "OFFLINE"),version); |
|
|
|
|
|
|
|
good = true; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
json_value_free(j); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
if (good) { |
|
|
|
|
|
|
|
return 0; |
|
|
|
|
|
|
|
} else { |
|
|
|
|
|
|
|
printf("%u %s invalid JSON response"ZT_EOL_S,scode,command.c_str()); |
|
|
|
|
|
|
|
return 1; |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} else { |
|
|
|
} else { |
|
|
|
printf("%u %s %s"ZT_EOL_S,scode,command.c_str(),responseBody.c_str()); |
|
|
|
printf("%u %s %s"ZT_EOL_S,scode,command.c_str(),responseBody.c_str()); |
|
|
|
@ -273,6 +307,88 @@ static int cli(int argc,char **argv) |
|
|
|
printf("%s",cliFixJsonCRs(responseBody).c_str()); |
|
|
|
printf("%s",cliFixJsonCRs(responseBody).c_str()); |
|
|
|
return 0; |
|
|
|
return 0; |
|
|
|
} else { |
|
|
|
} else { |
|
|
|
|
|
|
|
printf("200 listpeers <ztaddr> <paths> <latency> <version> <role>"ZT_EOL_S); |
|
|
|
|
|
|
|
json_value *j = json_parse(responseBody.c_str(),responseBody.length()); |
|
|
|
|
|
|
|
if (j) { |
|
|
|
|
|
|
|
if (j->type == json_array) { |
|
|
|
|
|
|
|
for(unsigned int p=0;p<j->u.array.length;++p) { |
|
|
|
|
|
|
|
json_value *jp = j->u.array.values[p]; |
|
|
|
|
|
|
|
if (jp->type == json_object) { |
|
|
|
|
|
|
|
const char *address = (const char *)0; |
|
|
|
|
|
|
|
std::string paths; |
|
|
|
|
|
|
|
int64_t latency = 0; |
|
|
|
|
|
|
|
int64_t versionMajor = -1,versionMinor = -1,versionRev = -1; |
|
|
|
|
|
|
|
const char *role = (const char *)0; |
|
|
|
|
|
|
|
for(unsigned int k=0;k<jp->u.object.length;++k) { |
|
|
|
|
|
|
|
if ((!strcmp(jp->u.object.values[k].name,"address"))&&(jp->u.object.values[k].value->type == json_string)) |
|
|
|
|
|
|
|
address = jp->u.object.values[k].value->u.string.ptr; |
|
|
|
|
|
|
|
else if ((!strcmp(jp->u.object.values[k].name,"versionMajor"))&&(jp->u.object.values[k].value->type == json_integer)) |
|
|
|
|
|
|
|
versionMajor = jp->u.object.values[k].value->u.integer; |
|
|
|
|
|
|
|
else if ((!strcmp(jp->u.object.values[k].name,"versionMinor"))&&(jp->u.object.values[k].value->type == json_integer)) |
|
|
|
|
|
|
|
versionMinor = jp->u.object.values[k].value->u.integer; |
|
|
|
|
|
|
|
else if ((!strcmp(jp->u.object.values[k].name,"versionRev"))&&(jp->u.object.values[k].value->type == json_integer)) |
|
|
|
|
|
|
|
versionRev = jp->u.object.values[k].value->u.integer; |
|
|
|
|
|
|
|
else if ((!strcmp(jp->u.object.values[k].name,"role"))&&(jp->u.object.values[k].value->type == json_string)) |
|
|
|
|
|
|
|
role = jp->u.object.values[k].value->u.string.ptr; |
|
|
|
|
|
|
|
else if ((!strcmp(jp->u.object.values[k].name,"latency"))&&(jp->u.object.values[k].value->type == json_integer)) |
|
|
|
|
|
|
|
latency = jp->u.object.values[k].value->u.integer; |
|
|
|
|
|
|
|
else if ((!strcmp(jp->u.object.values[k].name,"paths"))&&(jp->u.object.values[k].value->type == json_array)) { |
|
|
|
|
|
|
|
for(unsigned int pp=0;pp<jp->u.object.values[k].value->u.array.length;++pp) { |
|
|
|
|
|
|
|
json_value *jpath = jp->u.object.values[k].value->u.array.values[pp]; |
|
|
|
|
|
|
|
if (jpath->type == json_object) { |
|
|
|
|
|
|
|
const char *paddr = (const char *)0; |
|
|
|
|
|
|
|
int64_t lastSend = 0; |
|
|
|
|
|
|
|
int64_t lastReceive = 0; |
|
|
|
|
|
|
|
bool fixed = false; |
|
|
|
|
|
|
|
bool active = false; // fixed/active/inactive
|
|
|
|
|
|
|
|
for(unsigned int kk=0;kk<jpath->u.object.length;++kk) { |
|
|
|
|
|
|
|
if ((!strcmp(jpath->u.object.values[kk].name,"address"))&&(jpath->u.object.values[kk].value->type == json_string)) |
|
|
|
|
|
|
|
paddr = jpath->u.object.values[kk].value->u.string.ptr; |
|
|
|
|
|
|
|
else if ((!strcmp(jpath->u.object.values[kk].name,"lastSend"))&&(jpath->u.object.values[kk].value->type == json_integer)) |
|
|
|
|
|
|
|
lastSend = jpath->u.object.values[kk].value->u.integer; |
|
|
|
|
|
|
|
else if ((!strcmp(jpath->u.object.values[kk].name,"lastReceive"))&&(jpath->u.object.values[kk].value->type == json_integer)) |
|
|
|
|
|
|
|
lastReceive = jpath->u.object.values[kk].value->u.integer; |
|
|
|
|
|
|
|
else if ((!strcmp(jpath->u.object.values[kk].name,"fixed"))&&(jpath->u.object.values[kk].value->type == json_boolean)) |
|
|
|
|
|
|
|
fixed = (jpath->u.object.values[kk].value->u.boolean != 0); |
|
|
|
|
|
|
|
else if ((!strcmp(jpath->u.object.values[kk].name,"active"))&&(jpath->u.object.values[kk].value->type == json_boolean)) |
|
|
|
|
|
|
|
active = (jpath->u.object.values[kk].value->u.boolean != 0); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
if (paddr) { |
|
|
|
|
|
|
|
int64_t now = (int64_t)OSUtils::now(); |
|
|
|
|
|
|
|
if (lastSend > 0) |
|
|
|
|
|
|
|
lastSend = now - lastSend; |
|
|
|
|
|
|
|
if (lastReceive > 0) |
|
|
|
|
|
|
|
lastReceive = now - lastReceive; |
|
|
|
|
|
|
|
char pathtmp[256]; |
|
|
|
|
|
|
|
Utils::snprintf(pathtmp,sizeof(pathtmp),"%s;%lld;%lld;%s", |
|
|
|
|
|
|
|
paddr, |
|
|
|
|
|
|
|
lastSend, |
|
|
|
|
|
|
|
lastReceive, |
|
|
|
|
|
|
|
(fixed ? "fixed" : (active ? "active" : "inactive"))); |
|
|
|
|
|
|
|
if (paths.length()) |
|
|
|
|
|
|
|
paths.push_back(','); |
|
|
|
|
|
|
|
paths.append(pathtmp); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
if ((address)&&(role)) { |
|
|
|
|
|
|
|
char verstr[64]; |
|
|
|
|
|
|
|
if ((versionMajor >= 0)&&(versionMinor >= 0)&&(versionRev >= 0)) |
|
|
|
|
|
|
|
Utils::snprintf(verstr,sizeof(verstr),"%lld.%lld.%lld",versionMajor,versionMinor,versionRev); |
|
|
|
|
|
|
|
else { |
|
|
|
|
|
|
|
verstr[0] = '-'; |
|
|
|
|
|
|
|
verstr[1] = (char)0; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
printf("200 listpeers %s %s %lld %s %s"ZT_EOL_S,address,(paths.length()) ? paths.c_str() : "-",latency,verstr,role); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
json_value_free(j); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
return 0; |
|
|
|
} |
|
|
|
} |
|
|
|
} else { |
|
|
|
} else { |
|
|
|
printf("%u %s %s"ZT_EOL_S,scode,command.c_str(),responseBody.c_str()); |
|
|
|
printf("%u %s %s"ZT_EOL_S,scode,command.c_str(),responseBody.c_str()); |
|
|
|
|