Add network local.conf stuff to save network permission settings and wire it all through via the JSON API. Default route and route management stuff just about done.

This commit is contained in:
Adam Ierymenko 2016-06-21 16:52:49 -07:00
parent 8ca4f22f1d
commit f765597526
3 changed files with 97 additions and 6 deletions

View File

@ -28,6 +28,12 @@
#include "../ext/http-parser/http_parser.h" #include "../ext/http-parser/http_parser.h"
#endif #endif
#ifdef ZT_USE_SYSTEM_JSON_PARSER
#include <json-parser/json.h>
#else
#include "../ext/json-parser/json.h"
#endif
#ifdef ZT_ENABLE_NETWORK_CONTROLLER #ifdef ZT_ENABLE_NETWORK_CONTROLLER
#include "../controller/SqliteNetworkController.hpp" #include "../controller/SqliteNetworkController.hpp"
#endif #endif
@ -96,7 +102,7 @@ static std::string _jsonEnumerate(const ZT_VirtualNetworkRoute *routes,unsigned
return buf; return buf;
} }
static void _jsonAppend(unsigned int depth,std::string &buf,const ZT_VirtualNetworkConfig *nc,const std::string &portDeviceName) static void _jsonAppend(unsigned int depth,std::string &buf,const ZT_VirtualNetworkConfig *nc,const std::string &portDeviceName,const OneService::NetworkSettings &localSettings)
{ {
char json[4096]; char json[4096];
char prefix[32]; char prefix[32];
@ -136,7 +142,10 @@ static void _jsonAppend(unsigned int depth,std::string &buf,const ZT_VirtualNetw
"%s\t\"netconfRevision\": %lu,\n" "%s\t\"netconfRevision\": %lu,\n"
"%s\t\"assignedAddresses\": %s,\n" "%s\t\"assignedAddresses\": %s,\n"
"%s\t\"routes\": %s,\n" "%s\t\"routes\": %s,\n"
"%s\t\"portDeviceName\": \"%s\"\n" "%s\t\"portDeviceName\": \"%s\",\n"
"%s\t\"allowManaged\": %s,\n"
"%s\t\"allowGlobal\": %s,\n"
"%s\t\"allowDefault\": %s\n"
"%s}", "%s}",
prefix, prefix,
prefix,nc->nwid, prefix,nc->nwid,
@ -153,6 +162,9 @@ static void _jsonAppend(unsigned int depth,std::string &buf,const ZT_VirtualNetw
prefix,_jsonEnumerate(nc->assignedAddresses,nc->assignedAddressCount).c_str(), prefix,_jsonEnumerate(nc->assignedAddresses,nc->assignedAddressCount).c_str(),
prefix,_jsonEnumerate(nc->routes,nc->routeCount).c_str(), prefix,_jsonEnumerate(nc->routes,nc->routeCount).c_str(),
prefix,_jsonEscape(portDeviceName).c_str(), prefix,_jsonEscape(portDeviceName).c_str(),
prefix,(localSettings.allowManaged) ? "true" : "false",
prefix,(localSettings.allowGlobal) ? "true" : "false",
prefix,(localSettings.allowDefault) ? "true" : "false",
prefix); prefix);
buf.append(json); buf.append(json);
} }
@ -424,7 +436,9 @@ unsigned int ControlPlane::handleRequest(
for(unsigned long i=0;i<nws->networkCount;++i) { for(unsigned long i=0;i<nws->networkCount;++i) {
if (i > 0) if (i > 0)
responseBody.append(","); responseBody.append(",");
_jsonAppend(1,responseBody,&(nws->networks[i]),_svc->portDeviceName(nws->networks[i].nwid)); OneService::NetworkSettings localSettings;
_svc->getNetworkSettings(nws->networks[i].nwid,localSettings);
_jsonAppend(1,responseBody,&(nws->networks[i]),_svc->portDeviceName(nws->networks[i].nwid),localSettings);
} }
responseBody.append("\n]\n"); responseBody.append("\n]\n");
scode = 200; scode = 200;
@ -434,7 +448,9 @@ unsigned int ControlPlane::handleRequest(
for(unsigned long i=0;i<nws->networkCount;++i) { for(unsigned long i=0;i<nws->networkCount;++i) {
if (nws->networks[i].nwid == wantnw) { if (nws->networks[i].nwid == wantnw) {
responseContentType = "application/json"; responseContentType = "application/json";
_jsonAppend(0,responseBody,&(nws->networks[i]),_svc->portDeviceName(nws->networks[i].nwid)); OneService::NetworkSettings localSettings;
_svc->getNetworkSettings(nws->networks[i].nwid,localSettings);
_jsonAppend(0,responseBody,&(nws->networks[i]),_svc->portDeviceName(nws->networks[i].nwid),localSettings);
responseBody.push_back('\n'); responseBody.push_back('\n');
scode = 200; scode = 200;
break; break;
@ -506,8 +522,32 @@ unsigned int ControlPlane::handleRequest(
if (nws) { if (nws) {
for(unsigned long i=0;i<nws->networkCount;++i) { for(unsigned long i=0;i<nws->networkCount;++i) {
if (nws->networks[i].nwid == wantnw) { if (nws->networks[i].nwid == wantnw) {
OneService::NetworkSettings localSettings;
_svc->getNetworkSettings(nws->networks[i].nwid,localSettings);
json_value *j = json_parse(body.c_str(),body.length());
if (j) {
if (j->type == json_object) {
for(unsigned int k=0;k<j->u.object.length;++k) {
if (!strcmp(j->u.object.values[k].name,"allowManaged")) {
if (j->u.object.values[k].value->type == json_boolean)
localSettings.allowManaged = (j->u.object.values[k].value->u.boolean != 0);
} else if (!strcmp(j->u.object.values[k].name,"allowGlobal")) {
if (j->u.object.values[k].value->type == json_boolean)
localSettings.allowGlobal = (j->u.object.values[k].value->u.boolean != 0);
} else if (!strcmp(j->u.object.values[k].name,"allowDefault")) {
if (j->u.object.values[k].value->type == json_boolean)
localSettings.allowDefault = (j->u.object.values[k].value->u.boolean != 0);
}
}
}
json_value_free(j);
}
_svc->setNetworkSettings(nws->networks[i].nwid,localSettings);
responseContentType = "application/json"; responseContentType = "application/json";
_jsonAppend(0,responseBody,&(nws->networks[i]),_svc->portDeviceName(nws->networks[i].nwid)); _jsonAppend(0,responseBody,&(nws->networks[i]),_svc->portDeviceName(nws->networks[i].nwid),localSettings);
responseBody.push_back('\n'); responseBody.push_back('\n');
scode = 200; scode = 200;
break; break;

View File

@ -534,7 +534,7 @@ public:
NetworkState() : NetworkState() :
tap((EthernetTap *)0) tap((EthernetTap *)0)
{ {
// Default network permission settings: allow management of IPs and routes but only for private and "pseudo-private" IP spaces // Real defaults are in network 'up' code in network event handler
settings.allowManaged = true; settings.allowManaged = true;
settings.allowGlobal = false; settings.allowGlobal = false;
settings.allowDefault = false; settings.allowDefault = false;
@ -1013,6 +1013,31 @@ public:
return true; return true;
} }
virtual bool setNetworkSettings(const uint64_t nwid,const NetworkSettings &settings)
{
Mutex::Lock _l(_nets_m);
std::map<uint64_t,NetworkState>::iterator n(_nets.find(nwid));
if (n == _nets.end())
return false;
memcpy(&(n->second.settings),&settings,sizeof(NetworkSettings));
char nlcpath[256];
Utils::snprintf(nlcpath,sizeof(nlcpath),"%s" ZT_PATH_SEPARATOR_S "networks.d" ZT_PATH_SEPARATOR_S "%.16llx.local.conf",_homePath.c_str(),nwid);
FILE *out = fopen(nlcpath,"w");
if (out) {
fprintf(out,"allowManaged=%d\n",(int)n->second.settings.allowManaged);
fprintf(out,"allowGlobal=%d\n",(int)n->second.settings.allowGlobal);
fprintf(out,"allowDefault=%d\n",(int)n->second.settings.allowDefault);
fclose(out);
}
if (n->second.tap)
syncManagedStuff(n->second,true,true);
return true;
}
// Begin private implementation methods // Begin private implementation methods
// Checks if a managed IP or route target is allowed // Checks if a managed IP or route target is allowed
@ -1038,6 +1063,7 @@ public:
// Apply or update managed IPs for a configured network (be sure n.tap exists) // Apply or update managed IPs for a configured network (be sure n.tap exists)
void syncManagedStuff(NetworkState &n,bool syncIps,bool syncRoutes) void syncManagedStuff(NetworkState &n,bool syncIps,bool syncRoutes)
{ {
// assumes _nets_m is locked
if (syncIps) { if (syncIps) {
std::vector<InetAddress> newManagedIps; std::vector<InetAddress> newManagedIps;
newManagedIps.reserve(n.config.assignedAddressCount); newManagedIps.reserve(n.config.assignedAddressCount);
@ -1384,6 +1410,17 @@ public:
StapFrameHandler, StapFrameHandler,
(void *)this); (void *)this);
*nuptr = (void *)&n; *nuptr = (void *)&n;
char nlcpath[256];
Utils::snprintf(nlcpath,sizeof(nlcpath),"%s" ZT_PATH_SEPARATOR_S "networks.d" ZT_PATH_SEPARATOR_S "%.16llx.local.conf",_homePath.c_str(),nwid);
std::string nlcbuf;
if (OSUtils::readFile(nlcpath,nlcbuf)) {
Dictionary<4096> nc;
nc.load(nlcbuf.c_str());
n.settings.allowManaged = nc.getB("allowManaged",true);
n.settings.allowGlobal = nc.getB("allowGlobal",false);
n.settings.allowDefault = nc.getB("allowDefault",false);
}
} catch (std::exception &exc) { } catch (std::exception &exc) {
#ifdef __WINDOWS__ #ifdef __WINDOWS__
FILE *tapFailLog = fopen((_homePath + ZT_PATH_SEPARATOR_S"port_error_log.txt").c_str(),"a"); FILE *tapFailLog = fopen((_homePath + ZT_PATH_SEPARATOR_S"port_error_log.txt").c_str(),"a");
@ -1425,6 +1462,11 @@ public:
if ((op == ZT_VIRTUAL_NETWORK_CONFIG_OPERATION_DESTROY)&&(winInstanceId.length() > 0)) if ((op == ZT_VIRTUAL_NETWORK_CONFIG_OPERATION_DESTROY)&&(winInstanceId.length() > 0))
WindowsEthernetTap::deletePersistentTapDevice(winInstanceId.c_str()); WindowsEthernetTap::deletePersistentTapDevice(winInstanceId.c_str());
#endif #endif
if (op == ZT_VIRTUAL_NETWORK_CONFIG_OPERATION_DESTROY) {
char nlcpath[256];
Utils::snprintf(nlcpath,sizeof(nlcpath),"%s" ZT_PATH_SEPARATOR_S "networks.d" ZT_PATH_SEPARATOR_S "%.16llx.local.conf",_homePath.c_str(),nwid);
OSUtils::rm(nlcpath);
}
} else { } else {
_nets.erase(nwid); _nets.erase(nwid);
} }

View File

@ -160,6 +160,15 @@ public:
*/ */
virtual bool getNetworkSettings(const uint64_t nwid,NetworkSettings &settings) const = 0; virtual bool getNetworkSettings(const uint64_t nwid,NetworkSettings &settings) const = 0;
/**
* Set local settings for a network
*
* @param nwid Network ID
* @param settings New network local settings
* @return True if network was found and setting modified
*/
virtual bool setNetworkSettings(const uint64_t nwid,const NetworkSettings &settings) = 0;
/** /**
* @return True if service is still running * @return True if service is still running
*/ */