diff options
Diffstat (limited to 'service')
-rw-r--r-- | service/ControlPlane.cpp | 50 | ||||
-rw-r--r-- | service/OneService.cpp | 44 | ||||
-rw-r--r-- | service/OneService.hpp | 9 |
3 files changed, 97 insertions, 6 deletions
diff --git a/service/ControlPlane.cpp b/service/ControlPlane.cpp index df2568a3..0e2b530d 100644 --- a/service/ControlPlane.cpp +++ b/service/ControlPlane.cpp @@ -28,6 +28,12 @@ #include "../ext/http-parser/http_parser.h" #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 #include "../controller/SqliteNetworkController.hpp" #endif @@ -96,7 +102,7 @@ static std::string _jsonEnumerate(const ZT_VirtualNetworkRoute *routes,unsigned 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 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\"assignedAddresses\": %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}", prefix, 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->routes,nc->routeCount).c_str(), prefix,_jsonEscape(portDeviceName).c_str(), + prefix,(localSettings.allowManaged) ? "true" : "false", + prefix,(localSettings.allowGlobal) ? "true" : "false", + prefix,(localSettings.allowDefault) ? "true" : "false", prefix); buf.append(json); } @@ -424,7 +436,9 @@ unsigned int ControlPlane::handleRequest( for(unsigned long i=0;i<nws->networkCount;++i) { if (i > 0) 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"); scode = 200; @@ -434,7 +448,9 @@ unsigned int ControlPlane::handleRequest( for(unsigned long i=0;i<nws->networkCount;++i) { if (nws->networks[i].nwid == wantnw) { 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'); scode = 200; break; @@ -506,8 +522,32 @@ unsigned int ControlPlane::handleRequest( if (nws) { for(unsigned long i=0;i<nws->networkCount;++i) { 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"; - _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'); scode = 200; break; diff --git a/service/OneService.cpp b/service/OneService.cpp index 139b1e15..534dfbf9 100644 --- a/service/OneService.cpp +++ b/service/OneService.cpp @@ -534,7 +534,7 @@ public: NetworkState() : 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.allowGlobal = false; settings.allowDefault = false; @@ -1013,6 +1013,31 @@ public: 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 // 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) void syncManagedStuff(NetworkState &n,bool syncIps,bool syncRoutes) { + // assumes _nets_m is locked if (syncIps) { std::vector<InetAddress> newManagedIps; newManagedIps.reserve(n.config.assignedAddressCount); @@ -1384,6 +1410,17 @@ public: StapFrameHandler, (void *)this); *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) { #ifdef __WINDOWS__ 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)) WindowsEthernetTap::deletePersistentTapDevice(winInstanceId.c_str()); #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 { _nets.erase(nwid); } diff --git a/service/OneService.hpp b/service/OneService.hpp index 0faf62f1..cead381d 100644 --- a/service/OneService.hpp +++ b/service/OneService.hpp @@ -161,6 +161,15 @@ public: 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 */ inline bool isRunning() const { return (this->reasonForTermination() == ONE_STILL_RUNNING); } |