From 38fe46837aae576b8d1fdaa3177ddb3c24fa6018 Mon Sep 17 00:00:00 2001
From: Radek Zikmund <32671551+rzikm@users.noreply.github.com>
Date: Wed, 30 Mar 2022 12:40:32 +0200
Subject: [PATCH] Use shared SocketAddress code in QUIC (#66794)
* Use shared SocketAddress code in QUIC
* Code review feedback
* Disable broken tests
* Rename file
---
.../src/Resources/Strings.resx | 7 +++
.../src/System.Net.Quic.csproj | 9 ++++
.../Quic/Implementations/Mock/MockListener.cs | 2 +-
.../MsQuic/Internal/MsQuicAddressHelpers.cs | 43 ++-------------
.../MsQuic/Internal/MsQuicParameterHelpers.cs | 38 ++++++++++---
.../MsQuic/Interop/MsQuicNativeMethods.cs | 53 ++-----------------
.../MsQuic/MsQuicConnection.cs | 31 ++++-------
.../Implementations/MsQuic/MsQuicListener.cs | 16 +++---
.../tests/FunctionalTests/MsQuicTests.cs | 11 ++++
.../FunctionalTests/QuicListenerTests.cs | 16 ++++++
10 files changed, 103 insertions(+), 123 deletions(-)
diff --git a/src/libraries/System.Net.Quic/src/Resources/Strings.resx b/src/libraries/System.Net.Quic/src/Resources/Strings.resx
index af6bfa4d295..4eb23ece75c 100644
--- a/src/libraries/System.Net.Quic/src/Resources/Strings.resx
+++ b/src/libraries/System.Net.Quic/src/Resources/Strings.resx
@@ -168,5 +168,12 @@
Could not use a TLS version required by Quic. TLS 1.3 may have been disabled in the registry.
+
+
+ The AddressFamily {0} is not valid for the {1} end point, use {2} instead.
+
+
+ The supplied {0} is an invalid size for the {1} end point.
+
diff --git a/src/libraries/System.Net.Quic/src/System.Net.Quic.csproj b/src/libraries/System.Net.Quic/src/System.Net.Quic.csproj
index 171290fcbb3..c1f0c1ac644 100644
--- a/src/libraries/System.Net.Quic/src/System.Net.Quic.csproj
+++ b/src/libraries/System.Net.Quic/src/System.Net.Quic.csproj
@@ -50,6 +50,10 @@
+
+
+
+
@@ -70,12 +74,15 @@
+
+
+
@@ -97,6 +104,7 @@
+
@@ -129,6 +137,7 @@
+
diff --git a/src/libraries/System.Net.Quic/src/System/Net/Quic/Implementations/Mock/MockListener.cs b/src/libraries/System.Net.Quic/src/System/Net/Quic/Implementations/Mock/MockListener.cs
index 48ebf8a0603..1be34005051 100644
--- a/src/libraries/System.Net.Quic/src/System/Net/Quic/Implementations/Mock/MockListener.cs
+++ b/src/libraries/System.Net.Quic/src/System/Net/Quic/Implementations/Mock/MockListener.cs
@@ -22,7 +22,7 @@ internal sealed class MockListener : QuicListenerProvider
internal MockListener(QuicListenerOptions options)
{
- if (options.ListenEndPoint is null || options.ListenEndPoint.Address != IPAddress.Loopback || options.ListenEndPoint.Port != 0)
+ if (options.ListenEndPoint is null || (options.ListenEndPoint.Address != IPAddress.Loopback && options.ListenEndPoint.Address != IPAddress.IPv6Loopback) || options.ListenEndPoint.Port != 0)
{
throw new ArgumentException("Must pass loopback address and port 0");
}
diff --git a/src/libraries/System.Net.Quic/src/System/Net/Quic/Implementations/MsQuic/Internal/MsQuicAddressHelpers.cs b/src/libraries/System.Net.Quic/src/System/Net/Quic/Implementations/MsQuic/Internal/MsQuicAddressHelpers.cs
index d280fb8d039..9163794f7a0 100644
--- a/src/libraries/System.Net.Quic/src/System/Net/Quic/Implementations/MsQuic/Internal/MsQuicAddressHelpers.cs
+++ b/src/libraries/System.Net.Quic/src/System/Net/Quic/Implementations/MsQuic/Internal/MsQuicAddressHelpers.cs
@@ -9,46 +9,11 @@ namespace System.Net.Quic.Implementations.MsQuic.Internal
{
internal static class MsQuicAddressHelpers
{
- internal static unsafe IPEndPoint INetToIPEndPoint(ref SOCKADDR_INET inetAddress)
+ internal static unsafe IPEndPoint INetToIPEndPoint(IntPtr pInetAddress)
{
- if (inetAddress.si_family == QUIC_ADDRESS_FAMILY.INET)
- {
- return new IPEndPoint(new IPAddress(MemoryMarshal.CreateReadOnlySpan(ref inetAddress.Ipv4.sin_addr[0], 4)), (ushort)IPAddress.NetworkToHostOrder((short)inetAddress.Ipv4.sin_port));
- }
- else
- {
- return new IPEndPoint(new IPAddress(MemoryMarshal.CreateReadOnlySpan(ref inetAddress.Ipv6.sin6_addr[0], 16)), (ushort)IPAddress.NetworkToHostOrder((short)inetAddress.Ipv6.sin6_port));
- }
- }
-
- internal static unsafe SOCKADDR_INET IPEndPointToINet(IPEndPoint endpoint)
- {
- SOCKADDR_INET socketAddress = default;
- if (!endpoint.Address.Equals(IPAddress.Any) && !endpoint.Address.Equals(IPAddress.IPv6Any))
- {
- switch (endpoint.Address.AddressFamily)
- {
- case AddressFamily.InterNetwork:
- endpoint.Address.TryWriteBytes(MemoryMarshal.CreateSpan(ref socketAddress.Ipv4.sin_addr[0], 4), out _);
- socketAddress.Ipv4.sin_family = QUIC_ADDRESS_FAMILY.INET;
- break;
- case AddressFamily.InterNetworkV6:
- endpoint.Address.TryWriteBytes(MemoryMarshal.CreateSpan(ref socketAddress.Ipv6.sin6_addr[0], 16), out _);
- socketAddress.Ipv6.sin6_family = QUIC_ADDRESS_FAMILY.INET6;
- break;
- default:
- throw new ArgumentException(SR.net_quic_addressfamily_notsupported);
- }
- }
-
- SetPort(endpoint.Address.AddressFamily, ref socketAddress, endpoint.Port);
- return socketAddress;
- }
-
- private static void SetPort(AddressFamily addressFamily, ref SOCKADDR_INET socketAddrInet, int originalPort)
- {
- ushort convertedPort = (ushort)IPAddress.HostToNetworkOrder((short)originalPort);
- socketAddrInet.Ipv4.sin_port = convertedPort;
+ // MsQuic always uses storage size as if IPv6 was used
+ Span addressBytes = new Span((byte*)pInetAddress, Internals.SocketAddress.IPv6AddressSize);
+ return new Internals.SocketAddress(SocketAddressPal.GetAddressFamily(addressBytes), addressBytes).GetIPEndPoint();
}
}
}
diff --git a/src/libraries/System.Net.Quic/src/System/Net/Quic/Implementations/MsQuic/Internal/MsQuicParameterHelpers.cs b/src/libraries/System.Net.Quic/src/System/Net/Quic/Implementations/MsQuic/Internal/MsQuicParameterHelpers.cs
index 63672d2a6e1..33ba18920d9 100644
--- a/src/libraries/System.Net.Quic/src/System/Net/Quic/Implementations/MsQuic/Internal/MsQuicParameterHelpers.cs
+++ b/src/libraries/System.Net.Quic/src/System/Net/Quic/Implementations/MsQuic/Internal/MsQuicParameterHelpers.cs
@@ -3,22 +3,46 @@
using System.Diagnostics;
using System.Runtime.InteropServices;
+using System.Net.Sockets;
using static System.Net.Quic.Implementations.MsQuic.Internal.MsQuicNativeMethods;
namespace System.Net.Quic.Implementations.MsQuic.Internal
{
internal static class MsQuicParameterHelpers
{
- internal static unsafe SOCKADDR_INET GetINetParam(MsQuicApi api, SafeHandle nativeObject, QUIC_PARAM_LEVEL level, uint param)
+ internal static unsafe IPEndPoint GetIPEndPointParam(MsQuicApi api, SafeHandle nativeObject, QUIC_PARAM_LEVEL level, uint param)
{
- SOCKADDR_INET value;
- uint valueLen = (uint)sizeof(SOCKADDR_INET);
+ // MsQuic always uses storage size as if IPv6 was used
+ uint valueLen = (uint)Internals.SocketAddress.IPv6AddressSize;
+ Span address = stackalloc byte[Internals.SocketAddress.IPv6AddressSize];
- uint status = api.GetParamDelegate(nativeObject, level, param, ref valueLen, (byte*)&value);
- QuicExceptionHelpers.ThrowIfFailed(status, "GetINETParam failed.");
- Debug.Assert(valueLen == sizeof(SOCKADDR_INET));
+ fixed (byte* paddress = &MemoryMarshal.GetReference(address))
+ {
+ uint status = api.GetParamDelegate(nativeObject, level, param, ref valueLen, paddress);
+ QuicExceptionHelpers.ThrowIfFailed(status, "GetIPEndPointParam failed.");
+ }
- return value;
+ address = address.Slice(0, (int)valueLen);
+
+ return new Internals.SocketAddress(SocketAddressPal.GetAddressFamily(address), address)
+ .GetIPEndPoint();
+ }
+
+ internal static unsafe void SetIPEndPointParam(MsQuicApi api, SafeHandle nativeObject, QUIC_PARAM_LEVEL level, uint param, IPEndPoint value)
+ {
+ Internals.SocketAddress socketAddress = IPEndPointExtensions.Serialize(value);
+
+ // MsQuic always reads same amount of memory as if IPv6 was used, so we can't pass pointer to socketAddress.Buffer directly
+ Span address = stackalloc byte[Internals.SocketAddress.IPv6AddressSize];
+ socketAddress.Buffer.AsSpan(0, socketAddress.Size).CopyTo(address);
+ address.Slice(socketAddress.Size).Clear();
+
+ fixed (byte* paddress = &MemoryMarshal.GetReference(address))
+ {
+ QuicExceptionHelpers.ThrowIfFailed(
+ api.SetParamDelegate(nativeObject, level, param, (uint)address.Length, paddress),
+ "Could not set IPEndPoint");
+ }
}
internal static unsafe ushort GetUShortParam(MsQuicApi api, SafeHandle nativeObject, QUIC_PARAM_LEVEL level, uint param)
diff --git a/src/libraries/System.Net.Quic/src/System/Net/Quic/Implementations/MsQuic/Interop/MsQuicNativeMethods.cs b/src/libraries/System.Net.Quic/src/System/Net/Quic/Implementations/MsQuic/Interop/MsQuicNativeMethods.cs
index d863398e0d8..681bc94bdb4 100644
--- a/src/libraries/System.Net.Quic/src/System/Net/Quic/Implementations/MsQuic/Interop/MsQuicNativeMethods.cs
+++ b/src/libraries/System.Net.Quic/src/System/Net/Quic/Implementations/MsQuic/Interop/MsQuicNativeMethods.cs
@@ -422,7 +422,7 @@ internal struct NewConnectionInfo
SafeMsQuicListenerHandle listener,
QuicBuffer* alpnBuffers,
uint alpnBufferCount,
- ref SOCKADDR_INET localAddress);
+ byte* localAddress);
internal delegate void ListenerStopDelegate(
SafeMsQuicListenerHandle listener);
@@ -649,48 +649,6 @@ internal struct StreamEvent
internal StreamEventDataUnion Data;
}
- // TODO: rename to C#-like
- [StructLayout(LayoutKind.Sequential)]
- internal struct SOCKADDR_IN
- {
-#if SOCKADDR_HAS_LENGTH
- internal byte sin_len;
-#endif
- internal QUIC_ADDRESS_FAMILY sin_family;
- internal ushort sin_port;
- internal fixed byte sin_addr[4];
- }
-
- // TODO: rename to C#-like
- [StructLayout(LayoutKind.Sequential)]
- internal struct SOCKADDR_IN6
- {
-#if SOCKADDR_HAS_LENGTH
- internal byte sin6_len;
-#endif
- internal QUIC_ADDRESS_FAMILY sin6_family;
- internal ushort sin6_port;
- internal uint sin6_flowinfo;
- internal fixed byte sin6_addr[16];
- internal uint sin6_scope_id;
- }
-
- // TODO: rename to C#-like
- [StructLayout(LayoutKind.Explicit)]
- internal struct SOCKADDR_INET
- {
- [FieldOffset(0)]
- internal SOCKADDR_IN Ipv4;
- [FieldOffset(0)]
- internal SOCKADDR_IN6 Ipv6;
-#if SOCKADDR_HAS_LENGTH
- [FieldOffset(1)]
-#else
- [FieldOffset(0)]
-#endif
- internal QUIC_ADDRESS_FAMILY si_family;
- }
-
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
internal delegate uint StreamCallbackDelegate(
IntPtr stream,
@@ -1061,9 +1019,9 @@ internal uint ListenerOpen(SafeMsQuicRegistrationHandle registration, ListenerCa
return __retVal;
}
- internal uint ListenerStart(SafeMsQuicListenerHandle listener, QuicBuffer* alpnBuffers, uint alpnBufferCount, ref SOCKADDR_INET localAddress)
+ internal uint ListenerStart(SafeMsQuicListenerHandle listener, QuicBuffer* alpnBuffers, uint alpnBufferCount, byte* localAddress)
{
- IntPtr __listener_gen_native = default;
+ IntPtr __listener_gen_native;
uint __retVal;
//
// Setup
@@ -1076,10 +1034,7 @@ internal uint ListenerStart(SafeMsQuicListenerHandle listener, QuicBuffer* alpnB
//
listener.DangerousAddRef(ref listener__addRefd);
__listener_gen_native = listener.DangerousGetHandle();
- fixed (SOCKADDR_INET* __localAddress_gen_native = &localAddress)
- {
- __retVal = ((delegate* unmanaged[Cdecl])_functionPointer)(__listener_gen_native, alpnBuffers, alpnBufferCount, __localAddress_gen_native);
- }
+ __retVal = ((delegate* unmanaged[Cdecl])_functionPointer)(__listener_gen_native, alpnBuffers, alpnBufferCount, localAddress);
}
finally
{
diff --git a/src/libraries/System.Net.Quic/src/System/Net/Quic/Implementations/MsQuic/MsQuicConnection.cs b/src/libraries/System.Net.Quic/src/System/Net/Quic/Implementations/MsQuic/MsQuicConnection.cs
index 7b9903a313c..5d3a7e868a7 100644
--- a/src/libraries/System.Net.Quic/src/System/Net/Quic/Implementations/MsQuic/MsQuicConnection.cs
+++ b/src/libraries/System.Net.Quic/src/System/Net/Quic/Implementations/MsQuic/MsQuicConnection.cs
@@ -252,10 +252,10 @@ private static uint HandleEventConnected(State state, ref ConnectionEvent connec
{
// Connected will already be true for connections accepted from a listener.
Debug.Assert(!Monitor.IsEntered(state));
- SOCKADDR_INET inetAddress = MsQuicParameterHelpers.GetINetParam(MsQuicApi.Api, state.Handle, QUIC_PARAM_LEVEL.CONNECTION, (uint)QUIC_PARAM_CONN.LOCAL_ADDRESS);
+
Debug.Assert(state.Connection != null);
- state.Connection._localEndPoint = MsQuicAddressHelpers.INetToIPEndPoint(ref inetAddress);
+ state.Connection._localEndPoint = MsQuicParameterHelpers.GetIPEndPointParam(MsQuicApi.Api, state.Handle, QUIC_PARAM_LEVEL.CONNECTION, (uint)QUIC_PARAM_CONN.LOCAL_ADDRESS);
state.Connection.SetNegotiatedAlpn(connectionEvent.Data.Connected.NegotiatedAlpn, connectionEvent.Data.Connected.NegotiatedAlpnLength);
state.Connection = null;
@@ -640,24 +640,18 @@ internal override ValueTask ConnectAsync(CancellationToken cancellationToken = d
string targetHost;
int port;
- if (_remoteEndPoint is IPEndPoint)
+ if (_remoteEndPoint is IPEndPoint ipEndPoint)
{
- SOCKADDR_INET address = MsQuicAddressHelpers.IPEndPointToINet((IPEndPoint)_remoteEndPoint);
- unsafe
- {
- Debug.Assert(!Monitor.IsEntered(_state), "!Monitor.IsEntered(_state)");
- status = MsQuicApi.Api.SetParamDelegate(_state.Handle, QUIC_PARAM_LEVEL.CONNECTION, (uint)QUIC_PARAM_CONN.REMOTE_ADDRESS, (uint)sizeof(SOCKADDR_INET), (byte*)&address);
- QuicExceptionHelpers.ThrowIfFailed(status, "Failed to connect to peer.");
- }
-
+ Debug.Assert(!Monitor.IsEntered(_state), "!Monitor.IsEntered(_state)");
+ MsQuicParameterHelpers.SetIPEndPointParam(MsQuicApi.Api, _state.Handle, QUIC_PARAM_LEVEL.CONNECTION, (uint)QUIC_PARAM_CONN.REMOTE_ADDRESS, ipEndPoint);
targetHost = _state.TargetHost ?? ((IPEndPoint)_remoteEndPoint).Address.ToString();
port = ((IPEndPoint)_remoteEndPoint).Port;
}
- else if (_remoteEndPoint is DnsEndPoint)
+ else if (_remoteEndPoint is DnsEndPoint dnsEndPoint)
{
- port = ((DnsEndPoint)_remoteEndPoint).Port;
- string dnsHost = ((DnsEndPoint)_remoteEndPoint).Host!;
+ port = dnsEndPoint.Port;
+ string dnsHost = dnsEndPoint.Host!;
// We don't have way how to set separate SNI and name for connection at this moment.
// If the name is actually IP address we can use it to make at least some cases work for people
@@ -665,13 +659,8 @@ internal override ValueTask ConnectAsync(CancellationToken cancellationToken = d
if (!string.IsNullOrEmpty(_state.TargetHost) && !dnsHost.Equals(_state.TargetHost, StringComparison.InvariantCultureIgnoreCase) && IPAddress.TryParse(dnsHost, out IPAddress? address))
{
// This is form of IPAddress and _state.TargetHost is set to different string
- SOCKADDR_INET quicAddress = MsQuicAddressHelpers.IPEndPointToINet(new IPEndPoint(address, port));
- unsafe
- {
- Debug.Assert(!Monitor.IsEntered(_state), "!Monitor.IsEntered(_state)");
- status = MsQuicApi.Api.SetParamDelegate(_state.Handle, QUIC_PARAM_LEVEL.CONNECTION, (uint)QUIC_PARAM_CONN.REMOTE_ADDRESS, (uint)sizeof(SOCKADDR_INET), (byte*)&quicAddress);
- QuicExceptionHelpers.ThrowIfFailed(status, "Failed to connect to peer.");
- }
+ Debug.Assert(!Monitor.IsEntered(_state), "!Monitor.IsEntered(_state)");
+ MsQuicParameterHelpers.SetIPEndPointParam(MsQuicApi.Api, _state.Handle, QUIC_PARAM_LEVEL.CONNECTION, (uint)QUIC_PARAM_CONN.REMOTE_ADDRESS, new IPEndPoint(address, port));
targetHost = _state.TargetHost!;
}
else
diff --git a/src/libraries/System.Net.Quic/src/System/Net/Quic/Implementations/MsQuic/MsQuicListener.cs b/src/libraries/System.Net.Quic/src/System/Net/Quic/Implementations/MsQuic/MsQuicListener.cs
index 0e65bf662aa..ab4969a8178 100644
--- a/src/libraries/System.Net.Quic/src/System/Net/Quic/Implementations/MsQuic/MsQuicListener.cs
+++ b/src/libraries/System.Net.Quic/src/System/Net/Quic/Implementations/MsQuic/MsQuicListener.cs
@@ -13,6 +13,7 @@
using System.Threading.Channels;
using System.Threading.Tasks;
using static System.Net.Quic.Implementations.MsQuic.Internal.MsQuicNativeMethods;
+using System.Net.Sockets;
namespace System.Net.Quic.Implementations.MsQuic
{
@@ -176,7 +177,7 @@ private unsafe IPEndPoint Start(QuicListenerOptions options)
List applicationProtocols = options.ServerAuthenticationOptions!.ApplicationProtocols!;
IPEndPoint listenEndPoint = options.ListenEndPoint!;
- SOCKADDR_INET address = MsQuicAddressHelpers.IPEndPointToINet(listenEndPoint);
+ Internals.SocketAddress address = IPEndPointExtensions.Serialize(listenEndPoint);
uint status;
@@ -188,7 +189,10 @@ private unsafe IPEndPoint Start(QuicListenerOptions options)
{
Debug.Assert(!Monitor.IsEntered(_state), "!Monitor.IsEntered(_state)");
MsQuicAlpnHelper.Prepare(applicationProtocols, out handles, out buffers);
- status = MsQuicApi.Api.ListenerStartDelegate(_state.Handle, (QuicBuffer*)Marshal.UnsafeAddrOfPinnedArrayElement(buffers, 0), (uint)applicationProtocols.Count, ref address);
+ fixed (byte* paddress = address.Buffer)
+ {
+ status = MsQuicApi.Api.ListenerStartDelegate(_state.Handle, (QuicBuffer*)Marshal.UnsafeAddrOfPinnedArrayElement(buffers, 0), (uint)applicationProtocols.Count, paddress);
+ }
}
catch
{
@@ -203,8 +207,7 @@ private unsafe IPEndPoint Start(QuicListenerOptions options)
QuicExceptionHelpers.ThrowIfFailed(status, "ListenerStart failed.");
Debug.Assert(!Monitor.IsEntered(_state), "!Monitor.IsEntered(_state)");
- SOCKADDR_INET inetAddress = MsQuicParameterHelpers.GetINetParam(MsQuicApi.Api, _state.Handle, QUIC_PARAM_LEVEL.LISTENER, (uint)QUIC_PARAM_LISTENER.LOCAL_ADDRESS);
- return MsQuicAddressHelpers.INetToIPEndPoint(ref inetAddress);
+ return MsQuicParameterHelpers.GetIPEndPointParam(MsQuicApi.Api, _state.Handle, QUIC_PARAM_LEVEL.LISTENER, (uint)QUIC_PARAM_LISTENER.LOCAL_ADDRESS);
}
private void Stop()
@@ -244,8 +247,9 @@ private void Stop()
{
ref NewConnectionInfo connectionInfo = ref *evt->Data.NewConnection.Info;
- IPEndPoint localEndPoint = MsQuicAddressHelpers.INetToIPEndPoint(ref *(SOCKADDR_INET*)connectionInfo.LocalAddress);
- IPEndPoint remoteEndPoint = MsQuicAddressHelpers.INetToIPEndPoint(ref *(SOCKADDR_INET*)connectionInfo.RemoteAddress);
+ IPEndPoint localEndPoint = MsQuicAddressHelpers.INetToIPEndPoint(connectionInfo.LocalAddress);
+ IPEndPoint remoteEndPoint = MsQuicAddressHelpers.INetToIPEndPoint(connectionInfo.RemoteAddress);
+
string targetHost = string.Empty; // compat with SslStream
if (connectionInfo.ServerNameLength > 0 && connectionInfo.ServerName != IntPtr.Zero)
{
diff --git a/src/libraries/System.Net.Quic/tests/FunctionalTests/MsQuicTests.cs b/src/libraries/System.Net.Quic/tests/FunctionalTests/MsQuicTests.cs
index be36ad9c39f..7db083a8da2 100644
--- a/src/libraries/System.Net.Quic/tests/FunctionalTests/MsQuicTests.cs
+++ b/src/libraries/System.Net.Quic/tests/FunctionalTests/MsQuicTests.cs
@@ -8,12 +8,14 @@
using System.Linq;
using System.Net.Security;
using System.Net.Sockets;
+using System.Runtime.InteropServices;
using System.Security.Authentication;
using System.Security.Cryptography;
using System.Security.Cryptography.X509Certificates;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
+using Microsoft.DotNet.XUnitExtensions;
using Xunit;
using Xunit.Abstractions;
@@ -141,6 +143,7 @@ public async Task UntrustedClientCertificateFails()
}
[Fact]
+ [ActiveIssue("https://github.com/dotnet/runtime/issues/67301", TestPlatforms.Linux)]
public async Task CertificateCallbackThrowPropagates()
{
using CancellationTokenSource cts = new CancellationTokenSource(PassingTestTimeout);
@@ -182,6 +185,7 @@ public async Task CertificateCallbackThrowPropagates()
}
[Fact]
+ [ActiveIssue("https://github.com/dotnet/runtime/issues/67301", TestPlatforms.Linux)]
public async Task ConnectWithCertificateCallback()
{
X509Certificate2 c1 = System.Net.Test.Common.Configuration.Certificates.GetServerCertificate();
@@ -311,6 +315,13 @@ public async Task ConnectWithCertificateForDifferentName_Throws()
public async Task ConnectWithCertificateForLoopbackIP_IndicatesExpectedError(string ipString, bool expectsError)
{
var ipAddress = IPAddress.Parse(ipString);
+
+ if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux) && ipAddress.AddressFamily == AddressFamily.InterNetworkV6)
+ {
+ // [ActiveIssue("https://github.com/dotnet/runtime/issues/67301")]
+ throw new SkipTestException("IPv6 on Linux is temporarily broken");
+ }
+
(X509Certificate2 certificate, _) = System.Net.Security.Tests.TestHelper.GenerateCertificates(expectsError ? "badhost" : "localhost");
var listenerOptions = new QuicListenerOptions();
diff --git a/src/libraries/System.Net.Quic/tests/FunctionalTests/QuicListenerTests.cs b/src/libraries/System.Net.Quic/tests/FunctionalTests/QuicListenerTests.cs
index 7e3097fa273..bacc79bc968 100644
--- a/src/libraries/System.Net.Quic/tests/FunctionalTests/QuicListenerTests.cs
+++ b/src/libraries/System.Net.Quic/tests/FunctionalTests/QuicListenerTests.cs
@@ -26,6 +26,22 @@ public async Task Listener_Backlog_Success()
await clientStreamTask;
}).WaitAsync(TimeSpan.FromSeconds(6));
}
+
+ [Fact]
+ [ActiveIssue("https://github.com/dotnet/runtime/issues/67301", TestPlatforms.Linux)]
+ public async Task Listener_Backlog_Success_IPv6()
+ {
+ await Task.Run(async () =>
+ {
+ using QuicListener listener = CreateQuicListener(new IPEndPoint(IPAddress.IPv6Loopback, 0));
+
+ using QuicConnection clientConnection = CreateQuicConnection(listener.ListenEndPoint);
+ var clientStreamTask = clientConnection.ConnectAsync();
+
+ using QuicConnection serverConnection = await listener.AcceptConnectionAsync();
+ await clientStreamTask;
+ }).WaitAsync(TimeSpan.FromSeconds(6));
+ }
}
[ConditionalClass(typeof(QuicTestBase), nameof(QuicTestBase.IsSupported))]
--
GitLab