Bug 20048

Summary: Socket ctor missing
Product: [Mono] Class Libraries Reporter: David Fowler <davidfowl>
Component: SystemAssignee: Martin Baulig <martin.baulig>
Status: RESOLVED FIXED    
Severity: normal CC: borgdylan, masafa, miguel, mono-bugs+mono, muo
Priority: ---    
Version: master   
Target Milestone: Untriaged   
Hardware: PC   
OS: Mac OS   
Tags: Is this bug a regression?: ---
Last known good build:

Description David Fowler 2014-05-26 13:20:43 UTC
http://msdn.microsoft.com/en-us/library/hh264899(v=vs.110).aspx

This constructor sets up the Socket in dual mode (it can handle be bound to both IPV4 and IPV6 addresses). Mono doesn't seem to have this overload. Creating a Socket that listens that works for both IPV6 and IPV4 addresses is impossible without an ifdeffing.

Reference:

https://github.com/aspnet/KRuntime/blob/dev/src/Microsoft.Framework.DesignTimeHost/Program.cs#L49
Comment 1 David Fowler 2014-05-26 13:21:53 UTC
Bah, typo, it can be bound to* not handle be bound to :)
Comment 2 Dylan Borg 2014-08-14 12:27:22 UTC
Is this being worked on, at least for a single mode implementation?
Comment 3 Dylan Borg 2014-08-14 15:42:22 UTC
This currently impedes Asp.net vnext from running on mono.
Comment 4 Kei Nakazawa 2014-10-25 09:45:20 UTC
I noticed ASP.NET vNext's Kestrel HTTP Server uses this 2 args ctor inside their test code.

> Is this being worked on, at least for a single mode implementation?
I dug source code a bit and found out dual network (v4/v6) support need bunch of works, so I gave up full version support and wrote a tiny patch to add simple IPv4-only proxy ctor.

I just sent a pull-req to Mono team.
https://github.com/mono/mono/pull/1364
Let's see how it goes.
Comment 5 Miguel de Icaza [MSFT] 2014-10-25 23:59:08 UTC
The patch merely moves the hardcoding from one place to another.

I do not believe Unix supports this, so I am not sure that this idiom should be used in KRuntime in the first place.
Comment 6 Kei Nakazawa 2014-10-30 00:09:10 UTC
Miguel,

thanks for your comment. Here's the second-stage consideration.

Section 5.3 of RFC 3493 http://tools.ietf.org/html/rfc3493#section-5.3 states:

> AF_INET6 sockets may be used for both IPv4 and IPv6 communications.
> Some applications may want to restrict their use of an AF_INET6 socket to IPv6 communications only.  For these applications the IPV6_V6ONLY socket option is defined.

So, most IPv6 implementations should behave just fine as v4/v6 dual stack with AF_INET6 option.

So, my guess is just putting AddressFamily.InterNetworkV6 on Socket ctor (w/ combination of OSSupportsIPv6 property) work on Linux/FreeBSD/MacOSX. But needs tests.

I'll continue to work on this to find out whether it works or not, then it it does, I'll also write some test code for regression testing.

If this approach doesn't work, I'll dig into C implementation of socket:
mono/io-layer/sockets.c
mono/metadata/socket-io.c
and find out another way.
Comment 7 Miguel de Icaza [MSFT] 2015-04-18 22:04:47 UTC
Thanks for the pointer, I am making the constructor explicitly use InterNetworkV6 as this is what Unix does in general.   

For now, I am leaving the Unix defaults in place.   This means that the original constructor when passed an AddressFamily.InterNetworkV6 will bind to both ipv4 and ipv6 addresses, just like Unix does by default.

The rationale for doing this, and not adding a separate code path to explicitly call the setsockopt to turn off binding to an IPV4 address is two fold: it would be a breaking change for existing working applications and because that the mere existence and use of the IPV6_V6ONY is hotly debated.
Comment 8 Miguel de Icaza [MSFT] 2015-04-20 15:30:26 UTC
This is now in, and will default to binding to both ipv4 and ipv6.

I incorporated some of the .NET code to bring the "DualMode" property, but did
not bring the enforcement pieces, as we do not want to break Mono's existing
behavior (which was that binding to the IPV6 port would also bind to IPV4).

The .NET behavior causes InternetWorkv6 sockets to set DualMode to false, which
prevents the binding to either address.

Mono's behavior is different, to prevent breaking compatibility and if you want
to merely bind to IpV6, you need to manually set DualMode to false on the
socket after it has been created.