diff --git a/src/libraries/System.Net.Quic/ref/System.Net.Quic.cs b/src/libraries/System.Net.Quic/ref/System.Net.Quic.cs index 1958aed186b996..dcebe2b547ea3d 100644 --- a/src/libraries/System.Net.Quic/ref/System.Net.Quic.cs +++ b/src/libraries/System.Net.Quic/ref/System.Net.Quic.cs @@ -64,8 +64,8 @@ public sealed partial class QuicException : System.IO.IOException { public QuicException(System.Net.Quic.QuicError error, long? applicationErrorCode, string message) { } public long? ApplicationErrorCode { get { throw null; } } - public long? TransportErrorCode { get { throw null; } } public System.Net.Quic.QuicError QuicError { get { throw null; } } + public long? TransportErrorCode { get { throw null; } } } public sealed partial class QuicListener : System.IAsyncDisposable { @@ -136,3 +136,63 @@ public enum QuicStreamType Bidirectional = 1, } } +namespace System.Net.Quic.Implementations.Managed +{ + public sealed partial class ManagedQuicConnection : System.IAsyncDisposable + { + public ManagedQuicConnection(System.Net.Quic.QuicClientConnectionOptions options) { } + public System.Net.IPEndPoint LocalEndPoint { get { throw null; } } + public System.Net.Security.SslApplicationProtocol NegotiatedApplicationProtocol { get { throw null; } } + public System.Security.Cryptography.X509Certificates.X509Certificate? RemoteCertificate { get { throw null; } } + public System.Net.EndPoint RemoteEndPoint { get { throw null; } } + public System.Threading.Tasks.ValueTask AcceptInboundStreamAsync(System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } + public System.Threading.Tasks.ValueTask CloseAsync(long errorCode, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } + public System.Threading.Tasks.ValueTask DisposeAsync() { throw null; } + public System.Threading.Tasks.ValueTask OpenOutboundStreamAsync(System.Net.Quic.QuicStreamType type, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } + } + public sealed partial class ManagedQuicListener : System.IAsyncDisposable + { + internal ManagedQuicListener() { } + public static bool IsSupported { get { throw null; } } + public System.Net.IPEndPoint ListenEndPoint { get { throw null; } } + public System.Threading.Tasks.ValueTask AcceptConnectionAsync(System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } + public System.Threading.Tasks.ValueTask DisposeAsync() { throw null; } + public static System.Threading.Tasks.ValueTask ListenAsync(System.Net.Quic.QuicListenerOptions options, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } + } + public sealed partial class ManagedQuicStream : System.IO.Stream + { + internal ManagedQuicStream() { } + public override bool CanRead { get { throw null; } } + public override bool CanSeek { get { throw null; } } + public override bool CanTimeout { get { throw null; } } + public override bool CanWrite { get { throw null; } } + public long Id { get { throw null; } } + public override long Length { get { throw null; } } + public override long Position { get { throw null; } set { } } + public System.Threading.Tasks.Task ReadClosed { get { throw null; } } + public override int ReadTimeout { get { throw null; } set { } } + public System.Threading.Tasks.Task WriteClosed { get { throw null; } } + public override int WriteTimeout { get { throw null; } set { } } + public void Abort(System.Net.Quic.QuicAbortDirection abortDirection, long errorCode) { } + public void CompleteWrites() { } + protected override void Dispose(bool disposing) { } + public override System.Threading.Tasks.ValueTask DisposeAsync() { throw null; } + public override void Flush() { } + public override System.Threading.Tasks.Task FlushAsync(System.Threading.CancellationToken cancellationToken) { throw null; } + public override int Read(byte[] buffer, int offset, int count) { throw null; } + public override int Read(System.Span buffer) { throw null; } + public override System.Threading.Tasks.ValueTask ReadAsync(System.Memory buffer, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } + public override long Seek(long offset, System.IO.SeekOrigin origin) { throw null; } + public override void SetLength(long value) { } + public System.Threading.Tasks.ValueTask ShutdownCompleted(System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } + public override void Write(byte[] buffer, int offset, int count) { } + public override void Write(System.ReadOnlySpan buffer) { } + public void Write(System.ReadOnlySpan buffer, bool endStream) { } + public System.Threading.Tasks.ValueTask WriteAsync(System.Buffers.ReadOnlySequence buffers, bool endStream, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } + public System.Threading.Tasks.ValueTask WriteAsync(System.Buffers.ReadOnlySequence buffers, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } + public System.Threading.Tasks.ValueTask WriteAsync(System.ReadOnlyMemory buffer, bool endStream, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } + public override System.Threading.Tasks.ValueTask WriteAsync(System.ReadOnlyMemory buffer, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } + public System.Threading.Tasks.ValueTask WriteAsync(System.ReadOnlyMemory> buffers, bool endStream, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } + public System.Threading.Tasks.ValueTask WriteAsync(System.ReadOnlyMemory> buffers, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } + } +} diff --git a/src/libraries/System.Net.Quic/src/System/Net/Quic/Implementations/Managed/Internal/Crypto/CryptoSealAesGcm.cs b/src/libraries/System.Net.Quic/src/System/Net/Quic/Implementations/Managed/Internal/Crypto/CryptoSealAesGcm.cs index 2c18dcd0df369e..7075f8cffb5fcd 100644 --- a/src/libraries/System.Net.Quic/src/System/Net/Quic/Implementations/Managed/Internal/Crypto/CryptoSealAesGcm.cs +++ b/src/libraries/System.Net.Quic/src/System/Net/Quic/Implementations/Managed/Internal/Crypto/CryptoSealAesGcm.cs @@ -22,7 +22,7 @@ internal CryptoSealAesGcm(byte[] key, byte[] headerKey, TlsCipherSuite cipherSui Debug.Assert(headerKey.Length == 16); CipherSuite = cipherSuite; - _aesGcm = new AesGcm(key); + _aesGcm = new AesGcm(key, IntegrityTagLength); } internal override TlsCipherSuite CipherSuite { get; } diff --git a/src/libraries/System.Net.Quic/src/System/Net/Quic/Implementations/Managed/Internal/Recovery/NewRenoCongestionController.cs b/src/libraries/System.Net.Quic/src/System/Net/Quic/Implementations/Managed/Internal/Recovery/NewRenoCongestionController.cs index 273807f571d4e5..16b56002cad750 100644 --- a/src/libraries/System.Net.Quic/src/System/Net/Quic/Implementations/Managed/Internal/Recovery/NewRenoCongestionController.cs +++ b/src/libraries/System.Net.Quic/src/System/Net/Quic/Implementations/Managed/Internal/Recovery/NewRenoCongestionController.cs @@ -90,7 +90,9 @@ private static bool InCongestionRecovery(RecoveryController recovery, long sentT return sentTimestamp < recovery.CongestionRecoveryStartTime; } +#pragma warning disable IDE0060 // Remove unused parameter private static bool InPersistentCongestion(SentPacket largestLostPacket) +#pragma warning restore IDE0060 // Remove unused parameter { // var pto = SmoothedRtt.Ticks + Math.Max(4 * RttVariation.Ticks, Recovery.TimerGranularity.Ticks) + // MaxAckDelay.Ticks; diff --git a/src/libraries/System.Net.Quic/src/System/Net/Quic/Implementations/Managed/Internal/Sockets/QuicConnectionContext.cs b/src/libraries/System.Net.Quic/src/System/Net/Quic/Implementations/Managed/Internal/Sockets/QuicConnectionContext.cs index 49faeff1f55ffa..f94fd986a761b8 100644 --- a/src/libraries/System.Net.Quic/src/System/Net/Quic/Implementations/Managed/Internal/Sockets/QuicConnectionContext.cs +++ b/src/libraries/System.Net.Quic/src/System/Net/Quic/Implementations/Managed/Internal/Sockets/QuicConnectionContext.cs @@ -41,7 +41,8 @@ internal sealed class QuicConnectionContext public QuicConnectionContext(QuicServerSocketContext parent, EndPoint remoteEndpoint, ReadOnlySpan odcid, TlsFactory tlsFactory) { _parent = parent; - Connection = new ManagedQuicConnection(parent.ListenerOptions, this, remoteEndpoint, odcid, tlsFactory); + // TODO-RZ: move processing of first packet to Listener and create connection context only after we get the QuicServerConnectionOptions. + Connection = new ManagedQuicConnection(parent.ListenerOptions.ConnectionOptionsCallback(null!, default, default).AsTask().GetAwaiter().GetResult(), this, remoteEndpoint, odcid, tlsFactory); Connection.SetSocketContext(this); ObjectPool? sentPacketPool = new ObjectPool(256); diff --git a/src/libraries/System.Net.Quic/src/System/Net/Quic/Implementations/Managed/Internal/Streams/ReceiveStream.cs b/src/libraries/System.Net.Quic/src/System/Net/Quic/Implementations/Managed/Internal/Streams/ReceiveStream.cs index 1f239d6db4c9d1..abb3511fe88c3e 100644 --- a/src/libraries/System.Net.Quic/src/System/Net/Quic/Implementations/Managed/Internal/Streams/ReceiveStream.cs +++ b/src/libraries/System.Net.Quic/src/System/Net/Quic/Implementations/Managed/Internal/Streams/ReceiveStream.cs @@ -455,7 +455,8 @@ private static void ReturnMemory(in StreamChunk chunk) public void OnFatalException(Exception e) { - if (e is QuicException qe && qe.QuicError == QuicError.ConnectionAborted && abortedException.ErrorCode == 0) + // TODO-RZ: This feels a bit fishy now, I don't remember why it was necesary. + if (e is QuicException qe && qe.QuicError == QuicError.ConnectionAborted && qe.ApplicationErrorCode == null) { _deliverableChannel.Writer.TryComplete(null); } @@ -484,7 +485,7 @@ private void SetStreamAborted(long errorCode, bool byUs) { _deliverableChannel.Writer.TryComplete(byUs ? new QuicException(QuicError.OperationAborted, null, "Stream aborted by us.") - : new QuicException(QuicError.StreamAborted, errorCode)); + : new QuicException(QuicError.StreamAborted, errorCode, "Read aborted by peer.")); } } } diff --git a/src/libraries/System.Net.Quic/src/System/Net/Quic/Implementations/Managed/Internal/Streams/SendStream.cs b/src/libraries/System.Net.Quic/src/System/Net/Quic/Implementations/Managed/Internal/Streams/SendStream.cs index 0f9fbba513f4a5..711d661fce9ef9 100644 --- a/src/libraries/System.Net.Quic/src/System/Net/Quic/Implementations/Managed/Internal/Streams/SendStream.cs +++ b/src/libraries/System.Net.Quic/src/System/Net/Quic/Implementations/Managed/Internal/Streams/SendStream.cs @@ -538,18 +538,18 @@ internal void ThrowIfAborted() { if (ResetByUs) { - throw new QuicOperationAbortedException(); + throw new QuicException(QuicError.OperationAborted, null, "Operation aborted."); } else { - throw new QuicStreamAbortedException("Stream aborted", Error.Value); + throw new QuicException(QuicError.StreamAborted, Error.Value, "Stream aborted"); } } } -#pragma warning disable CA1822 // mark as static +#pragma warning disable CA1822, IDE0060 // mark as static, remove unused parameter public void OnFatalException(Exception exception) -#pragma warning restore CA1822 // mark as static +#pragma warning restore CA1822, IDE0060 // mark as static { // TODO-RZ: handle callers blocking on other async tasks } diff --git a/src/libraries/System.Net.Quic/src/System/Net/Quic/Implementations/Managed/Internal/Tls/MockTls.cs b/src/libraries/System.Net.Quic/src/System/Net/Quic/Implementations/Managed/Internal/Tls/MockTls.cs index 657d3e57a09d3b..aaeeef68b2ff62 100644 --- a/src/libraries/System.Net.Quic/src/System/Net/Quic/Implementations/Managed/Internal/Tls/MockTls.cs +++ b/src/libraries/System.Net.Quic/src/System/Net/Quic/Implementations/Managed/Internal/Tls/MockTls.cs @@ -231,9 +231,9 @@ private void AddHandshakeData(EncryptionLevel level, ReadOnlySpan data) _connection.AddHandshakeData(level, data); } - private void SendTlsAlert(EncryptionLevel level, int alert) + private void SendTlsAlert(int alert) { - _connection.SendTlsAlert(level, alert); + _connection.SendTlsAlert(alert); } private void SetEncryptionSecrets(EncryptionLevel level, ReadOnlySpan readSecret, diff --git a/src/libraries/System.Net.Quic/src/System/Net/Quic/Implementations/Managed/Internal/Tls/OpenSsl/OpenSslTls.cs b/src/libraries/System.Net.Quic/src/System/Net/Quic/Implementations/Managed/Internal/Tls/OpenSsl/OpenSslTls.cs index 1291fe366f26f4..cd8f7117394d79 100644 --- a/src/libraries/System.Net.Quic/src/System/Net/Quic/Implementations/Managed/Internal/Tls/OpenSsl/OpenSslTls.cs +++ b/src/libraries/System.Net.Quic/src/System/Net/Quic/Implementations/Managed/Internal/Tls/OpenSsl/OpenSslTls.cs @@ -48,6 +48,7 @@ internal sealed class OpenSslTls : ITls Interop.OpenSslQuic.CryptoGetExNewIndex(Interop.OpenSslQuic.CRYPTO_EX_INDEX_SSL, 0, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero); +#if LINUX private static readonly TlsCipherSuite[] _supportedCiphers = { TlsCipherSuite.TLS_AES_128_GCM_SHA256, @@ -56,6 +57,7 @@ internal sealed class OpenSslTls : ITls // not supported yet // TlsCipherSuite.TLS_CHACHA20_POLY1305_SHA256 }; +#endif private static readonly IntPtr _callbacksPtr; @@ -150,8 +152,10 @@ private unsafe OpenSslTls(ManagedQuicConnection connection, Interop.OpenSslQuic.SslCtrl(_ssl, SslCtrlCommand.SetMaxProtoVersion, (long)OpenSslTlsVersion.Tls13, IntPtr.Zero); +#if LINUX // explicitly set allowed suites SetCiphersuites(cipherSuitesPolicy); +#endif // init transport parameters byte[] buffer = new byte[1024]; @@ -161,10 +165,7 @@ private unsafe OpenSslTls(ManagedQuicConnection connection, Interop.OpenSslQuic.SslSetQuicTransportParams(_ssl, pData, new IntPtr(written)); } - if (applicationProtocols == null) - { - throw new ArgumentNullException(nameof(SslServerAuthenticationOptions.ApplicationProtocols)); - } + ArgumentNullException.ThrowIfNull(applicationProtocols, nameof(SslServerAuthenticationOptions.ApplicationProtocols)); _alpnProtocols = applicationProtocols; SetAlpn(applicationProtocols); @@ -245,6 +246,7 @@ private bool ValidateClientHostname(string hostname) return true; } +#if LINUX private void SetCiphersuites(CipherSuitesPolicy? policy) { // if no policy supplied, use all supported ciphers @@ -278,6 +280,7 @@ private void SetCiphersuites(CipherSuitesPolicy? policy) Interop.OpenSslQuic.SslSetCiphersuites(_ssl, ciphersString); } +#endif private unsafe void SetAlpn(List protos) { @@ -404,7 +407,9 @@ public SslApplicationProtocol GetNegotiatedProtocol() return default; } +#pragma warning disable IDE0060 // Remove unused parameter private static int TlsExtCallbackImpl(IntPtr ssl, ref int al, IntPtr arg) +#pragma warning restore IDE0060 // Remove unused parameter { var namePtr = Interop.OpenSslQuic.SslGetServername(ssl, 0); var tls = GetTlsInstance(ssl); @@ -447,11 +452,13 @@ private static int FlushFlightImpl(IntPtr ssl) return 1; } +#pragma warning disable IDE0060 // Remove unused parameter private static int SendAlertImpl(IntPtr ssl, OpenSslEncryptionLevel level, byte alert) +#pragma warning restore IDE0060 // Remove unused parameter { var tls = GetTlsInstance(ssl); - tls._connection.SendTlsAlert(ToManagedEncryptionLevel(level), alert); + tls._connection.SendTlsAlert(alert); return 1; } diff --git a/src/libraries/System.Net.Quic/src/System/Net/Quic/Implementations/Managed/Internal/Tls/TlsFactory.cs b/src/libraries/System.Net.Quic/src/System/Net/Quic/Implementations/Managed/Internal/Tls/TlsFactory.cs index e5a6500c12f4e2..ede72734099f64 100644 --- a/src/libraries/System.Net.Quic/src/System/Net/Quic/Implementations/Managed/Internal/Tls/TlsFactory.cs +++ b/src/libraries/System.Net.Quic/src/System/Net/Quic/Implementations/Managed/Internal/Tls/TlsFactory.cs @@ -10,5 +10,7 @@ internal abstract ITls CreateClient(ManagedQuicConnection connection, QuicClient internal abstract ITls CreateServer(ManagedQuicConnection connection, QuicServerConnectionOptions options, TransportParameters localTransportParams); + + internal static TlsFactory Default => MockTlsFactory.Instance; } } diff --git a/src/libraries/System.Net.Quic/src/System/Net/Quic/Implementations/Managed/ManagedQuicConnection.Frames.cs b/src/libraries/System.Net.Quic/src/System/Net/Quic/Implementations/Managed/ManagedQuicConnection.Frames.cs index dc87bed6618d04..beabbca41e24e2 100644 --- a/src/libraries/System.Net.Quic/src/System/Net/Quic/Implementations/Managed/ManagedQuicConnection.Frames.cs +++ b/src/libraries/System.Net.Quic/src/System/Net/Quic/Implementations/Managed/ManagedQuicConnection.Frames.cs @@ -572,7 +572,7 @@ private ProcessPacketResult ProcessConnectionClose(QuicReader reader, QuicSocket // keep only the first error if (_inboundError == null) { - _inboundError = new QuicError((TransportErrorCode)frame.ErrorCode, frame.ReasonPhrase, + _inboundError = new QuicTransportError((TransportErrorCode)frame.ErrorCode, frame.ReasonPhrase, frame.FrameType, frame.IsQuicError); if (_closingPeriodEndTimestamp == null) @@ -584,7 +584,7 @@ private ProcessPacketResult ProcessConnectionClose(QuicReader reader, QuicSocket { // From RFC: An endpoint that receives a CONNECTION_CLOSE frame MAY send a single packet containing a // CONNECTION_CLOSE frame before entering the draining state, using NO_ERROR code if appropriate. - _outboundError = new QuicError(TransportErrorCode.NoError); + _outboundError = new QuicTransportError(TransportErrorCode.NoError); // draining state will be entered once the error is sent. } else diff --git a/src/libraries/System.Net.Quic/src/System/Net/Quic/Implementations/Managed/ManagedQuicConnection.Packets.cs b/src/libraries/System.Net.Quic/src/System/Net/Quic/Implementations/Managed/ManagedQuicConnection.Packets.cs index 9dff96eb552e9a..5a7a489ecfd668 100644 --- a/src/libraries/System.Net.Quic/src/System/Net/Quic/Implementations/Managed/ManagedQuicConnection.Packets.cs +++ b/src/libraries/System.Net.Quic/src/System/Net/Quic/Implementations/Managed/ManagedQuicConnection.Packets.cs @@ -22,7 +22,9 @@ public sealed partial class ManagedQuicConnection private bool _doKeyUpdate; +#pragma warning disable IDE0060 // Remove unused parameter internal void ReceiveData(QuicReader reader, EndPoint sender, QuicSocketContext.RecvContext ctx) +#pragma warning restore IDE0060 // Remove unused parameter { if (_isDraining) { @@ -243,7 +245,7 @@ private ProcessPacketResult ReceiveOne(QuicReader reader, QuicSocketContext.Recv QuicTransportError.InvalidReservedBits); } - result = ReceiveCore(reader, pnSpace, pnOffset, header.PacketNumberLength, packetType, recvSeal, + result = ReceiveCore(reader, pnSpace, header.PacketNumberLength, packetType, recvSeal, context); } @@ -336,11 +338,11 @@ private ProcessPacketResult ReceiveLongHeader(QuicReader reader, in LongPacketHe QuicTransportError.InvalidReservedBits); } - return ReceiveCore(reader, pnSpace, pnOffset, header.PacketNumberLength, packetType, seal, + return ReceiveCore(reader, pnSpace, header.PacketNumberLength, packetType, seal, context); } - private ProcessPacketResult ReceiveCore(QuicReader reader, PacketNumberSpace pnSpace, int pnOffset, + private ProcessPacketResult ReceiveCore(QuicReader reader, PacketNumberSpace pnSpace, int pnLength, PacketType packetType, CryptoSeal seal, QuicSocketContext.RecvContext context) { diff --git a/src/libraries/System.Net.Quic/src/System/Net/Quic/Implementations/Managed/ManagedQuicConnection.cs b/src/libraries/System.Net.Quic/src/System/Net/Quic/Implementations/Managed/ManagedQuicConnection.cs index 5c7ae8957591dc..3ebfa33f1bec9d 100644 --- a/src/libraries/System.Net.Quic/src/System/Net/Quic/Implementations/Managed/ManagedQuicConnection.cs +++ b/src/libraries/System.Net.Quic/src/System/Net/Quic/Implementations/Managed/ManagedQuicConnection.cs @@ -229,6 +229,10 @@ internal void Ping() /// internal EndPoint UnsafeRemoteEndPoint => _remoteEndpoint; + public ManagedQuicConnection(QuicClientConnectionOptions options) : this(options, TlsFactory.Default) + { + } + // client constructor internal ManagedQuicConnection(QuicClientConnectionOptions options, TlsFactory tlsFactory) { @@ -611,6 +615,7 @@ internal ValueTask DisposeAsync(long errorCode) if (!Connected) { + // TODO: is this necessary? // abandon connection attempt _connectTcs.TryCompleteException(new QuicException(QuicError.ConnectionAborted, errorCode, "Abandon connection attempt")); _closeTcs.TryComplete(); @@ -671,7 +676,7 @@ internal void FlushHandshakeData() } } - internal void SendTlsAlert(EncryptionLevel level, int alert) + internal void SendTlsAlert(int alert) { // RFC: A TLS alert is turned into a QUIC connection error by converting the // one-byte alert description into a QUIC error code. The alert @@ -708,7 +713,9 @@ private enum ProcessPacketResult // TODO-RZ: create a defensive copy of the endpoint public EndPoint RemoteEndPoint => _remoteEndpoint; +#pragma warning disable IDE0060 // Remove unused parameter internal ValueTask ConnectAsync(CancellationToken cancellationToken = default) +#pragma warning restore IDE0060 // Remove unused parameter { ThrowIfDisposed(); ThrowIfError(); @@ -764,10 +771,7 @@ public ValueTask CloseAsync(long errorCode, CancellationToken cancellationToken private void ThrowIfDisposed() { - if (_disposed) - { - throw new ObjectDisposedException(nameof(ManagedQuicConnection)); - } + ObjectDisposedException.ThrowIf(_disposed, typeof(ManagedQuicConnection)); } internal void ThrowIfError() @@ -780,7 +784,7 @@ internal void ThrowIfError() if (!_outboundError.IsQuicError) { // connection close initiated by application - throw new QuicException(QuicError.ConnectionAborted, (long)_outboundError.ErrorCode, "Connection close initiated by application"); + throw new QuicException(QuicError.OperationAborted, null, "Operation Aborted"); } else if (_outboundError.ErrorCode != TransportErrorCode.NoError) { @@ -898,12 +902,12 @@ private QuicException MakeOperationAbortedException() { return _inboundError != null ? MakeConnectionAbortedException(_inboundError) // initiated by peer - : new QuicException(QuicError.OperationAborted, null, "Initiated by us"); + : new QuicException(QuicError.OperationAborted, null, "Operation Aborted"); // initiated by us } private static QuicException MakeConnectionAbortedException(QuicTransportError error) { - return new QuicException(QuicError.ConnectionAborted, (long)error.ErrorCode, error.ReasonPhrase ?? ""); + return new QuicException(QuicError.ConnectionAborted, (long)error.ErrorCode, error.ReasonPhrase ?? "Connection aborted"); } internal void OnSocketContextException(Exception e) diff --git a/src/libraries/System.Net.Quic/src/System/Net/Quic/Implementations/Managed/ManagedQuicListener.cs b/src/libraries/System.Net.Quic/src/System/Net/Quic/Implementations/Managed/ManagedQuicListener.cs index 8d0dd840c205b3..7b51c78f2ec519 100644 --- a/src/libraries/System.Net.Quic/src/System/Net/Quic/Implementations/Managed/ManagedQuicListener.cs +++ b/src/libraries/System.Net.Quic/src/System/Net/Quic/Implementations/Managed/ManagedQuicListener.cs @@ -37,7 +37,7 @@ private ManagedQuicListener(QuicListenerOptions options) }); _acceptQueue = channel.Reader; - _socketContext = new QuicServerSocketContext(listenEndPoint, options, channel.Writer, OpenSslTlsFactory.Instance); + _socketContext = new QuicServerSocketContext(listenEndPoint, options, channel.Writer, TlsFactory.Default); _socketContext.Start(); } @@ -56,6 +56,7 @@ public ValueTask DisposeAsync() _disposed = true; + // TODO: wait until close? _socketContext.StopOrOrphan(); return ValueTask.CompletedTask;