Skip to content

Reusing the same SocketAsyncEventArgs for different udp remote endpoints does not work anymore #97965

Closed
@rmja

Description

@rmja

Description

It has been introduced in .NET 8 that the _socketAddress inside the SocketAsyncEventArgs is only serialized if it is null. This means that it is only serialized the first time the SocketAsyncEventArgs is used for a socket operation. However, e.g. in https://github.com/chronoxor/NetCoreServer/blob/master/source/NetCoreServer/UdpServer.cs#L692-L694 the SocketAsyncEventArgs is used multiple times for different remote endpoints.

This is what is going on in .NET 8:
https://github.com/dotnet/runtime/blob/v8.0.1/src/libraries/System.Net.Sockets/src/System/Net/Sockets/Socket.cs#L3098-L3107

This is the previous same file in .NET 7:
https://github.com/dotnet/runtime/blob/v7.0.15/src/libraries/System.Net.Sockets/src/System/Net/Sockets/Socket.cs#L3027

When comparing the two files, it seems that, if one changes the remote endpoint and calls e.g. Socket.SendToAsync() then it will not re-serialize the _socketAddress and the payload will not be transmitted to the socket address of the newly configured remote endpoint - instead they whill be transmitted to the first configured remote endpoint.

Reproduction Steps

  • Create a single instance of var ea = SocketAsyncEventArgs.
  • Call ea.RemoteEndPoint = firstEndpoint.
  • Call socket.SendToAsync(ea).
  • The data is correctly sent to firstEndpoint, now set a different remote endpoint ea.RemoteEndpoint = secondEndpoint
  • Call socket.SendToAsync(ea).
  • The data is not sent secondEndpoint , it is sent to the old firstEndpoint which is clearly not correct.

Expected behavior

It is expected that consequitive calls to e.g. Socket.SendToAsync() with the same instance of SocketAsyncEventArgs but with reconfigured RemoteEndpoint, actually transmits to different endpoints.

Actual behavior

All consequitive calls to e.g. Socket.SendToAsync() are transmitted to the remote endpoint configured when Socket.SendToAsync() is first called. This is verified in wireshark.

Regression?

This worked fine in .NET 7.

Known Workarounds

I made the following PR in NetCoreServer in case the re-use of SocketAsyncEventArgs for different remote endpoints is in fact not legal, see: chronoxor/NetCoreServer#284

Configuration

No response

Other information

No response

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions