From 6c131ea240b928fd4b2ea39231b6dff58f63a4a3 Mon Sep 17 00:00:00 2001 From: Stephen Halter Date: Tue, 21 Mar 2017 18:31:29 -0700 Subject: [PATCH] Verify scopeids are connectable using Socket before testing Kestrel (#1536) --- .../AddressRegistrationTests.cs | 43 ++++++++++++++++++- 1 file changed, 42 insertions(+), 1 deletion(-) diff --git a/test/Microsoft.AspNetCore.Server.Kestrel.FunctionalTests/AddressRegistrationTests.cs b/test/Microsoft.AspNetCore.Server.Kestrel.FunctionalTests/AddressRegistrationTests.cs index 572b45aa68..21dba18436 100644 --- a/test/Microsoft.AspNetCore.Server.Kestrel.FunctionalTests/AddressRegistrationTests.cs +++ b/test/Microsoft.AspNetCore.Server.Kestrel.FunctionalTests/AddressRegistrationTests.cs @@ -8,6 +8,7 @@ using System.Linq; using System.Net; using System.Net.NetworkInformation; using System.Net.Sockets; +using System.Threading; using System.Threading.Tasks; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; @@ -451,7 +452,9 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests // Dynamic port var ipv6Addresses = GetIPAddresses() .Where(ip => ip.AddressFamily == AddressFamily.InterNetworkV6) - .Where(ip => ip.ScopeId != 0); + .Where(ip => ip.ScopeId != 0) + .Where(ip => CanBindAndConnectToEndpoint(new IPEndPoint(ip, 0))); + foreach (var ip in ipv6Addresses) { dataset.Add($"http://[{ip}]:0/", GetTestUrls); @@ -531,6 +534,44 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests } } + private static bool CanBindAndConnectToEndpoint(IPEndPoint endPoint) + { + try + { + using (var serverSocket = new Socket(endPoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp)) + { + serverSocket.Bind(endPoint); + serverSocket.Listen(1); + + var socketArgs = new SocketAsyncEventArgs + { + RemoteEndPoint = serverSocket.LocalEndPoint + }; + + var mre = new ManualResetEventSlim(); + socketArgs.Completed += (s, e) => + { + mre.Set(); + e.ConnectSocket?.Dispose(); + }; + + // Connect can take a couple minutes to time out. + if (Socket.ConnectAsync(SocketType.Stream, ProtocolType.Tcp, socketArgs)) + { + return mre.Wait(5000) && socketArgs.SocketError == SocketError.Success; + } + else + { + return socketArgs.SocketError == SocketError.Success; + } + } + } + catch (SocketException) + { + return false; + } + } + [AttributeUsage(AttributeTargets.Method, AllowMultiple = false)] private class PortSupportedConditionAttribute : Attribute, ITestCondition {