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: NEW
Alias: None
Product: Runtime
Classification: Mono
Component: io-layer (show other bugs)
Version: 4.6.0 (C8)
Hardware: All Mac OS
: --- normal
Target Milestone: ---
Assignee: Bugzilla
URL:
Depends on:
Blocks:
 
Reported: 2016-10-18 19:10 UTC by Matthew Evans
Modified: 2016-12-02 17:58 UTC (History)
4 users (show)

See Also:
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

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)

Note You need to log in before you can comment on or make changes to this bug.