Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Socket on Unix behaves inconsistently between IPAddress[] and DnsEndPoint connects #110124

Open
stephentoub opened this issue Nov 24, 2024 · 2 comments
Assignees
Milestone

Comments

@stephentoub
Copy link
Member

A socket on unix doesn't support reconnecting with the same file descriptor after a failed connection. This has created an issue for the .NET Socket design, whereby options can be set onto a Socket instance, and then that Socket instance can be connected to something that might actually require multiple attempts. To make this work, the Socket tracks known settings, and recreates the file descriptor under the covers upon a failed attempt. If an unknown setting is used, Socket refuses to connect to an endpoint that might possibly require multiple attempts, e.g. a DnsEndPoint. Unfortunately, we're not applying this consistently across such connect methods.

This:

using System.Net;
using System.Net.Sockets;

Socket s = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
s.SetSocketOption(SocketOptionLevel.Tcp, SocketOptionName.TcpKeepAliveRetryCount, 1);
await s.ConnectAsync(new DnsEndPoint("microsoft.com", 80));

throws the exception:

Unhandled exception. System.PlatformNotSupportedException: Sockets on this platform are invalid for use after a failed connection attempt.
   at System.Net.Sockets.Socket.ThrowMultiConnectNotSupported()
   at System.Net.Sockets.Socket.ConnectAsync(SocketAsyncEventArgs e, Boolean userSocket, Boolean saeaCancelable)
   at System.Net.Sockets.Socket.AwaitableSocketAsyncEventArgs.ConnectAsync(Socket socket)
   at System.Net.Sockets.Socket.ConnectAsync(EndPoint remoteEP, CancellationToken cancellationToken)
   at System.Net.Sockets.Socket.ConnectAsync(EndPoint remoteEP)
   at Program.<Main>$(String[] args)

But this:

using System.Net;
using System.Net.Sockets;

Socket s = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
s.SetSocketOption(SocketOptionLevel.Tcp, SocketOptionName.TcpKeepAliveRetryCount, 1);
await s.ConnectAsync(Dns.GetHostAddresses("microsoft.com"), 80);

completes successfully, even though they're logically the same, with the former just doing the DNS lookup and effectively then behaving as if that list was provided.

At this point, it'd likely be a significant breaking change to make the latter fail like the former.

We should reconsider the behavior for the former, and possibly revisit the whole retry mechanism, caching more aggressively such that few-to-no settings knock us off the golden path.

@dotnet-policy-service dotnet-policy-service bot added the untriaged New issue has not been triaged by the area owner label Nov 24, 2024
@stephentoub stephentoub added this to the 10.0.0 milestone Nov 24, 2024
Copy link
Contributor

Tagging subscribers to this area: @dotnet/ncl
See info in area-owners.md if you want to be subscribed.

@dotnet-policy-service dotnet-policy-service bot removed the untriaged New issue has not been triaged by the area owner label Nov 24, 2024
@stephentoub stephentoub added the untriaged New issue has not been triaged by the area owner label Nov 24, 2024
@dotnet-policy-service dotnet-policy-service bot removed the untriaged New issue has not been triaged by the area owner label Nov 24, 2024
@stephentoub stephentoub added untriaged New issue has not been triaged by the area owner and removed bug labels Nov 25, 2024
@dotnet-policy-service dotnet-policy-service bot removed the untriaged New issue has not been triaged by the area owner label Nov 25, 2024
@stephentoub stephentoub added untriaged New issue has not been triaged by the area owner and removed area-System.Net.Sockets labels Dec 4, 2024
@stephentoub stephentoub removed this from the 10.0.0 milestone Dec 4, 2024
Copy link
Contributor

Tagging subscribers to this area: @dotnet/ncl
See info in area-owners.md if you want to be subscribed.

@antonfirsov antonfirsov self-assigned this Dec 4, 2024
@antonfirsov antonfirsov removed the untriaged New issue has not been triaged by the area owner label Dec 4, 2024
@antonfirsov antonfirsov added this to the 10.0.0 milestone Dec 4, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants