Controller fixes...
This commit is contained in:
parent
1254dece5b
commit
faa9a06bf5
4 changed files with 148 additions and 83 deletions
|
@ -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);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue