summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAdam Ierymenko <adam.ierymenko@zerotier.com>2017-04-21 13:26:02 -0700
committerAdam Ierymenko <adam.ierymenko@zerotier.com>2017-04-21 13:26:02 -0700
commite700165eba892f58a00d21a19a802adf725e14a7 (patch)
treef1f5c83ae37e693f7620f747d59a95fbc4290a48
parent8542ee59db85e4cb86c1b6fc9ac2330f24129de4 (diff)
downloadinfinitytier-e700165eba892f58a00d21a19a802adf725e14a7.tar.gz
infinitytier-e700165eba892f58a00d21a19a802adf725e14a7.zip
GitHub issue #465 - Windows route amnesia
-rw-r--r--osdep/ManagedRoute.cpp36
1 files changed, 34 insertions, 2 deletions
diff --git a/osdep/ManagedRoute.cpp b/osdep/ManagedRoute.cpp
index f24b6b34..3a020d61 100644
--- a/osdep/ManagedRoute.cpp
+++ b/osdep/ManagedRoute.cpp
@@ -346,6 +346,38 @@ static bool _winRoute(bool del,const NET_LUID &interfaceLuid,const NET_IFINDEX &
}
}
+static bool _winHasRoute(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;
+ return (GetIpForwardEntry2(&rtrow) == NO_ERROR);
+}
+
#endif // __WINDOWS__ --------------------------------------------------------
#ifndef ZT_ROUTING_SUPPORT_FOUND
@@ -463,11 +495,11 @@ bool ManagedRoute::sync()
#ifdef __WINDOWS__ // --------------------------------------------------------
- if (!_applied.count(leftt)) {
+ if ( (!_applied.count(leftt)) || (!_winHasRoute(interfaceLuid,interfaceIndex,leftt,_via)) ) {
_applied[leftt] = false; // boolean unused
_winRoute(false,interfaceLuid,interfaceIndex,leftt,_via);
}
- if ((rightt)&&(!_applied.count(rightt))) {
+ if ( (rightt) && ( (!_applied.count(rightt)) || (!_winHasRoute(interfaceLuid,interfaceIndex,rightt,_via)) ) ) {
_applied[rightt] = false; // boolean unused
_winRoute(false,interfaceLuid,interfaceIndex,rightt,_via);
}