Bug 53229 - SocketAsyncEventArgs doesn't trigger ConnectionReset error on server side
Summary: SocketAsyncEventArgs doesn't trigger ConnectionReset error on server side
Status: RESOLVED FEATURE
Alias: None
Product: Class Libraries
Classification: Mono
Component: System (show other bugs)
Version: 4.8.0 (C9)
Hardware: PC All
: --- normal
Target Milestone: Future Release
Assignee: Egorbo
URL:
Depends on:
Blocks:
 
Reported: 2017-03-10 17:59 UTC by Bartosz Sypytkowski
Modified: 2017-11-06 23:02 UTC (History)
4 users (show)

Tags: bugpool-archive
Is this bug a regression?: ---
Last known good build:


Attachments
wireshark results (75.23 KB, image/png)
2017-10-10 01:19 UTC, Egorbo
Details


Notice (2018-05-24): bugzilla.xamarin.com is now in read-only mode.

Please join us on Visual Studio Developer Community and in the Xamarin and Mono organizations on GitHub to continue tracking issues. Bugzilla will remain available for reference in read-only mode. We will continue to work on open Bugzilla bugs, copy them to the new locations as needed for follow-up, and add the new items under Related Links.

Our sincere thanks to everyone who has contributed on this bug tracker over the years. Thanks also for your understanding as we make these adjustments and improvements for the future.


Please create a new report on GitHub or Developer Community with your current version information, steps to reproduce, and relevant error messages or log files if you are hitting an issue that looks similar to this resolved bug and you do not yet see a matching new report.

Related Links:
Status:
RESOLVED FEATURE

Description Bartosz Sypytkowski 2017-03-10 17:59:05 UTC
Issue: SocketAsyncEventArgs.Completed event reaction on TCP Connection Reset by Peer error is invalid (it should be triggered with e.SocketError == SocketError.ConnectionReset , but on the linux/mono it's SocketError.Success instead).

This behavior has been confirmed on two independent applications.

The example, that can be used to reproduce: https://github.com/Horusiath/SocketAsyncEventArgsSample 

Consider following scenario:

1. Server starts listening
2. Client connects to a server
3. Connection gets accepted and both sides can exchange messages
4. Client crashes (client process gets killed without warning)

After pt. 4 accordingly to MSDN (see last paragraph of Remarks section: https://msdn.microsoft.com/en-us/library/system.net.sockets.socket.acceptasync(v=vs.110).aspx) in this situation a correct SocketError message on the server side should be ConnectionReset (as TCP connection reset by peer error has happened).

This is log from a SocketAsyncServer process on windows/clr build (which is correct):

    Server listening on port 9900. Press any key to terminate the server process...
    Client connection accepted from 127.0.0.1:55348. There are 1 clients connected to the server
    Received operation:Receive, error:Success
    Received operation:Send, error:Success
    Received operation:Send, error:Success
    Received operation:Send, error:Success
    Received operation:Send, error:Success
    Received operation:Send, error:Success
    Received operation:Receive, error:ConnectionReset
    A client has been disconnected from the server. There are 0 clients connected to the server

However the same scenario build and run under linux/mono (I've tested in on Mono v4.6.2 and v4.8) produces:

    Server listening on port 9900. Press any key to terminate the server process...
    Client connection accepted from 127.0.0.1:55348. There are 1 clients connected to the server
    Received operation:Receive, error:Success
    Received operation:Send, error:Success
    Received operation:Send, error:Success
    Received operation:Send, error:Success
    Received operation:Send, error:Success
    Received operation:Send, error:Success
    Received operation:Receive, error:Success
    A client has been disconnected from the server. There are 0 clients connected to the server
Comment 1 Marek Safar 2017-10-06 21:38:26 UTC
I can still reproduce it with master
Comment 2 Egorbo 2017-10-10 01:17:39 UTC
In your test when you kill the 'windows/clr' client - Windows OS sends an [RST, ACK] tcp packet to the server which will trigger the ConnectionReset event. MacOS\Linux clients most likely will send a graceful [FIN,ACK] packet instead (won't trigger ConnectionReset event on the server side). You can simulate RST (hard close) by using SO_LINGER:

socket.LingerState = new LingerOption(true, 0);
socket.Close();
Comment 3 Egorbo 2017-10-10 01:19:00 UTC
Created attachment 25232 [details]
wireshark results