summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAdam Ierymenko <adam.ierymenko@gmail.com>2015-06-13 11:34:31 +0200
committerAdam Ierymenko <adam.ierymenko@gmail.com>2015-06-13 11:34:31 +0200
commit96a58becf8fe10efceab38c49553b009754d2632 (patch)
treeb4e73bbced3c94eb16ac79cfc8dd2b78eccb7938
parent8a9715f183096e35e964a195b61f84bb263a9f85 (diff)
downloadinfinitytier-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.cpp130
-rw-r--r--controller/SqliteNetworkController.hpp5
-rw-r--r--controller/schema.sql9
-rw-r--r--controller/schema.sql.c9
-rw-r--r--node/InetAddress.hpp10
-rw-r--r--node/NetworkConfig.hpp37
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
*