Fix for issue #6: OSX tap device forgets it has IPv6

This commit is contained in:
Adam Ierymenko 2013-07-08 20:36:33 -04:00
parent 366f556e5b
commit 6eb77da094
4 changed files with 39 additions and 13 deletions

View File

@ -164,6 +164,11 @@ EthernetTap::~EthernetTap()
delete [] _putBuf; delete [] _putBuf;
} }
void EthernetTap::whack()
{
// Linux requires nothing here
}
static bool ___removeIp(const char *_dev,std::set<InetAddress> &_ips,const InetAddress &ip) static bool ___removeIp(const char *_dev,std::set<InetAddress> &_ips,const InetAddress &ip)
{ {
long cpid; 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 whack(); // turns on IPv6 on OSX
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");
}
}
_putBuf = new unsigned char[((mtu + 14) * 2)]; _putBuf = new unsigned char[((mtu + 14) * 2)];
_getBuf = _putBuf + (mtu + 14); _getBuf = _putBuf + (mtu + 14);
@ -484,6 +478,21 @@ EthernetTap::~EthernetTap()
delete [] _putBuf; 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 // Helper function to actually remove IP from network device, execs ifconfig
static bool ___removeIp(const char *_dev,const InetAddress &ip) static bool ___removeIp(const char *_dev,const InetAddress &ip)
{ {

View File

@ -68,6 +68,11 @@ public:
~EthernetTap(); ~EthernetTap();
/**
* Perform OS dependent actions on network configuration change detection
*/
void whack();
/** /**
* @return MAC address of this interface * @return MAC address of this interface
*/ */

View File

@ -273,11 +273,12 @@ Node::ReasonForTermination Node::run()
lastNetworkFingerprintCheck = now; lastNetworkFingerprintCheck = now;
uint64_t fp = _r->sysEnv->getNetworkConfigurationFingerprint(); uint64_t fp = _r->sysEnv->getNetworkConfigurationFingerprint();
if (fp != networkConfigurationFingerprint) { 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; networkConfigurationFingerprint = fp;
pingAll = true; pingAll = true;
lastAutoconfigureCheck = 0; // check autoconf after network config change lastAutoconfigureCheck = 0; // check autoconf after network config change
lastMulticastCheck = 0; // check multicast group membership after network config change lastMulticastCheck = 0; // check multicast group membership after network config change
_r->nc->whackAllTaps(); // call whack() on all tap devices
} }
} }

View File

@ -78,6 +78,17 @@ public:
return nwlist; return nwlist;
} }
/**
* 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 * @param nwid Network ID
* @return True if this network exists * @return True if this network exists