diff options
-rw-r--r-- | node/EthernetTap.cpp | 33 | ||||
-rw-r--r-- | node/EthernetTap.hpp | 5 | ||||
-rw-r--r-- | node/Node.cpp | 3 | ||||
-rw-r--r-- | node/NodeConfig.hpp | 11 |
4 files changed, 39 insertions, 13 deletions
diff --git a/node/EthernetTap.cpp b/node/EthernetTap.cpp index b90c8708..62eee69c 100644 --- a/node/EthernetTap.cpp +++ b/node/EthernetTap.cpp @@ -164,6 +164,11 @@ EthernetTap::~EthernetTap() delete [] _putBuf; } +void EthernetTap::whack() +{ + // Linux requires nothing here +} + static bool ___removeIp(const char *_dev,std::set<InetAddress> &_ips,const InetAddress &ip) { long cpid; @@ -461,18 +466,7 @@ EthernetTap::EthernetTap(const RuntimeEnvironment *renv,const MAC &mac,unsigned } } - // OSX seems to require that IPv6 be turned on on tap devices - if ((cpid = (int)fork()) == 0) { - execl(ZT_MAC_IPCONFIG,ZT_MAC_IPCONFIG,"set",_dev,"AUTOMATIC-V6",(const char *)0); - exit(-1); - } else { - int exitcode = -1; - waitpid(cpid,&exitcode,0); - if (exitcode) { - ::close(_fd); - throw std::runtime_error("ipconfig failure enabling IPv6 link-local addressing"); - } - } + whack(); // turns on IPv6 on OSX _putBuf = new unsigned char[((mtu + 14) * 2)]; _getBuf = _putBuf + (mtu + 14); @@ -484,6 +478,21 @@ EthernetTap::~EthernetTap() delete [] _putBuf; } +void EthernetTap::whack() +{ + int cpid = fork(); + if (cpid == 0) { + execl(ZT_MAC_IPCONFIG,ZT_MAC_IPCONFIG,"set",_dev,"AUTOMATIC-V6",(const char *)0); + exit(-1); + } else { + int exitcode = -1; + waitpid(cpid,&exitcode,0); + if (exitcode) { + LOG("%s: ipconfig set AUTOMATIC-V6 failed",_dev); + } + } +} + // Helper function to actually remove IP from network device, execs ifconfig static bool ___removeIp(const char *_dev,const InetAddress &ip) { diff --git a/node/EthernetTap.hpp b/node/EthernetTap.hpp index 5c666907..280bd990 100644 --- a/node/EthernetTap.hpp +++ b/node/EthernetTap.hpp @@ -69,6 +69,11 @@ public: ~EthernetTap(); /** + * Perform OS dependent actions on network configuration change detection + */ + void whack(); + + /** * @return MAC address of this interface */ inline const MAC &mac() const throw() { return _mac; } diff --git a/node/Node.cpp b/node/Node.cpp index 85029e81..ab7794b8 100644 --- a/node/Node.cpp +++ b/node/Node.cpp @@ -273,11 +273,12 @@ Node::ReasonForTermination Node::run() lastNetworkFingerprintCheck = now; uint64_t fp = _r->sysEnv->getNetworkConfigurationFingerprint(); if (fp != networkConfigurationFingerprint) { - LOG("netconf fingerprint change: %.16llx != %.16llx, pinging all peers",networkConfigurationFingerprint,fp); + LOG("netconf fingerprint change: %.16llx != %.16llx, resyncing with network",networkConfigurationFingerprint,fp); networkConfigurationFingerprint = fp; pingAll = true; lastAutoconfigureCheck = 0; // check autoconf after network config change lastMulticastCheck = 0; // check multicast group membership after network config change + _r->nc->whackAllTaps(); // call whack() on all tap devices } } diff --git a/node/NodeConfig.hpp b/node/NodeConfig.hpp index a6ea6293..5caf18ab 100644 --- a/node/NodeConfig.hpp +++ b/node/NodeConfig.hpp @@ -79,6 +79,17 @@ public: } /** + * Call whack() on all networks' tap devices + */ + inline void whackAllTaps() + { + std::vector< SharedPtr<Network> > nwlist; + Mutex::Lock _l(_networks_m); + for(std::map< uint64_t,SharedPtr<Network> >::const_iterator n(_networks.begin());n!=_networks.end();++n) + n->second->tap().whack(); + } + + /** * @param nwid Network ID * @return True if this network exists */ |