|
|
|
|
@ -104,20 +104,10 @@ bool Network::Certificate::qualifyMembership(const Network::Certificate &mc) con
|
|
|
|
|
return true; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
Network::Network(const RuntimeEnvironment *renv,uint64_t id) |
|
|
|
|
throw(std::runtime_error) : |
|
|
|
|
_r(renv), |
|
|
|
|
_tap(renv,renv->identity.address().toMAC(),ZT_IF_MTU,&_CBhandleTapData,this), |
|
|
|
|
_id(id), |
|
|
|
|
_lastConfigUpdate(0), |
|
|
|
|
_destroyOnDelete(false) |
|
|
|
|
{ |
|
|
|
|
if (controller() == _r->identity.address()) |
|
|
|
|
throw std::runtime_error("cannot add a network for which I am the netconf master"); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
Network::~Network() |
|
|
|
|
{ |
|
|
|
|
delete _tap; |
|
|
|
|
|
|
|
|
|
if (_destroyOnDelete) { |
|
|
|
|
std::string confPath(_r->homePath + ZT_PATH_SEPARATOR_S + "networks.d" + ZT_PATH_SEPARATOR_S + toString() + ".conf"); |
|
|
|
|
std::string mcdbPath(_r->homePath + ZT_PATH_SEPARATOR_S + "networks.d" + ZT_PATH_SEPARATOR_S + toString() + ".mcerts"); |
|
|
|
|
@ -129,26 +119,25 @@ Network::~Network()
|
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void Network::restoreState() |
|
|
|
|
SharedPtr<Network> Network::newInstance(const RuntimeEnvironment *renv,uint64_t id) |
|
|
|
|
throw(std::runtime_error) |
|
|
|
|
{ |
|
|
|
|
std::string confPath(_r->homePath + ZT_PATH_SEPARATOR_S + "networks.d" + ZT_PATH_SEPARATOR_S + toString() + ".conf"); |
|
|
|
|
std::string confs; |
|
|
|
|
if (Utils::readFile(confPath.c_str(),confs)) { |
|
|
|
|
try { |
|
|
|
|
if (confs.length()) { |
|
|
|
|
Config conf(confs); |
|
|
|
|
if (conf.containsAllFields()) |
|
|
|
|
setConfiguration(conf); |
|
|
|
|
} |
|
|
|
|
} catch ( ... ) {} // ignore invalid config on disk, we will re-request
|
|
|
|
|
} else { |
|
|
|
|
// If the conf file isn't present, "touch" it so we'll remember
|
|
|
|
|
// the existence of this network.
|
|
|
|
|
FILE *tmp = fopen(confPath.c_str(),"w"); |
|
|
|
|
if (tmp) |
|
|
|
|
fclose(tmp); |
|
|
|
|
} |
|
|
|
|
// TODO: restore membership certs
|
|
|
|
|
// We construct Network via a static method to ensure that it is immediately
|
|
|
|
|
// wrapped in a SharedPtr<>. Otherwise if there is traffic on the Ethernet
|
|
|
|
|
// tap device, a SharedPtr<> wrap can occur in the Ethernet frame handler
|
|
|
|
|
// that then causes the Network instance to be deleted before it is finished
|
|
|
|
|
// being constructed. C++ edge cases, how I love thee.
|
|
|
|
|
SharedPtr<Network> nw(new Network()); |
|
|
|
|
nw->_r = renv; |
|
|
|
|
nw->_tap = new EthernetTap(renv,renv->identity.address().toMAC(),ZT_IF_MTU,&_CBhandleTapData,nw.ptr()); |
|
|
|
|
nw->_id = id; |
|
|
|
|
nw->_lastConfigUpdate = 0; |
|
|
|
|
nw->_destroyOnDelete = false; |
|
|
|
|
if (nw->controller() == renv->identity.address()) // sanity check, this isn't supported for now
|
|
|
|
|
throw std::runtime_error("cannot add a network for which I am the netconf master"); |
|
|
|
|
nw->_restoreState(); |
|
|
|
|
nw->requestConfiguration(); |
|
|
|
|
return nw; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void Network::setConfiguration(const Network::Config &conf) |
|
|
|
|
@ -160,7 +149,7 @@ void Network::setConfiguration(const Network::Config &conf)
|
|
|
|
|
_myCertificate = conf.certificateOfMembership(); |
|
|
|
|
_lastConfigUpdate = Utils::now(); |
|
|
|
|
|
|
|
|
|
_tap.setIps(conf.staticAddresses()); |
|
|
|
|
_tap->setIps(conf.staticAddresses()); |
|
|
|
|
|
|
|
|
|
std::string confPath(_r->homePath + ZT_PATH_SEPARATOR_S + "networks.d" + ZT_PATH_SEPARATOR_S + toString() + ".conf"); |
|
|
|
|
if (!Utils::writeFile(confPath.c_str(),conf.toString())) { |
|
|
|
|
@ -210,11 +199,13 @@ bool Network::isAllowed(const Address &peer) const
|
|
|
|
|
|
|
|
|
|
void Network::clean() |
|
|
|
|
{ |
|
|
|
|
std::string mcdbPath(_r->homePath + ZT_PATH_SEPARATOR_S + "networks.d" + ZT_PATH_SEPARATOR_S + toString() + ".mcerts"); |
|
|
|
|
|
|
|
|
|
Mutex::Lock _l(_lock); |
|
|
|
|
if (_configuration.isOpen()) |
|
|
|
|
if (_configuration.isOpen()) { |
|
|
|
|
_membershipCertificates.clear(); |
|
|
|
|
else { |
|
|
|
|
std::string mcdbPath(_r->homePath + ZT_PATH_SEPARATOR_S + "networks.d" + ZT_PATH_SEPARATOR_S + toString() + ".mcerts"); |
|
|
|
|
unlink(mcdbPath.c_str()); |
|
|
|
|
} else { |
|
|
|
|
FILE *mcdb = fopen(mcdbPath.c_str(),"wb"); |
|
|
|
|
bool writeError = false; |
|
|
|
|
if (!mcdb) { |
|
|
|
|
@ -263,4 +254,26 @@ void Network::_CBhandleTapData(void *arg,const MAC &from,const MAC &to,unsigned
|
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void Network::_restoreState() |
|
|
|
|
{ |
|
|
|
|
std::string confPath(_r->homePath + ZT_PATH_SEPARATOR_S + "networks.d" + ZT_PATH_SEPARATOR_S + toString() + ".conf"); |
|
|
|
|
std::string confs; |
|
|
|
|
if (Utils::readFile(confPath.c_str(),confs)) { |
|
|
|
|
try { |
|
|
|
|
if (confs.length()) { |
|
|
|
|
Config conf(confs); |
|
|
|
|
if (conf.containsAllFields()) |
|
|
|
|
setConfiguration(conf); |
|
|
|
|
} |
|
|
|
|
} catch ( ... ) {} // ignore invalid config on disk, we will re-request
|
|
|
|
|
} else { |
|
|
|
|
// If the conf file isn't present, "touch" it so we'll remember
|
|
|
|
|
// the existence of this network.
|
|
|
|
|
FILE *tmp = fopen(confPath.c_str(),"w"); |
|
|
|
|
if (tmp) |
|
|
|
|
fclose(tmp); |
|
|
|
|
} |
|
|
|
|
// TODO: restore membership certs
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
} // namespace ZeroTier
|
|
|
|
|
|