From 8986374ea73f1e5b1977dd0058fbdf591936408a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marie=20P=C3=ADchov=C3=A1?= <11718369+ManickaP@users.noreply.github.com> Date: Mon, 14 Aug 2023 09:19:10 +0200 Subject: [PATCH] [QUIC] Merge 7.0 fix (#90228) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Merge pull request #90173 from vseanreesermsft/internal-merge-7.0-2023-08-08-1042 Merging internal commits for release/7.0 * Consume MsQuic release package on Win --------- Co-authored-by: Carlos Sánchez López <1175054+carlossanlop@users.noreply.github.com> Co-authored-by: Natalia Kondratyeva --- eng/Versions.props | 2 +- .../src/System.Net.Quic.csproj | 2 +- .../src/System/Net/Quic/Internal/MsQuicApi.cs | 2 +- .../Net/Quic/Interop/msquic_generated.cs | 1 + .../src/System/Net/Quic/QuicConnection.cs | 1 + .../tests/FunctionalTests/MsQuicTests.cs | 45 +++++++++++++++++-- 6 files changed, 47 insertions(+), 6 deletions(-) diff --git a/eng/Versions.props b/eng/Versions.props index b029396062b..72913567f07 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -217,7 +217,7 @@ 8.0.0-rc.1.23407.2 - 2.1.7 + 2.2.2 8.0.0-alpha.1.23180.2 16.0.5-alpha.1.23408.1 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 281657f4ba5..ba05cef37b5 100644 --- a/src/libraries/System.Net.Quic/src/System.Net.Quic.csproj +++ b/src/libraries/System.Net.Quic/src/System.Net.Quic.csproj @@ -14,7 +14,7 @@ ExcludeApiList.PNSE.txt - true + false diff --git a/src/libraries/System.Net.Quic/src/System/Net/Quic/Internal/MsQuicApi.cs b/src/libraries/System.Net.Quic/src/System/Net/Quic/Internal/MsQuicApi.cs index 193a3db833c..e07a99b13f7 100644 --- a/src/libraries/System.Net.Quic/src/System/Net/Quic/Internal/MsQuicApi.cs +++ b/src/libraries/System.Net.Quic/src/System/Net/Quic/Internal/MsQuicApi.cs @@ -18,7 +18,7 @@ internal sealed unsafe partial class MsQuicApi { private static readonly Version s_minWindowsVersion = new Version(10, 0, 20145, 1000); - private static readonly Version s_minMsQuicVersion = new Version(2, 1); + private static readonly Version s_minMsQuicVersion = new Version(2, 2, 2); private static readonly delegate* unmanaged[Cdecl] MsQuicOpenVersion; private static readonly delegate* unmanaged[Cdecl] MsQuicClose; diff --git a/src/libraries/System.Net.Quic/src/System/Net/Quic/Interop/msquic_generated.cs b/src/libraries/System.Net.Quic/src/System/Net/Quic/Interop/msquic_generated.cs index 732de352749..2fb9196ae70 100644 --- a/src/libraries/System.Net.Quic/src/System/Net/Quic/Interop/msquic_generated.cs +++ b/src/libraries/System.Net.Quic/src/System/Net/Quic/Interop/msquic_generated.cs @@ -151,6 +151,7 @@ internal enum QUIC_STREAM_OPEN_FLAGS NONE = 0x0000, UNIDIRECTIONAL = 0x0001, ZERO_RTT = 0x0002, + DELAY_FC_UPDATES = 0x0004, } [System.Flags] diff --git a/src/libraries/System.Net.Quic/src/System/Net/Quic/QuicConnection.cs b/src/libraries/System.Net.Quic/src/System/Net/Quic/QuicConnection.cs index a25ce5b9e4f..a2ade033afe 100644 --- a/src/libraries/System.Net.Quic/src/System/Net/Quic/QuicConnection.cs +++ b/src/libraries/System.Net.Quic/src/System/Net/Quic/QuicConnection.cs @@ -515,6 +515,7 @@ private unsafe int HandleEventPeerStreamStarted(ref PEER_STREAM_STARTED_DATA dat return QUIC_STATUS_SUCCESS; } + data.Flags |= QUIC_STREAM_OPEN_FLAGS.DELAY_FC_UPDATES; return QUIC_STATUS_SUCCESS; } private unsafe int HandleEventPeerCertificateReceived(ref PEER_CERTIFICATE_RECEIVED_DATA data) diff --git a/src/libraries/System.Net.Quic/tests/FunctionalTests/MsQuicTests.cs b/src/libraries/System.Net.Quic/tests/FunctionalTests/MsQuicTests.cs index 2b18c840556..503c2d40683 100644 --- a/src/libraries/System.Net.Quic/tests/FunctionalTests/MsQuicTests.cs +++ b/src/libraries/System.Net.Quic/tests/FunctionalTests/MsQuicTests.cs @@ -709,6 +709,32 @@ public async Task OpenStreamAsync_BlocksUntilAvailable(bool unidirectional) await serverConnection.DisposeAsync(); } + [Fact] + public async Task OpenStreamAsync_BlocksUntilAvailable_PeerClosesWritingUnidirectional() + { + QuicListenerOptions listenerOptions = new QuicListenerOptions() + { + ListenEndPoint = new IPEndPoint(IPAddress.Loopback, 0), + ApplicationProtocols = new List() { ApplicationProtocol }, + ConnectionOptionsCallback = (_, _, _) => + { + var serverOptions = CreateQuicServerOptions(); + serverOptions.MaxInboundBidirectionalStreams = 1; + serverOptions.MaxInboundUnidirectionalStreams = 1; + return ValueTask.FromResult(serverOptions); + } + }; + (QuicConnection clientConnection, QuicConnection serverConnection) = await CreateConnectedQuicConnection(null, listenerOptions); + + // Open one stream, second call should block + await using var stream = await clientConnection.OpenOutboundStreamAsync(QuicStreamType.Unidirectional); + await stream.WriteAsync(new byte[64*1024], completeWrites: true); + await Assert.ThrowsAsync(() => clientConnection.OpenOutboundStreamAsync(QuicStreamType.Unidirectional).AsTask().WaitAsync(TimeSpan.FromSeconds(1))); + + await clientConnection.DisposeAsync(); + await serverConnection.DisposeAsync(); + } + [Theory] [InlineData(false)] [InlineData(true)] @@ -747,11 +773,24 @@ public async Task OpenStreamAsync_Canceled_Throws_OperationCanceledException(boo // Close the streams, the waitTask should finish as a result. await stream.DisposeAsync(); - QuicStream newStream = await serverConnection.AcceptInboundStreamAsync(); - await newStream.DisposeAsync(); + // Drain all server streams. + while (true) + { + using var acceptCts = new CancellationTokenSource(TimeSpan.FromSeconds(0.5)); + try + { + QuicStream serverStream = await serverConnection.AcceptInboundStreamAsync(acceptCts.Token); + await serverStream.DisposeAsync(); + } + catch (OperationCanceledException) + { + // Token expired, no more streams in the server queue, exit the loop. + break; + } + } // next call should work as intended - newStream = await OpenStreamAsync(clientConnection).AsTask().WaitAsync(TimeSpan.FromSeconds(10)); + var newStream = await OpenStreamAsync(clientConnection).AsTask().WaitAsync(TimeSpan.FromSeconds(10)); await newStream.DisposeAsync(); await clientConnection.DisposeAsync(); -- GitLab