Bug 36192

Summary: Error binding Socket to Loopback
Product: [Mono] Class Libraries Reporter: Stefan <stefan.sedich>
Component: SystemAssignee: Ludovic Henry <ludovic>
Status: RESOLVED FIXED    
Severity: normal CC: joao.matos, mono-bugs+mono
Priority: ---    
Version: master   
Target Milestone: Untriaged   
Hardware: PC   
OS: Linux   
Tags: Is this bug a regression?: ---
Last known good build:

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);
socket.Bind(host);

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.

https://github.com/dotnet/corefx/blob/master/src/System.Net.Sockets/src/System/Net/Sockets/Socket.cs

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!

Ludovic
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.



Thanks
Stefan
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?



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