Add 6plane assignment support to network controller, and cleanup.

This commit is contained in:
Adam Ierymenko 2016-06-24 06:40:50 -07:00
parent 20d155e630
commit ee649ae69a
4 changed files with 110 additions and 128 deletions

View file

@ -84,6 +84,14 @@
// Nodes are considered active if they've queried in less than this long // Nodes are considered active if they've queried in less than this long
#define ZT_NETCONF_NODE_ACTIVE_THRESHOLD ((ZT_NETWORK_AUTOCONF_DELAY * 2) + 5000) #define ZT_NETCONF_NODE_ACTIVE_THRESHOLD ((ZT_NETWORK_AUTOCONF_DELAY * 2) + 5000)
// Flags for Network 'flags' field in table
#define ZT_DB_NETWORK_FLAG_ZT_MANAGED_V4 1
#define ZT_DB_NETWORK_FLAG_ZT_MANAGED_V6_RFC4193 2
#define ZT_DB_NETWORK_FLAG_ZT_MANAGED_V6_6PLANE 4
// Flags with all V6 managed mode flags flipped off -- for masking in update operation and in string form for SQL building
#define ZT_DB_NETWORK_FLAG_ZT_MANAGED_V6_MASK_S "268435449"
namespace ZeroTier { namespace ZeroTier {
namespace { namespace {
@ -136,8 +144,7 @@ struct MemberRecord {
struct NetworkRecord { struct NetworkRecord {
char id[24]; char id[24];
const char *name; const char *name;
const char *v4AssignMode; int flags;
const char *v6AssignMode;
bool isPrivate; bool isPrivate;
bool enableBroadcast; bool enableBroadcast;
bool allowPassiveBridging; bool allowPassiveBridging;
@ -208,7 +215,8 @@ SqliteNetworkController::SqliteNetworkController(Node *node,const char *dbPath,c
if (schemaVersion < 3) { if (schemaVersion < 3) {
// Create Route table to upgrade from version 2 to version 3 and migrate old // Create Route table to upgrade from version 2 to version 3 and migrate old
// data. Also delete obsolete Gateway table that was never actually used. // data. Also delete obsolete Gateway table that was never actually used, and
// migrate Network flags to a bitwise flags field instead of ASCII cruft.
if (sqlite3_exec(_db, if (sqlite3_exec(_db,
"DROP TABLE Gateway;\n" "DROP TABLE Gateway;\n"
"CREATE TABLE Route (\n" "CREATE TABLE Route (\n"
@ -222,6 +230,11 @@ SqliteNetworkController::SqliteNetworkController(Node *node,const char *dbPath,c
");\n" ");\n"
"CREATE INDEX Route_networkId ON Route (networkId);\n" "CREATE INDEX Route_networkId ON Route (networkId);\n"
"INSERT INTO Route SELECT DISTINCT networkId,\"ip\" AS \"target\",NULL AS \"via\",ipNetmaskBits AS targetNetmaskBits,ipVersion,0 AS \"flags\",0 AS \"metric\" FROM IpAssignment WHERE nodeId IS NULL AND \"type\" = 1;\n" "INSERT INTO Route SELECT DISTINCT networkId,\"ip\" AS \"target\",NULL AS \"via\",ipNetmaskBits AS targetNetmaskBits,ipVersion,0 AS \"flags\",0 AS \"metric\" FROM IpAssignment WHERE nodeId IS NULL AND \"type\" = 1;\n"
"ALTER TABLE Network ADD COLUMN \"flags\" integer NOT NULL DEFAULT(0);\n"
"UPDATE Network SET \"flags\" = (\"flags\" | 1) WHERE v4AssignMode = 'zt';\n"
"UPDATE Network SET \"flags\" = (\"flags\" | 2) WHERE v6AssignMode = 'rfc4193';\n"
"UPDATE Network SET \"flags\" = (\"flags\" | 4) WHERE v6AssignMode = '6plane';\n"
"ALTER TABLE Member ADD COLUMN \"flags\" integer NOT NULL DEFAULT(0);\n"
"DELETE FROM IpAssignment WHERE nodeId IS NULL AND \"type\" = 1;\n" "DELETE FROM IpAssignment WHERE nodeId IS NULL AND \"type\" = 1;\n"
"UPDATE \"Config\" SET \"v\" = 3 WHERE \"k\" = 'schemaVersion';\n" "UPDATE \"Config\" SET \"v\" = 3 WHERE \"k\" = 'schemaVersion';\n"
,0,0,0) != SQLITE_OK) { ,0,0,0) != SQLITE_OK) {
@ -252,7 +265,7 @@ SqliteNetworkController::SqliteNetworkController(Node *node,const char *dbPath,c
if ( if (
/* Network */ /* Network */
(sqlite3_prepare_v2(_db,"SELECT name,private,enableBroadcast,allowPassiveBridging,v4AssignMode,v6AssignMode,multicastLimit,creationTime,revision,memberRevisionCounter,(SELECT COUNT(1) FROM Member WHERE Member.networkId = Network.id AND Member.authorized > 0) FROM Network WHERE id = ?",-1,&_sGetNetworkById,(const char **)0) != SQLITE_OK) (sqlite3_prepare_v2(_db,"SELECT name,private,enableBroadcast,allowPassiveBridging,\"flags\",multicastLimit,creationTime,revision,memberRevisionCounter,(SELECT COUNT(1) FROM Member WHERE Member.networkId = Network.id AND Member.authorized > 0) FROM Network WHERE id = ?",-1,&_sGetNetworkById,(const char **)0) != SQLITE_OK)
||(sqlite3_prepare_v2(_db,"SELECT revision FROM Network WHERE id = ?",-1,&_sGetNetworkRevision,(const char **)0) != SQLITE_OK) ||(sqlite3_prepare_v2(_db,"SELECT revision FROM Network WHERE id = ?",-1,&_sGetNetworkRevision,(const char **)0) != SQLITE_OK)
||(sqlite3_prepare_v2(_db,"UPDATE Network SET revision = ? WHERE id = ?",-1,&_sSetNetworkRevision,(const char **)0) != SQLITE_OK) ||(sqlite3_prepare_v2(_db,"UPDATE Network SET revision = ? WHERE id = ?",-1,&_sSetNetworkRevision,(const char **)0) != SQLITE_OK)
||(sqlite3_prepare_v2(_db,"INSERT INTO Network (id,name,creationTime,revision) VALUES (?,?,?,1)",-1,&_sCreateNetwork,(const char **)0) != SQLITE_OK) ||(sqlite3_prepare_v2(_db,"INSERT INTO Network (id,name,creationTime,revision) VALUES (?,?,?,1)",-1,&_sCreateNetwork,(const char **)0) != SQLITE_OK)
@ -721,16 +734,32 @@ unsigned int SqliteNetworkController::handleControlPlaneHttpPOST(
if (sqlite3_prepare_v2(_db,"UPDATE Network SET allowPassiveBridging = ? WHERE id = ?",-1,&stmt,(const char **)0) == SQLITE_OK) if (sqlite3_prepare_v2(_db,"UPDATE Network SET allowPassiveBridging = ? WHERE id = ?",-1,&stmt,(const char **)0) == SQLITE_OK)
sqlite3_bind_int(stmt,1,(j->u.object.values[k].value->u.boolean == 0) ? 0 : 1); sqlite3_bind_int(stmt,1,(j->u.object.values[k].value->u.boolean == 0) ? 0 : 1);
} }
} else if (!strcmp(j->u.object.values[k].name,"flags")) {
if (j->u.object.values[k].value->type == json_integer) {
if (sqlite3_prepare_v2(_db,"UPDATE Network SET \"flags\" = ? WHERE id = ?",-1,&stmt,(const char **)0) == SQLITE_OK)
sqlite3_bind_int(stmt,1,(int)((unsigned int)j->u.object.values[k].value->u.integer & 0xfffffff));
}
} else if (!strcmp(j->u.object.values[k].name,"v4AssignMode")) { } else if (!strcmp(j->u.object.values[k].name,"v4AssignMode")) {
if (j->u.object.values[k].value->type == json_string) { if ((j->u.object.values[k].value->type == json_string)&&(!strcmp(j->u.object.values[k].value->u.string.ptr,"zt"))) {
if (sqlite3_prepare_v2(_db,"UPDATE Network SET v4AssignMode = ? WHERE id = ?",-1,&stmt,(const char **)0) == SQLITE_OK) if (sqlite3_prepare_v2(_db,"UPDATE Network SET \"flags\" = (\"flags\" | ?) WHERE id = ?",-1,&stmt,(const char **)0) == SQLITE_OK)
sqlite3_bind_text(stmt,1,j->u.object.values[k].value->u.string.ptr,-1,SQLITE_STATIC); sqlite3_bind_int(stmt,1,(int)ZT_DB_NETWORK_FLAG_ZT_MANAGED_V4);
} else {
if (sqlite3_prepare_v2(_db,"UPDATE Network SET \"flags\" = (\"flags\" & ?) WHERE id = ?",-1,&stmt,(const char **)0) == SQLITE_OK)
sqlite3_bind_int(stmt,1,(int)(ZT_DB_NETWORK_FLAG_ZT_MANAGED_V4 ^ 0xfffffff));
} }
} else if (!strcmp(j->u.object.values[k].name,"v6AssignMode")) { } else if (!strcmp(j->u.object.values[k].name,"v6AssignMode")) {
int fl = 0;
if (j->u.object.values[k].value->type == json_string) { if (j->u.object.values[k].value->type == json_string) {
if (sqlite3_prepare_v2(_db,"UPDATE Network SET v6AssignMode = ? WHERE id = ?",-1,&stmt,(const char **)0) == SQLITE_OK) char *saveptr = (char *)0;
sqlite3_bind_text(stmt,1,j->u.object.values[k].value->u.string.ptr,-1,SQLITE_STATIC); for(char *f=Utils::stok(j->u.object.values[k].value->u.string.ptr,",",&saveptr);(f);f=Utils::stok((char *)0,",",&saveptr)) {
if (!strcmp(f,"rfc4193"))
fl |= ZT_DB_NETWORK_FLAG_ZT_MANAGED_V6_RFC4193;
else if (!strcmp(f,"6plane"))
fl |= ZT_DB_NETWORK_FLAG_ZT_MANAGED_V6_6PLANE;
}
} }
if (sqlite3_prepare_v2(_db,"UPDATE Network SET \"flags\" = ((\"flags\" & " ZT_DB_NETWORK_FLAG_ZT_MANAGED_V6_MASK_S ") | ?) WHERE id = ?",-1,&stmt,(const char **)0) == SQLITE_OK)
sqlite3_bind_int(stmt,1,fl);
} else if (!strcmp(j->u.object.values[k].name,"multicastLimit")) { } else if (!strcmp(j->u.object.values[k].name,"multicastLimit")) {
if (j->u.object.values[k].value->type == json_integer) { if (j->u.object.values[k].value->type == json_integer) {
if (sqlite3_prepare_v2(_db,"UPDATE Network SET multicastLimit = ? WHERE id = ?",-1,&stmt,(const char **)0) == SQLITE_OK) if (sqlite3_prepare_v2(_db,"UPDATE Network SET multicastLimit = ? WHERE id = ?",-1,&stmt,(const char **)0) == SQLITE_OK)
@ -1346,6 +1375,18 @@ unsigned int SqliteNetworkController::_doCPGet(
sqlite3_reset(_sGetNetworkById); sqlite3_reset(_sGetNetworkById);
sqlite3_bind_text(_sGetNetworkById,1,nwids,16,SQLITE_STATIC); sqlite3_bind_text(_sGetNetworkById,1,nwids,16,SQLITE_STATIC);
if (sqlite3_step(_sGetNetworkById) == SQLITE_ROW) { if (sqlite3_step(_sGetNetworkById) == SQLITE_ROW) {
unsigned int fl = (unsigned int)sqlite3_column_int(_sGetNetworkById,4);
std::string v6modes;
if ((fl & ZT_DB_NETWORK_FLAG_ZT_MANAGED_V6_RFC4193) != 0)
v6modes.append("rfc4193");
if ((fl & ZT_DB_NETWORK_FLAG_ZT_MANAGED_V6_6PLANE) != 0) {
if (v6modes.length() > 0)
v6modes.push_back(',');
v6modes.append("6plane");
}
if (v6modes.length() == 0)
v6modes = "none";
Utils::snprintf(json,sizeof(json), Utils::snprintf(json,sizeof(json),
"{\n" "{\n"
"\t\"nwid\": \"%s\",\n" "\t\"nwid\": \"%s\",\n"
@ -1355,6 +1396,7 @@ unsigned int SqliteNetworkController::_doCPGet(
"\t\"private\": %s,\n" "\t\"private\": %s,\n"
"\t\"enableBroadcast\": %s,\n" "\t\"enableBroadcast\": %s,\n"
"\t\"allowPassiveBridging\": %s,\n" "\t\"allowPassiveBridging\": %s,\n"
"\t\"flags\": %u,\n"
"\t\"v4AssignMode\": \"%s\",\n" "\t\"v4AssignMode\": \"%s\",\n"
"\t\"v6AssignMode\": \"%s\",\n" "\t\"v6AssignMode\": \"%s\",\n"
"\t\"multicastLimit\": %d,\n" "\t\"multicastLimit\": %d,\n"
@ -1370,13 +1412,14 @@ unsigned int SqliteNetworkController::_doCPGet(
(sqlite3_column_int(_sGetNetworkById,1) > 0) ? "true" : "false", (sqlite3_column_int(_sGetNetworkById,1) > 0) ? "true" : "false",
(sqlite3_column_int(_sGetNetworkById,2) > 0) ? "true" : "false", (sqlite3_column_int(_sGetNetworkById,2) > 0) ? "true" : "false",
(sqlite3_column_int(_sGetNetworkById,3) > 0) ? "true" : "false", (sqlite3_column_int(_sGetNetworkById,3) > 0) ? "true" : "false",
_jsonEscape((const char *)sqlite3_column_text(_sGetNetworkById,4)).c_str(), fl,
_jsonEscape((const char *)sqlite3_column_text(_sGetNetworkById,5)).c_str(), (((fl & ZT_DB_NETWORK_FLAG_ZT_MANAGED_V4) != 0) ? "zt" : "none"),
sqlite3_column_int(_sGetNetworkById,6), v6modes.c_str(),
sqlite3_column_int(_sGetNetworkById,5),
(unsigned long long)sqlite3_column_int64(_sGetNetworkById,6),
(unsigned long long)sqlite3_column_int64(_sGetNetworkById,7), (unsigned long long)sqlite3_column_int64(_sGetNetworkById,7),
(unsigned long long)sqlite3_column_int64(_sGetNetworkById,8), (unsigned long long)sqlite3_column_int64(_sGetNetworkById,8),
(unsigned long long)sqlite3_column_int64(_sGetNetworkById,9), (unsigned long long)sqlite3_column_int64(_sGetNetworkById,9));
(unsigned long long)sqlite3_column_int64(_sGetNetworkById,10));
responseBody = json; responseBody = json;
sqlite3_reset(_sGetRelays); sqlite3_reset(_sGetRelays);
@ -1637,12 +1680,11 @@ NetworkController::ResultCode SqliteNetworkController::_doNetworkConfigRequest(c
network.isPrivate = (sqlite3_column_int(_sGetNetworkById,1) > 0); network.isPrivate = (sqlite3_column_int(_sGetNetworkById,1) > 0);
network.enableBroadcast = (sqlite3_column_int(_sGetNetworkById,2) > 0); network.enableBroadcast = (sqlite3_column_int(_sGetNetworkById,2) > 0);
network.allowPassiveBridging = (sqlite3_column_int(_sGetNetworkById,3) > 0); network.allowPassiveBridging = (sqlite3_column_int(_sGetNetworkById,3) > 0);
network.v4AssignMode = (const char *)sqlite3_column_text(_sGetNetworkById,4); network.flags = sqlite3_column_int(_sGetNetworkById,4);
network.v6AssignMode = (const char *)sqlite3_column_text(_sGetNetworkById,5); network.multicastLimit = sqlite3_column_int(_sGetNetworkById,5);
network.multicastLimit = sqlite3_column_int(_sGetNetworkById,6); network.creationTime = (uint64_t)sqlite3_column_int64(_sGetNetworkById,6);
network.creationTime = (uint64_t)sqlite3_column_int64(_sGetNetworkById,7); network.revision = (uint64_t)sqlite3_column_int64(_sGetNetworkById,7);
network.revision = (uint64_t)sqlite3_column_int64(_sGetNetworkById,8); network.memberRevisionCounter = (uint64_t)sqlite3_column_int64(_sGetNetworkById,8);
network.memberRevisionCounter = (uint64_t)sqlite3_column_int64(_sGetNetworkById,9);
} else { } else {
return NetworkController::NETCONF_QUERY_OBJECT_NOT_FOUND; return NetworkController::NETCONF_QUERY_OBJECT_NOT_FOUND;
} }
@ -1737,20 +1779,6 @@ NetworkController::ResultCode SqliteNetworkController::_doNetworkConfigRequest(c
if (network.allowPassiveBridging) nc.flags |= ZT_NETWORKCONFIG_FLAG_ALLOW_PASSIVE_BRIDGING; if (network.allowPassiveBridging) nc.flags |= ZT_NETWORKCONFIG_FLAG_ALLOW_PASSIVE_BRIDGING;
memcpy(nc.name,network.name,std::min((unsigned int)ZT_MAX_NETWORK_SHORT_NAME_LENGTH,(unsigned int)strlen(network.name))); memcpy(nc.name,network.name,std::min((unsigned int)ZT_MAX_NETWORK_SHORT_NAME_LENGTH,(unsigned int)strlen(network.name)));
/*
char tss[24],rs[24];
Utils::snprintf(tss,sizeof(tss),"%.16llx",(unsigned long long)now);
Utils::snprintf(rs,sizeof(rs),"%.16llx",(unsigned long long)network.revision);
legacy[ZT_NETWORKCONFIG_DICT_KEY_TIMESTAMP] = tss;
legacy[ZT_NETWORKCONFIG_DICT_KEY_REVISION] = rs;
legacy[ZT_NETWORKCONFIG_DICT_KEY_NETWORK_ID] = network.id;
legacy[ZT_NETWORKCONFIG_DICT_KEY_ISSUED_TO] = member.nodeId;
legacy[ZT_NETWORKCONFIG_DICT_KEY_PRIVATE] = network.isPrivate ? "1" : "0";
legacy[ZT_NETWORKCONFIG_DICT_KEY_NAME] = (network.name) ? network.name : "";
legacy[ZT_NETWORKCONFIG_DICT_KEY_ENABLE_BROADCAST] = network.enableBroadcast ? "1" : "0";
legacy[ZT_NETWORKCONFIG_DICT_KEY_ALLOW_PASSIVE_BRIDGING] = network.allowPassiveBridging ? "1" : "0";
*/
{ // TODO: right now only etherTypes are supported in rules { // TODO: right now only etherTypes are supported in rules
std::vector<int> allowedEtherTypes; std::vector<int> allowedEtherTypes;
sqlite3_reset(_sGetEtherTypesFromRuleTable); sqlite3_reset(_sGetEtherTypesFromRuleTable);
@ -1779,32 +1807,12 @@ NetworkController::ResultCode SqliteNetworkController::_doNetworkConfigRequest(c
} }
nc.rules[nc.ruleCount++].t = ZT_NETWORK_RULE_ACTION_ACCEPT; nc.rules[nc.ruleCount++].t = ZT_NETWORK_RULE_ACTION_ACCEPT;
} }
/*
std::string allowedEtherTypesCsv;
for(std::vector<int>::const_iterator i(allowedEtherTypes.begin());i!=allowedEtherTypes.end();++i) {
if (allowedEtherTypesCsv.length())
allowedEtherTypesCsv.push_back(',');
char tmp[16];
Utils::snprintf(tmp,sizeof(tmp),"%.4x",(unsigned int)*i);
allowedEtherTypesCsv.append(tmp);
}
legacy[ZT_NETWORKCONFIG_DICT_KEY_ALLOWED_ETHERNET_TYPES] = allowedEtherTypesCsv;
*/
} }
nc.multicastLimit = network.multicastLimit; nc.multicastLimit = network.multicastLimit;
/*
if (network.multicastLimit > 0) {
char ml[16];
Utils::snprintf(ml,sizeof(ml),"%lx",(unsigned long)network.multicastLimit);
legacy[ZT_NETWORKCONFIG_DICT_KEY_MULTICAST_LIMIT] = ml;
}
*/
bool amActiveBridge = false; bool amActiveBridge = false;
{ {
//std::string activeBridges;
sqlite3_reset(_sGetActiveBridges); sqlite3_reset(_sGetActiveBridges);
sqlite3_bind_text(_sGetActiveBridges,1,network.id,16,SQLITE_STATIC); sqlite3_bind_text(_sGetActiveBridges,1,network.id,16,SQLITE_STATIC);
while (sqlite3_step(_sGetActiveBridges) == SQLITE_ROW) { while (sqlite3_step(_sGetActiveBridges) == SQLITE_ROW) {
@ -1812,27 +1820,15 @@ NetworkController::ResultCode SqliteNetworkController::_doNetworkConfigRequest(c
if ((ab)&&(strlen(ab) == 10)) { if ((ab)&&(strlen(ab) == 10)) {
const uint64_t ab2 = Utils::hexStrToU64(ab); const uint64_t ab2 = Utils::hexStrToU64(ab);
nc.addSpecialist(Address(ab2),ZT_NETWORKCONFIG_SPECIALIST_TYPE_ACTIVE_BRIDGE); nc.addSpecialist(Address(ab2),ZT_NETWORKCONFIG_SPECIALIST_TYPE_ACTIVE_BRIDGE);
/*
if (activeBridges.length())
activeBridges.push_back(',');
activeBridges.append(ab);
*/
if (!strcmp(member.nodeId,ab)) if (!strcmp(member.nodeId,ab))
amActiveBridge = true; amActiveBridge = true;
} }
} }
/*
if (activeBridges.length())
legacy[ZT_NETWORKCONFIG_DICT_KEY_ACTIVE_BRIDGES] = activeBridges;
*/
} }
// Do not send relays to 1.1.0 since it had a serious bug in using them // Do not send relays to 1.1.0 since it had a serious bug in using them
// 1.1.0 will still work, it'll just fall back to roots instead of using network preferred relays // 1.1.0 will still work, it'll just fall back to roots instead of using network preferred relays
if (!((metaData.getUI(ZT_NETWORKCONFIG_REQUEST_METADATA_KEY_NODE_MAJOR_VERSION,0) == 1)&&(metaData.getUI(ZT_NETWORKCONFIG_REQUEST_METADATA_KEY_NODE_MINOR_VERSION,0) == 1)&&(metaData.getUI(ZT_NETWORKCONFIG_REQUEST_METADATA_KEY_NODE_REVISION,0) == 0))) { if (!((metaData.getUI(ZT_NETWORKCONFIG_REQUEST_METADATA_KEY_NODE_MAJOR_VERSION,0) == 1)&&(metaData.getUI(ZT_NETWORKCONFIG_REQUEST_METADATA_KEY_NODE_MINOR_VERSION,0) == 1)&&(metaData.getUI(ZT_NETWORKCONFIG_REQUEST_METADATA_KEY_NODE_REVISION,0) == 0))) {
//std::string relays;
sqlite3_reset(_sGetRelays); sqlite3_reset(_sGetRelays);
sqlite3_bind_text(_sGetRelays,1,network.id,16,SQLITE_STATIC); sqlite3_bind_text(_sGetRelays,1,network.id,16,SQLITE_STATIC);
while (sqlite3_step(_sGetRelays) == SQLITE_ROW) { while (sqlite3_step(_sGetRelays) == SQLITE_ROW) {
@ -1841,24 +1837,10 @@ NetworkController::ResultCode SqliteNetworkController::_doNetworkConfigRequest(c
if ((n)&&(a)) { if ((n)&&(a)) {
Address node(n); Address node(n);
InetAddress addr(a); InetAddress addr(a);
if (node) { if (node)
nc.addSpecialist(node,ZT_NETWORKCONFIG_SPECIALIST_TYPE_NETWORK_PREFERRED_RELAY); nc.addSpecialist(node,ZT_NETWORKCONFIG_SPECIALIST_TYPE_NETWORK_PREFERRED_RELAY);
/*
if (relays.length())
relays.push_back(',');
relays.append(node.toString());
if (addr) {
relays.push_back(';');
relays.append(addr.toString());
}
*/
}
} }
} }
/*
if (relays.length())
legacy[ZT_NETWORKCONFIG_DICT_KEY_RELAYS] = relays;
*/
} }
sqlite3_reset(_sGetRoutes); sqlite3_reset(_sGetRoutes);
@ -1893,15 +1875,14 @@ NetworkController::ResultCode SqliteNetworkController::_doNetworkConfigRequest(c
++nc.routeCount; ++nc.routeCount;
} }
if ((network.v6AssignMode)&&(!strcmp(network.v6AssignMode,"rfc4193"))) { if (((network.flags & ZT_DB_NETWORK_FLAG_ZT_MANAGED_V6_RFC4193) != 0)&&(nc.staticIpCount < ZT_MAX_ZT_ASSIGNED_ADDRESSES)) {
InetAddress rfc4193Addr(InetAddress::makeIpv6rfc4193(nwid,identity.address().toInt())); nc.staticIps[nc.staticIpCount++] = InetAddress::makeIpv6rfc4193(nwid,identity.address().toInt());
//legacy[ZT_NETWORKCONFIG_DICT_KEY_IPV6_STATIC] = rfc4193Addr.toString(); }
if (nc.staticIpCount < ZT_MAX_ZT_ASSIGNED_ADDRESSES) if (((network.flags & ZT_DB_NETWORK_FLAG_ZT_MANAGED_V6_6PLANE) != 0)&&(nc.staticIpCount < ZT_MAX_ZT_ASSIGNED_ADDRESSES)) {
nc.staticIps[nc.staticIpCount++] = rfc4193Addr; nc.staticIps[nc.staticIpCount++] = InetAddress::makeIpv66plane(nwid,identity.address().toInt());
} }
if ((network.v4AssignMode)&&(!strcmp(network.v4AssignMode,"zt"))) { if ((network.flags & ZT_DB_NETWORK_FLAG_ZT_MANAGED_V4) != 0) {
//std::string v4s;
bool haveStaticIpAssignment = false; bool haveStaticIpAssignment = false;
sqlite3_reset(_sGetIpAssignmentsForNode); sqlite3_reset(_sGetIpAssignmentsForNode);
@ -1915,25 +1896,19 @@ NetworkController::ResultCode SqliteNetworkController::_doNetworkConfigRequest(c
int ipNetmaskBits = sqlite3_column_int(_sGetIpAssignmentsForNode,2); int ipNetmaskBits = sqlite3_column_int(_sGetIpAssignmentsForNode,2);
if ((ipNetmaskBits <= 0)||(ipNetmaskBits > 32)) if ((ipNetmaskBits <= 0)||(ipNetmaskBits > 32))
continue; continue;
char ips[32];
Utils::snprintf(ips,sizeof(ips),"%d.%d.%d.%d/%d",(int)ip[12],(int)ip[13],(int)ip[14],(int)ip[15],ipNetmaskBits);
if (sqlite3_column_int(_sGetIpAssignmentsForNode,0) == 0 /*ZT_IP_ASSIGNMENT_TYPE_ADDRESS*/) { if (sqlite3_column_int(_sGetIpAssignmentsForNode,0) == 0 /*ZT_IP_ASSIGNMENT_TYPE_ADDRESS*/) {
if (nc.staticIpCount < ZT_MAX_ZT_ASSIGNED_ADDRESSES) {
struct sockaddr_in *const v4ip = reinterpret_cast<struct sockaddr_in *>(&(nc.staticIps[nc.staticIpCount++]));
v4ip->sin_family = AF_INET;
v4ip->sin_port = Utils::hton((uint16_t)ipNetmaskBits);
memcpy(&(v4ip->sin_addr.s_addr),ip + 12,4);
}
haveStaticIpAssignment = true; haveStaticIpAssignment = true;
InetAddress tmp2(ips);
if (tmp2)
nc.staticIps[nc.staticIpCount++] = tmp2;
/*
if (v4s.length())
v4s.push_back(',');
v4s.append(ips);
*/
} }
} }
if ((!haveStaticIpAssignment)&&(!amActiveBridge)) { if ((!haveStaticIpAssignment)&&(!amActiveBridge)) {
// Attempt to auto-assign an IPv4 address from an available routed pool // Attempt to auto-assign an IPv4 address from an available routed pool if there is one
sqlite3_reset(_sGetIpAssignmentPools); sqlite3_reset(_sGetIpAssignmentPools);
sqlite3_bind_text(_sGetIpAssignmentPools,1,network.id,16,SQLITE_STATIC); sqlite3_bind_text(_sGetIpAssignmentPools,1,network.id,16,SQLITE_STATIC);
sqlite3_bind_int(_sGetIpAssignmentPools,2,4); // 4 == IPv4 sqlite3_bind_int(_sGetIpAssignmentPools,2,4); // 4 == IPv4
@ -1974,9 +1949,8 @@ NetworkController::ResultCode SqliteNetworkController::_doNetworkConfigRequest(c
// If it's routed, then try to claim and assign it and if successful end loop // If it's routed, then try to claim and assign it and if successful end loop
if (routedNetmaskBits > 0) { if (routedNetmaskBits > 0) {
uint32_t ipBlob[4]; uint32_t ipBlob[4]; // actually a 16-byte blob, we put IPv4s in the last 4 bytes
ipBlob[0] = 0; ipBlob[1] = 0; ipBlob[2] = 0; ipBlob[3] = Utils::hton(ip); ipBlob[0] = 0; ipBlob[1] = 0; ipBlob[2] = 0; ipBlob[3] = Utils::hton(ip);
sqlite3_reset(_sCheckIfIpIsAllocated); sqlite3_reset(_sCheckIfIpIsAllocated);
sqlite3_bind_text(_sCheckIfIpIsAllocated,1,network.id,16,SQLITE_STATIC); sqlite3_bind_text(_sCheckIfIpIsAllocated,1,network.id,16,SQLITE_STATIC);
sqlite3_bind_blob(_sCheckIfIpIsAllocated,2,(const void *)ipBlob,16,SQLITE_STATIC); sqlite3_bind_blob(_sCheckIfIpIsAllocated,2,(const void *)ipBlob,16,SQLITE_STATIC);
@ -1992,21 +1966,12 @@ NetworkController::ResultCode SqliteNetworkController::_doNetworkConfigRequest(c
sqlite3_bind_int(_sAllocateIp,5,routedNetmaskBits); // IP netmask bits from matching route sqlite3_bind_int(_sAllocateIp,5,routedNetmaskBits); // IP netmask bits from matching route
sqlite3_bind_int(_sAllocateIp,6,4); // 4 == IPv4 sqlite3_bind_int(_sAllocateIp,6,4); // 4 == IPv4
if (sqlite3_step(_sAllocateIp) == SQLITE_DONE) { if (sqlite3_step(_sAllocateIp) == SQLITE_DONE) {
char ips[32];
Utils::snprintf(ips,sizeof(ips),"%d.%d.%d.%d/%d",(int)((ip >> 24) & 0xff),(int)((ip >> 16) & 0xff),(int)((ip >> 8) & 0xff),(int)(ip & 0xff),routedNetmaskBits);
if (nc.staticIpCount < ZT_MAX_ZT_ASSIGNED_ADDRESSES) { if (nc.staticIpCount < ZT_MAX_ZT_ASSIGNED_ADDRESSES) {
InetAddress tmp2(ips); struct sockaddr_in *const v4ip = reinterpret_cast<struct sockaddr_in *>(&(nc.staticIps[nc.staticIpCount++]));
if (tmp2) v4ip->sin_family = AF_INET;
nc.staticIps[nc.staticIpCount++] = tmp2; v4ip->sin_port = Utils::hton((uint16_t)routedNetmaskBits);
v4ip->sin_addr.s_addr = Utils::hton(ip);
} }
/*
if (v4s.length())
v4s.push_back(',');
v4s.append(ips);
*/
haveStaticIpAssignment = true; haveStaticIpAssignment = true;
break; break;
} }
@ -2015,17 +1980,11 @@ NetworkController::ResultCode SqliteNetworkController::_doNetworkConfigRequest(c
} }
} }
} }
/*
if (v4s.length())
legacy[ZT_NETWORKCONFIG_DICT_KEY_IPV4_STATIC] = v4s;
*/
} }
if (network.isPrivate) { if (network.isPrivate) {
CertificateOfMembership com(now,ZT_NETWORK_COM_DEFAULT_REVISION_MAX_DELTA,nwid,identity.address()); CertificateOfMembership com(now,ZT_NETWORK_COM_DEFAULT_REVISION_MAX_DELTA,nwid,identity.address());
if (com.sign(signingId)) { if (com.sign(signingId)) {
//legacy[ZT_NETWORKCONFIG_DICT_KEY_CERTIFICATE_OF_MEMBERSHIP] = com.toString();
nc.com = com; nc.com = com;
} else { } else {
return NETCONF_QUERY_INTERNAL_SERVER_ERROR; return NETCONF_QUERY_INTERNAL_SERVER_ERROR;

View file

@ -78,6 +78,7 @@ CREATE TABLE Member (
authorized integer NOT NULL DEFAULT(0), authorized integer NOT NULL DEFAULT(0),
activeBridge integer NOT NULL DEFAULT(0), activeBridge integer NOT NULL DEFAULT(0),
memberRevision integer NOT NULL DEFAULT(0), memberRevision integer NOT NULL DEFAULT(0),
flags integer NOT NULL DEFAULT(0),
PRIMARY KEY (networkId, nodeId) PRIMARY KEY (networkId, nodeId)
); );

View file

@ -395,7 +395,6 @@ bool InetAddress::operator<(const InetAddress &a) const
} }
InetAddress InetAddress::makeIpv6LinkLocal(const MAC &mac) InetAddress InetAddress::makeIpv6LinkLocal(const MAC &mac)
throw()
{ {
struct sockaddr_in6 sin6; struct sockaddr_in6 sin6;
sin6.sin6_family = AF_INET6; sin6.sin6_family = AF_INET6;
@ -420,7 +419,6 @@ InetAddress InetAddress::makeIpv6LinkLocal(const MAC &mac)
} }
InetAddress InetAddress::makeIpv6rfc4193(uint64_t nwid,uint64_t zeroTierAddress) InetAddress InetAddress::makeIpv6rfc4193(uint64_t nwid,uint64_t zeroTierAddress)
throw()
{ {
InetAddress r; InetAddress r;
struct sockaddr_in6 *const sin6 = reinterpret_cast<struct sockaddr_in6 *>(&r); struct sockaddr_in6 *const sin6 = reinterpret_cast<struct sockaddr_in6 *>(&r);
@ -445,4 +443,25 @@ InetAddress InetAddress::makeIpv6rfc4193(uint64_t nwid,uint64_t zeroTierAddress)
return r; return r;
} }
InetAddress InetAddress::makeIpv66plane(uint64_t nwid,uint64_t zeroTierAddress)
{
nwid ^= (nwid >> 32);
InetAddress r;
struct sockaddr_in6 *const sin6 = reinterpret_cast<struct sockaddr_in6 *>(&r);
sin6->sin6_family = AF_INET6;
sin6->sin6_addr.s6_addr[0] = 0xfc;
sin6->sin6_addr.s6_addr[1] = (uint8_t)(nwid >> 24);
sin6->sin6_addr.s6_addr[2] = (uint8_t)(nwid >> 16);
sin6->sin6_addr.s6_addr[3] = (uint8_t)(nwid >> 8);
sin6->sin6_addr.s6_addr[4] = (uint8_t)nwid;
sin6->sin6_addr.s6_addr[5] = (uint8_t)(zeroTierAddress >> 32);
sin6->sin6_addr.s6_addr[6] = (uint8_t)(zeroTierAddress >> 24);
sin6->sin6_addr.s6_addr[7] = (uint8_t)(zeroTierAddress >> 16);
sin6->sin6_addr.s6_addr[8] = (uint8_t)(zeroTierAddress >> 8);
sin6->sin6_addr.s6_addr[9] = (uint8_t)zeroTierAddress;
sin6->sin6_addr.s6_addr[15] = 0x01;
sin6->sin6_port = Utils::hton((uint16_t)40);
return r;
}
} // namespace ZeroTier } // namespace ZeroTier

View file

@ -471,8 +471,7 @@ struct InetAddress : public sockaddr_storage
* @param mac MAC address seed * @param mac MAC address seed
* @return IPv6 link-local address * @return IPv6 link-local address
*/ */
static InetAddress makeIpv6LinkLocal(const MAC &mac) static InetAddress makeIpv6LinkLocal(const MAC &mac);
throw();
/** /**
* Compute private IPv6 unicast address from network ID and ZeroTier address * Compute private IPv6 unicast address from network ID and ZeroTier address
@ -515,8 +514,12 @@ struct InetAddress : public sockaddr_storage
* @param zeroTierAddress 40-bit device address (in least significant 40 bits, highest 24 bits ignored) * @param zeroTierAddress 40-bit device address (in least significant 40 bits, highest 24 bits ignored)
* @return IPv6 private unicast address with /88 netmask * @return IPv6 private unicast address with /88 netmask
*/ */
static InetAddress makeIpv6rfc4193(uint64_t nwid,uint64_t zeroTierAddress) static InetAddress makeIpv6rfc4193(uint64_t nwid,uint64_t zeroTierAddress);
throw();
/**
* Compute a private IPv6 "6plane" unicast address from network ID and ZeroTier address
*/
static InetAddress makeIpv66plane(uint64_t nwid,uint64_t zeroTierAddress);
}; };
} // namespace ZeroTier } // namespace ZeroTier