Skip to content

Commit 88b3ebf

Browse files
authored
improve resiliency of quic test (#57020)
* improve resiliency of quic test * feedback from review * remove debug counters
1 parent 10402b3 commit 88b3ebf

File tree

8 files changed

+238
-234
lines changed

8 files changed

+238
-234
lines changed

src/libraries/System.Net.Quic/ref/System.Net.Quic.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ public partial class QuicException : System.Exception
4444
{
4545
public QuicException(string? message) { }
4646
public QuicException(string? message, System.Exception? innerException) { }
47+
public QuicException(string? message, System.Exception? innerException, int result) { }
4748
}
4849
public static partial class QuicImplementationProviders
4950
{

src/libraries/System.Net.Quic/src/Resources/Strings.resx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,9 @@
165165
<data name="net_quic_cert_chain_validation" xml:space="preserve">
166166
<value>The remote certificate is invalid because of errors in the certificate chain: {0}</value>
167167
</data>
168+
<data name="net_quic_not_connected" xml:space="preserve">
169+
<value>Connection is not connected.</value>
170+
</data>
168171
<data name="net_ssl_app_protocols_invalid" xml:space="preserve">
169172
<value>The application protocol list is invalid.</value>
170173
</data>

src/libraries/System.Net.Quic/src/System/Net/Quic/Implementations/MsQuic/Internal/QuicExceptionHelpers.cs

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
// Licensed to the .NET Foundation under one or more agreements.
22
// The .NET Foundation licenses this file to you under the MIT license.
33

4+
using System.Net.Sockets;
5+
46
namespace System.Net.Quic.Implementations.MsQuic.Internal
57
{
68
internal static class QuicExceptionHelpers
@@ -15,7 +17,22 @@ internal static void ThrowIfFailed(uint status, string? message = null, Exceptio
1517

1618
internal static Exception CreateExceptionForHResult(uint status, string? message = null, Exception? innerException = null)
1719
{
18-
return new QuicException($"{message} Error Code: {MsQuicStatusCodes.GetError(status)}", innerException);
20+
return new QuicException($"{message} Error Code: {MsQuicStatusCodes.GetError(status)}", innerException, MapMsQuicStatusToHResult(status));
21+
}
22+
23+
internal static int MapMsQuicStatusToHResult(uint status)
24+
{
25+
switch (status)
26+
{
27+
case MsQuicStatusCodes.ConnectionRefused:
28+
return (int)SocketError.ConnectionRefused; // 0x8007274D - WSAECONNREFUSED
29+
case MsQuicStatusCodes.ConnectionTimeout:
30+
return (int)SocketError.TimedOut; // 0x8007274C - WSAETIMEDOUT
31+
case MsQuicStatusCodes.HostUnreachable:
32+
return (int)SocketError.HostUnreachable;
33+
default:
34+
return 0;
35+
}
1936
}
2037
}
2138
}

src/libraries/System.Net.Quic/src/System/Net/Quic/Implementations/MsQuic/MsQuicConnection.cs

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -171,7 +171,12 @@ public MsQuicConnection(IPEndPoint localEndPoint, IPEndPoint remoteEndPoint, Saf
171171
// constructor for outbound connections
172172
public MsQuicConnection(QuicClientConnectionOptions options)
173173
{
174-
_remoteEndPoint = options.RemoteEndPoint!;
174+
if (options.RemoteEndPoint == null)
175+
{
176+
throw new ArgumentNullException(nameof(options.RemoteEndPoint));
177+
}
178+
179+
_remoteEndPoint = options.RemoteEndPoint;
175180
_configuration = SafeMsQuicConfigurationHandle.Create(options);
176181
_state.RemoteCertificateRequired = true;
177182
if (options.ClientAuthenticationOptions != null)
@@ -523,13 +528,21 @@ internal override ValueTask WaitForAvailableBidirectionalStreamsAsync(Cancellati
523528
internal override QuicStreamProvider OpenUnidirectionalStream()
524529
{
525530
ThrowIfDisposed();
531+
if (!Connected)
532+
{
533+
throw new InvalidOperationException(SR.net_quic_not_connected);
534+
}
526535

527536
return new MsQuicStream(_state, QUIC_STREAM_OPEN_FLAGS.UNIDIRECTIONAL);
528537
}
529538

530539
internal override QuicStreamProvider OpenBidirectionalStream()
531540
{
532541
ThrowIfDisposed();
542+
if (!Connected)
543+
{
544+
throw new InvalidOperationException(SR.net_quic_not_connected);
545+
}
533546

534547
return new MsQuicStream(_state, QUIC_STREAM_OPEN_FLAGS.NONE);
535548
}
@@ -552,15 +565,15 @@ internal override ValueTask ConnectAsync(CancellationToken cancellationToken = d
552565

553566
if (_configuration is null)
554567
{
555-
throw new Exception($"{nameof(ConnectAsync)} must not be called on a connection obtained from a listener.");
568+
throw new InvalidOperationException($"{nameof(ConnectAsync)} must not be called on a connection obtained from a listener.");
556569
}
557570

558571
QUIC_ADDRESS_FAMILY af = _remoteEndPoint.AddressFamily switch
559572
{
560573
AddressFamily.Unspecified => QUIC_ADDRESS_FAMILY.UNSPEC,
561574
AddressFamily.InterNetwork => QUIC_ADDRESS_FAMILY.INET,
562575
AddressFamily.InterNetworkV6 => QUIC_ADDRESS_FAMILY.INET6,
563-
_ => throw new Exception(SR.Format(SR.net_quic_unsupported_address_family, _remoteEndPoint.AddressFamily))
576+
_ => throw new ArgumentException(SR.Format(SR.net_quic_unsupported_address_family, _remoteEndPoint.AddressFamily))
564577
};
565578

566579
Debug.Assert(_state.StateGCHandle.IsAllocated);
@@ -592,7 +605,7 @@ internal override ValueTask ConnectAsync(CancellationToken cancellationToken = d
592605
}
593606
else
594607
{
595-
throw new Exception($"Unsupported remote endpoint type '{_remoteEndPoint.GetType()}'.");
608+
throw new ArgumentException($"Unsupported remote endpoint type '{_remoteEndPoint.GetType()}'.");
596609
}
597610

598611
// We store TCS to local variable to avoid NRE if callbacks finish fast and set _state.ConnectTcs to null.
@@ -759,7 +772,7 @@ private void Dispose(bool disposing)
759772
if (NetEventSource.Log.IsEnabled()) NetEventSource.Info(_state, $"{TraceId()} Connection disposing {disposing}");
760773

761774
// If we haven't already shutdown gracefully (via a successful CloseAsync call), then force an abortive shutdown.
762-
if (_state.Handle != null)
775+
if (_state.Handle != null && !_state.Handle.IsInvalid && !_state.Handle.IsClosed)
763776
{
764777
// Handle can be null if outbound constructor failed and we are called from finalizer.
765778
Debug.Assert(!Monitor.IsEntered(_state));

src/libraries/System.Net.Quic/src/System/Net/Quic/Implementations/MsQuic/MsQuicListener.cs

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@
1212
using System.Threading.Channels;
1313
using System.Threading.Tasks;
1414
using static System.Net.Quic.Implementations.MsQuic.Internal.MsQuicNativeMethods;
15-
using System.Security.Authentication;
1615

1716
namespace System.Net.Quic.Implementations.MsQuic
1817
{
@@ -219,15 +218,14 @@ private static unsafe uint NativeCallbackHandler(
219218
IntPtr context,
220219
ref ListenerEvent evt)
221220
{
222-
if (evt.Type != QUIC_LISTENER_EVENT.NEW_CONNECTION)
223-
{
224-
return MsQuicStatusCodes.InternalError;
225-
}
226-
227221
GCHandle gcHandle = GCHandle.FromIntPtr(context);
228222
Debug.Assert(gcHandle.IsAllocated);
229223
Debug.Assert(gcHandle.Target is not null);
230224
var state = (State)gcHandle.Target;
225+
if (evt.Type != QUIC_LISTENER_EVENT.NEW_CONNECTION)
226+
{
227+
return MsQuicStatusCodes.InternalError;
228+
}
231229

232230
SafeMsQuicConnectionHandle? connectionHandle = null;
233231
MsQuicConnection? msQuicConnection = null;

src/libraries/System.Net.Quic/src/System/Net/Quic/QuicException.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,5 +13,11 @@ public QuicException(string? message, Exception? innerException)
1313
: base(message, innerException)
1414
{
1515
}
16+
17+
public QuicException(string? message, Exception? innerException, int result)
18+
: base(message, innerException)
19+
{
20+
HResult = result;
21+
}
1622
}
1723
}

0 commit comments

Comments
 (0)