summaryrefslogtreecommitdiff
path: root/node/EthernetTap.cpp
diff options
context:
space:
mode:
authorAdam Ierymenko <adam.ierymenko@zerotier.com>2014-01-26 22:47:08 -0800
committerAdam Ierymenko <adam.ierymenko@zerotier.com>2014-01-26 22:47:08 -0800
commitafbbf615882b75171e05ca12e64697ec322d8ff7 (patch)
tree4bad1a8c88d711d6755a68d1d366409776b8af7c /node/EthernetTap.cpp
parent28665079a01d26345e1289f2eaaca3307f83ac29 (diff)
downloadinfinitytier-afbbf615882b75171e05ca12e64697ec322d8ff7.tar.gz
infinitytier-afbbf615882b75171e05ca12e64697ec322d8ff7.zip
Delete persistent tap device on Windows when we leave a network.
Diffstat (limited to 'node/EthernetTap.cpp')
-rw-r--r--node/EthernetTap.cpp101
1 files changed, 76 insertions, 25 deletions
diff --git a/node/EthernetTap.cpp b/node/EthernetTap.cpp
index fce30b61..c6decba8 100644
--- a/node/EthernetTap.cpp
+++ b/node/EthernetTap.cpp
@@ -570,6 +570,11 @@ std::string EthernetTap::deviceName() const
return std::string(_dev);
}
+std::string EthernetTap::persistentId() const
+{
+ return std::string();
+}
+
#ifdef __LINUX__
bool EthernetTap::updateMulticastGroups(std::set<MulticastGroup> &groups)
{
@@ -901,6 +906,11 @@ void EthernetTap::threadMain()
}
}
+bool EthernetTap::deletePersistentTapDevice(const RuntimeEnvironment *_r,const char *pid)
+{
+ return false;
+}
+
} // namespace ZeroTier
#endif // __UNIX_LIKE__ //////////////////////////////////////////////////////
@@ -1278,31 +1288,9 @@ bool EthernetTap::addIP(const InetAddress &ip)
}
}
- // Update registry to contain all non-link-local IPs for this interface
- std::string regMultiIps,regMultiNetmasks;
- for(std::set<InetAddress>::const_iterator i(haveIps.begin());i!=haveIps.end();++i) {
- if (!i->isLinkLocal()) {
- regMultiIps.append(i->toIpString());
- regMultiIps.push_back((char)0);
- regMultiNetmasks.append(i->netmask().toIpString());
- regMultiNetmasks.push_back((char)0);
- }
- }
- HKEY tcpIpInterfaces;
- if (RegOpenKeyExA(HKEY_LOCAL_MACHINE,"SYSTEM\\CurrentControlSet\\services\\Tcpip\\Parameters\\Interfaces",0,KEY_READ|KEY_WRITE,&tcpIpInterfaces) == ERROR_SUCCESS) {
- if (regMultiIps.length()) {
- regMultiIps.push_back((char)0);
- regMultiNetmasks.push_back((char)0);
- RegSetKeyValueA(tcpIpInterfaces,_myDeviceInstanceId.c_str(),"IPAddress",REG_MULTI_SZ,regMultiIps.data(),(DWORD)regMultiIps.length());
- RegSetKeyValueA(tcpIpInterfaces,_myDeviceInstanceId.c_str(),"SubnetMask",REG_MULTI_SZ,regMultiNetmasks.data(),(DWORD)regMultiNetmasks.length());
- } else {
- RegDeleteKeyValueA(tcpIpInterfaces,_myDeviceInstanceId.c_str(),"IPAddress");
- RegDeleteKeyValueA(tcpIpInterfaces,_myDeviceInstanceId.c_str(),"SubnetMask");
- }
- }
- RegCloseKey(tcpIpInterfaces);
+ _syncIpsWithRegistry(haveIps);
} catch (std::exception &exc) {
- LOG("unexpected exception adding IP address to %s: %s",ip.toString().c_str(),deviceName().c_str(),exc.what());
+ LOG("unexpected exception adding IP address %s to %s: %s",ip.toString().c_str(),deviceName().c_str(),exc.what());
} catch ( ... ) {
LOG("unexpected exception adding IP address %s to %s: unknown exception",ip.toString().c_str(),deviceName().c_str());
}
@@ -1331,13 +1319,18 @@ bool EthernetTap::removeIP(const InetAddress &ip)
if (addr == ip) {
DeleteUnicastIpAddressEntry(&(ipt->Table[i]));
FreeMibTable(ipt);
+ _syncIpsWithRegistry(ips());
return true;
}
}
}
FreeMibTable((PVOID)ipt);
}
- } catch ( ... ) {}
+ } catch (std::exception &exc) {
+ LOG("unexpected exception removing IP address %s from %s: %s",ip.toString().c_str(),deviceName().c_str(),exc.what());
+ } catch ( ... ) {
+ LOG("unexpected exception removing IP address %s from %s: unknown exception",ip.toString().c_str(),deviceName().c_str());
+ }
return false;
}
@@ -1398,6 +1391,11 @@ std::string EthernetTap::deviceName() const
return _myDeviceInstanceId;
}
+std::string EthernetTap::persistentId() const
+{
+ return _myDeviceInstanceIdPath;
+}
+
bool EthernetTap::updateMulticastGroups(std::set<MulticastGroup> &groups)
{
std::set<MulticastGroup> newGroups;
@@ -1501,6 +1499,59 @@ void EthernetTap::threadMain()
CancelIo(_tap);
}
+bool EthernetTap::deletePersistentTapDevice(const RuntimeEnvironment *_r,const char *pid)
+{
+#ifdef _WIN64
+ BOOL is64Bit = TRUE;
+ const char *devcon = "\\devcon_x64.exe";
+#else
+ BOOL is64Bit = FALSE;
+ IsWow64Process(GetCurrentProcess(),&is64Bit);
+ const char *devcon = ((is64Bit == TRUE) ? "\\devcon_x64.exe" : "\\devcon_x86.exe");
+#endif
+
+ STARTUPINFOA startupInfo;
+ startupInfo.cb = sizeof(startupInfo);
+ PROCESS_INFORMATION processInfo;
+ memset(&startupInfo,0,sizeof(STARTUPINFOA));
+ memset(&processInfo,0,sizeof(PROCESS_INFORMATION));
+ if (CreateProcessA(NULL,(LPSTR)(std::string("\"") + _r->homePath + devcon + "\" remove @" + pid).c_str(),NULL,NULL,FALSE,0,NULL,NULL,&startupInfo,&processInfo)) {
+ WaitForSingleObject(processInfo.hProcess,INFINITE);
+ CloseHandle(processInfo.hProcess);
+ CloseHandle(processInfo.hThread);
+ return true;
+ }
+
+ return false;
+}
+
+void EthernetTap::_syncIpsWithRegistry(const std::set<InetAddress> &haveIps)
+{
+ // Update registry to contain all non-link-local IPs for this interface
+ std::string regMultiIps,regMultiNetmasks;
+ for(std::set<InetAddress>::const_iterator i(haveIps.begin());i!=haveIps.end();++i) {
+ if (!i->isLinkLocal()) {
+ regMultiIps.append(i->toIpString());
+ regMultiIps.push_back((char)0);
+ regMultiNetmasks.append(i->netmask().toIpString());
+ regMultiNetmasks.push_back((char)0);
+ }
+ }
+ HKEY tcpIpInterfaces;
+ if (RegOpenKeyExA(HKEY_LOCAL_MACHINE,"SYSTEM\\CurrentControlSet\\services\\Tcpip\\Parameters\\Interfaces",0,KEY_READ|KEY_WRITE,&tcpIpInterfaces) == ERROR_SUCCESS) {
+ if (regMultiIps.length()) {
+ regMultiIps.push_back((char)0);
+ regMultiNetmasks.push_back((char)0);
+ RegSetKeyValueA(tcpIpInterfaces,_myDeviceInstanceId.c_str(),"IPAddress",REG_MULTI_SZ,regMultiIps.data(),(DWORD)regMultiIps.length());
+ RegSetKeyValueA(tcpIpInterfaces,_myDeviceInstanceId.c_str(),"SubnetMask",REG_MULTI_SZ,regMultiNetmasks.data(),(DWORD)regMultiNetmasks.length());
+ } else {
+ RegDeleteKeyValueA(tcpIpInterfaces,_myDeviceInstanceId.c_str(),"IPAddress");
+ RegDeleteKeyValueA(tcpIpInterfaces,_myDeviceInstanceId.c_str(),"SubnetMask");
+ }
+ }
+ RegCloseKey(tcpIpInterfaces);
+}
+
} // namespace ZeroTier
#endif // __WINDOWS__ ////////////////////////////////////////////////////////