diff --git a/src/windows/common/WslCoreNetworkingSupport.h b/src/windows/common/WslCoreNetworkingSupport.h index f1a0b726c..6e584ac8f 100644 --- a/src/windows/common/WslCoreNetworkingSupport.h +++ b/src/windows/common/WslCoreNetworkingSupport.h @@ -136,6 +136,16 @@ inline constexpr auto* c_ipv4TestRequestTargetA = "www.msftconnecttest.com"; inline constexpr auto* c_ipv6TestRequestTarget = L"ipv6.msftconnecttest.com"; inline constexpr auto* c_ipv6TestRequestTargetA = "ipv6.msftconnecttest.com"; +inline HRESULT GetGnsCallbackResult(LX_MESSAGE_TYPE messageType, HRESULT transportResult, int linuxResultCode) noexcept +{ + if (FAILED(transportResult) || messageType == LxGnsMessageConnectTestRequest || linuxResultCode == 0) + { + return transportResult; + } + + return E_FAIL; +} + inline constexpr GUID c_wslFirewallVmCreatorId = {0x40E0AC32, 0x46A5, 0x438A, {0xA0, 0xB2, 0x2B, 0x47, 0x9E, 0x8F, 0x2E, 0x90}}; inline constexpr auto c_networkAdapterPrefix = L"VirtualMachine/Devices/NetworkAdapters/"; diff --git a/src/windows/service/exe/MirroredNetworking.cpp b/src/windows/service/exe/MirroredNetworking.cpp index 417006ea7..5cc22319f 100644 --- a/src/windows/service/exe/MirroredNetworking.cpp +++ b/src/windows/service/exe/MirroredNetworking.cpp @@ -667,41 +667,43 @@ try WI_ASSERT(WI_IsFlagSet(callbackFlags, wsl::core::networking::GnsCallbackFlags::Wait)); } - auto sendGnsMessage = - [this, messageType, capturedNotificationString = std::move(notificationString), callbackFlags, returnedValueFromGns]() mutable { - try - { - auto retryCount = 0ul; - // RetryWithTimeout throws if fails after the timeout has elapsed - which is caught and returned by m_gnsMessageQueue below - return wsl::shared::retry::RetryWithTimeout( - [&]() { - const auto hr = wil::ResultFromException([&] { - if (returnedValueFromGns && WI_IsFlagSet(callbackFlags, wsl::core::networking::GnsCallbackFlags::Wait)) - { - *returnedValueFromGns = - m_gnsChannel.SendNetworkDeviceMessageReturnResult(messageType, capturedNotificationString.c_str()); - } - else - { - m_gnsChannel.SendNetworkDeviceMessage(messageType, capturedNotificationString.c_str()); - } - }); - WSL_LOG( - "MirroredNetworking::NetworkManagerGnsMessageCallback", - TraceLoggingValue(ToString(messageType), "messageType"), - TraceLoggingValue(capturedNotificationString.c_str(), "notificationString"), - TraceLoggingValue(hr, "hr"), - TraceLoggingValue(returnedValueFromGns ? *returnedValueFromGns : 0xFFFFFFFF, "returnedValueFromGns"), - TraceLoggingValue(retryCount, "retryCount")); - - ++retryCount; - return hr; - }, - std::chrono::milliseconds(100), - std::chrono::seconds(3)); - } - CATCH_RETURN() - }; + auto sendGnsMessage = [this, messageType, capturedNotificationString = std::move(notificationString), callbackFlags, returnedValueFromGns]() mutable { + try + { + auto retryCount = 0ul; + auto sendMessage = [&]() { + const auto hr = wil::ResultFromException([&] { + if (returnedValueFromGns && WI_IsFlagSet(callbackFlags, wsl::core::networking::GnsCallbackFlags::Wait)) + { + *returnedValueFromGns = + m_gnsChannel.SendNetworkDeviceMessageReturnResult(messageType, capturedNotificationString.c_str()); + } + else + { + m_gnsChannel.SendNetworkDeviceMessage(messageType, capturedNotificationString.c_str()); + } + }); + const bool hasLinuxResult = returnedValueFromGns != nullptr; + const int linuxResultCode = hasLinuxResult ? *returnedValueFromGns : 0; + WSL_LOG( + "MirroredNetworking::NetworkManagerGnsMessageCallback", + TraceLoggingValue(ToString(messageType), "messageType"), + TraceLoggingValue(capturedNotificationString.c_str(), "notificationString"), + TraceLoggingValue(hr, "hr"), + TraceLoggingValue(hasLinuxResult, "hasLinuxResult"), + TraceLoggingValue(linuxResultCode, "linuxResultCode"), + TraceLoggingValue(retryCount, "retryCount")); + + ++retryCount; + THROW_IF_FAILED(hr); + return networking::GetGnsCallbackResult(messageType, hr, linuxResultCode); + }; + + // RetryWithTimeout throws if transport fails after the timeout has elapsed. + return wsl::shared::retry::RetryWithTimeout(sendMessage, std::chrono::milliseconds(100), std::chrono::seconds(3)); + } + CATCH_RETURN() + }; if (WI_IsFlagSet(callbackFlags, wsl::core::networking::GnsCallbackFlags::Wait)) { diff --git a/test/windows/NetworkTests.cpp b/test/windows/NetworkTests.cpp index b06aae02b..65d603dd1 100644 --- a/test/windows/NetworkTests.cpp +++ b/test/windows/NetworkTests.cpp @@ -18,6 +18,7 @@ Module Name: #include "wslpolicies.h" #include "hns_schema.h" #include "WslCoreNetworkEndpointSettings.h" +#include "WslCoreNetworkingSupport.h" #include #include @@ -3950,6 +3951,36 @@ class NetworkTests } }; +class GnsCallbackResultTests +{ + WSL_TEST_CLASS(GnsCallbackResultTests) + + TEST_METHOD(GnsCallbackSuccessfulTransportAndLinuxResultSucceeds) + { + VERIFY_SUCCEEDED(wsl::core::networking::GetGnsCallbackResult(LxGnsMessageDeviceSettingRequest, S_OK, 0)); + } + + TEST_METHOD(GnsCallbackSuccessfulTransportAndLinuxFailureFails) + { + VERIFY_ARE_EQUAL(E_FAIL, wsl::core::networking::GetGnsCallbackResult(LxGnsMessageDeviceSettingRequest, S_OK, -1)); + } + + TEST_METHOD(GnsCallbackTransportFailureFails) + { + VERIFY_ARE_EQUAL(E_ABORT, wsl::core::networking::GetGnsCallbackResult(LxGnsMessageDeviceSettingRequest, E_ABORT, 0)); + } + + TEST_METHOD(GnsCallbackConnectTestBusinessResultSucceeds) + { + VERIFY_SUCCEEDED(wsl::core::networking::GetGnsCallbackResult(LxGnsMessageConnectTestRequest, S_OK, -1)); + } + + TEST_METHOD(GnsCallbackConnectTestTransportFailureFails) + { + VERIFY_ARE_EQUAL(E_ABORT, wsl::core::networking::GetGnsCallbackResult(LxGnsMessageConnectTestRequest, E_ABORT, -1)); + } +}; + class MirroredTests { WSL_TEST_CLASS(MirroredTests)