summaryrefslogtreecommitdiffhomepage
path: root/windows
diff options
context:
space:
mode:
authorDavid Lönnhager <david.l@mullvad.net>2022-03-16 09:35:37 +0100
committerDavid Lönnhager <david.l@mullvad.net>2022-03-18 10:27:41 +0100
commit302bf767db78b7cb1e76ea64414e33daa52e809f (patch)
treef005b12db400d5da2ad7d331012e9fbd291a0e46 /windows
parent7f0ce804744d3e76afee25f06186764ddc6fe524 (diff)
downloadmullvadvpn-302bf767db78b7cb1e76ea64414e33daa52e809f.tar.xz
mullvadvpn-302bf767db78b7cb1e76ea64414e33daa52e809f.zip
Forward default route interface changes to the daemon, including
changes to its IP addresses
Diffstat (limited to 'windows')
-rw-r--r--windows/winnet/src/winnet/routing/defaultroutemonitor.cpp26
-rw-r--r--windows/winnet/src/winnet/routing/defaultroutemonitor.h6
-rw-r--r--windows/winnet/src/winnet/winnet.cpp14
-rw-r--r--windows/winnet/src/winnet/winnet.h6
4 files changed, 47 insertions, 5 deletions
diff --git a/windows/winnet/src/winnet/routing/defaultroutemonitor.cpp b/windows/winnet/src/winnet/routing/defaultroutemonitor.cpp
index 523c2d7ba0..56521ec9d8 100644
--- a/windows/winnet/src/winnet/routing/defaultroutemonitor.cpp
+++ b/windows/winnet/src/winnet/routing/defaultroutemonitor.cpp
@@ -47,6 +47,16 @@ DefaultRouteMonitor::DefaultRouteMonitor
THROW_WINDOWS_ERROR(status, "Register for network interface change notifications");
}
+ status = NotifyUnicastIpAddressChange(AF_UNSPEC, AddressChangeCallback, this,
+ FALSE, &m_addressNotificationHandle);
+
+ if (NO_ERROR != status)
+ {
+ CancelMibChangeNotify2(m_routeNotificationHandle);
+ CancelMibChangeNotify2(m_interfaceNotificationHandle);
+ THROW_WINDOWS_ERROR(status, "Register for unicast address change notifications");
+ }
+
try
{
m_bestRoute = GetBestDefaultRoute(m_family);
@@ -62,6 +72,7 @@ DefaultRouteMonitor::~DefaultRouteMonitor()
// Cancel notifications to stop triggering the BurstGuard.
//
+ CancelMibChangeNotify2(m_addressNotificationHandle);
CancelMibChangeNotify2(m_interfaceNotificationHandle);
CancelMibChangeNotify2(m_routeNotificationHandle);
@@ -105,6 +116,17 @@ void NETIOAPI_API_ DefaultRouteMonitor::InterfaceChangeCallback
reinterpret_cast<DefaultRouteMonitor *>(context)->m_evaluateRoutesGuard->trigger();
}
+//static
+void NETIOAPI_API_ DefaultRouteMonitor::AddressChangeCallback
+(
+ void* context,
+ MIB_UNICASTIPADDRESS_ROW*,
+ MIB_NOTIFICATION_TYPE
+)
+{
+ reinterpret_cast<DefaultRouteMonitor*>(context)->m_evaluateRoutesGuard->trigger();
+}
+
void DefaultRouteMonitor::evaluateRoutes()
{
std::scoped_lock<std::mutex> lock(m_evaluationLock);
@@ -173,6 +195,10 @@ void DefaultRouteMonitor::evaluateRoutesInner()
m_bestRoute = currentBestRoute;
m_callback(EventType::Updated, m_bestRoute);
}
+ else
+ {
+ m_callback(EventType::UpdatedDetails, m_bestRoute);
+ }
}
}
diff --git a/windows/winnet/src/winnet/routing/defaultroutemonitor.h b/windows/winnet/src/winnet/routing/defaultroutemonitor.h
index 5575685a82..24be69a835 100644
--- a/windows/winnet/src/winnet/routing/defaultroutemonitor.h
+++ b/windows/winnet/src/winnet/routing/defaultroutemonitor.h
@@ -22,6 +22,10 @@ public:
// The best default route changed.
Updated,
+ // Interface details changed; the associated interface and
+ // gateway did not.
+ UpdatedDetails,
+
// No default routes exist.
Removed,
};
@@ -56,11 +60,13 @@ private:
HANDLE m_routeNotificationHandle;
HANDLE m_interfaceNotificationHandle;
+ HANDLE m_addressNotificationHandle;
std::mutex m_evaluationLock;
static void NETIOAPI_API_ RouteChangeCallback(void *context, MIB_IPFORWARD_ROW2 *row, MIB_NOTIFICATION_TYPE notificationType);
static void NETIOAPI_API_ InterfaceChangeCallback(void *context, MIB_IPINTERFACE_ROW *row, MIB_NOTIFICATION_TYPE notificationType);
+ static void NETIOAPI_API_ AddressChangeCallback(void *context, MIB_UNICASTIPADDRESS_ROW *row, MIB_NOTIFICATION_TYPE notificationType);
void evaluateRoutes();
void evaluateRoutesInner();
diff --git a/windows/winnet/src/winnet/winnet.cpp b/windows/winnet/src/winnet/winnet.cpp
index c1b864612e..2e35830c96 100644
--- a/windows/winnet/src/winnet/winnet.cpp
+++ b/windows/winnet/src/winnet/winnet.cpp
@@ -395,6 +395,7 @@ WinNet_RegisterDefaultRouteChangedCallback(
static const std::pair<from_t, to_t> eventTypeMap[] =
{
{ from_t::Updated, WINNET_DEFAULT_ROUTE_CHANGED_EVENT_TYPE_UPDATED },
+ { from_t::UpdatedDetails, WINNET_DEFAULT_ROUTE_CHANGED_EVENT_TYPE_UPDATED_DETAILS },
{ from_t::Removed, WINNET_DEFAULT_ROUTE_CHANGED_EVENT_TYPE_REMOVED }
};
@@ -418,11 +419,16 @@ WinNet_RegisterDefaultRouteChangedCallback(
// Determine which LUID and gateway to forward.
//
- if (RouteManager::DefaultRouteChangedEventType::Updated == eventType)
+ switch (eventType)
{
- const auto ips = winnet::ConvertNativeAddresses(&route.value().gateway, 1);
- defaultRoute.gateway = ips[0];
- defaultRoute.interfaceLuid = route.value().iface.Value;
+ case RouteManager::DefaultRouteChangedEventType::Updated:
+ case RouteManager::DefaultRouteChangedEventType::UpdatedDetails:
+ {
+ const auto ips = winnet::ConvertNativeAddresses(&route.value().gateway, 1);
+ defaultRoute.gateway = ips[0];
+ defaultRoute.interfaceLuid = route.value().iface.Value;
+ break;
+ }
}
//
diff --git a/windows/winnet/src/winnet/winnet.h b/windows/winnet/src/winnet/winnet.h
index 3f2f80a5e5..f6f8d56074 100644
--- a/windows/winnet/src/winnet/winnet.h
+++ b/windows/winnet/src/winnet/winnet.h
@@ -168,8 +168,12 @@ enum WINNET_DEFAULT_ROUTE_CHANGED_EVENT_TYPE
// Best default route changed.
WINNET_DEFAULT_ROUTE_CHANGED_EVENT_TYPE_UPDATED = 0,
+ // The route (gateway or interface) did not change, but
+ // interface details may have changed.
+ WINNET_DEFAULT_ROUTE_CHANGED_EVENT_TYPE_UPDATED_DETAILS = 1,
+
// No default routes exist.
- WINNET_DEFAULT_ROUTE_CHANGED_EVENT_TYPE_REMOVED = 1,
+ WINNET_DEFAULT_ROUTE_CHANGED_EVENT_TYPE_REMOVED = 2,
};
typedef void (WINNET_API *WinNetDefaultRouteChangedCallback)