@samitouri / QOSAMI-WSL / commits / 2fbf2f5d

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)