Description
Description
Appears to have been introduced here with the removal of the early pin /cc @stephentoub
WSAConnect
supports connect+transmit, which is supported in SocketAsyncEventArgs
, and implemented in DoOperationConnectEx
- however, a critical bug stops it working when a buffer is specified, faulting with "The system detected an invalid pointer address in attempting to use a pointer argument in a call.".
This is because the code sends (IntPtr)((byte*)_singleBufferHandle.Pointer + _offset),
as the payload pointer, but _singleBufferHandle
is not initialized until after ConnectEx
, in ProcessIOCPResult
(to avoid pins in the synchronous case).
Proposed fix: pass bufferPtr
instead.
This API should probably be passing bufferPtr
here, which is the same address via fixed
(fine for the synchronous case, and ends up pinned while fixed in the async case)
Reproduction Steps
Fails on net7.0
(note I haven't bothered with a server here; not needed for demonstration)
using var client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
var saea = new SocketAsyncEventArgs();
saea.RemoteEndPoint = new IPEndPoint(IPAddress.Loopback, 42);
saea.SetBuffer(new byte[42]); // <== the presence of the buffer is what triggers the failure
Console.WriteLine(client.ConnectAsync(saea)); // reports false, so: not pending
Console.WriteLine(saea.SocketError); // reports Fault
Expected behavior
Connects and transmits; specifically, ConnectAsync
should return true
(pending), or should report false
(complete) with a suitable SocketError
Actual behavior
ConnectAsync
reports false
(complete) with SocketError
as Fault
Regression?
Yes; works in net6.0
Known Workarounds
connect without a buffer, then send afterwards
Configuration
No response
Other information
No response