Skip to content

Commit ead0769

Browse files
oskirbybakulf
authored andcommitted
Windows: Ignore hidden interfaces for exclusion routes. (#3282)
1 parent bbc3978 commit ead0769

File tree

1 file changed

+28
-3
lines changed

1 file changed

+28
-3
lines changed

src/platforms/windows/daemon/windowsroutemonitor.cpp

Lines changed: 28 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -70,11 +70,13 @@ WindowsRouteMonitor::~WindowsRouteMonitor() {
7070

7171
void WindowsRouteMonitor::updateExclusionRoute(MIB_IPFORWARD_ROW2* data,
7272
void* ptable) {
73-
PMIB_IPFORWARD_TABLE2 table = (PMIB_IPFORWARD_TABLE2)ptable;
74-
SOCKADDR_INET nexthop;
73+
PMIB_IPFORWARD_TABLE2 table = reinterpret_cast<PMIB_IPFORWARD_TABLE2>(ptable);
74+
SOCKADDR_INET nexthop = {0};
7575
quint64 bestLuid = 0;
7676
int bestMatch = -1;
77+
ULONG bestMetric = ULONG_MAX;
7778

79+
nexthop.si_family = data->DestinationPrefix.Prefix.si_family;
7880
for (ULONG i = 0; i < table->NumEntries; i++) {
7981
MIB_IPFORWARD_ROW2* row = &table->Table[i];
8082
// Ignore routes into the VPN interface.
@@ -114,10 +116,28 @@ void WindowsRouteMonitor::updateExclusionRoute(MIB_IPFORWARD_ROW2* data,
114116
continue;
115117
}
116118

119+
// Ensure that the outgoing network interface is actually online and usable.
120+
DWORD result;
121+
NL_NETWORK_CONNECTIVITY_HINT hint;
122+
result = GetNetworkConnectivityHintForInterface(row->InterfaceIndex, &hint);
123+
if ((result != NO_ERROR) ||
124+
(hint.ConnectivityLevel == NetworkConnectivityLevelHintHidden)) {
125+
logger.debug() << "Ignoring hidden ifindex:" << row->InterfaceIndex;
126+
continue;
127+
}
128+
129+
// Prefer routes with lower metric if we find multiple matches
130+
// with the same prefix length.
131+
if ((row->DestinationPrefix.PrefixLength == bestMatch) &&
132+
(row->Metric >= bestMetric)) {
133+
continue;
134+
}
135+
117136
// If we got here, then this is the longest prefix match so far.
118137
memcpy(&nexthop, &row->NextHop, sizeof(SOCKADDR_INET));
119138
bestLuid = row->InterfaceLuid.Value;
120139
bestMatch = row->DestinationPrefix.PrefixLength;
140+
bestMetric = row->Metric;
121141
}
122142

123143
// If neither the interface nor next-hop have changed, then do nothing.
@@ -135,7 +155,12 @@ void WindowsRouteMonitor::updateExclusionRoute(MIB_IPFORWARD_ROW2* data,
135155
}
136156
data->InterfaceLuid.Value = bestLuid;
137157
memcpy(&data->NextHop, &nexthop, sizeof(SOCKADDR_INET));
138-
CreateIpForwardEntry2(data);
158+
if (data->InterfaceLuid.Value != 0) {
159+
DWORD result = CreateIpForwardEntry2(data);
160+
if (result != NO_ERROR) {
161+
logger.error() << "Failed to update route:" << result;
162+
}
163+
}
139164
}
140165

141166
bool WindowsRouteMonitor::addExclusionRoute(const QHostAddress& address) {

0 commit comments

Comments
 (0)