From 0dbf42ca0f00e56c45cb920bac1cbec8e4e005c6 Mon Sep 17 00:00:00 2001 From: antonfirsov Date: Wed, 14 Dec 2022 20:36:31 +0100 Subject: [PATCH 1/2] fix ConnectAsync with buffer on Windows --- .../Sockets/SocketAsyncEventArgs.Windows.cs | 2 +- .../tests/FunctionalTests/Connect.cs | 41 +++++++++++++++++++ 2 files changed, 42 insertions(+), 1 deletion(-) diff --git a/src/libraries/System.Net.Sockets/src/System/Net/Sockets/SocketAsyncEventArgs.Windows.cs b/src/libraries/System.Net.Sockets/src/System/Net/Sockets/SocketAsyncEventArgs.Windows.cs index 1ac42e04d237f..9a6c84ad43ee7 100644 --- a/src/libraries/System.Net.Sockets/src/System/Net/Sockets/SocketAsyncEventArgs.Windows.cs +++ b/src/libraries/System.Net.Sockets/src/System/Net/Sockets/SocketAsyncEventArgs.Windows.cs @@ -307,7 +307,7 @@ internal unsafe SocketError DoOperationConnectEx(Socket socket, SafeSocketHandle handle, PtrSocketAddressBuffer, _socketAddress!.Size, - (IntPtr)((byte*)_singleBufferHandle.Pointer + _offset), + (IntPtr)(bufferPtr + _offset), _count, out int bytesTransferred, overlapped); diff --git a/src/libraries/System.Net.Sockets/tests/FunctionalTests/Connect.cs b/src/libraries/System.Net.Sockets/tests/FunctionalTests/Connect.cs index 9643314a0de27..66ed8054a059c 100644 --- a/src/libraries/System.Net.Sockets/tests/FunctionalTests/Connect.cs +++ b/src/libraries/System.Net.Sockets/tests/FunctionalTests/Connect.cs @@ -8,6 +8,7 @@ using Xunit; using Xunit.Abstractions; using Xunit.Sdk; +using System.Linq; namespace System.Net.Sockets.Tests { @@ -241,6 +242,46 @@ public static void Connect_ThrowSocketException_Success() public sealed class ConnectEap : Connect { public ConnectEap(ITestOutputHelper output) : base(output) {} + + [Fact] + [PlatformSpecific(TestPlatforms.Windows)] + public async Task ConnectAsync_WithData_DataReceived() + { + using Socket listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); + listener.Bind(new IPEndPoint(IPAddress.Loopback, 0)); + IPEndPoint serverEp = (IPEndPoint)listener.LocalEndPoint!; + listener.Listen(); + + var serverTask = Task.Run(async () => + { + using Socket handler = await listener.AcceptAsync(); + using var cts = new CancellationTokenSource(TestSettings.PassingTestTimeout); + byte[] recvBuffer = new byte[6]; + int received = await handler.ReceiveAsync(recvBuffer, SocketFlags.None, cts.Token); + Assert.True(received == 4); + + recvBuffer.AsSpan(0, 4).SequenceEqual(new byte[] { 2, 3, 4, 5 }); + }); + + using var client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); + + Memory buffer = new byte[] { 0, 1, 2, 3, 4, 5, 6, 7 }.AsMemory(2, 4); + + var mre = new ManualResetEventSlim(false); + var saea = new SocketAsyncEventArgs(); + saea.RemoteEndPoint = serverEp; + saea.SetBuffer(buffer); + saea.Completed += (_, __) => mre.Set(); + + if (client.ConnectAsync(saea)) + { + Assert.True(mre.Wait(TestSettings.PassingTestTimeout), "Timed out while waiting for connection"); + } + + Assert.Equal(SocketError.Success, saea.SocketError); + + await serverTask; + } } public sealed class ConnectCancellableTask : Connect From ce67ed6601b3a922c2bc8fedcc7a921dc5ed7df3 Mon Sep 17 00:00:00 2001 From: antonfirsov Date: Wed, 14 Dec 2022 21:13:59 +0100 Subject: [PATCH 2/2] better tests --- .../tests/FunctionalTests/Connect.cs | 20 +++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/src/libraries/System.Net.Sockets/tests/FunctionalTests/Connect.cs b/src/libraries/System.Net.Sockets/tests/FunctionalTests/Connect.cs index 66ed8054a059c..762e446ea6439 100644 --- a/src/libraries/System.Net.Sockets/tests/FunctionalTests/Connect.cs +++ b/src/libraries/System.Net.Sockets/tests/FunctionalTests/Connect.cs @@ -243,9 +243,11 @@ public sealed class ConnectEap : Connect { public ConnectEap(ITestOutputHelper output) : base(output) {} - [Fact] + [Theory] [PlatformSpecific(TestPlatforms.Windows)] - public async Task ConnectAsync_WithData_DataReceived() + [InlineData(true)] + [InlineData(false)] + public async Task ConnectAsync_WithData_DataReceived(bool useArrayApi) { using Socket listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); listener.Bind(new IPEndPoint(IPAddress.Loopback, 0)); @@ -265,12 +267,22 @@ public async Task ConnectAsync_WithData_DataReceived() using var client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); - Memory buffer = new byte[] { 0, 1, 2, 3, 4, 5, 6, 7 }.AsMemory(2, 4); + byte[] buffer = new byte[] { 0, 1, 2, 3, 4, 5, 6, 7 }; var mre = new ManualResetEventSlim(false); var saea = new SocketAsyncEventArgs(); saea.RemoteEndPoint = serverEp; - saea.SetBuffer(buffer); + + // Slice the buffer to test the offset management: + if (useArrayApi) + { + saea.SetBuffer(buffer, 2, 4); + } + else + { + saea.SetBuffer(buffer.AsMemory(2, 4)); + } + saea.Completed += (_, __) => mre.Set(); if (client.ConnectAsync(saea))