diff options
author | Adam Ierymenko <adam.ierymenko@gmail.com> | 2016-08-15 18:49:50 -0700 |
---|---|---|
committer | Adam Ierymenko <adam.ierymenko@gmail.com> | 2016-08-15 18:49:50 -0700 |
commit | bd15262e5459c6003e54bcfd1d98966ff6bd1f97 (patch) | |
tree | 0394061608856c2597622e75e3c55a2a0eb615a9 | |
parent | 3cb2e1197ff7ba1371ae69a09e631a7b87a880bc (diff) | |
download | infinitytier-bd15262e5459c6003e54bcfd1d98966ff6bd1f97.tar.gz infinitytier-bd15262e5459c6003e54bcfd1d98966ff6bd1f97.zip |
Bunch of rule JSON stuff.
-rw-r--r-- | controller/SqliteNetworkController.cpp | 440 | ||||
-rw-r--r-- | node/InetAddress.hpp | 13 |
2 files changed, 420 insertions, 33 deletions
diff --git a/controller/SqliteNetworkController.cpp b/controller/SqliteNetworkController.cpp index 226da657..16c02295 100644 --- a/controller/SqliteNetworkController.cpp +++ b/controller/SqliteNetworkController.cpp @@ -81,6 +81,271 @@ using json = nlohmann::json; namespace ZeroTier { +struct json::object _renderRule(ZT_VirtualNetworkRule &rule) +{ + char tmp[128]; + json::object r; + r["not"] = ((rule.t & 0x80) != 0); + switch((rule.t) & 0x7f) { + case ZT_NETWORK_RULE_ACTION_DROP: + r["type"] = "ACTION_DROP"; + break; + case ZT_NETWORK_RULE_ACTION_ACCEPT: + r["type"] = "ACTION_ACCEPT"; + break; + case ZT_NETWORK_RULE_ACTION_TEE: + r["type"] = "ACTION_TEE"; + r["zt"] = Address(rule.v.zt).toString(); + break; + case ZT_NETWORK_RULE_ACTION_REDIRECT: + r["type"] = "ACTION_REDIRECT"; + r["zt"] = Address(rule.v.zt).toString(); + break; + case ZT_NETWORK_RULE_MATCH_SOURCE_ZEROTIER_ADDRESS: + r["type"] = "MATCH_SOURCE_ZEROTIER_ADDRESS"; + r["zt"] = Address(rule.v.zt).toString(); + break; + case ZT_NETWORK_RULE_MATCH_DEST_ZEROTIER_ADDRESS: + r["type"] = "MATCH_DEST_ZEROTIER_ADDRESS"; + r["zt"] = Address(rule.v.zt).toString(); + break; + case ZT_NETWORK_RULE_MATCH_VLAN_ID: + r["type"] = "MATCH_VLAN_ID"; + r["vlanId"] = (uint64_t)rule.v.vlanId; + break; + case ZT_NETWORK_RULE_MATCH_VLAN_PCP: + r["type"] = "MATCH_VLAN_PCP"; + r["vlanPcp"] = (uint64_t)rule.v.vlanPcp; + break; + case ZT_NETWORK_RULE_MATCH_VLAN_DEI: + r["type"] = "MATCH_VLAN_DEI"; + r["vlanDei"] = (uint64_t)rule.v.vlanDei; + break; + case ZT_NETWORK_RULE_MATCH_ETHERTYPE: + r["type"] = "MATCH_ETHERTYPE"; + r["etherType"] = (uint64_t)rule.v.etherType; + break; + case ZT_NETWORK_RULE_MATCH_MAC_SOURCE: + r["type"] = "MATCH_MAC_SOURCE"; + Utils::snprintf(tmp,sizeof(tmp),"%.2x:%.2x:%.2x:%.2x:%.2x:%.2x",(unsigned int)rule.v.mac[0],(unsigned int)rule.v.mac[1],(unsigned int)rule.v.mac[2],(unsigned int)rule.v.mac[3],(unsigned int)rule.v.mac[4],(unsigned int)rule.v.mac[5]); + r["mac"] = tmp; + break; + case ZT_NETWORK_RULE_MATCH_MAC_DEST: + r["type"] = "MATCH_MAC_DEST"; + Utils::snprintf(tmp,sizeof(tmp),"%.2x:%.2x:%.2x:%.2x:%.2x:%.2x",(unsigned int)rule.v.mac[0],(unsigned int)rule.v.mac[1],(unsigned int)rule.v.mac[2],(unsigned int)rule.v.mac[3],(unsigned int)rule.v.mac[4],(unsigned int)rule.v.mac[5]); + r["mac"] = tmp; + break; + case ZT_NETWORK_RULE_MATCH_IPV4_SOURCE: + r["type"] = "MATCH_IPV4_SOURCE"; + r["ip"] = InetAddress(&(rule.v.ipv4.ip),4,(unsigned int)rule.v.ipv4.mask).toString(); + break; + case ZT_NETWORK_RULE_MATCH_IPV4_DEST: + r["type"] = "MATCH_IPV4_DEST"; + r["ip"] = InetAddress(&(rule.v.ipv4.ip),4,(unsigned int)rule.v.ipv4.mask).toString(); + break; + case ZT_NETWORK_RULE_MATCH_IPV6_SOURCE: + r["type"] = "MATCH_IPV6_SOURCE"; + r["ip"] = InetAddress(rule.v.ipv6.ip,16,(unsigned int)rule.v.ipv6.mask).toString(); + break; + case ZT_NETWORK_RULE_MATCH_IPV6_DEST: + r["type"] = "MATCH_IPV6_DEST"; + r["ip"] = InetAddress(rule.v.ipv6.ip,16,(unsigned int)rule.v.ipv6.mask).toString(); + break; + case ZT_NETWORK_RULE_MATCH_IP_TOS: + r["type"] = "MATCH_IP_TOS"; + r["ipTos"] = (uint64_t)rule.v.ipTos; + break; + case ZT_NETWORK_RULE_MATCH_IP_PROTOCOL: + r["type"] = "MATCH_IP_PROTOCOL"; + r["ipProtocol"] = (uint64_t)rule.v.ipProtocol; + break; + case ZT_NETWORK_RULE_MATCH_IP_SOURCE_PORT_RANGE: + r["type"] = "MATCH_IP_SOURCE_PORT_RANGE"; + r["start"] = (uint64_t)rule.v.port[0]; + r["end"] = (uint64_t)rule.v.port[1]; + break; + case ZT_NETWORK_RULE_MATCH_IP_DEST_PORT_RANGE: + r["type"] = "MATCH_IP_DEST_PORT_RANGE"; + r["start"] = (uint64_t)rule.v.port[0]; + r["end"] = (uint64_t)rule.v.port[1]; + break; + case ZT_NETWORK_RULE_MATCH_CHARACTERISTICS: + r["type"] = "MATCH_CHARACTERISTICS"; + Utils::snprintf(tmp,sizeof(tmp),"%.16llx",rule.v.characteristics[0]); + r["mask"] = tmp; + Utils::snprintf(tmp,sizeof(tmp),"%.16llx",rule.v.characteristics[1]); + r["value"] = tmp; + break; + case ZT_NETWORK_RULE_MATCH_FRAME_SIZE_RANGE: + r["type"] = "MATCH_FRAME_SIZE_RANGE"; + r["start"] = (uint64_t)rule.v.frameSize[0]; + r["end"] = (uint64_t)rule.v.frameSize[1]; + break; + case ZT_NETWORK_RULE_MATCH_TAGS_SAMENESS: + r["type"] = "MATCH_TAGS_SAMENESS"; + r["id"] = (uint64_t)rule.v.tag.id; + r["value"] = (uint64_t)rule.v.tag.value; + break; + case ZT_NETWORK_RULE_MATCH_TAGS_BITWISE_AND: + r["type"] = "MATCH_TAGS_BITWISE_AND"; + r["id"] = (uint64_t)rule.v.tag.id; + r["value"] = (uint64_t)rule.v.tag.value; + break; + case ZT_NETWORK_RULE_MATCH_TAGS_BITWISE_OR: + r["type"] = "MATCH_TAGS_BITWISE_OR"; + r["id"] = (uint64_t)rule.v.tag.id; + r["value"] = (uint64_t)rule.v.tag.value; + break; + case ZT_NETWORK_RULE_MATCH_TAGS_BITWISE_XOR: + r["type"] = "MATCH_TAGS_BITWISE_XOR"; + r["id"] = (uint64_t)rule.v.tag.id; + r["value"] = (uint64_t)rule.v.tag.value; + break; + } + return r; +} + +struct bool _parseRule(const json::object &r,ZT_VirtualNetworkRule &rule) +{ + std::string t = r["type"]; + memset(&rule,0,sizeof(ZT_VirtualNetworkRule)); + if (r.value("not",false)) + rule.t = 0x80; + else rule.t = 0x00; + if (t == "ACTION_DROP") { + rule.t |= ZT_NETWORK_RULE_ACTION_DROP; + return true; + } else if (t == "ACTION_ACCEPT") { + rule.t |= ZT_NETWORK_RULE_ACTION_ACCEPT; + return true; + } else if (t == "ACTION_TEE") { + rule.t |= ZT_NETWORK_RULE_ACTION_TEE; + rule.v.zt = Utils::hexStrToU64(r.value("zt","0")) & 0xffffffffffULL; + return true; + } else if (t == "ACTION_REDIRECT") { + rule.t |= ZT_NETWORK_RULE_ACTION_REDIRECT; + rule.v.zt = Utils::hexStrToU64(r.value("zt","0")) & 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")) & 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")) & 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); + 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); + 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); + return true; + } else if (t == "MATCH_ETHERTYPE") { + rule.t |= ZT_NETWORK_RULE_MATCH_ETHERTYPE; + rule.v.etherType = (uint16_t)(r.value("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")); + 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")); + 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")); + 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")); + 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")); + 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")); + 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); + 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); + 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",0ULL) & 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",0ULL) & 0xffffULL); + return true; + } else if (t == "MATCH_CHARACTERISTICS") { + rule.t |= ZT_NETWORK_RULE_MATCH_CHARACTERISTICS; + if (r.count("mask")) { + auto mask = r["mask"]; + rule.v.characteristics[0] = (mask.is_integer() ? (uint64_t)mask : Utils::hexStrToU64(mask)); + } + if (r.count("value")) { + auto value = r["value"]; + rule.v.characteristics[1] = (value.is_integer() ? (uint64_t)value : Utils::hexStrToU64(value)); + } + return true; + } else if (t == "MATCH_FRAME_SIZE_RANGE") { + rule.t |= ZT_NETWORK_RULE_MATCH_FRAME_SIZE_RANGE; + rule.v.frameSize[0] = (uint16_t)(Utils::hexStrToU64(r.value("start","0")) & 0xffffULL); + rule.v.frameSize[1] = (uint16_t)(Utils::hexStrToU64(r.value("end","0")) & 0xffffULL); + return true; + } else if (t == "MATCH_TAGS_SAMENESS") { + rule.t |= ZT_NETWORK_RULE_MATCH_TAGS_SAMENESS; + rule.v.tag.id = (uint32_t)(Utils::hexStrToU64(r.value("id","0")) & 0xffffffffULL); + rule.v.tag.value = (uint32_t)(Utils::hexStrToU64(r.value("value","0")) & 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)(Utils::hexStrToU64(r.value("id","0")) & 0xffffffffULL); + rule.v.tag.value = (uint32_t)(Utils::hexStrToU64(r.value("value","0")) & 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)(Utils::hexStrToU64(r.value("id","0")) & 0xffffffffULL); + rule.v.tag.value = (uint32_t)(Utils::hexStrToU64(r.value("value","0")) & 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)(Utils::hexStrToU64(r.value("id","0")) & 0xffffffffULL); + rule.v.tag.value = (uint32_t)(Utils::hexStrToU64(r.value("value","0")) & 0xffffffffULL); + return true; + } + return false; +} + SqliteNetworkController::SqliteNetworkController(Node *node,const char *dbPath,const char *circuitTestPath) : _node(node), _db(dbPath), @@ -1050,49 +1315,157 @@ unsigned int SqliteNetworkController::handleControlPlaneHttpPOST( } // else 404 } else { - std::vector<std::string> path_copy(path); + // POST to network ID - if (!networkExists) { - if (path[1].substr(10) == "______") { - // A special POST /network/##########______ feature lets users create a network - // with an arbitrary unused network number at this controller. - nwid = 0; + json::object b; + try { + b = json::parse(body); + } catch ( ... ) { + return 403; + } - uint64_t nwidPrefix = (Utils::hexStrToU64(path[1].substr(0,10).c_str()) << 24) & 0xffffffffff000000ULL; - uint64_t nwidPostfix = 0; + // Magic ID ending with ______ picks a random unused network ID + if (path[1].substr(10) == "______") { + nwid = 0; + uint64_t nwidPrefix = (Utils::hexStrToU64(path[1].substr(0,10).c_str()) << 24) & 0xffffffffff000000ULL; + uint64_t nwidPostfix = 0; + for(unsigned long k=0;k<100000;++k) { // sanity limit on trials Utils::getSecureRandom(&nwidPostfix,sizeof(nwidPostfix)); - uint64_t nwidOriginalPostfix = nwidPostfix; - do { - uint64_t tryNwid = nwidPrefix | (nwidPostfix & 0xffffffULL); - if (!nwidPostfix) - tryNwid |= 1; - Utils::snprintf(nwids,sizeof(nwids),"%.16llx",(unsigned long long)tryNwid); - - sqlite3_reset(_sGetNetworkRevision); - sqlite3_bind_text(_sGetNetworkRevision,1,nwids,16,SQLITE_STATIC); - if (sqlite3_step(_sGetNetworkRevision) != SQLITE_ROW) { - nwid = tryNwid; - break; + uint64_t tryNwid = nwidPrefix | (nwidPostfix & 0xffffffULL); + if ((tryNwid & 0xffffffULL) == 0ULL) tryNwid |= 1ULL; + Utils::snprintf(nwids,sizeof(nwids),"%.16llx",(unsigned long long)tryNwid); + if (!networks.get<const json::object_t *>(nwids)) { + nwid = tryNwid; + break; + } + } + if (!nwid) + return 503; + } + + json::object &network = networks[nwids]; + if (!network.is_object()) network = json::object(); + + try { + if (b.count("name")) network["name"] = b.get<std::string>("name"); + if (b.count("private")) network["private"] = b.get<bool>("private"); + if (b.count("enableBroadcast")) network["enableBroadcast"] = b.get<bool>("enableBroadcast"); + if (b.count("allowPassiveBridging")) network["allowPassiveBridging"] = b.get<bool>("allowPassiveBridging"); + if (b.count("multicastLimit")) network["multicastLimit"] = b.get<uint64_t>("multicastLimit"); + + if (b.count("v4AssignMode")) { + auto nv4m = network["v4AssignMode"]; + if (!nv4m.is_object()) nv6m = json::object(); + if (b["v4AssignMode"].is_string()) { // backward compatibility + nv4m["zt"] = (b.get<std::string>("v4AssignMode") == "zt"); + } else if (b["v4AssignMode"].is_object()) { + auto v4m = b["v4AssignMode"]; + if (v4m.count("zt")) nv4m["zt"] = v4m.get<bool>("zt"); + } + if (!nv4m.count("zt")) nv4m["zt"] = false; + } + + if (b.count("v6AssignMode")) { + 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.get<std::string>("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) { + if (*i == "rfc4193") + nv6m["rfc4193"] = true; + else if (*i == "zt") + nv6m["zt"] = true; + else if (*i == "6plane") + nv6m["6plane"] = true; } + } else if (b["v6AssignMode"].is_object()) { + auto v6m = b["v6AssignMode"]; + if (v6m.count("rfc4193")) nv6m["rfc4193"] = v6m.get<bool>("rfc4193"); + if (v6m.count("zt")) nv6m["rfc4193"] = v6m.get<bool>("zt"); + if (v6m.count("6plane")) nv6m["rfc4193"] = v6m.get<bool>("6plane"); + } + if (!nv6m.count("rfc4193")) nv6m["rfc4193"] = false; + if (!nv6m.count("zt")) nv6m["zt"] = false; + if (!nv6m.count("6plane")) nv6m["6plane"] = false; + } - ++nwidPostfix; - } while (nwidPostfix != nwidOriginalPostfix); + if (b.count("routes")) { + auto rts = b["routes"]; + if (rts.is_array()) { + 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.get<std::string>("target")); + InetAddress v(rt.get<std::string>("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(); + json::object tmp; + tmp["target"] = target.toString(); + tmp["via"] = target.toIpString(); + nrts.push_back(tmp); + } + } + } + } + } - // 503 means we have no more free IDs for this prefix. You shouldn't host anywhere - // near 16 million networks on the same controller, so shouldn't happen. - if (!nwid) - return 503; + if (b.count("ipAssignmentPools")) { + auto ipp = b["ipAssignmentPools"]; + if (ipp.is_array()) { + 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.get<std::string>("ipRangeStart")); + InetAddress t(ip.get<std::string>("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(); + json::object tmp; + tmp["ipRangeStart"] = f.toIpString(); + tmp["ipRangeEnd"] = t.toIpString(); + nipp.push_back(tmp); + } + } + } + } } - sqlite3_reset(_sCreateNetwork); - sqlite3_bind_text(_sCreateNetwork,1,nwids,16,SQLITE_STATIC); - sqlite3_bind_text(_sCreateNetwork,2,"",0,SQLITE_STATIC); - sqlite3_bind_int64(_sCreateNetwork,3,(long long)OSUtils::now()); - if (sqlite3_step(_sCreateNetwork) != SQLITE_DONE) - return 500; - path_copy[1].assign(nwids); + if (b.count("rules")) { + auto rules = b["rules"]; + if (rules.is_array()) { + for(unsigned long i=0;i<rules.size();++i) { + auto rule = rules[i]; + if (rule.is_object()) { + } + } + } + } + } catch ( ... ) { + // TODO: report? + } + + if (!network.count("private")) network["private"] = true; + 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("revision")) network["revision"] = (uint64_t)0; + if (!network.count("memberRevisionCounter")) network["memberRevisionCounter"] = (uint64_t)0; + if (!network.count("memberLastModified")) network["memberLastModified"] = (uint64_t)0; + 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("rules")) { } + network["lastModified"] = OSUtils::now(); + network["revision"] = network.get<uint64_t>("revision") + 1ULL; + + return _doCPGet(path_copy,urlArgs,headers,body,responseBody,responseContentType); + + /* json_value *j = json_parse(body.c_str(),body.length()); if (j) { if (j->type == json_object) { @@ -1409,6 +1782,7 @@ unsigned int SqliteNetworkController::handleControlPlaneHttpPOST( return _doCPGet(path_copy,urlArgs,headers,body,responseBody,responseContentType); } + */ } // else 404 diff --git a/node/InetAddress.hpp b/node/InetAddress.hpp index b97e2ca6..2cd4dbd3 100644 --- a/node/InetAddress.hpp +++ b/node/InetAddress.hpp @@ -301,6 +301,19 @@ struct InetAddress : public sockaddr_storage inline unsigned int netmaskBits() const throw() { return port(); } /** + * @return True if netmask bits is valid for the address type + */ + inline bool netmaskBitsValid() const + { + const unsigned int n = port(); + switch(ss_family) { + case AF_INET: return (n <= 32); + case AF_INET6: return (n <= 128); + } + return false; + } + + /** * Alias for port() * * This just aliases port() because for gateways we use this field to |