Handle Linux failures from GNS callbacks (#41396)
* Handle Linux failures from GNS callbacks * Update tests * Address GNS callback review feedback Co-Authored-By: Claude <noreply@anthropic.com> * Address GNS callback review comments Co-Authored-By: Claude <noreply@anthropic.com> * Preserve GNS transport failure behavior Co-Authored-By: Claude <noreply@anthropic.com> --------- Co-authored-by: Claude <noreply@anthropic.com>
Shawn Yuan committed
Aug 25, 2026 at 08:15 UTC
2fbf2f5dfbb781acb48b5a16ad0acb67c535c1c0
3 files changed
+76
-35
src/windows/common/WslCoreNetworkingSupport.h
+10
@@ -136,6 +136,16 @@ inline constexpr auto* c_ipv4TestRequestTargetA = "www.msftconnecttest.com";
136
inline constexpr auto* c_ipv6TestRequestTarget = L"ipv6.msftconnecttest.com";
137
inline constexpr auto* c_ipv6TestRequestTargetA = "ipv6.msftconnecttest.com";
138
139
+inline HRESULT GetGnsCallbackResult(LX_MESSAGE_TYPE messageType, HRESULT transportResult, int linuxResultCode) noexcept
140
+{
141
+ if (FAILED(transportResult) || messageType == LxGnsMessageConnectTestRequest || linuxResultCode == 0)
142
+ {
143
+ return transportResult;
144
+ }
145
+
146
+ return E_FAIL;
147
+}
148
+
149
inline constexpr GUID c_wslFirewallVmCreatorId = {0x40E0AC32, 0x46A5, 0x438A, {0xA0, 0xB2, 0x2B, 0x47, 0x9E, 0x8F, 0x2E, 0x90}};
150
151
inline constexpr auto c_networkAdapterPrefix = L"VirtualMachine/Devices/NetworkAdapters/";
src/windows/service/exe/MirroredNetworking.cpp
+35
-35
@@ -667,41 +667,41 @@ try
667
WI_ASSERT(WI_IsFlagSet(callbackFlags, wsl::core::networking::GnsCallbackFlags::Wait));
668
}
669
670
- auto sendGnsMessage =
671
- [this, messageType, capturedNotificationString = std::move(notificationString), callbackFlags, returnedValueFromGns]() mutable {
672
- try
673
- {
674
- auto retryCount = 0ul;
675
- // RetryWithTimeout throws if fails after the timeout has elapsed - which is caught and returned by m_gnsMessageQueue below
676
- return wsl::shared::retry::RetryWithTimeout<HRESULT>(
677
- [&]() {
678
- const auto hr = wil::ResultFromException([&] {
679
- if (returnedValueFromGns && WI_IsFlagSet(callbackFlags, wsl::core::networking::GnsCallbackFlags::Wait))
680
- {
681
- *returnedValueFromGns =
682
- m_gnsChannel.SendNetworkDeviceMessageReturnResult(messageType, capturedNotificationString.c_str());
683
- }
684
- else
685
- {
686
- m_gnsChannel.SendNetworkDeviceMessage(messageType, capturedNotificationString.c_str());
687
- }
688
- });
689
- WSL_LOG(
690
- "MirroredNetworking::NetworkManagerGnsMessageCallback",
691
- TraceLoggingValue(ToString(messageType), "messageType"),
692
- TraceLoggingValue(capturedNotificationString.c_str(), "notificationString"),
693
- TraceLoggingValue(hr, "hr"),
694
- TraceLoggingValue(returnedValueFromGns ? *returnedValueFromGns : 0xFFFFFFFF, "returnedValueFromGns"),
695
- TraceLoggingValue(retryCount, "retryCount"));
696
-
697
- ++retryCount;
698
- return hr;
699
- },
700
- std::chrono::milliseconds(100),
701
- std::chrono::seconds(3));
702
- }
703
- CATCH_RETURN()
704
- };
670
+ auto sendGnsMessage = [this, messageType, capturedNotificationString = std::move(notificationString), callbackFlags, returnedValueFromGns]() mutable {
671
+ try
672
+ {
673
+ auto retryCount = 0ul;
674
+ auto sendMessage = [&]() {
675
+ const auto hr = wil::ResultFromException([&] {
676
+ if (returnedValueFromGns && WI_IsFlagSet(callbackFlags, wsl::core::networking::GnsCallbackFlags::Wait))
677
+ {
678
+ *returnedValueFromGns =
679
+ m_gnsChannel.SendNetworkDeviceMessageReturnResult(messageType, capturedNotificationString.c_str());
680
+ }
681
+ else
682
+ {
683
+ m_gnsChannel.SendNetworkDeviceMessage(messageType, capturedNotificationString.c_str());
684
+ }
685
+ });
686
+ const bool hasLinuxResult = returnedValueFromGns != nullptr;
687
+ const int linuxResultCode = hasLinuxResult ? *returnedValueFromGns : 0;
688
+ WSL_LOG(
689
+ "MirroredNetworking::NetworkManagerGnsMessageCallback",
690
+ TraceLoggingValue(ToString(messageType), "messageType"),
691
+ TraceLoggingValue(capturedNotificationString.c_str(), "notificationString"),
692
+ TraceLoggingValue(hr, "hr"),
693
+ TraceLoggingValue(hasLinuxResult, "hasLinuxResult"),
694
+ TraceLoggingValue(linuxResultCode, "linuxResultCode"),
695
+ TraceLoggingValue(retryCount, "retryCount"));
696
+
697
+ ++retryCount;
698
+ return networking::GetGnsCallbackResult(messageType, hr, linuxResultCode);
699
+ };
700
+
701
+ return wsl::shared::retry::RetryWithTimeout<HRESULT>(sendMessage, std::chrono::milliseconds(100), std::chrono::seconds(3));
702
+ }
703
+ CATCH_RETURN()
704
+ };
705
706
if (WI_IsFlagSet(callbackFlags, wsl::core::networking::GnsCallbackFlags::Wait))
707
{
test/windows/NetworkTests.cpp
+31
@@ -18,6 +18,7 @@ Abstract:
18
#include "wslpolicies.h"
19
#include "hns_schema.h"
20
#include "WslCoreNetworkEndpointSettings.h"
21
+#include "WslCoreNetworkingSupport.h"
22
23
#include <mstcpip.h>
24
#include <winhttp.h>
@@ -3950,6 +3951,36 @@ class NetworkTests
3951
}
3952
};
3953
3954
+class GnsCallbackResultTests
3955
+{
3956
+ WSL_TEST_CLASS(GnsCallbackResultTests)
3957
+
3958
+ TEST_METHOD(GnsCallbackSuccessfulTransportAndLinuxResultSucceeds)
3959
+ {
3960
+ VERIFY_SUCCEEDED(wsl::core::networking::GetGnsCallbackResult(LxGnsMessageDeviceSettingRequest, S_OK, 0));
3961
+ }
3962
+
3963
+ TEST_METHOD(GnsCallbackSuccessfulTransportAndLinuxFailureFails)
3964
+ {
3965
+ VERIFY_ARE_EQUAL(E_FAIL, wsl::core::networking::GetGnsCallbackResult(LxGnsMessageDeviceSettingRequest, S_OK, -1));
3966
+ }
3967
+
3968
+ TEST_METHOD(GnsCallbackTransportFailureFails)
3969
+ {
3970
+ VERIFY_ARE_EQUAL(E_ABORT, wsl::core::networking::GetGnsCallbackResult(LxGnsMessageDeviceSettingRequest, E_ABORT, 0));
3971
+ }
3972
+
3973
+ TEST_METHOD(GnsCallbackConnectTestBusinessResultSucceeds)
3974
+ {
3975
+ VERIFY_SUCCEEDED(wsl::core::networking::GetGnsCallbackResult(LxGnsMessageConnectTestRequest, S_OK, -1));
3976
+ }
3977
+
3978
+ TEST_METHOD(GnsCallbackConnectTestTransportFailureFails)
3979
+ {
3980
+ VERIFY_ARE_EQUAL(E_ABORT, wsl::core::networking::GetGnsCallbackResult(LxGnsMessageConnectTestRequest, E_ABORT, -1));
3981
+ }
3982
+};
3983
+
3984
class MirroredTests
3985
{
3986
WSL_TEST_CLASS(MirroredTests)