diff options
author | Adam Ierymenko <adam.ierymenko@gmail.com> | 2015-06-13 11:34:31 +0200 |
---|---|---|
committer | Adam Ierymenko <adam.ierymenko@gmail.com> | 2015-06-13 11:34:31 +0200 |
commit | 96a58becf8fe10efceab38c49553b009754d2632 (patch) | |
tree | b4e73bbced3c94eb16ac79cfc8dd2b78eccb7938 | |
parent | 8a9715f183096e35e964a195b61f84bb263a9f85 (diff) | |
download | infinitytier-96a58becf8fe10efceab38c49553b009754d2632.tar.gz infinitytier-96a58becf8fe10efceab38c49553b009754d2632.zip |
Gateways support in network controller schema and database (not implemented yet in client) toward GitHub issue #178
-rw-r--r-- | controller/SqliteNetworkController.cpp | 130 | ||||
-rw-r--r-- | controller/SqliteNetworkController.hpp | 5 | ||||
-rw-r--r-- | controller/schema.sql | 9 | ||||
-rw-r--r-- | controller/schema.sql.c | 9 | ||||
-rw-r--r-- | node/InetAddress.hpp | 10 | ||||
-rw-r--r-- | node/NetworkConfig.hpp | 37 |
6 files changed, 194 insertions, 6 deletions
diff --git a/controller/SqliteNetworkController.cpp b/controller/SqliteNetworkController.cpp index 5aad49ff..35666fdb 100644 --- a/controller/SqliteNetworkController.cpp +++ b/controller/SqliteNetworkController.cpp @@ -179,7 +179,10 @@ SqliteNetworkController::SqliteNetworkController(const char *dbPath) : ||(sqlite3_prepare_v2(_db,"DELETE FROM Rule WHERE networkId = ?",-1,&_sDeleteRulesForNetwork,(const char **)0) != SQLITE_OK) ||(sqlite3_prepare_v2(_db,"INSERT INTO IpAssignmentPool (networkId,ipNetwork,ipNetmaskBits,ipVersion) VALUES (?,?,?,?)",-1,&_sCreateIpAssignmentPool,(const char **)0) != SQLITE_OK) ||(sqlite3_prepare_v2(_db,"DELETE FROM Member WHERE networkId = ? AND nodeId = ?",-1,&_sDeleteMember,(const char **)0) != SQLITE_OK) - ||(sqlite3_prepare_v2(_db,"DELETE FROM Network WHERE id = ?;",-1,&_sDeleteNetworkAndRelated,(const char **)0) != SQLITE_OK) + ||(sqlite3_prepare_v2(_db,"DELETE FROM Network WHERE id = ?",-1,&_sDeleteNetwork,(const char **)0) != SQLITE_OK) + ||(sqlite3_prepare_v2(_db,"SELECT ip,ipVersion,metric FROM Gateway WHERE networkId = ? ORDER BY metric ASC",-1,&_sGetGateways,(const char **)0) != SQLITE_OK) + ||(sqlite3_prepare_v2(_db,"DELETE FROM Gateway WHERE networkId = ?",-1,&_sDeleteGateways,(const char **)0) != SQLITE_OK) + ||(sqlite3_prepare_v2(_db,"INSERT INTO Gateway (networkId,ip,ipVersion,metric) VALUES (?,?,?,?)",-1,&_sCreateGateway,(const char **)0) != SQLITE_OK) ) { //printf("!!! %s\n",sqlite3_errmsg(_db)); sqlite3_close(_db); @@ -222,7 +225,10 @@ SqliteNetworkController::~SqliteNetworkController() sqlite3_finalize(_sDeleteIpAssignmentPoolsForNetwork); sqlite3_finalize(_sDeleteRulesForNetwork); sqlite3_finalize(_sCreateIpAssignmentPool); - sqlite3_finalize(_sDeleteNetworkAndRelated); + sqlite3_finalize(_sDeleteNetwork); + sqlite3_finalize(_sGetGateways); + sqlite3_finalize(_sDeleteGateways); + sqlite3_finalize(_sCreateGateway); sqlite3_close(_db); } } @@ -455,6 +461,52 @@ NetworkController::ResultCode SqliteNetworkController::doNetworkConfigRequest(co netconf[ZT_NETWORKCONFIG_DICT_KEY_RELAYS] = relays; } + { + char tmp[128]; + std::string gateways; + sqlite3_reset(_sGetGateways); + sqlite3_bind_text(_sGetGateways,1,network.id,16,SQLITE_STATIC); + while (sqlite3_step(_sGetGateways) == SQLITE_ROW) { + const unsigned char *ip = (const unsigned char *)sqlite3_column_blob(_sGetGateways,0); + switch(sqlite3_column_int(_sGetGateways,1)) { // ipVersion + case 4: + Utils::snprintf(tmp,sizeof(tmp),"%s%d.%d.%d.%d/%d", + (gateways.length() > 0) ? "," : "", + (int)ip[0], + (int)ip[1], + (int)ip[2], + (int)ip[3], + (int)sqlite3_column_int(_sGetGateways,2)); // metric + gateways.append(tmp); + break; + case 6: + Utils::snprintf(tmp,sizeof(tmp),"%s%.2x%.2x:%.2x%.2x:%.2x%.2x:%.2x%.2x:%.2x%.2x:%.2x%.2x:%.2x%.2x:%.2x%.2x/%d", + (gateways.length() > 0) ? "," : "", + (int)ip[0], + (int)ip[1], + (int)ip[2], + (int)ip[3], + (int)ip[4], + (int)ip[5], + (int)ip[6], + (int)ip[7], + (int)ip[8], + (int)ip[9], + (int)ip[10], + (int)ip[11], + (int)ip[12], + (int)ip[13], + (int)ip[14], + (int)ip[15], + (int)sqlite3_column_int(_sGetGateways,2)); // metric + gateways.append(tmp); + break; + } + } + if (gateways.length()) + netconf[ZT_NETWORKCONFIG_DICT_KEY_GATEWAYS] = gateways; + } + if ((network.v4AssignMode)&&(!strcmp(network.v4AssignMode,"zt"))) { std::string v4s; @@ -808,6 +860,31 @@ unsigned int SqliteNetworkController::handleControlPlaneHttpPOST( sqlite3_step(_sCreateRelay); } } + } else if (!strcmp(j->u.object.values[k].name,"gateways")) { + sqlite3_reset(_sDeleteGateways); + sqlite3_bind_text(_sDeleteGateways,1,nwids,16,SQLITE_STATIC); + sqlite3_step(_sDeleteGateways); + if (j->u.object.values[k].value->type == json_array) { + for(unsigned int kk=0;kk<j->u.object.values[k].value->u.array.length;++kk) { + json_value *gateway = j->u.object.values[k].value->u.array.values[kk]; + if ((gateway)&&(gateway->type == json_string)) { + InetAddress gwip(gateway->u.string.ptr); + int ipVersion = 0; + if (gwip.ss_family == AF_INET) + ipVersion = 4; + else if (gwip.ss_family == AF_INET6) + ipVersion = 6; + if (ipVersion) { + sqlite3_reset(_sCreateGateway); + sqlite3_bind_text(_sCreateGateway,1,nwids,16,SQLITE_STATIC); + sqlite3_bind_blob(_sCreateGateway,2,gwip.rawIpData(),(gwip.ss_family == AF_INET6) ? 16 : 4,SQLITE_STATIC); + sqlite3_bind_int(_sCreateGateway,3,ipVersion); + sqlite3_bind_int(_sCreateGateway,4,(int)gwip.metric()); + sqlite3_step(_sCreateGateway); + } + } + } + } } else if (!strcmp(j->u.object.values[k].name,"ipAssignmentPools")) { if (j->u.object.values[k].value->type == json_array) { std::set<InetAddress> pools; @@ -1027,9 +1104,9 @@ unsigned int SqliteNetworkController::handleControlPlaneHttpDELETE( } else { - sqlite3_reset(_sDeleteNetworkAndRelated); - sqlite3_bind_text(_sDeleteNetworkAndRelated,1,nwids,16,SQLITE_STATIC); - return ((sqlite3_step(_sDeleteNetworkAndRelated) == SQLITE_DONE) ? 200 : 500); + sqlite3_reset(_sDeleteNetwork); + sqlite3_bind_text(_sDeleteNetwork,1,nwids,16,SQLITE_STATIC); + return ((sqlite3_step(_sDeleteNetwork) == SQLITE_DONE) ? 200 : 500); } } // else 404 @@ -1212,6 +1289,49 @@ unsigned int SqliteNetworkController::_doCPGet( responseBody.append(_jsonEscape((const char *)sqlite3_column_text(_sGetRelays,1))); responseBody.append("\"}"); } + responseBody.append("],\n\t\"gateways\": ["); + + sqlite3_reset(_sGetGateways); + sqlite3_bind_text(_sGetGateways,1,nwids,16,SQLITE_STATIC); + bool firstGateway = true; + while (sqlite3_step(_sGetGateways) == SQLITE_ROW) { + char tmp[128]; + const unsigned char *ip = (const unsigned char *)sqlite3_column_blob(_sGetGateways,0); + switch(sqlite3_column_int(_sGetGateways,1)) { // ipVersion + case 4: + Utils::snprintf(tmp,sizeof(tmp),"%s%d.%d.%d.%d/%d\"", + (firstGateway) ? "\"" : ",\"", + (int)ip[0], + (int)ip[1], + (int)ip[2], + (int)ip[3], + (int)sqlite3_column_int(_sGetGateways,2)); // metric + break; + case 6: + Utils::snprintf(tmp,sizeof(tmp),"%s%.2x%.2x:%.2x%.2x:%.2x%.2x:%.2x%.2x:%.2x%.2x:%.2x%.2x:%.2x%.2x:%.2x%.2x/%d\"", + (firstGateway) ? "\"" : ",\"", + (int)ip[0], + (int)ip[1], + (int)ip[2], + (int)ip[3], + (int)ip[4], + (int)ip[5], + (int)ip[6], + (int)ip[7], + (int)ip[8], + (int)ip[9], + (int)ip[10], + (int)ip[11], + (int)ip[12], + (int)ip[13], + (int)ip[14], + (int)ip[15], + (int)sqlite3_column_int(_sGetGateways,2)); // metric + break; + } + responseBody.append(tmp); + firstGateway = false; + } responseBody.append("],\n\t\"ipAssignmentPools\": ["); sqlite3_reset(_sGetIpAssignmentPools2); diff --git a/controller/SqliteNetworkController.hpp b/controller/SqliteNetworkController.hpp index 5c92cc0b..d258933d 100644 --- a/controller/SqliteNetworkController.hpp +++ b/controller/SqliteNetworkController.hpp @@ -123,7 +123,10 @@ private: sqlite3_stmt *_sDeleteRulesForNetwork; sqlite3_stmt *_sCreateIpAssignmentPool; sqlite3_stmt *_sDeleteMember; - sqlite3_stmt *_sDeleteNetworkAndRelated; + sqlite3_stmt *_sDeleteNetwork; + sqlite3_stmt *_sGetGateways; + sqlite3_stmt *_sDeleteGateways; + sqlite3_stmt *_sCreateGateway; Mutex _lock; }; diff --git a/controller/schema.sql b/controller/schema.sql index 25adce40..809c7161 100644 --- a/controller/schema.sql +++ b/controller/schema.sql @@ -24,6 +24,15 @@ CREATE TABLE Node ( firstSeen integer NOT NULL DEFAULT(0) ); +CREATE TABLE Gateway ( + networkId char(16) NOT NULL REFERENCES Network(id) ON DELETE CASCADE, + ip blob(16) NOT NULL, + ipVersion integer NOT NULL DEFAULT(4), + metric integer NOT NULL DEFAULT(0) +); + +CREATE UNIQUE INDEX Gateway_networkId_ip ON Gateway (networkId, ip); + CREATE TABLE IpAssignment ( networkId char(16) NOT NULL REFERENCES Network(id) ON DELETE CASCADE, nodeId char(10) NOT NULL REFERENCES Node(id) ON DELETE CASCADE, diff --git a/controller/schema.sql.c b/controller/schema.sql.c index 243d37d5..f1c66358 100644 --- a/controller/schema.sql.c +++ b/controller/schema.sql.c @@ -25,6 +25,15 @@ " firstSeen integer NOT NULL DEFAULT(0)\n"\ ");\n"\ "\n"\ +"CREATE TABLE Gateway (\n"\ +" networkId char(16) NOT NULL REFERENCES Network(id) ON DELETE CASCADE,\n"\ +" ip blob(16) NOT NULL,\n"\ +" ipVersion integer NOT NULL DEFAULT(4),\n"\ +" metric integer NOT NULL DEFAULT(0)\n"\ +");\n"\ +"\n"\ +"CREATE UNIQUE INDEX Gateway_networkId_ip ON Gateway (networkId, ip);\n"\ +"\n"\ "CREATE TABLE IpAssignment (\n"\ " networkId char(16) NOT NULL REFERENCES Network(id) ON DELETE CASCADE,\n"\ " nodeId char(10) NOT NULL REFERENCES Node(id) ON DELETE CASCADE,\n"\ diff --git a/node/InetAddress.hpp b/node/InetAddress.hpp index 5b725174..16e3f4d5 100644 --- a/node/InetAddress.hpp +++ b/node/InetAddress.hpp @@ -266,6 +266,16 @@ struct InetAddress : public sockaddr_storage inline unsigned int netmaskBits() const throw() { return port(); } /** + * Alias for port() + * + * This just aliases port() because for gateways we use this field to + * store the gateway metric. + * + * @return Gateway metric + */ + inline unsigned int metric() const throw() { return port(); } + + /** * Construct a full netmask as an InetAddress */ InetAddress netmask() const diff --git a/node/NetworkConfig.hpp b/node/NetworkConfig.hpp index 89d1aec5..afbff3bf 100644 --- a/node/NetworkConfig.hpp +++ b/node/NetworkConfig.hpp @@ -49,24 +49,61 @@ namespace ZeroTier { // These dictionary keys are short so they don't take up much room in // netconf response packets. + +// integer(hex)[,integer(hex),...] #define ZT_NETWORKCONFIG_DICT_KEY_ALLOWED_ETHERNET_TYPES "et" + +// network ID #define ZT_NETWORKCONFIG_DICT_KEY_NETWORK_ID "nwid" + +// integer(hex) #define ZT_NETWORKCONFIG_DICT_KEY_TIMESTAMP "ts" + +// integer(hex) #define ZT_NETWORKCONFIG_DICT_KEY_REVISION "r" + +// address of member #define ZT_NETWORKCONFIG_DICT_KEY_ISSUED_TO "id" + +// integer(hex) #define ZT_NETWORKCONFIG_DICT_KEY_MULTICAST_LIMIT "ml" + +// dictionary of one or more of: MAC/ADI=preload,maxbalance,accrual #define ZT_NETWORKCONFIG_DICT_KEY_MULTICAST_RATES "mr" + +// 0/1 #define ZT_NETWORKCONFIG_DICT_KEY_PRIVATE "p" + +// text #define ZT_NETWORKCONFIG_DICT_KEY_NAME "n" + +// text #define ZT_NETWORKCONFIG_DICT_KEY_DESC "d" + +// IP/bits[,IP/bits,...] #define ZT_NETWORKCONFIG_DICT_KEY_IPV4_STATIC "v4s" + +// IP/bits[,IP/bits,...] #define ZT_NETWORKCONFIG_DICT_KEY_IPV6_STATIC "v6s" + +// serialized CertificateOfMembership #define ZT_NETWORKCONFIG_DICT_KEY_CERTIFICATE_OF_MEMBERSHIP "com" + +// 0/1 #define ZT_NETWORKCONFIG_DICT_KEY_ENABLE_BROADCAST "eb" + +// 0/1 #define ZT_NETWORKCONFIG_DICT_KEY_ALLOW_PASSIVE_BRIDGING "pb" + +// node[,node,...] #define ZT_NETWORKCONFIG_DICT_KEY_ACTIVE_BRIDGES "ab" + +// node;IP/port[,node;IP/port] #define ZT_NETWORKCONFIG_DICT_KEY_RELAYS "rl" +// IP/metric[,IP/metric,...] +#define ZT_NETWORKCONFIG_DICT_KEY_GATEWAYS "gw" + /** * Network configuration received from network controller nodes * |