mirror of
https://github.com/zerotier/ZeroTierOne.git
synced 2025-06-06 20:43:44 +02:00
Route management now works on Windows, including default route override! 1.1.6 very close!
This commit is contained in:
parent
5b2d2efb45
commit
4f237687ce
4 changed files with 106 additions and 2 deletions
|
@ -284,6 +284,59 @@ static void _routeCmd(const char *op,const InetAddress &target,const InetAddress
|
||||||
#ifdef __WINDOWS__ // --------------------------------------------------------
|
#ifdef __WINDOWS__ // --------------------------------------------------------
|
||||||
#define ZT_ROUTING_SUPPORT_FOUND 1
|
#define ZT_ROUTING_SUPPORT_FOUND 1
|
||||||
|
|
||||||
|
static bool _winRoute(bool del,const NET_LUID &interfaceLuid,const NET_IFINDEX &interfaceIndex,const InetAddress &target,const InetAddress &via)
|
||||||
|
{
|
||||||
|
MIB_IPFORWARD_ROW2 rtrow;
|
||||||
|
InitializeIpForwardEntry(&rtrow);
|
||||||
|
rtrow.InterfaceLuid.Value = interfaceLuid.Value;
|
||||||
|
rtrow.InterfaceIndex = interfaceIndex;
|
||||||
|
if (target.ss_family == AF_INET) {
|
||||||
|
rtrow.DestinationPrefix.Prefix.si_family = AF_INET;
|
||||||
|
rtrow.DestinationPrefix.Prefix.Ipv4.sin_family = AF_INET;
|
||||||
|
rtrow.DestinationPrefix.Prefix.Ipv4.sin_addr.S_un.S_addr = reinterpret_cast<const struct sockaddr_in *>(&target)->sin_addr.S_un.S_addr;
|
||||||
|
if (via.ss_family == AF_INET) {
|
||||||
|
rtrow.NextHop.si_family = AF_INET;
|
||||||
|
rtrow.NextHop.Ipv4.sin_family = AF_INET;
|
||||||
|
rtrow.NextHop.Ipv4.sin_addr.S_un.S_addr = reinterpret_cast<const struct sockaddr_in *>(&via)->sin_addr.S_un.S_addr;
|
||||||
|
}
|
||||||
|
} else if (target.ss_family == AF_INET6) {
|
||||||
|
rtrow.DestinationPrefix.Prefix.si_family = AF_INET6;
|
||||||
|
rtrow.DestinationPrefix.Prefix.Ipv6.sin6_family = AF_INET6;
|
||||||
|
memcpy(rtrow.DestinationPrefix.Prefix.Ipv6.sin6_addr.u.Byte,reinterpret_cast<const struct sockaddr_in6 *>(&target)->sin6_addr.u.Byte,16);
|
||||||
|
if (via.ss_family == AF_INET6) {
|
||||||
|
rtrow.NextHop.si_family = AF_INET6;
|
||||||
|
rtrow.NextHop.Ipv6.sin6_family = AF_INET6;
|
||||||
|
memcpy(rtrow.NextHop.Ipv6.sin6_addr.u.Byte,reinterpret_cast<const struct sockaddr_in6 *>(&via)->sin6_addr.u.Byte,16);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
rtrow.DestinationPrefix.PrefixLength = target.netmaskBits();
|
||||||
|
rtrow.SitePrefixLength = rtrow.DestinationPrefix.PrefixLength;
|
||||||
|
rtrow.ValidLifetime = 0xffffffff;
|
||||||
|
rtrow.PreferredLifetime = 0xffffffff;
|
||||||
|
rtrow.Metric = -1;
|
||||||
|
rtrow.Protocol = MIB_IPPROTO_NETMGMT;
|
||||||
|
rtrow.Loopback = FALSE;
|
||||||
|
rtrow.AutoconfigureAddress = FALSE;
|
||||||
|
rtrow.Publish = FALSE;
|
||||||
|
rtrow.Immortal = FALSE;
|
||||||
|
rtrow.Age = 0;
|
||||||
|
rtrow.Origin = NlroManual;
|
||||||
|
if (del) {
|
||||||
|
return (DeleteIpForwardEntry2(&rtrow) == NO_ERROR);
|
||||||
|
} else {
|
||||||
|
NTSTATUS r = CreateIpForwardEntry2(&rtrow);
|
||||||
|
if (r == NO_ERROR) {
|
||||||
|
return true;
|
||||||
|
} else if (r == ERROR_OBJECT_ALREADY_EXISTS) {
|
||||||
|
return (SetIpForwardEntry2(&rtrow) == NO_ERROR);
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#endif // __WINDOWS__ --------------------------------------------------------
|
#endif // __WINDOWS__ --------------------------------------------------------
|
||||||
|
|
||||||
#ifndef ZT_ROUTING_SUPPORT_FOUND
|
#ifndef ZT_ROUTING_SUPPORT_FOUND
|
||||||
|
@ -305,6 +358,14 @@ static void _routeCmd(const char *op,const InetAddress &target,const InetAddress
|
||||||
|
|
||||||
bool ManagedRoute::sync()
|
bool ManagedRoute::sync()
|
||||||
{
|
{
|
||||||
|
#ifdef __WINDOWS__
|
||||||
|
NET_LUID interfaceLuid;
|
||||||
|
interfaceLuid.Value = (ULONG64)Utils::hexStrToU64(_device); // on Windows we use the hex LUID as the "interface name" for ManagedRoute
|
||||||
|
NET_IFINDEX interfaceIndex = -1;
|
||||||
|
if (ConvertInterfaceLuidToIndex(&interfaceLuid,&interfaceIndex) != NO_ERROR)
|
||||||
|
return false;
|
||||||
|
#endif
|
||||||
|
|
||||||
if ((_target.isDefaultRoute())||((_target.ss_family == AF_INET)&&(_target.netmaskBits() < 32))) {
|
if ((_target.isDefaultRoute())||((_target.ss_family == AF_INET)&&(_target.netmaskBits() < 32))) {
|
||||||
/* In ZeroTier we create two more specific routes for every one route. We
|
/* In ZeroTier we create two more specific routes for every one route. We
|
||||||
* do this for default routes and IPv4 routes other than /32s. If there
|
* do this for default routes and IPv4 routes other than /32s. If there
|
||||||
|
@ -399,6 +460,12 @@ bool ManagedRoute::sync()
|
||||||
|
|
||||||
#ifdef __WINDOWS__ // --------------------------------------------------------
|
#ifdef __WINDOWS__ // --------------------------------------------------------
|
||||||
|
|
||||||
|
if (!_applied) {
|
||||||
|
_winRoute(false,interfaceLuid,interfaceIndex,leftt,_via);
|
||||||
|
_winRoute(false,interfaceLuid,interfaceIndex,rightt,_via);
|
||||||
|
_applied = true;
|
||||||
|
}
|
||||||
|
|
||||||
#endif // __WINDOWS__ --------------------------------------------------------
|
#endif // __WINDOWS__ --------------------------------------------------------
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
@ -420,10 +487,20 @@ bool ManagedRoute::sync()
|
||||||
|
|
||||||
#ifdef __LINUX__ // ----------------------------------------------------------
|
#ifdef __LINUX__ // ----------------------------------------------------------
|
||||||
|
|
||||||
|
if (!_applied) {
|
||||||
|
_routeCmd("replace",_target,_via,(_via) ? _device : (const char *)0);
|
||||||
|
_applied = true;
|
||||||
|
}
|
||||||
|
|
||||||
#endif // __LINUX__ ----------------------------------------------------------
|
#endif // __LINUX__ ----------------------------------------------------------
|
||||||
|
|
||||||
#ifdef __WINDOWS__ // --------------------------------------------------------
|
#ifdef __WINDOWS__ // --------------------------------------------------------
|
||||||
|
|
||||||
|
if (!_applied) {
|
||||||
|
_winRoute(false,interfaceLuid,interfaceIndex,_target,_via);
|
||||||
|
_applied = true;
|
||||||
|
}
|
||||||
|
|
||||||
#endif // __WINDOWS__ --------------------------------------------------------
|
#endif // __WINDOWS__ --------------------------------------------------------
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -433,6 +510,14 @@ bool ManagedRoute::sync()
|
||||||
|
|
||||||
void ManagedRoute::remove()
|
void ManagedRoute::remove()
|
||||||
{
|
{
|
||||||
|
#ifdef __WINDOWS__
|
||||||
|
NET_LUID interfaceLuid;
|
||||||
|
interfaceLuid.Value = (ULONG64)Utils::hexStrToU64(_device); // on Windows we use the hex LUID as the "interface name" for ManagedRoute
|
||||||
|
NET_IFINDEX interfaceIndex = -1;
|
||||||
|
if (ConvertInterfaceLuidToIndex(&interfaceLuid,&interfaceIndex) != NO_ERROR)
|
||||||
|
return;
|
||||||
|
#endif
|
||||||
|
|
||||||
if (_applied) {
|
if (_applied) {
|
||||||
if ((_target.isDefaultRoute())||((_target.ss_family == AF_INET)&&(_target.netmaskBits() < 32))) {
|
if ((_target.isDefaultRoute())||((_target.ss_family == AF_INET)&&(_target.netmaskBits() < 32))) {
|
||||||
InetAddress leftt,rightt;
|
InetAddress leftt,rightt;
|
||||||
|
@ -463,6 +548,9 @@ void ManagedRoute::remove()
|
||||||
|
|
||||||
#ifdef __WINDOWS__ // --------------------------------------------------------
|
#ifdef __WINDOWS__ // --------------------------------------------------------
|
||||||
|
|
||||||
|
_winRoute(true,interfaceLuid,interfaceIndex,leftt,_via);
|
||||||
|
_winRoute(true,interfaceLuid,interfaceIndex,rightt,_via);
|
||||||
|
|
||||||
#endif // __WINDOWS__ --------------------------------------------------------
|
#endif // __WINDOWS__ --------------------------------------------------------
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
@ -485,6 +573,8 @@ void ManagedRoute::remove()
|
||||||
|
|
||||||
#ifdef __WINDOWS__ // --------------------------------------------------------
|
#ifdef __WINDOWS__ // --------------------------------------------------------
|
||||||
|
|
||||||
|
_winRoute(true,interfaceLuid,interfaceIndex,_target,_via);
|
||||||
|
|
||||||
#endif // __WINDOWS__ --------------------------------------------------------
|
#endif // __WINDOWS__ --------------------------------------------------------
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -861,6 +861,14 @@ void WindowsEthernetTap::scanMulticastGroups(std::vector<MulticastGroup> &added,
|
||||||
_multicastGroups.swap(newGroups);
|
_multicastGroups.swap(newGroups);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NET_IFINDEX WindowsEthernetTap::interfaceIndex() const
|
||||||
|
{
|
||||||
|
NET_IFINDEX idx = -1;
|
||||||
|
if (ConvertInterfaceLuidToIndex(&_deviceLuid,&idx) == NO_ERROR)
|
||||||
|
return idx;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
void WindowsEthernetTap::threadMain()
|
void WindowsEthernetTap::threadMain()
|
||||||
throw()
|
throw()
|
||||||
{
|
{
|
||||||
|
|
|
@ -105,6 +105,7 @@ public:
|
||||||
inline const NET_LUID &luid() const { return _deviceLuid; }
|
inline const NET_LUID &luid() const { return _deviceLuid; }
|
||||||
inline const GUID &guid() const { return _deviceGuid; }
|
inline const GUID &guid() const { return _deviceGuid; }
|
||||||
inline const std::string &instanceId() const { return _deviceInstanceId; }
|
inline const std::string &instanceId() const { return _deviceInstanceId; }
|
||||||
|
NET_IFINDEX interfaceIndex() const;
|
||||||
|
|
||||||
void threadMain()
|
void threadMain()
|
||||||
throw();
|
throw();
|
||||||
|
|
|
@ -1051,7 +1051,12 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
if (syncRoutes) {
|
if (syncRoutes) {
|
||||||
const std::string tapdev(n.tap->deviceName());
|
char tapdev[64];
|
||||||
|
#ifdef __WINDOWS__
|
||||||
|
Utils::snprintf(tapdev,sizeof(tapdev),"%.16llx",(unsigned long long)n.tap->luid().Value);
|
||||||
|
#else
|
||||||
|
Utils::scopy(tapdev,sizeof(tapdev),n.tap->deviceName().c_str());
|
||||||
|
#endif
|
||||||
|
|
||||||
// Nuke applied routes that are no longer in n.config.routes[] and/or are not allowed
|
// Nuke applied routes that are no longer in n.config.routes[] and/or are not allowed
|
||||||
for(std::list<ManagedRoute>::iterator mr(n.managedRoutes.begin());mr!=n.managedRoutes.end();) {
|
for(std::list<ManagedRoute>::iterator mr(n.managedRoutes.begin());mr!=n.managedRoutes.end();) {
|
||||||
|
@ -1106,7 +1111,7 @@ public:
|
||||||
|
|
||||||
// Add and apply new routes
|
// Add and apply new routes
|
||||||
n.managedRoutes.push_back(ManagedRoute());
|
n.managedRoutes.push_back(ManagedRoute());
|
||||||
if (!n.managedRoutes.back().set(*target,*via,tapdev.c_str()))
|
if (!n.managedRoutes.back().set(*target,*via,tapdev))
|
||||||
n.managedRoutes.pop_back();
|
n.managedRoutes.pop_back();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue