-
Notifications
You must be signed in to change notification settings - Fork 4.8k
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
GetSocketOption/SetSocketOption should not close underlying socket #59055
Comments
Tagging subscribers to this area: @dotnet/ncl Issue DetailsDescriptionAssume that _socket is an open (active) TCP socket. The following call will throw an exception and close the socket Socket _socket;
_socket.NoDelay = true;
_socket.Blocking = true;
_socket.ReceiveTimeout = -1;
_socket.SendTimeout = -1;
...
IPAddress ipaddr = <setup your server ip>;
IPEndPoint svrEndPoint = new IPEndPoint(ipaddr, _serverPort);
var listener = new Socket(ipaddr.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
listener.Bind(svrEndPoint);
listener.Listen(2);
_socket = listener.Accept();
_socket.GetSocketOption(SocketOptionLevel.Socket, SocketOptionName.DontLinger) This option (DontLinger) isn't supported on Linux so the exception is appropriate, but closing the socket isn't. To quote a friend this "violates the principle of least astonishment". ConfigurationVersion: .NET core 5.0 Regression?I do not believe this is a regression. Other informationHere is what I see in the codebase.
So if the call returns a not supported error, UpdateStatusAfterSocketErrorAndThrowExecption is called.
Honestly, that looks correct to me, but perhaps the errorCode isn't what I would be expecting for an unsupported option name, or the handled has somehow (?) become invalid. I wasn't able to look at this in the debugger, so I can't say what the conditions were or if this is even the right spot (but I don't see anywhere else) A few nights ago I was down in some mono code and that clearly would have created this effect. It check the options first and if they failed an exception was thrown (never calling the OS). I assume that code is no longer used in the v5 .net runtime.
|
@tmds @wfurt would it make sense to implement To me it looks like this is what it does on Windows: |
The issue with the setter is that we need to pick a timeout. And a getter is not so useful, this is an option a user will want to set.
We should consider to change |
I would think we can pick reasonable default for timeout oof needed. But aside from that I would agree that failing to set options should not close the underlying socket. |
Triage: We agree we should not close underlying sockets when set options fails. Retitling to track it here. |
Description
Assume that _socket is an open (active) TCP socket. The following call will throw an exception and close the socket
This option (DontLinger) isn't supported on Linux so the exception is appropriate, but closing the socket isn't. To quote a friend this "violates the principle of least astonishment".
Configuration
Version: .NET core 5.0
OS: Linux Ubuntu 20.04.lts
Arch: x64
Configuration: The option isn't supported on this Linux distro but is on Windows. My code caught the exception but did not expect the socket to be closed.
Regression?
I do not believe this is a regression.
Other information
Here is what I see in the codebase.
in /src/libraries/System.Net.Sockets/src/System/Net/Sockets/Socket.cs
The GetSocketOption methods call into the OS:
So if the call returns a not supported error, UpdateStatusAfterSocketErrorAndThrowExecption is called.
That calls an internal method named UpdateStatusAfterSocketError which:
Honestly, that looks correct to me, but perhaps the errorCode isn't what I would be expecting for an unsupported option name, or the handled has somehow (?) become invalid. I wasn't able to look at this in the debugger, so I can't say what the conditions were or if this is even the right spot (but I don't see anywhere else)
A few nights ago I was down in some mono code and that clearly would have created this effect. It check the options first and if they failed an exception was thrown (never calling the OS). I assume that code is no longer used in the v5 .net runtime.
Workaround is the check the Linger option.
The text was updated successfully, but these errors were encountered: