summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--node/EthernetTap.cpp33
-rw-r--r--node/EthernetTap.hpp5
-rw-r--r--node/Node.cpp3
-rw-r--r--node/NodeConfig.hpp11
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
*/