Bug 45662 - Receive() on blocking Socket with ReceiveTimeout > 0 throws SocketException with WouldBlock SocketErrorCode
Summary: Receive() on blocking Socket with ReceiveTimeout > 0 throws SocketException w...
Status: CONFIRMED
Alias: None
Product: Runtime
Classification: Mono
Component: io-layer (show other bugs)
Version: master
Hardware: All Mac OS
: --- normal
Target Milestone: Future Cycle (TBD)
Assignee: Bugzilla
URL:
Depends on:
Blocks:
 
Reported: 2016-10-18 19:10 UTC by Matthew Evans
Modified: 2018-01-18 22:33 UTC (History)
5 users (show)

Tags:
Is this bug a regression?: No
Last known good build:


Attachments
Test Case (1.32 KB, application/octet-stream)
2016-10-18 19:10 UTC, Matthew Evans
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 for Bug 45662 on GitHub or Developer Community if you have new information to add and do not yet see a matching new report.

If the latest results still closely match this report, you can use the original description:

  • Export the original title and description: GitHub Markdown or Developer Community HTML
  • Copy the title and description into the new report. Adjust them to be up-to-date if needed.
  • Add your new information.

In special cases on GitHub you might also want the comments: GitHub Markdown with public comments

Related Links:
Status:
CONFIRMED

Description Matthew Evans 2016-10-18 19:10:25 UTC
Created attachment 18111 [details]
Test Case

On Linux and macOS, Receive() on a blocking Socket with ReceiveTimeout > 0 throws a SocketException with SocketErrorCode = WouldBlock. On Windows, SocketErrorCode = TimedOut. 

Attached test case takes two arguments, an IP address and port to bind to. It can be built with 'mcs Program.cs'.

Output on mono/macOS:
$ uname -a
Darwin hostname.local 15.6.0 Darwin Kernel Version 15.6.0: Mon Aug 29 20:21:34 PDT 2016; root:xnu-3248.60.11~1/RELEASE_X86_64 x86_64

$ mono -V
Mono JIT compiler version 4.6.1 (mono-4.6.0-branch-c8sr0/ef43c15 Mon Oct  3 14:35:32 EDT 2016)
Copyright (C) 2002-2014 Novell, Inc, Xamarin Inc and Contributors. www.mono-project.com
	TLS:           normal
	SIGSEGV:       altstack
	Notification:  kqueue
	Architecture:  x86
	Disabled:      none
	Misc:          softdebug
	LLVM:          yes(3.6.0svn-mono-master/8b1520c)
	GC:            sgen

$ mono Program.exe 10.20.1.68 6666
endpoint: 10.20.1.68:6666
Threw SocketException
SocketErrorCode: WouldBlock
ErrorCode: 10035
Message: A connection attempt failed because the connected party did not properly respondafter a period of time, or established connection failed because connected host has failed to respond

System.Net.Sockets.SocketException (0x80004005): A connection attempt failed because the connected party did not properly respondafter a period of time, or established connection failed because connected host has failed to respond
  at System.Net.Sockets.Socket.Receive (System.Byte[] buffer, System.Int32 offset, System.Int32 size, System.Net.Sockets.SocketFlags socketFlags) [0x0004b] in <59be416de143456b88b9988284f43350>:0
  at SocketBug.Program.Main (System.String[] argv) [0x00070] in <6d64b642f0cd4df582bc17ba18f7714f>:0

Output on .Net/Windows:
>ver
Microsoft Windows [Version 6.3.9600]

>Program.exe 192.168.2.11 6666
SocketErrorCode: TimedOut
ErrorCode: 10060
Message: A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond

System.Net.Sockets.SocketException (0x80004005): A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond
   at SocketBug.Program.Main(String[] argv)

I'm not sure what the correct behavior here is, the MSDN documentation for Socket.Receive asks you to 'refer to the Windows Sockets version 2 API error code documentation'.

Npgsql 3.1 depends on the SocketErrorCode being TimedOut in this situation to detect timeouts while waiting for asynchronous notifications from PostgreSQL:
https://github.com/npgsql/npgsql/blob/550bfd6bf8bee2f81196601cb1fcd0aeb8e4dc11/src/Npgsql/ReadBuffer.cs#L122

This seems like the same issue as https://bugzilla.novell.com/show_bug.cgi?id=599488, but the commit (https://github.com/mono/mono/commit/5df31fb7877cdda9dbe160e7857dafe9428a5216) that fixed that bug only changed the behavior of _wapi_send, not _wapi_recvfrom.


Sidenote:

I thought running this test case on mono/Windows might provide some useful insight, but it actually doesn't throw any exception:

>mono --version
Mono JIT compiler version 4.6.1 (Visual Studio built mono)
Copyright (C) 2002-2014 Novell, Inc, Xamarin Inc and Contributors. www.mono-project.com
        TLS:           normal
        SIGSEGV:       normal
        Notification:  Thread + polling
        Architecture:  x86
        Disabled:      none
        Misc:          softdebug
        LLVM:          supported, not enabled.
        GC:            sgen

>mono Program.exe 192.168.2.11 6666
endpoint: 192.168.2.11:6666
Did not throw? ret=0
Comment 1 Roland Kuebert 2016-12-02 17:58:45 UTC
I can confirm the same behaviour on mono/Linux (SocketErrorCode = WouldBlock thrown while I expected SocketErrorCode = TimedOut):

$ uname -a
Linux localhost 4.8.0-1-amd64 #1 SMP Debian 4.8.7-1 (2016-11-13) x86_64 GNU/Linux

$ mono -V
Mono JIT compiler version 4.6.1 (Debian 4.6.1.3+dfsg-8)
Copyright (C) 2002-2014 Novell, Inc, Xamarin Inc and Contributors. www.mono-project.com
	TLS:           __thread
	SIGSEGV:       altstack
	Notifications: epoll
	Architecture:  amd64
	Disabled:      none
	Misc:          softdebug 
	LLVM:          supported, not enabled.
	GC:            sgen

$ mono Program.exe 127.0.0.1 50000
endpoint: 127.0.0.1:50000
Threw SocketException
SocketErrorCode: WouldBlock
ErrorCode: 10035
Message: A connection attempt failed because the connected party did not properly respondafter a period of time, or established connection failed because connected host has failed to respond

System.Net.Sockets.SocketException (0x80004005): A connection attempt failed because the connected party did not properly respondafter a period of time, or established connection failed because connected host has failed to respond
  at System.Net.Sockets.Socket.Receive (System.Byte[] buffer, System.Int32 size, System.Net.Sockets.SocketFlags socketFlags) [0x0004a] in <07e58fee265744b6a3510300e59793c1>:0 
  at SocketBug.Program.Main (System.String[] argv) [0x0006c] in <edf5824c2d4d4910a22db691c055d43f>:0

Running under mono/Windows for me results in an exception with the expected SocketErrorCode TimedOut / ErrorCode 10060:

> ver
Microsoft Windows [Version 6.1.7601]

> mono --version
Mono JIT compiler version 4.6.2 (Visual Studio built mono)
Copyright (C) 2002-2014 Novell, Inc, Xamarin Inc and Contributors. www.mono-proj
ect.com
        TLS:           normal
        SIGSEGV:       normal
        Notification:  Thread + polling
        Architecture:  x86
        Disabled:      none
        Misc:          softdebug
        LLVM:          supported, not enabled.
        GC:            sgen

> Program.exe 127.0.0.1 50000
endpoint: 127.0.0.1:50000
Threw SocketException
SocketErrorCode: TimedOut
ErrorCode: 10060
Message: A connection attempt failed because the connected party did not properly respond after a period of time, or est
ablished connection failed because connected host has failed to respond

System.Net.Sockets.SocketException (0x80004005): A connection attempt failed because the connected party did not properl
y respond after a period of time, or established connection failed because connected host has failed to respond
   at System.Net.Sockets.Socket.Receive(Byte[] buffer, Int32 offset, Int32 size, SocketFlags socketFlags)
   at SocketBug.Program.Main(String[] argv)
Comment 2 Ludovic Henry 2018-01-18 22:33:55 UTC
I can reproduce with Mono 5.11.0.276 (master/117468d740a)