diff options
author | Adam Ierymenko <adam.ierymenko@zerotier.com> | 2015-07-30 14:10:32 -0700 |
---|---|---|
committer | Adam Ierymenko <adam.ierymenko@zerotier.com> | 2015-07-30 14:10:32 -0700 |
commit | 922d9657b9d90df5cdf313b3ebe4d0280d0ff47a (patch) | |
tree | 62605985eae93df8bb5d1053f6b2820a7460ee08 /osdep | |
parent | 499b2dccad985f93003c53d8311b34d10a4b1ea3 (diff) | |
download | infinitytier-922d9657b9d90df5cdf313b3ebe4d0280d0ff47a.tar.gz infinitytier-922d9657b9d90df5cdf313b3ebe4d0280d0ff47a.zip |
Save enumeration of statically assigned IPs so they will always be reassigned on device "power cycle."
Diffstat (limited to 'osdep')
-rw-r--r-- | osdep/WindowsEthernetTap.cpp | 118 | ||||
-rw-r--r-- | osdep/WindowsEthernetTap.hpp | 7 |
2 files changed, 75 insertions, 50 deletions
diff --git a/osdep/WindowsEthernetTap.cpp b/osdep/WindowsEthernetTap.cpp index 426dd3cb..2c338516 100644 --- a/osdep/WindowsEthernetTap.cpp +++ b/osdep/WindowsEthernetTap.cpp @@ -639,63 +639,28 @@ bool WindowsEthernetTap::enabled() const bool WindowsEthernetTap::addIp(const InetAddress &ip) { - if (!_initialized) - return false; if (!ip.netmaskBits()) // sanity check... netmask of 0.0.0.0 is WUT? return false; - - std::vector<InetAddress> haveIps(ips()); - - try { - // Add IP to interface at the netlink level if not already assigned. - 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; - } + Mutex::Lock _l(_assignedIps_m); + if (std::find(_assignedIps.begin(),_assignedIps.end(),ip) != _assignedIps.end()) + return true; + _assignedIps.push_back(ip); + _syncIps(); return true; } 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) return false; + try { MIB_UNICASTIPADDRESS_TABLE *ipt = (MIB_UNICASTIPADDRESS_TABLE *)0; if (GetUnicastIpAddressTable(AF_UNSPEC,&ipt) == NO_ERROR) { @@ -972,6 +937,12 @@ void WindowsEthernetTap::threadMain() } #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)); tapOvlRead.hEvent = CreateEvent(NULL,TRUE,FALSE,NULL); 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 diff --git a/osdep/WindowsEthernetTap.hpp b/osdep/WindowsEthernetTap.hpp index 97113d97..dd60c0bf 100644 --- a/osdep/WindowsEthernetTap.hpp +++ b/osdep/WindowsEthernetTap.hpp @@ -41,6 +41,7 @@ #include "../node/Mutex.hpp" #include "../node/Array.hpp" #include "../node/MulticastGroup.hpp" +#include "../node/InetAddress.hpp" #include "../osdep/Thread.hpp" namespace ZeroTier { @@ -117,11 +118,10 @@ public: throw(); private: - bool _disableTapDevice(); - bool _enableTapDevice(); NET_IFINDEX _getDeviceIndex(); // throws on failure std::vector<std::string> _getRegistryIPv4Value(const char *regKey); 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 *_arg; @@ -137,6 +137,9 @@ private: std::string _netCfgInstanceId; std::string _deviceInstanceId; + std::vector<InetAddress> _assignedIps; // IPs assigned with addIp + Mutex _assignedIps_m; + std::vector<MulticastGroup> _multicastGroups; std::queue< std::pair< Array<char,ZT_IF_MTU + 32>,unsigned int > > _injectPending; |