Bug 31557 - Sockets with ReuseAddress does not seem to be working as expected
Summary: Sockets with ReuseAddress does not seem to be working as expected
Alias: None
Product: Runtime
Classification: Mono
Component: io-layer ()
Version: 4.0.0
Hardware: Other Linux
: Normal normal
Target Milestone: 4.2 (C6)
Assignee: marcos.henrich
Depends on:
Reported: 2015-07-01 17:21 UTC by Stefan
Modified: 2015-10-06 12:14 UTC (History)
5 users (show)

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

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:

Description Stefan 2015-07-01 17:21:39 UTC
The following example seems to have issues running under Mono (nightly 4.3.0, ubuntu 14.04), on windows as expected the second socket is bound and starts listening, but under mono this fails with an exception telling me that the "Address is already in use":

    var socket1 = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
    socket1.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
    socket1.Bind(new IPEndPoint(IPAddress.Loopback, 1234));

    var socket2 = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
    socket2.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
    socket2.Bind(new IPEndPoint(IPAddress.Loopback, 1234));

Should I expect this to work under Mono/Linux?

Comment 1 Stefan 2015-07-07 23:15:44 UTC
Just some more findings on this after looking into the sockets.c implementation, I can see the code that sets SO_REUSEPORT which is executed under Ubuntu, starting at line#729:

#if defined (SO_REUSEPORT)
	/* BSD's and MacOS X multicast sockets also need SO_REUSEPORT when SO_REUSEADDR is requested.  */
	if (level == SOL_SOCKET && optname == SO_REUSEADDR) {
		int type;
		socklen_t type_len = sizeof (type);

		if (!getsockopt (fd, level, SO_TYPE, &type, &type_len)) {
			if (type == SOCK_DGRAM)
				setsockopt (fd, level, SO_REUSEPORT, tmp_val, optlen);

The bit that interests me is starting at line#736:

if (type == SOCK_DGRAM)
				setsockopt (fd, level, SO_REUSEPORT, tmp_val, optlen);

Unless I am wrong will that only apply to UDP sockets? if I remove this check or change it to (type == SOCK_STREAM) it then works as expected for me with the example above, is there a reason that this check is there that I do not understand?

Comment 2 Rodrigo Kumpera 2015-08-16 03:16:44 UTC
Hey Marcos,

Can you take a look at this one?
Comment 3 Stefan 2015-09-10 18:18:32 UTC
Thanks Rodrigo, do you know if anyone got a chance to verify what I was seeing. Be great if I can have some clarification either way.

Comment 4 marcos.henrich 2015-09-11 12:46:42 UTC
Hi Stefan,

Thank you for the detailed bug report and for finding a fix for the issue.

Here is the pull request fixing the issue:
Comment 5 Stefan 2015-09-11 19:06:47 UTC
Thanks Marcos!

That was the exact fix I had in mind! I guess I just wasn't sure if there was a historical reason for it being like this that I did not know about.

Appreciate you looking into this done and fixing it up!

Comment 6 marcos.henrich 2015-09-21 09:17:19 UTC
Fixed in mono master 07bae963aea19bb6c293ad3176c3f707ac94d2a2.

Fixed in mono mono-4.2.0-branch 4a18c575ac105b920ec7fb37b24ffe74ad9b3bd7.