Bug 36192 - Error binding Socket to Loopback
Summary: Error binding Socket to Loopback
Alias: None
Product: Class Libraries
Classification: Mono
Component: System ()
Version: master
Hardware: PC Linux
: --- normal
Target Milestone: Untriaged
Assignee: Ludovic Henry
Depends on:
Reported: 2015-11-24 01:11 UTC by Stefan
Modified: 2016-02-01 10:48 UTC (History)
2 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-11-24 01:11:19 UTC
The following fails to Bind under mono (4.3 compiled from master using Ubuntu 15.10) but works fine under .NET on windows, it could be me not understanding something about sockets on linux.

var host = new IPEndPoint(IPAddress.Loopback, 0);
var socket = new Socket(SocketType.Stream, ProtocolType.Tcp);

If I were to use IPAddress.IPv6Loopback it works fine, and if I were to set the AddressFamily to Internetwork is works as expected also.

My understanding is that the constructor of socket I am using should allow me to bind to IPV4 or IPV6:

// This constructor is used by servers that want to listen for instance on both
// ipv4 and ipv6.   Mono has historically done that if you use InterNetworkV6 (at
// least on Unix), because that is the default behavior unless the IPV6_V6ONLY
// option is explicitly set by using setsockopt (sock, IPPROTO_IPV6, IPV6_ONLY)
public Socket (SocketType socketType, ProtocolType protocolType)

Am I expecting the wrong behavior here?
Comment 1 Stefan 2015-11-24 01:38:52 UTC
Looking at the .NET implementation when binding an IPV4 address to the DualMode socket it actually looks like it maps that address to an IPV6 address during the bind.


RemapIPEndPoint is called during Bind, makes more sense now, will put together a PR to fix this behavior if we agree this is the right fix.
Comment 2 João Matos 2015-12-07 17:05:42 UTC
Hi Stefan, your reasoning makes sense to me, but I am not very familiar with these low-level socket operations. Have you had time to submit a PR yet? Let me know if you are still working on it, and we can get it reviewed and pushed to master as soon as you submit it.
Comment 3 Stefan 2015-12-07 19:28:32 UTC
Hi João,

I have hacked up a solution in my fork to verify that it works and I had some success.

I am not overly familiar with the low-level socket things myself but I am happy to polish my changes up, add some tests around it and submit a PR.

I will get something together this week and get it across to be reviewed.
Comment 4 Ludovic Henry 2015-12-10 18:44:02 UTC
Hi Stefan,

I am the one taking care of the low-level Socket part of the runtime, so when submitting your PR, please assign it to me, so I can take a look at it as soon as possible.

Thank you very much!

Comment 5 Stefan 2015-12-29 17:58:53 UTC
Thanks Ludovic,

I have been on holiday so have been delayed getting to this, but will get back to it shortly and get a PR across for my fix.

Comment 6 Stefan 2016-01-05 21:39:06 UTC
Hi Ludovic,

I had sent you an email but thought I would comment here anyway with some final questions before I send across PR for final review.

To perform the mapping I had in mind I planned to use the IPAddress.MapToIPv6 method, which was added recently to master but is conditional only for .NET 4.5.

This would mean my changes to fix this issue would also be conditional and only apply to .NET 4.5, do you think this is the correct approach here?

Comment 7 Ludovic Henry 2016-02-01 10:48:56 UTC
Fixed with https://github.com/mono/mono/pull/2420