From 1c7d22f3e9117d4db00fbdda31439d5da09d0fea Mon Sep 17 00:00:00 2001 From: Radek Zikmund Date: Wed, 11 May 2022 13:59:09 +0200 Subject: [PATCH 1/9] Build msquic locally --- .../tests/StressTests/HttpStress/Dockerfile | 36 ++++++++++++++----- 1 file changed, 27 insertions(+), 9 deletions(-) diff --git a/src/libraries/System.Net.Http/tests/StressTests/HttpStress/Dockerfile b/src/libraries/System.Net.Http/tests/StressTests/HttpStress/Dockerfile index 5a929e376485f4..62b5d9113d7169 100644 --- a/src/libraries/System.Net.Http/tests/StressTests/HttpStress/Dockerfile +++ b/src/libraries/System.Net.Http/tests/StressTests/HttpStress/Dockerfile @@ -1,21 +1,39 @@ ARG SDK_BASE_IMAGE=mcr.microsoft.com/dotnet/nightly/sdk:6.0-bullseye-slim FROM $SDK_BASE_IMAGE -WORKDIR /app -COPY . . # Pulling the msquic Debian package from packages.microsoft.com +# Build latest msquic locally +WORKDIR /msquic RUN apt-get update -y -RUN apt-get install -y gnupg2 software-properties-common -RUN curl -sSL https://packages.microsoft.com/keys/microsoft.asc | apt-key add - -RUN apt-add-repository https://packages.microsoft.com/debian/11/prod -RUN apt-get update -y -RUN apt-get install -y libmsquic RUN apt-get upgrade -y +RUN apt-get install -y cmake clang ruby-dev gem lttng-tools libssl-dev && \ + gem install fpm +RUN git clone --recursive https://github.com/dotnet/msquic +RUN cd msquic/src/msquic && \ + mkdir build && \ + options="-DQUIC_BUILD_TOOLS=off -DQUIC_BUILD_TEST=off -DQUIC_BUILD_PERF=off" && \ + cmake -B build -DCMAKE_BUILD_TYPE=Release -DQUIC_ENABLE_LOGGING=true -DQUIC_USE_SYSTEM_LIBCRYPTO=true -DQUIC_BUILD_TOOLS=off -DQUIC_BUILD_TEST=off -DQUIC_BUILD_PERF=off && \ + cd build && \ + cmake --build . --config Release +RUN cd msquic/src/msquic/build/bin/Release && \ + rm libmsquic.so && \ + fpm -f -s dir -t deb -n libmsquic -v $( find -type f | cut -d "." -f 4- ) \ + --license MIT --url https://github.com/microsoft/msquic --log error \ + $( ls ./* | cut -d "/" -f 2 | sed -r "s/(.*)/\1=\/usr\/lib\/\1/g" ) && \ + dpkg -i libmsquic_*.deb ARG VERSION=7.0 ARG CONFIGURATION=Release +WORKDIR /app +COPY *.cs . +COPY *.csproj . +COPY *.props . +COPY *.targets . +COPY *.json . +COPY *.sln . + RUN dotnet build -c $CONFIGURATION \ -p:TargetingPacksTargetsLocation=/live-runtime-artifacts/targetingpacks.targets \ -p:MicrosoftNetCoreAppRefPackDir=/live-runtime-artifacts/microsoft.netcore.app.ref/ \ @@ -30,6 +48,6 @@ EXPOSE 5001 ENV VERSION=$VERSION ENV CONFIGURATION=$CONFIGURATION +# ENV LD_DEBUG=all ENV HTTPSTRESS_ARGS='' -CMD /live-runtime-artifacts/testhost/net$VERSION-Linux-$CONFIGURATION-x64/dotnet exec \ - ./bin/$CONFIGURATION/net$VERSION/HttpStress.dll $HTTPSTRESS_ARGS +CMD /live-runtime-artifacts/testhost/net$VERSION-Linux-$CONFIGURATION-x64/dotnet exec ./bin/$CONFIGURATION/net$VERSION/HttpStress.dll $HTTPSTRESS_ARGS From e27a38004dd93f8c38dce5788aad3e4d8d65252a Mon Sep 17 00:00:00 2001 From: Radek Zikmund Date: Wed, 11 May 2022 13:59:25 +0200 Subject: [PATCH 2/9] Use IPv4 addresses only when testing HTTP3 --- .../StressTests/HttpStress/StressServer.cs | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/src/libraries/System.Net.Http/tests/StressTests/HttpStress/StressServer.cs b/src/libraries/System.Net.Http/tests/StressTests/HttpStress/StressServer.cs index eb3f5db8b4a51b..83bd21d1690faf 100644 --- a/src/libraries/System.Net.Http/tests/StressTests/HttpStress/StressServer.cs +++ b/src/libraries/System.Net.Http/tests/StressTests/HttpStress/StressServer.cs @@ -83,7 +83,16 @@ public StressServer(Configuration configuration) { case "+": case "*": - ko.ListenAnyIP(port, ConfigureListenOptions); + // Workaround for a msquic bug: can't connect via IPv4 when listening on IPv6 + // https://github.com/microsoft/msquic/issues/2704 + if (configuration.HttpVersion == HttpVersion.Version30) + { + ko.Listen(IPAddress.Any, port, ConfigureListenOptions); + } + else + { + ko.ListenAnyIP(port, ConfigureListenOptions); + } break; default: IPAddress iPAddress = Dns.GetHostAddresses(hostname).First(); @@ -118,9 +127,9 @@ void ConfigureListenOptions(ListenOptions listenOptions) else { listenOptions.Protocols = - configuration.HttpVersion == HttpVersion.Version20 ? + configuration.HttpVersion == HttpVersion.Version20 ? HttpProtocols.Http2 : - HttpProtocols.Http1 ; + HttpProtocols.Http1; } } }); @@ -139,7 +148,8 @@ void ConfigureListenOptions(ListenOptions listenOptions) try { File.Delete(filename); - } catch {} + } + catch { } } loggerConfiguration = loggerConfiguration From 227af90eaf2cd87225f32e582ce8016682abd15a Mon Sep 17 00:00:00 2001 From: Radek Zikmund Date: Thu, 12 May 2022 13:25:50 +0200 Subject: [PATCH 3/9] Code review changes --- .../tests/StressTests/HttpStress/Dockerfile | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) diff --git a/src/libraries/System.Net.Http/tests/StressTests/HttpStress/Dockerfile b/src/libraries/System.Net.Http/tests/StressTests/HttpStress/Dockerfile index 62b5d9113d7169..a49e0cd3e6d8bf 100644 --- a/src/libraries/System.Net.Http/tests/StressTests/HttpStress/Dockerfile +++ b/src/libraries/System.Net.Http/tests/StressTests/HttpStress/Dockerfile @@ -5,15 +5,15 @@ FROM $SDK_BASE_IMAGE # Pulling the msquic Debian package from packages.microsoft.com # Build latest msquic locally WORKDIR /msquic -RUN apt-get update -y -RUN apt-get upgrade -y -RUN apt-get install -y cmake clang ruby-dev gem lttng-tools libssl-dev && \ +RUN apt-get update -y && \ + apt-get upgrade -y && \ + apt-get install -y cmake clang ruby-dev gem lttng-tools libssl-dev && \ gem install fpm RUN git clone --recursive https://github.com/dotnet/msquic RUN cd msquic/src/msquic && \ mkdir build && \ options="-DQUIC_BUILD_TOOLS=off -DQUIC_BUILD_TEST=off -DQUIC_BUILD_PERF=off" && \ - cmake -B build -DCMAKE_BUILD_TYPE=Release -DQUIC_ENABLE_LOGGING=true -DQUIC_USE_SYSTEM_LIBCRYPTO=true -DQUIC_BUILD_TOOLS=off -DQUIC_BUILD_TEST=off -DQUIC_BUILD_PERF=off && \ + cmake -B build -DCMAKE_BUILD_TYPE=Release -DQUIC_ENABLE_LOGGING=false -DQUIC_USE_SYSTEM_LIBCRYPTO=true -DQUIC_BUILD_TOOLS=off -DQUIC_BUILD_TEST=off -DQUIC_BUILD_PERF=off && \ cd build && \ cmake --build . --config Release RUN cd msquic/src/msquic/build/bin/Release && \ @@ -27,12 +27,7 @@ ARG VERSION=7.0 ARG CONFIGURATION=Release WORKDIR /app -COPY *.cs . -COPY *.csproj . -COPY *.props . -COPY *.targets . -COPY *.json . -COPY *.sln . +COPY . . RUN dotnet build -c $CONFIGURATION \ -p:TargetingPacksTargetsLocation=/live-runtime-artifacts/targetingpacks.targets \ @@ -48,6 +43,6 @@ EXPOSE 5001 ENV VERSION=$VERSION ENV CONFIGURATION=$CONFIGURATION -# ENV LD_DEBUG=all ENV HTTPSTRESS_ARGS='' -CMD /live-runtime-artifacts/testhost/net$VERSION-Linux-$CONFIGURATION-x64/dotnet exec ./bin/$CONFIGURATION/net$VERSION/HttpStress.dll $HTTPSTRESS_ARGS +CMD /live-runtime-artifacts/testhost/net$VERSION-Linux-$CONFIGURATION-x64/dotnet exec \ + ./bin/$CONFIGURATION/net$VERSION/HttpStress.dll $HTTPSTRESS_ARGS From bf029fe319bd65de9a7df6ad3cd3572f41fd2343 Mon Sep 17 00:00:00 2001 From: Radek Zikmund Date: Thu, 12 May 2022 13:56:33 +0200 Subject: [PATCH 4/9] fixup! Use IPv4 addresses only when testing HTTP3 --- .../System.Net.Http/tests/StressTests/HttpStress/Dockerfile | 1 - 1 file changed, 1 deletion(-) diff --git a/src/libraries/System.Net.Http/tests/StressTests/HttpStress/Dockerfile b/src/libraries/System.Net.Http/tests/StressTests/HttpStress/Dockerfile index a49e0cd3e6d8bf..7f1bd255c080da 100644 --- a/src/libraries/System.Net.Http/tests/StressTests/HttpStress/Dockerfile +++ b/src/libraries/System.Net.Http/tests/StressTests/HttpStress/Dockerfile @@ -12,7 +12,6 @@ RUN apt-get update -y && \ RUN git clone --recursive https://github.com/dotnet/msquic RUN cd msquic/src/msquic && \ mkdir build && \ - options="-DQUIC_BUILD_TOOLS=off -DQUIC_BUILD_TEST=off -DQUIC_BUILD_PERF=off" && \ cmake -B build -DCMAKE_BUILD_TYPE=Release -DQUIC_ENABLE_LOGGING=false -DQUIC_USE_SYSTEM_LIBCRYPTO=true -DQUIC_BUILD_TOOLS=off -DQUIC_BUILD_TEST=off -DQUIC_BUILD_PERF=off && \ cd build && \ cmake --build . --config Release From 44ca4ad57584d39cb133c7e8a85089d73bfceaa6 Mon Sep 17 00:00:00 2001 From: Radek Zikmund Date: Thu, 12 May 2022 15:08:03 +0200 Subject: [PATCH 5/9] Make listening on IPv6Any accept IPv4 connections as well --- .../StressTests/HttpStress/StressServer.cs | 11 +----- .../MsQuic/Internal/MsQuicAddressHelpers.cs | 18 ++++++++++ .../MsQuic/Internal/MsQuicParameterHelpers.cs | 16 +++++++++ .../Implementations/MsQuic/MsQuicListener.cs | 34 +++++++++++-------- .../FunctionalTests/QuicListenerTests.cs | 15 ++++++++ 5 files changed, 70 insertions(+), 24 deletions(-) diff --git a/src/libraries/System.Net.Http/tests/StressTests/HttpStress/StressServer.cs b/src/libraries/System.Net.Http/tests/StressTests/HttpStress/StressServer.cs index 83bd21d1690faf..503ac939ec3013 100644 --- a/src/libraries/System.Net.Http/tests/StressTests/HttpStress/StressServer.cs +++ b/src/libraries/System.Net.Http/tests/StressTests/HttpStress/StressServer.cs @@ -83,16 +83,7 @@ public StressServer(Configuration configuration) { case "+": case "*": - // Workaround for a msquic bug: can't connect via IPv4 when listening on IPv6 - // https://github.com/microsoft/msquic/issues/2704 - if (configuration.HttpVersion == HttpVersion.Version30) - { - ko.Listen(IPAddress.Any, port, ConfigureListenOptions); - } - else - { - ko.ListenAnyIP(port, ConfigureListenOptions); - } + ko.ListenAnyIP(port, ConfigureListenOptions); break; default: IPAddress iPAddress = Dns.GetHostAddresses(hostname).First(); 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 e5092f65620201..0c8d29722c098d 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 @@ -1,6 +1,11 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using System.Diagnostics; +using System.Net.Sockets; +using System.Runtime.InteropServices; +using Microsoft.Quic; + namespace System.Net.Quic.Implementations.MsQuic.Internal { internal static class MsQuicAddressHelpers @@ -11,5 +16,18 @@ internal static unsafe IPEndPoint INetToIPEndPoint(IntPtr pInetAddress) Span addressBytes = new Span((byte*)pInetAddress, Internals.SocketAddress.IPv6AddressSize); return new Internals.SocketAddress(SocketAddressPal.GetAddressFamily(addressBytes), addressBytes).GetIPEndPoint(); } + + internal static unsafe QuicAddr ToQuicAddr(this IPEndPoint iPEndPoint) + { + // TODO: is the layout same for SocketAddress.Buffer and QuicAddr? + QuicAddr result = default; + Span rawAddress = MemoryMarshal.AsBytes(MemoryMarshal.CreateSpan(ref result, 1)); + + Internals.SocketAddress address = IPEndPointExtensions.Serialize(iPEndPoint); + Debug.Assert(address.Size <= rawAddress.Length); + + address.Buffer.AsSpan(0, address.Size).CopyTo(rawAddress); + return result; + } } } 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 784d89566b3517..2b6ce81d88d43f 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 @@ -4,12 +4,28 @@ using System.Diagnostics; using System.Runtime.InteropServices; using System.Net.Sockets; +using Microsoft.Quic; using static Microsoft.Quic.MsQuic; namespace System.Net.Quic.Implementations.MsQuic.Internal { internal static class MsQuicParameterHelpers { + internal static unsafe QuicAddr GetQuicAddrParam(MsQuicApi api, MsQuicSafeHandle nativeObject, uint param) + { + QuicAddr value = default; + uint valueLen = (uint)sizeof(QuicAddr); + + ThrowIfFailure(api.ApiTable->GetParam( + nativeObject.QuicHandle, + param, + &valueLen, + (byte*)&value), "GetQuicAddrParam failed"); + Debug.Assert(valueLen == sizeof(QuicAddr)); + + return value; + } + internal static unsafe IPEndPoint GetIPEndPointParam(MsQuicApi api, MsQuicSafeHandle nativeObject, uint param) { // MsQuic always uses storage size as if IPv6 was used 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 8ae290b43a19dd..6421ad83a2d61e 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 @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. using System.Buffers; +using System.Buffers.Binary; using System.Collections.Generic; using System.Collections.Concurrent; using System.Diagnostics; @@ -12,7 +13,6 @@ using System.Threading; using System.Threading.Channels; using System.Threading.Tasks; -using System.Net.Sockets; using Microsoft.Quic; using System.Runtime.CompilerServices; using static Microsoft.Quic.MsQuic; @@ -179,26 +179,27 @@ private unsafe IPEndPoint Start(QuicListenerOptions options) List applicationProtocols = options.ServerAuthenticationOptions!.ApplicationProtocols!; IPEndPoint listenEndPoint = options.ListenEndPoint!; - Internals.SocketAddress address = IPEndPointExtensions.Serialize(listenEndPoint); - Debug.Assert(_stateHandle.IsAllocated); try { Debug.Assert(!Monitor.IsEntered(_state), "!Monitor.IsEntered(_state)"); using var msquicBuffers = new MsQuicBuffers(); msquicBuffers.Initialize(applicationProtocols, applicationProtocol => applicationProtocol.Protocol); - // TODO: is the layout same for SocketAddress.Buffer and QuicAddr? - // TODO: maybe add simple extensions/helpers: - // - QuicAddr ToQuicAddr(this IPEndPoint ipEndPoint) - // - IPEndPoint ToIPEndPoint(this ref QuicAddr quicAddress) - fixed (byte* paddress = address.Buffer) + + QuicAddr address = listenEndPoint.ToQuicAddr(); + + if (listenEndPoint.Address == IPAddress.IPv6Any) { - ThrowIfFailure(MsQuicApi.Api.ApiTable->ListenerStart( - _state.Handle.QuicHandle, - msquicBuffers.Buffers, - (uint)applicationProtocols.Count, - (QuicAddr*)paddress), "ListenerStart failed"); + // For IPv6Any, MsQuic would listen only for IPv6 connections. To mimic the behavior of TCP sockets, + // we leave the address family unspecified and let MsQuic handle connections from all IP addresses. + address.Family = QUIC_ADDRESS_FAMILY_UNSPEC; } + + ThrowIfFailure(MsQuicApi.Api.ApiTable->ListenerStart( + _state.Handle.QuicHandle, + msquicBuffers.Buffers, + (uint)applicationProtocols.Count, + &address), "ListenerStart failed"); } catch { @@ -206,8 +207,13 @@ private unsafe IPEndPoint Start(QuicListenerOptions options) throw; } + // return the actual bound address, including a port. Since the address family may be Unspecified, + // we cannot use GetIPEndPointParam. We have to manually read the port from the raw QuicAddr structure. + // The actual address is unchanged. Debug.Assert(!Monitor.IsEntered(_state), "!Monitor.IsEntered(_state)"); - return MsQuicParameterHelpers.GetIPEndPointParam(MsQuicApi.Api, _state.Handle, QUIC_PARAM_LISTENER_LOCAL_ADDRESS); + QuicAddr listenAddr = MsQuicParameterHelpers.GetQuicAddrParam(MsQuicApi.Api, _state.Handle, QUIC_PARAM_LISTENER_LOCAL_ADDRESS); + int port = BinaryPrimitives.ReadUInt16BigEndian(MemoryMarshal.AsBytes(MemoryMarshal.CreateSpan(ref listenAddr.Ipv4.sin_port, 1))); + return new IPEndPoint(listenEndPoint.Address, port); } private unsafe Task StopAsync() diff --git a/src/libraries/System.Net.Quic/tests/FunctionalTests/QuicListenerTests.cs b/src/libraries/System.Net.Quic/tests/FunctionalTests/QuicListenerTests.cs index e7586a31d9feb8..44473b22374a63 100644 --- a/src/libraries/System.Net.Quic/tests/FunctionalTests/QuicListenerTests.cs +++ b/src/libraries/System.Net.Quic/tests/FunctionalTests/QuicListenerTests.cs @@ -41,6 +41,21 @@ await Task.Run(async () => await clientStreamTask; }).WaitAsync(TimeSpan.FromSeconds(6)); } + + [ConditionalFact(nameof(IsMsQuicProvider))] + public async Task Listener_IPv6Any_Accepts_IPv4() + { + await Task.Run(async () => + { + using QuicListener listener = CreateQuicListener(new IPEndPoint(IPAddress.IPv6Any, 0)); + + using QuicConnection clientConnection = CreateQuicConnection(new IPEndPoint(IPAddress.Loopback, listener.ListenEndPoint.Port)); + var clientStreamTask = clientConnection.ConnectAsync(); + + using QuicConnection serverConnection = await listener.AcceptConnectionAsync(); + await clientStreamTask; + }).WaitAsync(TimeSpan.FromSeconds(6)); + } } [ConditionalClass(typeof(QuicTestBase), nameof(QuicTestBase.IsSupported))] From ec42d215cdd6f5039cbc4a4721aefb402a453c00 Mon Sep 17 00:00:00 2001 From: Radek Zikmund Date: Thu, 12 May 2022 15:10:49 +0200 Subject: [PATCH 6/9] Minor changes --- .../System.Net.Http/tests/StressTests/HttpStress/Dockerfile | 3 +-- .../Implementations/MsQuic/Internal/MsQuicAddressHelpers.cs | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/src/libraries/System.Net.Http/tests/StressTests/HttpStress/Dockerfile b/src/libraries/System.Net.Http/tests/StressTests/HttpStress/Dockerfile index 7f1bd255c080da..d69c760d327493 100644 --- a/src/libraries/System.Net.Http/tests/StressTests/HttpStress/Dockerfile +++ b/src/libraries/System.Net.Http/tests/StressTests/HttpStress/Dockerfile @@ -1,8 +1,6 @@ ARG SDK_BASE_IMAGE=mcr.microsoft.com/dotnet/nightly/sdk:6.0-bullseye-slim FROM $SDK_BASE_IMAGE - -# Pulling the msquic Debian package from packages.microsoft.com # Build latest msquic locally WORKDIR /msquic RUN apt-get update -y && \ @@ -25,6 +23,7 @@ RUN cd msquic/src/msquic/build/bin/Release && \ ARG VERSION=7.0 ARG CONFIGURATION=Release +# Build the stress server WORKDIR /app COPY . . 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 0c8d29722c098d..d081d9d26a489a 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 @@ -19,7 +19,7 @@ internal static unsafe IPEndPoint INetToIPEndPoint(IntPtr pInetAddress) internal static unsafe QuicAddr ToQuicAddr(this IPEndPoint iPEndPoint) { - // TODO: is the layout same for SocketAddress.Buffer and QuicAddr? + // TODO: is the layout same for SocketAddress.Buffer and QuicAddr on all platforms? QuicAddr result = default; Span rawAddress = MemoryMarshal.AsBytes(MemoryMarshal.CreateSpan(ref result, 1)); From d2a5f27f2f2c17bd18864ba20a27b8e16a9f0123 Mon Sep 17 00:00:00 2001 From: Radek Zikmund Date: Thu, 12 May 2022 20:20:59 +0200 Subject: [PATCH 7/9] Don't continue if runtime image build fails --- eng/pipelines/libraries/stress/http.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/eng/pipelines/libraries/stress/http.yml b/eng/pipelines/libraries/stress/http.yml index e72006472bc051..ba0bce72346005 100644 --- a/eng/pipelines/libraries/stress/http.yml +++ b/eng/pipelines/libraries/stress/http.yml @@ -39,13 +39,13 @@ jobs: fetchDepth: 5 - bash: | - $(dockerfilesFolder)/build-docker-sdk.sh -t $(sdkBaseImage) -c $(BUILD_CONFIGURATION) + $(dockerfilesFolder)/build-docker-sdk.sh -t $(sdkBaseImage) -c $(BUILD_CONFIGURATION) && \ echo "##vso[task.setvariable variable=succeeded;isOutput=true]true" name: buildRuntime displayName: Build CLR and Libraries - bash: | - $(httpStressProject)/run-docker-compose.sh -o -c $(BUILD_CONFIGURATION) -t $(sdkBaseImage) + $(httpStressProject)/run-docker-compose.sh -o -c $(BUILD_CONFIGURATION) -t $(sdkBaseImage) && \ echo "##vso[task.setvariable variable=succeeded;isOutput=true]true" name: buildStress displayName: Build HttpStress From 0bc8a4c2b3a32b8b92e459759dd8a9c4b2be5502 Mon Sep 17 00:00:00 2001 From: Radek Zikmund Date: Fri, 13 May 2022 10:25:13 +0200 Subject: [PATCH 8/9] Switch to 1es-ubuntu-1804-open image --- eng/pipelines/libraries/stress/http.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/eng/pipelines/libraries/stress/http.yml b/eng/pipelines/libraries/stress/http.yml index ba0bce72346005..7a3226a25626f4 100644 --- a/eng/pipelines/libraries/stress/http.yml +++ b/eng/pipelines/libraries/stress/http.yml @@ -31,7 +31,7 @@ jobs: DUMPS_SHARE_MOUNT_ROOT: "/dumps-share" pool: name: NetCore1ESPool-Public - demands: ImageOverride -equals Build.Ubuntu.1804.Amd64.Open + demands: ImageOverride -equals 1es-ubuntu-1804-open steps: - checkout: self From e6ebcea3012f242a341090deb6320bf0d608edd3 Mon Sep 17 00:00:00 2001 From: Radek Zikmund Date: Wed, 18 May 2022 16:34:50 +0200 Subject: [PATCH 9/9] Code review feedback --- .../Common/src/System/Net/SocketAddress.cs | 1 + .../MsQuic/Internal/MsQuicParameterHelpers.cs | 19 ++----------------- .../Implementations/MsQuic/MsQuicListener.cs | 8 ++------ 3 files changed, 5 insertions(+), 23 deletions(-) diff --git a/src/libraries/Common/src/System/Net/SocketAddress.cs b/src/libraries/Common/src/System/Net/SocketAddress.cs index 69c4b938a839c6..d3d71f5507c918 100644 --- a/src/libraries/Common/src/System/Net/SocketAddress.cs +++ b/src/libraries/Common/src/System/Net/SocketAddress.cs @@ -133,6 +133,7 @@ internal SocketAddress(AddressFamily addressFamily, ReadOnlySpan buffer) { Buffer = buffer.ToArray(); InternalSize = Buffer.Length; + SocketAddressPal.SetAddressFamily(Buffer, addressFamily); } internal IPAddress GetIPAddress() 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 2b6ce81d88d43f..67fdbabf4e449d 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 @@ -11,22 +11,7 @@ namespace System.Net.Quic.Implementations.MsQuic.Internal { internal static class MsQuicParameterHelpers { - internal static unsafe QuicAddr GetQuicAddrParam(MsQuicApi api, MsQuicSafeHandle nativeObject, uint param) - { - QuicAddr value = default; - uint valueLen = (uint)sizeof(QuicAddr); - - ThrowIfFailure(api.ApiTable->GetParam( - nativeObject.QuicHandle, - param, - &valueLen, - (byte*)&value), "GetQuicAddrParam failed"); - Debug.Assert(valueLen == sizeof(QuicAddr)); - - return value; - } - - internal static unsafe IPEndPoint GetIPEndPointParam(MsQuicApi api, MsQuicSafeHandle nativeObject, uint param) + internal static unsafe IPEndPoint GetIPEndPointParam(MsQuicApi api, MsQuicSafeHandle nativeObject, uint param, AddressFamily? addressFamilyOverride = null) { // MsQuic always uses storage size as if IPv6 was used uint valueLen = (uint)Internals.SocketAddress.IPv6AddressSize; @@ -43,7 +28,7 @@ internal static unsafe IPEndPoint GetIPEndPointParam(MsQuicApi api, MsQuicSafeHa address = address.Slice(0, (int)valueLen); - return new Internals.SocketAddress(SocketAddressPal.GetAddressFamily(address), address).GetIPEndPoint(); + return new Internals.SocketAddress(addressFamilyOverride ?? SocketAddressPal.GetAddressFamily(address), address).GetIPEndPoint(); } internal static unsafe void SetIPEndPointParam(MsQuicApi api, MsQuicSafeHandle nativeObject, uint param, IPEndPoint value) 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 6421ad83a2d61e..2768493e08fbb9 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 @@ -207,13 +207,9 @@ private unsafe IPEndPoint Start(QuicListenerOptions options) throw; } - // return the actual bound address, including a port. Since the address family may be Unspecified, - // we cannot use GetIPEndPointParam. We have to manually read the port from the raw QuicAddr structure. - // The actual address is unchanged. Debug.Assert(!Monitor.IsEntered(_state), "!Monitor.IsEntered(_state)"); - QuicAddr listenAddr = MsQuicParameterHelpers.GetQuicAddrParam(MsQuicApi.Api, _state.Handle, QUIC_PARAM_LISTENER_LOCAL_ADDRESS); - int port = BinaryPrimitives.ReadUInt16BigEndian(MemoryMarshal.AsBytes(MemoryMarshal.CreateSpan(ref listenAddr.Ipv4.sin_port, 1))); - return new IPEndPoint(listenEndPoint.Address, port); + // override the address family to the original value in case we had to use UNSPEC + return MsQuicParameterHelpers.GetIPEndPointParam(MsQuicApi.Api, _state.Handle, QUIC_PARAM_LISTENER_LOCAL_ADDRESS, listenEndPoint.AddressFamily); } private unsafe Task StopAsync()