mirror of
https://github.com/ZeroTier/ZeroTierOne
synced 2025-08-24 23:25:51 -07:00
Quick and dirty implementation of network-specific netns settings.
This commit is contained in:
parent
830250759c
commit
ecf3d103b2
2 changed files with 65 additions and 10 deletions
|
@ -20,6 +20,7 @@
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <map>
|
#include <map>
|
||||||
|
@ -1105,6 +1106,23 @@ 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)
|
||||||
{
|
{
|
||||||
|
int origns = 0;
|
||||||
|
if (!n.settings.nsname.empty()) {
|
||||||
|
origns = open("/proc/self/ns/net", O_RDONLY);
|
||||||
|
int fd = open(("/var/run/netns/" + n.settings.nsname).c_str(), O_RDONLY);
|
||||||
|
if (origns == -1 || fd == -1) {
|
||||||
|
if (fd > 0) close(fd);
|
||||||
|
if (origns > 0) close(origns);
|
||||||
|
throw std::runtime_error("unable to open network namespace");
|
||||||
|
}
|
||||||
|
if (setns(fd, 0) == -1) {
|
||||||
|
if (fd > 0) close(fd);
|
||||||
|
if (origns > 0) close(origns);
|
||||||
|
throw std::runtime_error("unable to open network namespace");
|
||||||
|
}
|
||||||
|
close(fd);
|
||||||
|
}
|
||||||
|
|
||||||
// assumes _nets_m is locked
|
// assumes _nets_m is locked
|
||||||
if (syncIps) {
|
if (syncIps) {
|
||||||
std::vector<InetAddress> newManagedIps;
|
std::vector<InetAddress> newManagedIps;
|
||||||
|
@ -1200,6 +1218,11 @@ public:
|
||||||
n.managedRoutes.pop_back();
|
n.managedRoutes.pop_back();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (origns > 0) {
|
||||||
|
// revert to our previous netns
|
||||||
|
setns(origns, 0);
|
||||||
|
close(origns);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void phyOnDatagram(PhySocket *sock,void **uptr,const struct sockaddr *localAddr,const struct sockaddr *from,void *data,unsigned long len)
|
inline void phyOnDatagram(PhySocket *sock,void **uptr,const struct sockaddr *localAddr,const struct sockaddr *from,void *data,unsigned long len)
|
||||||
|
@ -1444,6 +1467,38 @@ public:
|
||||||
try {
|
try {
|
||||||
char friendlyName[128];
|
char friendlyName[128];
|
||||||
Utils::snprintf(friendlyName,sizeof(friendlyName),"ZeroTier One [%.16llx]",nwid);
|
Utils::snprintf(friendlyName,sizeof(friendlyName),"ZeroTier One [%.16llx]",nwid);
|
||||||
|
|
||||||
|
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;
|
||||||
|
int origns = 0;
|
||||||
|
if (OSUtils::readFile(nlcpath,nlcbuf)) {
|
||||||
|
Dictionary<4096> nc;
|
||||||
|
char tmp[2048];
|
||||||
|
nc.load(nlcbuf.c_str());
|
||||||
|
if (nc.get("netns",tmp,sizeof(tmp)) > 0) {
|
||||||
|
n.settings.nsname = tmp;
|
||||||
|
// remember our current namespace so we can go
|
||||||
|
// back to it later
|
||||||
|
origns = open("/proc/self/ns/net", O_RDONLY);
|
||||||
|
int fd = open(("/var/run/netns/" + n.settings.nsname).c_str(), O_RDONLY);
|
||||||
|
if (origns == -1 || fd == -1) {
|
||||||
|
if (fd > 0) close(fd);
|
||||||
|
if (origns > 0) close(origns);
|
||||||
|
throw std::runtime_error("unable to open network namespace");
|
||||||
|
}
|
||||||
|
if (setns(fd, 0) == -1) {
|
||||||
|
if (fd > 0) close(fd);
|
||||||
|
if (origns > 0) close(origns);
|
||||||
|
throw std::runtime_error("unable to open network namespace");
|
||||||
|
}
|
||||||
|
close(fd);
|
||||||
|
}
|
||||||
|
n.settings.allowManaged = nc.getB("allowManaged",true);
|
||||||
|
n.settings.allowGlobal = nc.getB("allowGlobal",false);
|
||||||
|
n.settings.allowDefault = nc.getB("allowDefault",false);
|
||||||
|
}
|
||||||
|
|
||||||
n.tap = new EthernetTap(
|
n.tap = new EthernetTap(
|
||||||
_homePath.c_str(),
|
_homePath.c_str(),
|
||||||
MAC(nwc->mac),
|
MAC(nwc->mac),
|
||||||
|
@ -1455,16 +1510,11 @@ public:
|
||||||
(void *)this);
|
(void *)this);
|
||||||
*nuptr = (void *)&n;
|
*nuptr = (void *)&n;
|
||||||
|
|
||||||
char nlcpath[256];
|
if (origns > 0) {
|
||||||
Utils::snprintf(nlcpath,sizeof(nlcpath),"%s" ZT_PATH_SEPARATOR_S "networks.d" ZT_PATH_SEPARATOR_S "%.16llx.local.conf",_homePath.c_str(),nwid);
|
// revert to our previous netns
|
||||||
std::string nlcbuf;
|
setns(origns, 0);
|
||||||
if (OSUtils::readFile(nlcpath,nlcbuf)) {
|
close(origns);
|
||||||
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");
|
||||||
|
|
|
@ -86,6 +86,11 @@ public:
|
||||||
* Allow overriding of system default routes for "full tunnel" operation?
|
* Allow overriding of system default routes for "full tunnel" operation?
|
||||||
*/
|
*/
|
||||||
bool allowDefault;
|
bool allowDefault;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set a network namespace for the service
|
||||||
|
*/
|
||||||
|
std::string nsname;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue