summaryrefslogtreecommitdiff
path: root/controller/EmbeddedNetworkController.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'controller/EmbeddedNetworkController.cpp')
-rw-r--r--controller/EmbeddedNetworkController.cpp219
1 files changed, 138 insertions, 81 deletions
diff --git a/controller/EmbeddedNetworkController.cpp b/controller/EmbeddedNetworkController.cpp
index 30072f95..649ff094 100644
--- a/controller/EmbeddedNetworkController.cpp
+++ b/controller/EmbeddedNetworkController.cpp
@@ -60,6 +60,50 @@ using json = nlohmann::json;
namespace ZeroTier {
+static uint64_t _jI(const json &jv,const uint64_t dfl)
+{
+ if (jv.is_number()) {
+ return (uint64_t)jv;
+ } else if (jv.is_string()) {
+ std::string s = jv;
+ return Utils::strToU64(s.c_str());
+ } else if (jv.is_boolean()) {
+ return ((bool)jv ? 1ULL : 0ULL);
+ }
+ return dfl;
+}
+static bool _jB(const json &jv,const bool dfl)
+{
+ if (jv.is_boolean()) {
+ return (bool)jv;
+ } else if (jv.is_number()) {
+ return ((uint64_t)jv > 0ULL);
+ } else if (jv.is_string()) {
+ std::string s = jv;
+ if (s.length() > 0) {
+ switch(s[0]) {
+ case 't':
+ case 'T':
+ case '1':
+ return true;
+ }
+ }
+ return false;
+ }
+ return dfl;
+}
+static std::string _jS(const json &jv,const char *dfl)
+{
+ if (jv.is_string()) {
+ return jv;
+ } else if (jv.is_number()) {
+ return jv;
+ } else if (jv.is_boolean()) {
+ return ((bool)jv ? std::string("1") : std::string("0"));
+ }
+ return std::string((dfl) ? dfl : "");
+}
+
static json _renderRule(ZT_VirtualNetworkRule &rule)
{
char tmp[128];
@@ -190,7 +234,7 @@ static bool _parseRule(const json &r,ZT_VirtualNetworkRule &rule)
return false;
std::string t = r["type"];
memset(&rule,0,sizeof(ZT_VirtualNetworkRule));
- if (r.value("not",false))
+ if (_jB(r["not"],false))
rule.t = 0x80;
else rule.t = 0x00;
if (t == "ACTION_DROP") {
@@ -201,91 +245,91 @@ static bool _parseRule(const json &r,ZT_VirtualNetworkRule &rule)
return true;
} else if (t == "ACTION_TEE") {
rule.t |= ZT_NETWORK_RULE_ACTION_TEE;
- rule.v.zt = Utils::hexStrToU64(r.value("zt","0").c_str()) & 0xffffffffffULL;
+ rule.v.zt = Utils::hexStrToU64(_jS(r["zt"],"0").c_str()) & 0xffffffffffULL;
return true;
} else if (t == "ACTION_REDIRECT") {
rule.t |= ZT_NETWORK_RULE_ACTION_REDIRECT;
- rule.v.zt = Utils::hexStrToU64(r.value("zt","0").c_str()) & 0xffffffffffULL;
+ rule.v.zt = Utils::hexStrToU64(_jS(r["zt"],"0").c_str()) & 0xffffffffffULL;
return true;
} else if (t == "MATCH_SOURCE_ZEROTIER_ADDRESS") {
rule.t |= ZT_NETWORK_RULE_MATCH_SOURCE_ZEROTIER_ADDRESS;
- rule.v.zt = Utils::hexStrToU64(r.value("zt","0").c_str()) & 0xffffffffffULL;
+ rule.v.zt = Utils::hexStrToU64(_jS(r["zt"],"0").c_str()) & 0xffffffffffULL;
return true;
} else if (t == "MATCH_DEST_ZEROTIER_ADDRESS") {
rule.t |= ZT_NETWORK_RULE_MATCH_DEST_ZEROTIER_ADDRESS;
- rule.v.zt = Utils::hexStrToU64(r.value("zt","0").c_str()) & 0xffffffffffULL;
+ rule.v.zt = Utils::hexStrToU64(_jS(r["zt"],"0").c_str()) & 0xffffffffffULL;
return true;
} else if (t == "MATCH_VLAN_ID") {
rule.t |= ZT_NETWORK_RULE_MATCH_VLAN_ID;
- rule.v.vlanId = (uint16_t)(r.value("vlanId",0ULL) & 0xffffULL);
+ rule.v.vlanId = (uint16_t)(_jI(r["vlanId"],0ULL) & 0xffffULL);
return true;
} else if (t == "MATCH_VLAN_PCP") {
rule.t |= ZT_NETWORK_RULE_MATCH_VLAN_PCP;
- rule.v.vlanPcp = (uint8_t)(r.value("vlanPcp",0ULL) & 0xffULL);
+ rule.v.vlanPcp = (uint8_t)(_jI(r["vlanPcp"],0ULL) & 0xffULL);
return true;
} else if (t == "MATCH_VLAN_DEI") {
rule.t |= ZT_NETWORK_RULE_MATCH_VLAN_DEI;
- rule.v.vlanDei = (uint8_t)(r.value("vlanDei",0ULL) & 0xffULL);
+ rule.v.vlanDei = (uint8_t)(_jI(r["vlanDei"],0ULL) & 0xffULL);
return true;
} else if (t == "MATCH_ETHERTYPE") {
rule.t |= ZT_NETWORK_RULE_MATCH_ETHERTYPE;
- rule.v.etherType = (uint16_t)(r.value("etherType",0ULL) & 0xffffULL);
+ rule.v.etherType = (uint16_t)(_jI(r["etherType"],0ULL) & 0xffffULL);
return true;
} else if (t == "MATCH_MAC_SOURCE") {
rule.t |= ZT_NETWORK_RULE_MATCH_MAC_SOURCE;
- const std::string mac(r.value("mac","0"));
+ const std::string mac(_jS(r["mac"],"0"));
Utils::unhex(mac.c_str(),(unsigned int)mac.length(),rule.v.mac,6);
return true;
} else if (t == "MATCH_MAC_DEST") {
rule.t |= ZT_NETWORK_RULE_MATCH_MAC_DEST;
- const std::string mac(r.value("mac","0"));
+ const std::string mac(_jS(r["mac"],"0"));
Utils::unhex(mac.c_str(),(unsigned int)mac.length(),rule.v.mac,6);
return true;
} else if (t == "MATCH_IPV4_SOURCE") {
rule.t |= ZT_NETWORK_RULE_MATCH_IPV4_SOURCE;
- InetAddress ip(r.value("ip","0.0.0.0"));
+ InetAddress ip(_jS(r["ip"],"0.0.0.0"));
rule.v.ipv4.ip = reinterpret_cast<struct sockaddr_in *>(&ip)->sin_addr.s_addr;
rule.v.ipv4.mask = Utils::ntoh(reinterpret_cast<struct sockaddr_in *>(&ip)->sin_port) & 0xff;
if (rule.v.ipv4.mask > 32) rule.v.ipv4.mask = 32;
return true;
} else if (t == "MATCH_IPV4_DEST") {
rule.t |= ZT_NETWORK_RULE_MATCH_IPV4_DEST;
- InetAddress ip(r.value("ip","0.0.0.0"));
+ InetAddress ip(_jS(r["ip"],"0.0.0.0"));
rule.v.ipv4.ip = reinterpret_cast<struct sockaddr_in *>(&ip)->sin_addr.s_addr;
rule.v.ipv4.mask = Utils::ntoh(reinterpret_cast<struct sockaddr_in *>(&ip)->sin_port) & 0xff;
if (rule.v.ipv4.mask > 32) rule.v.ipv4.mask = 32;
return true;
} else if (t == "MATCH_IPV6_SOURCE") {
rule.t |= ZT_NETWORK_RULE_MATCH_IPV6_SOURCE;
- InetAddress ip(r.value("ip","::0"));
+ InetAddress ip(_jS(r["ip"],"::0"));
memcpy(rule.v.ipv6.ip,reinterpret_cast<struct sockaddr_in6 *>(&ip)->sin6_addr.s6_addr,16);
rule.v.ipv6.mask = Utils::ntoh(reinterpret_cast<struct sockaddr_in6 *>(&ip)->sin6_port) & 0xff;
if (rule.v.ipv6.mask > 128) rule.v.ipv6.mask = 128;
return true;
} else if (t == "MATCH_IPV6_DEST") {
rule.t |= ZT_NETWORK_RULE_MATCH_IPV6_DEST;
- InetAddress ip(r.value("ip","::0"));
+ InetAddress ip(_jS(r["ip"],"::0"));
memcpy(rule.v.ipv6.ip,reinterpret_cast<struct sockaddr_in6 *>(&ip)->sin6_addr.s6_addr,16);
rule.v.ipv6.mask = Utils::ntoh(reinterpret_cast<struct sockaddr_in6 *>(&ip)->sin6_port) & 0xff;
if (rule.v.ipv6.mask > 128) rule.v.ipv6.mask = 128;
return true;
} else if (t == "MATCH_IP_TOS") {
rule.t |= ZT_NETWORK_RULE_MATCH_IP_TOS;
- rule.v.ipTos = (uint8_t)(r.value("ipTos",0ULL) & 0xffULL);
+ rule.v.ipTos = (uint8_t)(_jI(r["ipTos"],0ULL) & 0xffULL);
return true;
} else if (t == "MATCH_IP_PROTOCOL") {
rule.t |= ZT_NETWORK_RULE_MATCH_IP_PROTOCOL;
- rule.v.ipProtocol = (uint8_t)(r.value("ipProtocol",0ULL) & 0xffULL);
+ rule.v.ipProtocol = (uint8_t)(_jI(r["ipProtocol"],0ULL) & 0xffULL);
return true;
} else if (t == "MATCH_IP_SOURCE_PORT_RANGE") {
rule.t |= ZT_NETWORK_RULE_MATCH_IP_SOURCE_PORT_RANGE;
- rule.v.port[0] = (uint16_t)(r.value("start",0ULL) & 0xffffULL);
- rule.v.port[1] = (uint16_t)(r.value("end",(uint64_t)rule.v.port[0]) & 0xffffULL);
+ rule.v.port[0] = (uint16_t)(_jI(r["start"],0ULL) & 0xffffULL);
+ rule.v.port[1] = (uint16_t)(_jI(r["end"],(uint64_t)rule.v.port[0]) & 0xffffULL);
return true;
} else if (t == "MATCH_IP_DEST_PORT_RANGE") {
rule.t |= ZT_NETWORK_RULE_MATCH_IP_DEST_PORT_RANGE;
- rule.v.port[0] = (uint16_t)(r.value("start",0ULL) & 0xffffULL);
- rule.v.port[1] = (uint16_t)(r.value("end",(uint64_t)rule.v.port[0]) & 0xffffULL);
+ rule.v.port[0] = (uint16_t)(_jI(r["start"],0ULL) & 0xffffULL);
+ rule.v.port[1] = (uint16_t)(_jI(r["end"],(uint64_t)rule.v.port[0]) & 0xffffULL);
return true;
} else if (t == "MATCH_CHARACTERISTICS") {
rule.t |= ZT_NETWORK_RULE_MATCH_CHARACTERISTICS;
@@ -310,28 +354,28 @@ static bool _parseRule(const json &r,ZT_VirtualNetworkRule &rule)
return true;
} else if (t == "MATCH_FRAME_SIZE_RANGE") {
rule.t |= ZT_NETWORK_RULE_MATCH_FRAME_SIZE_RANGE;
- rule.v.frameSize[0] = (uint16_t)(r.value("start",0ULL) & 0xffffULL);
- rule.v.frameSize[1] = (uint16_t)(r.value("end",(uint64_t)rule.v.frameSize[0]) & 0xffffULL);
+ rule.v.frameSize[0] = (uint16_t)(_jI(r["start"],0ULL) & 0xffffULL);
+ rule.v.frameSize[1] = (uint16_t)(_jI(r["end"],(uint64_t)rule.v.frameSize[0]) & 0xffffULL);
return true;
} else if (t == "MATCH_TAGS_SAMENESS") {
rule.t |= ZT_NETWORK_RULE_MATCH_TAGS_SAMENESS;
- rule.v.tag.id = (uint32_t)(r.value("id",0ULL) & 0xffffffffULL);
- rule.v.tag.value = (uint32_t)(r.value("value",0ULL) & 0xffffffffULL);
+ rule.v.tag.id = (uint32_t)(_jI(r["id"],0ULL) & 0xffffffffULL);
+ rule.v.tag.value = (uint32_t)(_jI(r["value"],0ULL) & 0xffffffffULL);
return true;
} else if (t == "MATCH_TAGS_BITWISE_AND") {
rule.t |= ZT_NETWORK_RULE_MATCH_TAGS_BITWISE_AND;
- rule.v.tag.id = (uint32_t)(r.value("id",0ULL) & 0xffffffffULL);
- rule.v.tag.value = (uint32_t)(r.value("value",0ULL) & 0xffffffffULL);
+ rule.v.tag.id = (uint32_t)(_jI(r["id"],0ULL) & 0xffffffffULL);
+ rule.v.tag.value = (uint32_t)(_jI(r["value"],0ULL) & 0xffffffffULL);
return true;
} else if (t == "MATCH_TAGS_BITWISE_OR") {
rule.t |= ZT_NETWORK_RULE_MATCH_TAGS_BITWISE_OR;
- rule.v.tag.id = (uint32_t)(r.value("id",0ULL) & 0xffffffffULL);
- rule.v.tag.value = (uint32_t)(r.value("value",0ULL) & 0xffffffffULL);
+ rule.v.tag.id = (uint32_t)(_jI(r["id"],0ULL) & 0xffffffffULL);
+ rule.v.tag.value = (uint32_t)(_jI(r["value"],0ULL) & 0xffffffffULL);
return true;
} else if (t == "MATCH_TAGS_BITWISE_XOR") {
rule.t |= ZT_NETWORK_RULE_MATCH_TAGS_BITWISE_XOR;
- rule.v.tag.id = (uint32_t)(r.value("id",0ULL) & 0xffffffffULL);
- rule.v.tag.value = (uint32_t)(r.value("value",0ULL) & 0xffffffffULL);
+ rule.v.tag.id = (uint32_t)(_jI(r["id"],0ULL) & 0xffffffffULL);
+ rule.v.tag.value = (uint32_t)(_jI(r["value"],0ULL) & 0xffffffffULL);
return true;
}
return false;
@@ -613,7 +657,7 @@ NetworkController::ResultCode EmbeddedNetworkController::doNetworkConfigRequest(
json member(_readJson(memberJP));
{
- std::string haveIdStr = member.value("identity","");
+ std::string haveIdStr(_jS(member["identity"],""));
if (haveIdStr.length() > 0) {
try {
if (Identity(haveIdStr.c_str()) != identity)
@@ -630,13 +674,18 @@ NetworkController::ResultCode EmbeddedNetworkController::doNetworkConfigRequest(
member["id"] = identity.address().toString();
member["address"] = member["id"];
member["nwid"] = network["id"];
- member["memberRevision"] = member.value("memberRevision",0ULL) + 1;
+ member["lastModified"] = now;
+ {
+ auto revj = member["revision"];
+ const uint64_t rev = (revj.is_number() ? ((uint64_t)revj + 1ULL) : 1ULL);
+ member["revision"] = rev;
+ }
// Determine whether and how member is authorized
const char *authorizedBy = (const char *)0;
- if (!network.value("private",true)) {
+ if (!_jB(network["private"],true)) {
authorizedBy = "networkIsPublic";
- } else if (member.value("authorized",false)) {
+ } else if (_jB(member["authorized"],false)) {
authorizedBy = "memberIsAuthorized";
} else {
char atok[256];
@@ -648,8 +697,8 @@ NetworkController::ResultCode EmbeddedNetworkController::doNetworkConfigRequest(
for(unsigned long i=0;i<authTokens.size();++i) {
auto at = authTokens[i];
if (at.is_object()) {
- const uint64_t expires = at.value("expires",0ULL);
- std::string tok = at.value("token","");
+ const uint64_t expires = _jI(at["expires"],0ULL);
+ std::string tok = _jS(at["token"],"");
if ( ((expires == 0ULL)||(expires > now)) && (tok.length() > 0) && (tok == atok) ) {
authorizedBy = "token";
break;
@@ -700,14 +749,14 @@ NetworkController::ResultCode EmbeddedNetworkController::doNetworkConfigRequest(
// If we made it this far, they are authorized.
nc.networkId = nwid;
- nc.type = network.value("private",true) ? ZT_NETWORK_TYPE_PRIVATE : ZT_NETWORK_TYPE_PUBLIC;
+ nc.type = _jB(network["private"],true) ? ZT_NETWORK_TYPE_PRIVATE : ZT_NETWORK_TYPE_PUBLIC;
nc.timestamp = now;
- nc.revision = network.value("revision",0ULL);
+ nc.revision = _jI(network["revision"],0ULL);
nc.issuedTo = identity.address();
- if (network.value("enableBroadcast",true)) nc.flags |= ZT_NETWORKCONFIG_FLAG_ENABLE_BROADCAST;
- if (network.value("allowPassiveBridging",false)) nc.flags |= ZT_NETWORKCONFIG_FLAG_ALLOW_PASSIVE_BRIDGING;
- Utils::scopy(nc.name,sizeof(nc.name),network.value("name","").c_str());
- nc.multicastLimit = (unsigned int)network.value("multicastLimit",32ULL);
+ if (_jB(network["enableBroadcast"],true)) nc.flags |= ZT_NETWORKCONFIG_FLAG_ENABLE_BROADCAST;
+ if (_jB(network["allowPassiveBridging"],false)) nc.flags |= ZT_NETWORKCONFIG_FLAG_ALLOW_PASSIVE_BRIDGING;
+ Utils::scopy(nc.name,sizeof(nc.name),_jS(network["name"],"").c_str());
+ nc.multicastLimit = (unsigned int)_jI(network["multicastLimit"],32ULL);
bool amActiveBridge = false;
{
@@ -732,11 +781,11 @@ NetworkController::ResultCode EmbeddedNetworkController::doNetworkConfigRequest(
auto rules = network["rules"];
if (v6AssignMode.is_object()) {
- if ((v6AssignMode.value("rfc4193",false))&&(nc.staticIpCount < ZT_MAX_ZT_ASSIGNED_ADDRESSES)) {
+ if ((_jB(v6AssignMode["rfc4193"],false))&&(nc.staticIpCount < ZT_MAX_ZT_ASSIGNED_ADDRESSES)) {
nc.staticIps[nc.staticIpCount++] = InetAddress::makeIpv6rfc4193(nwid,identity.address().toInt());
nc.flags |= ZT_NETWORKCONFIG_FLAG_ENABLE_IPV6_NDP_EMULATION;
}
- if ((v6AssignMode.value("6plane",false))&&(nc.staticIpCount < ZT_MAX_ZT_ASSIGNED_ADDRESSES)) {
+ if ((_jB(v6AssignMode["6plane"],false))&&(nc.staticIpCount < ZT_MAX_ZT_ASSIGNED_ADDRESSES)) {
nc.staticIps[nc.staticIpCount++] = InetAddress::makeIpv66plane(nwid,identity.address().toInt());
nc.flags |= ZT_NETWORKCONFIG_FLAG_ENABLE_IPV6_NDP_EMULATION;
}
@@ -757,8 +806,8 @@ NetworkController::ResultCode EmbeddedNetworkController::doNetworkConfigRequest(
if (nc.routeCount >= ZT_MAX_NETWORK_ROUTES)
break;
auto route = routes[i];
- InetAddress t(route.value("target",""));
- InetAddress v(route.value("via",""));
+ InetAddress t(_jS(route["target"],""));
+ InetAddress v(_jS(route["via"],""));
if ((t)&&(v)&&(t.ss_family == v.ss_family)) {
ZT_VirtualNetworkRoute *r = &(nc.routes[nc.routeCount]);
*(reinterpret_cast<InetAddress *>(&(r->target))) = t;
@@ -803,13 +852,13 @@ NetworkController::ResultCode EmbeddedNetworkController::doNetworkConfigRequest(
std::set<InetAddress> allocatedIps;
bool allocatedIpsLoaded = false;
- if ( (ipAssignmentPools.is_array()) && ((v6AssignMode.is_object())&&(v6AssignMode.value("zt",false))) && (!haveManagedIpv6AutoAssignment) && (!amActiveBridge) ) {
+ if ( (ipAssignmentPools.is_array()) && ((v6AssignMode.is_object())&&(_jB(v6AssignMode["zt"],false))) && (!haveManagedIpv6AutoAssignment) && (!amActiveBridge) ) {
if (!allocatedIpsLoaded) allocatedIps = _getAlreadyAllocatedIps(nwid);
for(unsigned long p=0;((p<ipAssignmentPools.size())&&(!haveManagedIpv6AutoAssignment));++p) {
auto pool = ipAssignmentPools[p];
if (pool.is_object()) {
- InetAddress ipRangeStart(std::string(pool.value("ipRangeStart","")));
- InetAddress ipRangeEnd(std::string(pool.value("ipRangeEnd","")));
+ InetAddress ipRangeStart(_jS(pool["ipRangeStart"],""));
+ InetAddress ipRangeEnd(_jS(pool["ipRangeEnd"],""));
if ( (ipRangeStart.ss_family == AF_INET6) && (ipRangeEnd.ss_family == AF_INET6) ) {
uint64_t s[2],e[2],x[2],xx[2];
memcpy(s,ipRangeStart.rawIpData(),16);
@@ -864,13 +913,13 @@ NetworkController::ResultCode EmbeddedNetworkController::doNetworkConfigRequest(
}
}
- if ( (ipAssignmentPools.is_array()) && ((v4AssignMode.is_object())&&(v4AssignMode.value("zt",false))) && (!haveManagedIpv4AutoAssignment) && (!amActiveBridge) ) {
+ if ( (ipAssignmentPools.is_array()) && ((v4AssignMode.is_object())&&(_jB(v4AssignMode["zt"],false))) && (!haveManagedIpv4AutoAssignment) && (!amActiveBridge) ) {
if (!allocatedIpsLoaded) allocatedIps = _getAlreadyAllocatedIps(nwid);
for(unsigned long p=0;((p<ipAssignmentPools.size())&&(!haveManagedIpv4AutoAssignment));++p) {
auto pool = ipAssignmentPools[p];
if (pool.is_object()) {
- InetAddress ipRangeStart(std::string(pool.value("ipRangeStart","")));
- InetAddress ipRangeEnd(std::string(pool.value("ipRangeEnd","")));
+ InetAddress ipRangeStart(_jS(pool["ipRangeStart"],""));
+ InetAddress ipRangeEnd(_jS(pool["ipRangeEnd"],""));
if ( (ipRangeStart.ss_family == AF_INET) && (ipRangeEnd.ss_family == AF_INET) ) {
uint32_t ipRangeStart = Utils::ntoh((uint32_t)(reinterpret_cast<struct sockaddr_in *>(&ipRangeStart)->sin_addr.s_addr));
uint32_t ipRangeEnd = Utils::ntoh((uint32_t)(reinterpret_cast<struct sockaddr_in *>(&ipRangeEnd)->sin_addr.s_addr));
@@ -921,7 +970,7 @@ NetworkController::ResultCode EmbeddedNetworkController::doNetworkConfigRequest(
}
}
- if (network.value("private",true)) {
+ if (_jB(network["private"],true)) {
CertificateOfMembership com(now,ZT_NETWORK_COM_DEFAULT_REVISION_MAX_DELTA,nwid,identity.address());
if (com.sign(signingId)) {
nc.com = com;
@@ -983,8 +1032,10 @@ unsigned int EmbeddedNetworkController::handleControlPlaneHttpGET(
responseBody.append((responseBody.length() == 1) ? "\"" : ",\"");
responseBody.append(*i);
responseBody.append("\":");
- const std::string rc = member.value("memberRevision","0");
- responseBody.append(rc);
+ auto rev = member["revision"];
+ if (rev.is_number())
+ responseBody.append(rev);
+ else responseBody.push_back('0');
}
}
}
@@ -1006,7 +1057,7 @@ unsigned int EmbeddedNetworkController::handleControlPlaneHttpGET(
auto recentLog = member["recentLog"];
if ((recentLog.is_array())&&(recentLog.size() > 0)) {
auto mostRecentLog = recentLog[0];
- if ((mostRecentLog.is_object())&&((uint64_t)mostRecentLog.value("ts",0ULL) >= threshold)) {
+ if ((mostRecentLog.is_object())&&(_jI(mostRecentLog["ts"],0ULL) >= threshold)) {
responseBody.append((responseBody.length() == 1) ? "\"" : ",\"");
responseBody.append(*i);
responseBody.append("\":");
@@ -1116,8 +1167,8 @@ unsigned int EmbeddedNetworkController::handleControlPlaneHttpPOST(
json member(_readJson(_memberJP(nwid,Address(address),true)));
try {
- if (b.count("authorized")) member["authorized"] = b.value("authorized",false);
- if ((b.count("identity"))&&(!member.count("identity"))) member["identity"] = b.value("identity",""); // allow identity to be populated only if not already known
+ if (b.count("authorized")) member["authorized"] = _jB(b["authorized"],false);
+ if ((b.count("identity"))&&(!member.count("identity"))) member["identity"] = _jS(b["identity"],""); // allow identity to be populated only if not already known
if (b.count("ipAssignments")) {
auto ipa = b["ipAssignments"];
@@ -1144,12 +1195,17 @@ unsigned int EmbeddedNetworkController::handleControlPlaneHttpPOST(
member["id"] = addrs;
member["address"] = addrs; // legacy
member["nwid"] = nwids;
- member["memberRevision"] = member.value("memberRevision",0ULL) + 1;
member["objtype"] = "member";
+ member["lastModified"] = OSUtils::now();
+ {
+ auto revj = member["revision"];
+ const uint64_t rev = (revj.is_number() ? ((uint64_t)revj + 1ULL) : 1ULL);
+ member["revision"] = rev;
+ }
_writeJson(_memberJP(nwid,Address(address),true).c_str(),member);
- member["clock"] = OSUtils::now();
+ member["clock"] = member["lastModified"];
responseBody = member.dump(2);
responseContentType = "application/json";
return 200;
@@ -1178,7 +1234,7 @@ unsigned int EmbeddedNetworkController::handleControlPlaneHttpPOST(
}
}
}
- test->reportAtEveryHop = (b.value("reportAtEveryHop",true) ? 1 : 0);
+ test->reportAtEveryHop = (_jB(b["reportAtEveryHop"],true) ? 1 : 0);
if (!test->hopCount) {
::free((void *)test);
@@ -1226,11 +1282,11 @@ unsigned int EmbeddedNetworkController::handleControlPlaneHttpPOST(
json network(_readJson(_networkJP(nwid,true)));
try {
- if (b.count("name")) network["name"] = b.value("name","");
- if (b.count("private")) network["private"] = b.value("private",true);
- if (b.count("enableBroadcast")) network["enableBroadcast"] = b.value("enableBroadcast",false);
- if (b.count("allowPassiveBridging")) network["allowPassiveBridging"] = b.value("allowPassiveBridging",false);
- if (b.count("multicastLimit")) network["multicastLimit"] = b.value("multicastLimit",32ULL);
+ if (b.count("name")) network["name"] = _jS(b["name"],"");
+ if (b.count("private")) network["private"] = _jB(b["private"],true);
+ if (b.count("enableBroadcast")) network["enableBroadcast"] = _jB(b["enableBroadcast"],false);
+ if (b.count("allowPassiveBridging")) network["allowPassiveBridging"] = _jB(b["allowPassiveBridging"],false);
+ if (b.count("multicastLimit")) network["multicastLimit"] = _jI(b["multicastLimit"],32ULL);
if (b.count("activeBridges")) {
auto ab = b["activeBridges"];
@@ -1249,10 +1305,10 @@ unsigned int EmbeddedNetworkController::handleControlPlaneHttpPOST(
auto nv4m = network["v4AssignMode"];
if (!nv4m.is_object()) nv4m = json::object();
if (b["v4AssignMode"].is_string()) { // backward compatibility
- nv4m["zt"] = (b.value("v4AssignMode","") == "zt");
+ nv4m["zt"] = (_jS(b["v4AssignMode"],"") == "zt");
} else if (b["v4AssignMode"].is_object()) {
auto v4m = b["v4AssignMode"];
- if (v4m.count("zt")) nv4m["zt"] = v4m.value("zt",false);
+ if (v4m.count("zt")) nv4m["zt"] = _jB(v4m["zt"],false);
}
if (!nv4m.count("zt")) nv4m["zt"] = false;
}
@@ -1261,7 +1317,7 @@ unsigned int EmbeddedNetworkController::handleControlPlaneHttpPOST(
auto nv6m = network["v6AssignMode"];
if (!nv6m.is_object()) nv6m = json::object();
if (b["v6AssignMode"].is_string()) { // backward compatibility
- std::vector<std::string> v6m(Utils::split(b.value("v6AssignMode","").c_str(),",","",""));
+ std::vector<std::string> v6m(Utils::split(_jS(b["v6AssignMode"],"").c_str(),",","",""));
std::sort(v6m.begin(),v6m.end());
v6m.erase(std::unique(v6m.begin(),v6m.end()),v6m.end());
for(std::vector<std::string>::iterator i(v6m.begin());i!=v6m.end();++i) {
@@ -1274,9 +1330,9 @@ unsigned int EmbeddedNetworkController::handleControlPlaneHttpPOST(
}
} else if (b["v6AssignMode"].is_object()) {
auto v6m = b["v6AssignMode"];
- if (v6m.count("rfc4193")) nv6m["rfc4193"] = v6m.value("rfc4193",false);
- if (v6m.count("zt")) nv6m["rfc4193"] = v6m.value("zt",false);
- if (v6m.count("6plane")) nv6m["rfc4193"] = v6m.value("6plane",false);
+ if (v6m.count("rfc4193")) nv6m["rfc4193"] = _jB(v6m["rfc4193"],false);
+ if (v6m.count("zt")) nv6m["rfc4193"] = _jB(v6m["zt"],false);
+ if (v6m.count("6plane")) nv6m["rfc4193"] = _jB(v6m["6plane"],false);
}
if (!nv6m.count("rfc4193")) nv6m["rfc4193"] = false;
if (!nv6m.count("zt")) nv6m["zt"] = false;
@@ -1289,8 +1345,8 @@ unsigned int EmbeddedNetworkController::handleControlPlaneHttpPOST(
for(unsigned long i=0;i<rts.size();++i) {
auto rt = rts[i];
if ((rt.is_object())&&(rt.count("target"))&&(rt.count("via"))) {
- InetAddress t(rt.value("target",""));
- InetAddress v(rt.value("via",""));
+ InetAddress t(_jS(rt["target"],""));
+ InetAddress v(_jS(rt["via"],""));
if ( ((t.ss_family == AF_INET)||(t.ss_family == AF_INET6)) && (t.ss_family == v.ss_family) && (t.netmaskBitsValid()) ) {
auto nrts = network["routes"];
if (!nrts.is_array()) nrts = json::array();
@@ -1310,8 +1366,8 @@ unsigned int EmbeddedNetworkController::handleControlPlaneHttpPOST(
for(unsigned long i=0;i<ipp.size();++i) {
auto ip = ipp[i];
if ((ip.is_object())&&(ip.count("ipRangeStart"))&&(ip.count("ipRangeEnd"))) {
- InetAddress f(ip.value("ipRangeStart",""));
- InetAddress t(ip.value("ipRangeEnd",""));
+ InetAddress f(_jS(ip["ipRangeStart"],""));
+ InetAddress t(_jS(ip["ipRangeEnd"],""));
if ( ((f.ss_family == AF_INET)||(f.ss_family == AF_INET6)) && (f.ss_family == t.ss_family) ) {
auto nipp = network["ipAssignmentPools"];
if (!nipp.is_array()) nipp = json::array();
@@ -1356,7 +1412,7 @@ unsigned int EmbeddedNetworkController::handleControlPlaneHttpPOST(
if (tstr.length() > 0) {
json t = json::object();
t["token"] = tstr;
- t["expires"] = token.value("expires",0ULL);
+ t["expires"] = _jI(token["expires"],0ULL);
nat.push_back(t);
}
}
@@ -1372,8 +1428,8 @@ unsigned int EmbeddedNetworkController::handleControlPlaneHttpPOST(
if (!network.count("creationTime")) network["creationTime"] = OSUtils::now();
if (!network.count("name")) network["name"] = "";
if (!network.count("multicastLimit")) network["multicastLimit"] = (uint64_t)32;
- if (!network.count("v4AssignMode")) network["v4AssignMode"] = "{\"zt\":false}"_json;
- if (!network.count("v6AssignMode")) network["v6AssignMode"] = "{\"rfc4193\":false,\"zt\":false,\"6plane\":false}"_json;
+ if (!network.count("v4AssignMode")) network["v4AssignMode"] = {{"zt",false}};
+ if (!network.count("v6AssignMode")) network["v6AssignMode"] = {{"rfc4193",false},{"zt",false},{"6plane",false}};
if (!network.count("activeBridges")) network["activeBridges"] = json::array();
if (!network.count("authTokens")) network["authTokens"] = json::array();
@@ -1387,7 +1443,8 @@ unsigned int EmbeddedNetworkController::handleControlPlaneHttpPOST(
network["id"] = nwids;
network["nwid"] = nwids; // legacy
- network["revision"] = network.value("revision",0ULL) + 1ULL;
+ auto rev = network["revision"];
+ network["revision"] = (rev.is_number() ? ((uint64_t)rev + 1ULL) : 1ULL);
network["objtype"] = "network";
_writeJson(_networkJP(nwid,true),network);