mirror of
https://github.com/zerotier/ZeroTierOne.git
synced 2025-04-09 04:04:13 +00:00
Delete persistent tap device on Windows when we leave a network.
This commit is contained in:
parent
28665079a0
commit
afbbf61588
@ -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__ ////////////////////////////////////////////////////////
|
||||
|
@ -175,6 +175,11 @@ public:
|
||||
*/
|
||||
std::string deviceName() const;
|
||||
|
||||
/**
|
||||
* @return OS-internal persistent device ID or empty string if not applicable to this platform or not persistent
|
||||
*/
|
||||
std::string persistentId() const;
|
||||
|
||||
/**
|
||||
* Fill or modify a set to contain multicast groups for this device
|
||||
*
|
||||
@ -195,6 +200,19 @@ public:
|
||||
void threadMain()
|
||||
throw();
|
||||
|
||||
/**
|
||||
* Remove persistent tap device by device name
|
||||
*
|
||||
* This has no effect on platforms that do not have persistent taps.
|
||||
* On platforms like Windows with persistent devices the device is
|
||||
* uninstalled.
|
||||
*
|
||||
* @param _r Runtime environment
|
||||
* @param pdev Device name as returned by persistentId() while tap is running
|
||||
* @return True if a device was deleted
|
||||
*/
|
||||
static bool deletePersistentTapDevice(const RuntimeEnvironment *_r,const char *pid);
|
||||
|
||||
private:
|
||||
const MAC _mac;
|
||||
const unsigned int _mtu;
|
||||
@ -215,6 +233,8 @@ private:
|
||||
#endif
|
||||
|
||||
#ifdef __WINDOWS__
|
||||
void _syncIpsWithRegistry(const std::set<InetAddress> &haveIps);
|
||||
|
||||
HANDLE _tap;
|
||||
OVERLAPPED _tapOvlRead,_tapOvlWrite;
|
||||
char _tapReadBuf[ZT_IF_MTU + 32];
|
||||
|
@ -36,6 +36,7 @@
|
||||
#include "Switch.hpp"
|
||||
#include "Packet.hpp"
|
||||
#include "Buffer.hpp"
|
||||
#include "EthernetTap.hpp"
|
||||
|
||||
#define ZT_NETWORK_CERT_WRITE_BUF_SIZE 131072
|
||||
|
||||
@ -55,13 +56,14 @@ const char *Network::statusString(const Status s)
|
||||
|
||||
Network::~Network()
|
||||
{
|
||||
std::string devPersistentId(_tap->persistentId());
|
||||
delete _tap;
|
||||
|
||||
if (_destroyOnDelete) {
|
||||
Utils::rm(std::string(_r->homePath + ZT_PATH_SEPARATOR_S + "networks.d" + ZT_PATH_SEPARATOR_S + idString() + ".conf"));
|
||||
Utils::rm(std::string(_r->homePath + ZT_PATH_SEPARATOR_S + "networks.d" + ZT_PATH_SEPARATOR_S + idString() + ".mcerts"));
|
||||
|
||||
// TODO: on Windows we need to also remove the tap interface since they're
|
||||
// sticky on that platform.
|
||||
if (devPersistentId.length())
|
||||
EthernetTap::deletePersistentTapDevice(_r,devPersistentId.c_str());
|
||||
} else {
|
||||
// Causes flush of membership certs to disk
|
||||
clean();
|
||||
|
Loading…
x
Reference in New Issue
Block a user