mirror of
https://github.com/zerotier/ZeroTierOne.git
synced 2025-06-06 12:33:44 +02:00
Save enumeration of statically assigned IPs so they will always be reassigned on device "power cycle."
This commit is contained in:
parent
499b2dccad
commit
922d9657b9
3 changed files with 76 additions and 51 deletions
|
@ -23,7 +23,7 @@
|
||||||
<ROW Property="CTRLS" Value="2"/>
|
<ROW Property="CTRLS" Value="2"/>
|
||||||
<ROW Property="MSIFASTINSTALL" MultiBuildValue="DefaultBuild:2"/>
|
<ROW Property="MSIFASTINSTALL" MultiBuildValue="DefaultBuild:2"/>
|
||||||
<ROW Property="Manufacturer" Value="ZeroTier, Inc."/>
|
<ROW Property="Manufacturer" Value="ZeroTier, Inc."/>
|
||||||
<ROW Property="ProductCode" Value="1033:{631AEF67-1E3B-4A70-BAAE-81C576D2A1E4} " Type="16"/>
|
<ROW Property="ProductCode" Value="1033:{B29840D5-AC05-4F09-970F-34071C06912C} " Type="16"/>
|
||||||
<ROW Property="ProductLanguage" Value="1033"/>
|
<ROW Property="ProductLanguage" Value="1033"/>
|
||||||
<ROW Property="ProductName" Value="ZeroTier One"/>
|
<ROW Property="ProductName" Value="ZeroTier One"/>
|
||||||
<ROW Property="ProductVersion" Value="1.0.4" Type="32"/>
|
<ROW Property="ProductVersion" Value="1.0.4" Type="32"/>
|
||||||
|
|
|
@ -639,63 +639,28 @@ bool WindowsEthernetTap::enabled() const
|
||||||
|
|
||||||
bool WindowsEthernetTap::addIp(const InetAddress &ip)
|
bool WindowsEthernetTap::addIp(const InetAddress &ip)
|
||||||
{
|
{
|
||||||
if (!_initialized)
|
|
||||||
return false;
|
|
||||||
if (!ip.netmaskBits()) // sanity check... netmask of 0.0.0.0 is WUT?
|
if (!ip.netmaskBits()) // sanity check... netmask of 0.0.0.0 is WUT?
|
||||||
return false;
|
return false;
|
||||||
|
Mutex::Lock _l(_assignedIps_m);
|
||||||
std::vector<InetAddress> haveIps(ips());
|
if (std::find(_assignedIps.begin(),_assignedIps.end(),ip) != _assignedIps.end())
|
||||||
|
return true;
|
||||||
try {
|
_assignedIps.push_back(ip);
|
||||||
// Add IP to interface at the netlink level if not already assigned.
|
_syncIps();
|
||||||
if (!std::binary_search(haveIps.begin(),haveIps.end(),ip)) {
|
|
||||||
MIB_UNICASTIPADDRESS_ROW ipr;
|
|
||||||
|
|
||||||
InitializeUnicastIpAddressEntry(&ipr);
|
|
||||||
if (ip.isV4()) {
|
|
||||||
ipr.Address.Ipv4.sin_family = AF_INET;
|
|
||||||
ipr.Address.Ipv4.sin_addr.S_un.S_addr = *((const uint32_t *)ip.rawIpData());
|
|
||||||
ipr.OnLinkPrefixLength = ip.port();
|
|
||||||
if (ipr.OnLinkPrefixLength >= 32)
|
|
||||||
return false;
|
|
||||||
} else if (ip.isV6()) {
|
|
||||||
ipr.Address.Ipv6.sin6_family = AF_INET6;
|
|
||||||
memcpy(ipr.Address.Ipv6.sin6_addr.u.Byte,ip.rawIpData(),16);
|
|
||||||
ipr.OnLinkPrefixLength = ip.port();
|
|
||||||
if (ipr.OnLinkPrefixLength >= 128)
|
|
||||||
return false;
|
|
||||||
} else return false;
|
|
||||||
|
|
||||||
ipr.PrefixOrigin = IpPrefixOriginManual;
|
|
||||||
ipr.SuffixOrigin = IpSuffixOriginManual;
|
|
||||||
ipr.ValidLifetime = 0xffffffff;
|
|
||||||
ipr.PreferredLifetime = 0xffffffff;
|
|
||||||
|
|
||||||
ipr.InterfaceLuid = _deviceLuid;
|
|
||||||
ipr.InterfaceIndex = _getDeviceIndex();
|
|
||||||
|
|
||||||
if (CreateUnicastIpAddressEntry(&ipr) != NO_ERROR)
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<std::string> regIps(_getRegistryIPv4Value("IPAddress"));
|
|
||||||
if (std::find(regIps.begin(),regIps.end(),ip.toIpString()) == regIps.end()) {
|
|
||||||
std::vector<std::string> regSubnetMasks(_getRegistryIPv4Value("SubnetMask"));
|
|
||||||
regIps.push_back(ip.toIpString());
|
|
||||||
regSubnetMasks.push_back(ip.netmask().toIpString());
|
|
||||||
_setRegistryIPv4Value("IPAddress",regIps);
|
|
||||||
_setRegistryIPv4Value("SubnetMask",regSubnetMasks);
|
|
||||||
}
|
|
||||||
} catch ( ... ) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool WindowsEthernetTap::removeIp(const InetAddress &ip)
|
bool WindowsEthernetTap::removeIp(const InetAddress &ip)
|
||||||
{
|
{
|
||||||
|
{
|
||||||
|
Mutex::Lock _l(_assignedIps_m);
|
||||||
|
std::vector<InetAddress>::iterator aip(std::find(_assignedIps.begin(),_assignedIps.end(),ip));
|
||||||
|
if (aip != _assignedIps.end())
|
||||||
|
_assignedIps.erase(aip);
|
||||||
|
}
|
||||||
|
|
||||||
if (!_initialized)
|
if (!_initialized)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
MIB_UNICASTIPADDRESS_TABLE *ipt = (MIB_UNICASTIPADDRESS_TABLE *)0;
|
MIB_UNICASTIPADDRESS_TABLE *ipt = (MIB_UNICASTIPADDRESS_TABLE *)0;
|
||||||
if (GetUnicastIpAddressTable(AF_UNSPEC,&ipt) == NO_ERROR) {
|
if (GetUnicastIpAddressTable(AF_UNSPEC,&ipt) == NO_ERROR) {
|
||||||
|
@ -972,6 +937,12 @@ void WindowsEthernetTap::threadMain()
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// Assign or re-assign any should-be-assigned IPs in case we have restarted
|
||||||
|
{
|
||||||
|
Mutex::Lock _l(_assignedIps_m);
|
||||||
|
_syncIps();
|
||||||
|
}
|
||||||
|
|
||||||
memset(&tapOvlRead,0,sizeof(tapOvlRead));
|
memset(&tapOvlRead,0,sizeof(tapOvlRead));
|
||||||
tapOvlRead.hEvent = CreateEvent(NULL,TRUE,FALSE,NULL);
|
tapOvlRead.hEvent = CreateEvent(NULL,TRUE,FALSE,NULL);
|
||||||
memset(&tapOvlWrite,0,sizeof(tapOvlWrite));
|
memset(&tapOvlWrite,0,sizeof(tapOvlWrite));
|
||||||
|
@ -1135,4 +1106,55 @@ void WindowsEthernetTap::_setRegistryIPv4Value(const char *regKey,const std::vec
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void WindowsEthernetTap::_syncIps()
|
||||||
|
{
|
||||||
|
// assumes _assignedIps_m is locked
|
||||||
|
|
||||||
|
if (!_initialized)
|
||||||
|
return;
|
||||||
|
|
||||||
|
std::vector<InetAddress> haveIps(ips());
|
||||||
|
|
||||||
|
for(std::vector<InetAddress>::const_iterator aip(_assignedIps.begin());aip!=_assignedIps.end();++aip) {
|
||||||
|
if (std::find(haveIps.begin(),haveIps.end(),*aip) == haveIps.end()) {
|
||||||
|
MIB_UNICASTIPADDRESS_ROW ipr;
|
||||||
|
|
||||||
|
InitializeUnicastIpAddressEntry(&ipr);
|
||||||
|
if (aip->isV4()) {
|
||||||
|
ipr.Address.Ipv4.sin_family = AF_INET;
|
||||||
|
ipr.Address.Ipv4.sin_addr.S_un.S_addr = *((const uint32_t *)aip->rawIpData());
|
||||||
|
ipr.OnLinkPrefixLength = aip->netmaskBits();
|
||||||
|
if (ipr.OnLinkPrefixLength >= 32)
|
||||||
|
continue;
|
||||||
|
} else if (aip->isV6()) {
|
||||||
|
ipr.Address.Ipv6.sin6_family = AF_INET6;
|
||||||
|
memcpy(ipr.Address.Ipv6.sin6_addr.u.Byte,aip->rawIpData(),16);
|
||||||
|
ipr.OnLinkPrefixLength = aip->netmaskBits();
|
||||||
|
if (ipr.OnLinkPrefixLength >= 128)
|
||||||
|
continue;
|
||||||
|
} else continue;
|
||||||
|
|
||||||
|
ipr.PrefixOrigin = IpPrefixOriginManual;
|
||||||
|
ipr.SuffixOrigin = IpSuffixOriginManual;
|
||||||
|
ipr.ValidLifetime = 0xffffffff;
|
||||||
|
ipr.PreferredLifetime = 0xffffffff;
|
||||||
|
|
||||||
|
ipr.InterfaceLuid = _deviceLuid;
|
||||||
|
ipr.InterfaceIndex = _getDeviceIndex();
|
||||||
|
|
||||||
|
CreateUnicastIpAddressEntry(&ipr);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string ipStr(aip->toString());
|
||||||
|
std::vector<std::string> regIps(_getRegistryIPv4Value("IPAddress"));
|
||||||
|
if (std::find(regIps.begin(),regIps.end(),ipStr) == regIps.end()) {
|
||||||
|
std::vector<std::string> regSubnetMasks(_getRegistryIPv4Value("SubnetMask"));
|
||||||
|
regIps.push_back(ipStr);
|
||||||
|
regSubnetMasks.push_back(aip->netmask().toIpString());
|
||||||
|
_setRegistryIPv4Value("IPAddress",regIps);
|
||||||
|
_setRegistryIPv4Value("SubnetMask",regSubnetMasks);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace ZeroTier
|
} // namespace ZeroTier
|
||||||
|
|
|
@ -41,6 +41,7 @@
|
||||||
#include "../node/Mutex.hpp"
|
#include "../node/Mutex.hpp"
|
||||||
#include "../node/Array.hpp"
|
#include "../node/Array.hpp"
|
||||||
#include "../node/MulticastGroup.hpp"
|
#include "../node/MulticastGroup.hpp"
|
||||||
|
#include "../node/InetAddress.hpp"
|
||||||
#include "../osdep/Thread.hpp"
|
#include "../osdep/Thread.hpp"
|
||||||
|
|
||||||
namespace ZeroTier {
|
namespace ZeroTier {
|
||||||
|
@ -117,11 +118,10 @@ public:
|
||||||
throw();
|
throw();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool _disableTapDevice();
|
|
||||||
bool _enableTapDevice();
|
|
||||||
NET_IFINDEX _getDeviceIndex(); // throws on failure
|
NET_IFINDEX _getDeviceIndex(); // throws on failure
|
||||||
std::vector<std::string> _getRegistryIPv4Value(const char *regKey);
|
std::vector<std::string> _getRegistryIPv4Value(const char *regKey);
|
||||||
void _setRegistryIPv4Value(const char *regKey,const std::vector<std::string> &value);
|
void _setRegistryIPv4Value(const char *regKey,const std::vector<std::string> &value);
|
||||||
|
void _syncIps();
|
||||||
|
|
||||||
void (*_handler)(void *,uint64_t,const MAC &,const MAC &,unsigned int,unsigned int,const void *,unsigned int);
|
void (*_handler)(void *,uint64_t,const MAC &,const MAC &,unsigned int,unsigned int,const void *,unsigned int);
|
||||||
void *_arg;
|
void *_arg;
|
||||||
|
@ -137,6 +137,9 @@ private:
|
||||||
std::string _netCfgInstanceId;
|
std::string _netCfgInstanceId;
|
||||||
std::string _deviceInstanceId;
|
std::string _deviceInstanceId;
|
||||||
|
|
||||||
|
std::vector<InetAddress> _assignedIps; // IPs assigned with addIp
|
||||||
|
Mutex _assignedIps_m;
|
||||||
|
|
||||||
std::vector<MulticastGroup> _multicastGroups;
|
std::vector<MulticastGroup> _multicastGroups;
|
||||||
|
|
||||||
std::queue< std::pair< Array<char,ZT_IF_MTU + 32>,unsigned int > > _injectPending;
|
std::queue< std::pair< Array<char,ZT_IF_MTU + 32>,unsigned int > > _injectPending;
|
||||||
|
|
Loading…
Add table
Reference in a new issue