summaryrefslogtreecommitdiff
path: root/controller/SqliteNetworkController.cpp
diff options
context:
space:
mode:
authorAdam Ierymenko <adam.ierymenko@gmail.com>2015-07-17 10:47:21 -0700
committerAdam Ierymenko <adam.ierymenko@gmail.com>2015-07-17 10:47:21 -0700
commit5515909c1e3481cc036c090bb66708773ddda17a (patch)
tree46eff444ca15684cb538b45ee419bfd9bf0a53e2 /controller/SqliteNetworkController.cpp
parent5ef806c43c394f94a6bc7d0080516dcb5f189398 (diff)
downloadinfinitytier-5515909c1e3481cc036c090bb66708773ddda17a.tar.gz
infinitytier-5515909c1e3481cc036c090bb66708773ddda17a.zip
Add a concept of an "instanceId" to the controller, which the OnePoint can use to determine whether it is the same running database instance it already knows.
Diffstat (limited to 'controller/SqliteNetworkController.cpp')
-rw-r--r--controller/SqliteNetworkController.cpp36
1 files changed, 32 insertions, 4 deletions
diff --git a/controller/SqliteNetworkController.cpp b/controller/SqliteNetworkController.cpp
index cc53d4d5..51d5a380 100644
--- a/controller/SqliteNetworkController.cpp
+++ b/controller/SqliteNetworkController.cpp
@@ -203,11 +203,33 @@ SqliteNetworkController::SqliteNetworkController(const char *dbPath) :
||(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)
+ /* Config */
+ ||(sqlite3_prepare_v2(_db,"SELECT \"v\" FROM \"Config\" WHERE \"k\" = ?",-1,&_sGetConfig,(const char **)0) != SQLITE_OK)
+ ||(sqlite3_prepare_v2(_db,"INSERT OR REPLACE INTO \"Config\" (\"k\",\"v\") VALUES (?,?)",-1,&_sSetConfig,(const char **)0) != SQLITE_OK)
+
) {
//printf("!!! %s\n",sqlite3_errmsg(_db));
sqlite3_close(_db);
throw std::runtime_error("SqliteNetworkController unable to initialize one or more prepared statements");
}
+
+ /* Generate a 128-bit / 32-character "instance ID" if one isn't already
+ * defined. Clients can use this to determine if this is the same controller
+ * database they know and love. */
+ sqlite3_reset(_sGetConfig);
+ sqlite3_bind_text(_sGetConfig,1,"instanceId",10,SQLITE_STATIC);
+ if (sqlite3_step(_sGetConfig) != SQLITE_ROW) {
+ char instanceId[32];
+ for(int i=0;i<32;++i)
+ instanceId[i] = "0123456789abcdef"[(rand() >> 8) & 0xf];
+ sqlite3_reset(_sSetConfig);
+ sqlite3_bind_text(_sSetConfig,1,"instanceId",10,SQLITE_STATIC);
+ sqlite3_bind_text(_sSetConfig,2,instanceId,32,SQLITE_STATIC);
+ if (sqlite3_step(_sSetConfig) != SQLITE_OK) {
+ sqlite3_close(_db);
+ throw std::runtime_error("SqliteNetworkController unable to read or initialize instanceId");
+ }
+ }
}
SqliteNetworkController::~SqliteNetworkController()
@@ -254,6 +276,8 @@ SqliteNetworkController::~SqliteNetworkController()
sqlite3_finalize(_sDeleteGateways);
sqlite3_finalize(_sCreateGateway);
sqlite3_finalize(_sIncrementMemberRevisionCounter);
+ sqlite3_finalize(_sGetConfig);
+ sqlite3_finalize(_sSetConfig);
sqlite3_close(_db);
}
}
@@ -1611,10 +1635,14 @@ unsigned int SqliteNetworkController::_doCPGet(
} else {
// GET /controller returns status and API version if controller is supported
- Utils::snprintf(json,sizeof(json),"{\n\t\"controller\": true,\n\t\"apiVersion\": %d,\n\t\"clock\": %llu\n}",ZT_NETCONF_CONTROLLER_API_VERSION,(unsigned long long)OSUtils::now());
- responseBody = json;
- responseContentType = "applicaiton/json";
- return 200;
+ sqlite3_reset(_sGetConfig);
+ sqlite3_bind_text(_sGetConfig,1,"instanceId",10,SQLITE_STATIC);
+ if (sqlite3_step(_sGetConfig) == SQLITE_ROW) {
+ Utils::snprintf(json,sizeof(json),"{\n\t\"controller\": true,\n\t\"apiVersion\": %d,\n\t\"clock\": %llu\n\t\"instanceId\": \"%s\"\n}",ZT_NETCONF_CONTROLLER_API_VERSION,(unsigned long long)OSUtils::now(),(const char *)sqlite3_column_text(_sGetConfig,0));
+ responseBody = json;
+ responseContentType = "applicaiton/json";
+ return 200;
+ } else return 500;
}
return 404;