diff options
author | Ludovic Henry <ludovic@xamarin.com> | 2016-01-27 12:51:42 +0300 |
---|---|---|
committer | Ludovic Henry <ludovic@xamarin.com> | 2016-01-27 12:51:42 +0300 |
commit | 78c758494a04132c0965f8af82dd7370da5f4af1 (patch) | |
tree | a4df8074d1e3275063659e798701508c6058450a | |
parent | 7c9e71be5e56f952ba14af8afcd9de5ebf89ca6f (diff) | |
parent | a30b26eeaa876fb06b841dde29db2d2d4ca7c670 (diff) |
Merge pull request #2420 from stefansedich/master
Handle automatically mapping IPv4 addresses to IPV6 for dual mode sockets, fixes #36192
-rw-r--r-- | mcs/class/System/System.Net.Sockets/Socket.cs | 25 | ||||
-rwxr-xr-x | mcs/class/System/Test/System.Net.Sockets/SocketTest.cs | 47 |
2 files changed, 70 insertions, 2 deletions
diff --git a/mcs/class/System/System.Net.Sockets/Socket.cs b/mcs/class/System/System.Net.Sockets/Socket.cs index 8d48b675ae8..0f1c977a71d 100644 --- a/mcs/class/System/System.Net.Sockets/Socket.cs +++ b/mcs/class/System/System.Net.Sockets/Socket.cs @@ -1147,7 +1147,12 @@ namespace System.Net.Sockets if (local_end == null) throw new ArgumentNullException("local_end"); - + + var ipEndPoint = local_end as IPEndPoint; + if (ipEndPoint != null) { + local_end = RemapIPEndPoint (ipEndPoint); + } + int error; Bind_internal (safe_handle, local_end.Serialize(), out error); @@ -1239,6 +1244,8 @@ namespace System.Net.Sockets int error = 0; foreach (IPAddress address in addresses) { IPEndPoint iep = new IPEndPoint (address, port); + + iep = RemapIPEndPoint (iep); Connect_internal (safe_handle, iep.Serialize (), out error); if (error == 0) { @@ -1283,6 +1290,10 @@ namespace System.Net.Sockets if (is_listening) throw new InvalidOperationException (); + + if (ep != null) { + remoteEP = RemapIPEndPoint (ep); + } SocketAddress serial = remoteEP.Serialize (); @@ -1408,6 +1419,8 @@ namespace System.Net.Sockets sockares.Complete (new SocketException ((int) SocketError.AddressNotAvailable), true); return sockares; } + + end_point = RemapIPEndPoint (ep); } int error = 0; @@ -3444,7 +3457,15 @@ namespace System.Net.Sockets throw new NotImplementedException (String.Format ("Operation {0} is not implemented", op)); } } - + + IPEndPoint RemapIPEndPoint (IPEndPoint input) { + // If socket is DualMode ensure we automatically handle mapping IPv4 addresses to IPv6. + if (IsDualMode && input.AddressFamily == AddressFamily.InterNetwork) + return new IPEndPoint (input.Address.MapToIPv6 (), input.Port); + + return input; + } + [StructLayout (LayoutKind.Sequential)] struct WSABUF { public int len; diff --git a/mcs/class/System/Test/System.Net.Sockets/SocketTest.cs b/mcs/class/System/Test/System.Net.Sockets/SocketTest.cs index 2f85b7b795e..c6ca3ef5b2d 100755 --- a/mcs/class/System/Test/System.Net.Sockets/SocketTest.cs +++ b/mcs/class/System/Test/System.Net.Sockets/SocketTest.cs @@ -4328,6 +4328,53 @@ namespace MonoTests.System.Net.Sockets } } + [Test] + public void ConnectToIPV4EndPointUsingDualModelSocket () { + using (var server = new Socket (SocketType.Stream, ProtocolType.Tcp)) + using (var client = new Socket (SocketType.Stream, ProtocolType.Tcp)) { + var host = new IPEndPoint (IPAddress.Loopback, 0); + + server.Bind (host); + server.Listen (0); + + var ep = server.LocalEndPoint as IPEndPoint; + + client.Connect (ep); + client.Disconnect (true); + + client.Connect (IPAddress.Loopback, ep.Port); + client.Disconnect (true); + + client.Connect (new [] {IPAddress.Loopback}, ep.Port); + client.Disconnect (true); + } + } + + [Test] + public void BeginConnectToIPV4EndPointUsingDualModelSocket () { + using (var server = new Socket (SocketType.Stream, ProtocolType.Tcp)) + using (var client = new Socket (SocketType.Stream, ProtocolType.Tcp)) { + var host = new IPEndPoint (IPAddress.Loopback, 0); + + server.Bind (host); + server.Listen (0); + + var ep = server.LocalEndPoint as IPEndPoint; + + var ar1 = client.BeginConnect (ep, BCCallback, client); + client.EndConnect (ar1); + client.Disconnect (true); + + var ar2 = client.BeginConnect (IPAddress.Loopback, ep.Port, BCCallback, client); + client.EndConnect (ar2); + client.Disconnect (true); + + var ar3 = client.BeginConnect (new [] {IPAddress.Loopback}, ep.Port, BCCallback, client); + client.EndConnect (ar3); + client.Disconnect (true); + } + } + Socket StartSocketServer () { |