Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[QUIC] Adopted msquic generated interop #68288

Merged
merged 28 commits into from
May 5, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
c6edafb
MsQuicApi adjusted
ManickaP Apr 8, 2022
ea31c49
QuicParamHelper adjusted
ManickaP Apr 8, 2022
8d41cbb
MsQuicConfiguration adjusted
ManickaP Apr 8, 2022
55dc554
Added MsQuicException
ManickaP Apr 9, 2022
259545e
MsQuicConnection adjusted
ManickaP Apr 9, 2022
d0fb04e
MsQuicListener adjusted
ManickaP Apr 9, 2022
b3d76cf
MsQuicStream adjusted
ManickaP Apr 9, 2022
103cd1f
It compiles!
ManickaP Apr 9, 2022
08b5b47
Some test fixes
ManickaP Apr 10, 2022
7794b58
Fixed stream read event handling
ManickaP Apr 20, 2022
46a7401
Re-enabled IPv6 tests
ManickaP Apr 20, 2022
182a8f0
latest greatest
ManickaP Apr 20, 2022
2b0172c
Update src/libraries/System.Net.Quic/src/System/Net/Quic/Implementati…
ManickaP Apr 20, 2022
3162353
MsQuic interop enum names
ManickaP Apr 21, 2022
88a5d89
Merge branch 'main' into mapichov/quic_interop
ManickaP Apr 21, 2022
166fa96
3rd Party notice, version check
ManickaP Apr 22, 2022
de307c3
SafeHandleType
ManickaP Apr 22, 2022
c955a4f
Replaced AlpnHelpers with MsQuicBuffers generic QUIC_BUFFER* helper
ManickaP Apr 25, 2022
6186a23
Sealed exception class
ManickaP Apr 25, 2022
f64b1d1
Feedback MsQuicBuffers
ManickaP Apr 25, 2022
43c6417
NativeMemory use
ManickaP Apr 25, 2022
059c3d4
Merge branch 'main' into mapichov/quic_interop
ManickaP May 3, 2022
cd3b00d
Newest msquic interop
ManickaP May 3, 2022
c6e0d6c
Buffers feedback
ManickaP May 3, 2022
de15868
Remove MemoryHandle pooling
ManickaP May 4, 2022
a73cfa8
Buffers feedback
ManickaP May 4, 2022
d52fcdb
Logging feedback
ManickaP May 4, 2022
cf2377c
Merge branch 'main' into mapichov/quic_interop
ManickaP May 5, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions THIRD-PARTY-NOTICES.TXT
Original file line number Diff line number Diff line change
Expand Up @@ -1065,3 +1065,11 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

License notice for MsQuic
--------------------------------------

Copyright (c) Microsoft Corporation.
Licensed under the MIT License.

Available at
https://github.com/microsoft/msquic/blob/main/LICENSE
25 changes: 3 additions & 22 deletions src/libraries/System.Net.Quic/src/System.Net.Quic.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -29,29 +29,16 @@
<Compile Include="System\Net\Quic\Implementations\Mock\*.cs" />
<Compile Include="System\Net\Quic\Implementations\MsQuic\*.cs" />
<Compile Include="System\Net\Quic\Implementations\MsQuic\Internal\*.cs" />
<Compile Include="System\Net\Quic\Implementations\MsQuic\Interop\MsQuicAlpnHelper.cs" />
<Compile Include="System\Net\Quic\Implementations\MsQuic\Interop\MsQuicEnums.cs" />
<Compile Include="System\Net\Quic\Implementations\MsQuic\Interop\MsQuicNativeMethods.cs" />
<Compile Include="System\Net\Quic\Implementations\MsQuic\Interop\MsQuicStatusCodes.cs" />
<Compile Include="System\Net\Quic\Implementations\MsQuic\Interop\MsQuicStatusHelper.cs" />
<Compile Include="System\Net\Quic\Implementations\MsQuic\Interop\MsQuicTraceHelper.cs" />
<Compile Include="System\Net\Quic\Implementations\MsQuic\Interop\SafeMsQuicConfigurationHandle.cs" />
<Compile Include="System\Net\Quic\Implementations\MsQuic\Interop\SafeMsQuicConnectionHandle.cs" />
<Compile Include="System\Net\Quic\Implementations\MsQuic\Interop\SafeMsQuicListenerHandle.cs" />
<Compile Include="System\Net\Quic\Implementations\MsQuic\Interop\SafeMsQuicRegistrationHandle.cs" />
<Compile Include="System\Net\Quic\Implementations\MsQuic\Interop\SafeMsQuicStreamHandle.cs" />
<Compile Include="$(CommonPath)DisableRuntimeMarshalling.cs">
<Link>Common\DisableRuntimeMarshalling.cs</Link>
</Compile>
<Compile Include="System\Net\Quic\Implementations\MsQuic\Interop\*.cs" />
<!-- System.Net common -->
<Compile Include="$(CommonPath)DisableRuntimeMarshalling.cs" Link="Common\DisableRuntimeMarshalling.cs" />
<Compile Include="$(CommonPath)System\Threading\Tasks\TaskToApm.cs" Link="Common\System\Threading\Tasks\TaskToApm.cs" />
<Compile Include="$(CommonPath)System\Net\ArrayBuffer.cs" Link="Common\System\Net\ArrayBuffer.cs" />
<Compile Include="$(CommonPath)System\Net\MultiArrayBuffer.cs" Link="Common\System\Net\MultiArrayBuffer.cs" />
<Compile Include="$(CommonPath)System\Net\Logging\NetEventSource.Common.cs" Link="Common\System\Net\Logging\NetEventSource.Common.cs" />
<Compile Include="$(CommonPath)System\Net\StreamBuffer.cs" Link="Common\System\Net\StreamBuffer.cs" />
<Compile Include="$(CommonPath)System\Net\SocketAddress.cs" Link="Common\System\Net\SocketAddress.cs" />
<Compile Include="$(CommonPath)System\Net\IPAddressParserStatics.cs" Link="Common\System\Net\IPAddressParserStatics.cs" />
<!-- System.Net.Internals -->
<Compile Include="$(CommonPath)System\Net\Internals\IPEndPointExtensions.cs" Link="Common\System\Net\Internals\IPEndPointExtensions.cs" />
</ItemGroup>
<!-- Unsupported platforms -->
Expand All @@ -74,7 +61,6 @@
<Compile Include="$(CommonPath)Interop\Windows\SChannel\Interop.SECURITY_STATUS.cs" Link="Common\Interop\Windows\SChannel\Interop.SECURITY_STATUS.cs" />
<Compile Include="$(CommonPath)System\Net\Security\CertificateValidation.Windows.cs" Link="Common\System\Net\Security\CertificateValidation.Windows.cs" />
<Compile Include="$(CommonPath)System\Net\SocketAddressPal.Windows.cs" Link="Common\System\Net\SocketAddressPal.Windows.cs" />
<Compile Include="System\Net\Quic\Implementations\MsQuic\Interop\MsQuicStatusCodes.Windows.cs" />
</ItemGroup>
<!-- Unix (OSX + Linux) specific files -->
<ItemGroup Condition="'$(TargetPlatformIdentifier)' == 'Linux' or '$(TargetPlatformIdentifier)' == 'OSX' or '$(TargetPlatformIdentifier)' == 'FreeBSD'">
Expand Down Expand Up @@ -107,26 +93,21 @@
</ItemGroup>
<!-- Linux specific files -->
<ItemGroup Condition="'$(TargetPlatformIdentifier)' == 'Linux'">
<Compile Include="$(CommonPath)Interop\Linux\Interop.Libraries.cs" Link="Common\Interop\Linux\Interop.Libraries.cs" />
<Compile Include="System\Net\Quic\Implementations\MsQuic\Interop\MsQuicStatusCodes.Linux.cs" />
<Compile Include="$(CommonPath)System\Net\Security\CertificateValidation.Unix.cs" Link="Common\System\Net\Security\CertificateValidation.Unix.cs" />
<Compile Include="$(CommonPath)Interop\Linux\Interop.Libraries.cs" Link="Common\Interop\Linux\Interop.Libraries.cs" />
</ItemGroup>
<!-- FreeBSD specific files -->
<ItemGroup Condition="'$(TargetPlatformIdentifier)' == 'FreeBSD' ">
<Compile Include="$(CommonPath)System\Net\Security\CertificateValidation.Unix.cs" Link="Common\System\Net\Security\CertificateValidation.Unix.cs" />
<Compile Include="$(CommonPath)Interop\FreeBSD\Interop.Libraries.cs" Link="Common\Interop\FreeBSD\Interop.Libraries.cs" />
<!-- Assume similarity with OSX for now -->
<Compile Include="System\Net\Quic\Implementations\MsQuic\Interop\MsQuicStatusCodes.OSX.cs" />
</ItemGroup>
<!-- OSX specific files -->
<ItemGroup Condition="'$(TargetPlatformIdentifier)' == 'OSX'">
<Compile Include="$(CommonPath)System\Net\Security\CertificateValidation.OSX.cs" Link="Common\System\Net\Security\CertificateValidation.OSX.cs" />
<Compile Include="$(CommonPath)Interop\OSX\Interop.Libraries.cs" Link="Common\Interop\OSX\Interop.Libraries.cs" />
<Compile Include="System\Net\Quic\Implementations\MsQuic\Interop\MsQuicStatusCodes.OSX.cs" />
</ItemGroup>

<!-- Project references -->

<ItemGroup>
<PackageReference Include="System.Net.MsQuic.Transport"
Version="$(SystemNetMsQuicTransportVersion)"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,6 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using System.Net.Sockets;
using System.Runtime.InteropServices;
using static System.Net.Quic.Implementations.MsQuic.Internal.MsQuicNativeMethods;

namespace System.Net.Quic.Implementations.MsQuic.Internal
{
internal static class MsQuicAddressHelpers
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,21 +3,29 @@

using System.Diagnostics.CodeAnalysis;
using System.Runtime.InteropServices;
using System.Text;
using Microsoft.Quic;

using static Microsoft.Quic.MsQuic;

#if TARGET_WINDOWS
using Microsoft.Win32;
#endif

using static System.Net.Quic.Implementations.MsQuic.Internal.MsQuicNativeMethods;

namespace System.Net.Quic.Implementations.MsQuic.Internal
{
internal sealed unsafe class MsQuicApi
{
private static readonly byte[] s_appName = Encoding.ASCII.GetBytes("System.Net.Quic");

private static readonly Version MinWindowsVersion = new Version(10, 0, 20145, 1000);

private static readonly Version MsQuicVersion = new Version(2, 0);

public SafeMsQuicRegistrationHandle Registration { get; }

public QUIC_API_TABLE* ApiTable { get; }

// This is workaround for a bug in ILTrimmer.
// Without these DynamicDependency attributes, .ctor() will be removed from the safe handles.
// Remove once fixed: https://github.com/mono/linker/issues/1660
Expand All @@ -26,89 +34,28 @@ internal sealed unsafe class MsQuicApi
[DynamicDependency(DynamicallyAccessedMemberTypes.PublicConstructors, typeof(SafeMsQuicListenerHandle))]
[DynamicDependency(DynamicallyAccessedMemberTypes.PublicConstructors, typeof(SafeMsQuicConnectionHandle))]
[DynamicDependency(DynamicallyAccessedMemberTypes.PublicConstructors, typeof(SafeMsQuicStreamHandle))]
private MsQuicApi(NativeApi* vtable)
private MsQuicApi(QUIC_API_TABLE* apiTable)
{
uint status;

SetParamDelegate =
new SetParamDelegate(new DelegateHelper(vtable->SetParam).SetParam);

GetParamDelegate =
new GetParamDelegate(new DelegateHelper(vtable->GetParam).GetParam);

SetCallbackHandlerDelegate =
new SetCallbackHandlerDelegate(new DelegateHelper(vtable->SetCallbackHandler).SetCallbackHandler);

RegistrationOpenDelegate =
new RegistrationOpenDelegate(new DelegateHelper(vtable->RegistrationOpen).RegistrationOpen);
RegistrationCloseDelegate =
Marshal.GetDelegateForFunctionPointer<RegistrationCloseDelegate>(
vtable->RegistrationClose);

ConfigurationOpenDelegate =
new ConfigurationOpenDelegate(new DelegateHelper(vtable->ConfigurationOpen).ConfigurationOpen);
ConfigurationCloseDelegate =
Marshal.GetDelegateForFunctionPointer<ConfigurationCloseDelegate>(
vtable->ConfigurationClose);
ConfigurationLoadCredentialDelegate =
new ConfigurationLoadCredentialDelegate(new DelegateHelper(vtable->ConfigurationLoadCredential).ConfigurationLoadCredential);

ListenerOpenDelegate =
new ListenerOpenDelegate(new DelegateHelper(vtable->ListenerOpen).ListenerOpen);
ListenerCloseDelegate =
Marshal.GetDelegateForFunctionPointer<ListenerCloseDelegate>(
vtable->ListenerClose);
ListenerStartDelegate =
new ListenerStartDelegate(new DelegateHelper(vtable->ListenerStart).ListenerStart);
ListenerStopDelegate =
new ListenerStopDelegate(new DelegateHelper(vtable->ListenerStop).ListenerStop);

ConnectionOpenDelegate =
new ConnectionOpenDelegate(new DelegateHelper(vtable->ConnectionOpen).ConnectionOpen);
ConnectionCloseDelegate =
Marshal.GetDelegateForFunctionPointer<ConnectionCloseDelegate>(
vtable->ConnectionClose);
ConnectionSetConfigurationDelegate =
new ConnectionSetConfigurationDelegate(new DelegateHelper(vtable->ConnectionSetConfiguration).ConnectionSetConfiguration);
ConnectionShutdownDelegate =
new ConnectionShutdownDelegate(new DelegateHelper(vtable->ConnectionShutdown).ConnectionShutdown);
ConnectionStartDelegate =
new ConnectionStartDelegate(new DelegateHelper(vtable->ConnectionStart).ConnectionStart);

StreamOpenDelegate =
new StreamOpenDelegate(new DelegateHelper(vtable->StreamOpen).StreamOpen);
StreamCloseDelegate =
Marshal.GetDelegateForFunctionPointer<StreamCloseDelegate>(
vtable->StreamClose);
StreamStartDelegate =
new StreamStartDelegate(new DelegateHelper(vtable->StreamStart).StreamStart);
StreamShutdownDelegate =
new StreamShutdownDelegate(new DelegateHelper(vtable->StreamShutdown).StreamShutdown);
StreamSendDelegate =
new StreamSendDelegate(new DelegateHelper(vtable->StreamSend).StreamSend);
StreamReceiveCompleteDelegate =
new StreamReceiveCompleteDelegate(new DelegateHelper(vtable->StreamReceiveComplete).StreamReceiveComplete);
StreamReceiveSetEnabledDelegate =
new StreamReceiveSetEnabledDelegate(new DelegateHelper(vtable->StreamReceiveSetEnabled).StreamReceiveSetEnabled);

var cfg = new RegistrationConfig
ApiTable = apiTable;

fixed (byte* pAppName = s_appName)
{
AppName = ".NET",
ExecutionProfile = QUIC_EXECUTION_PROFILE.QUIC_EXECUTION_PROFILE_LOW_LATENCY
};
var cfg = new QUIC_REGISTRATION_CONFIG {
AppName = (sbyte*)pAppName,
ExecutionProfile = QUIC_EXECUTION_PROFILE.LOW_LATENCY
};

status = RegistrationOpenDelegate(ref cfg, out SafeMsQuicRegistrationHandle handle);
QuicExceptionHelpers.ThrowIfFailed(status, "RegistrationOpen failed.");
QUIC_HANDLE* handle;
ThrowIfFailure(ApiTable->RegistrationOpen(&cfg, &handle), "RegistrationOpen failed");

Registration = handle;
Registration = new SafeMsQuicRegistrationHandle(handle);
}
}

internal static MsQuicApi Api { get; } = null!;

internal static bool IsQuicSupported { get; }

private const int MsQuicVersion = 2;

internal static bool Tls13MayBeDisabled { get; }

static MsQuicApi()
Expand All @@ -129,21 +76,36 @@ static MsQuicApi()
}

IntPtr msQuicHandle;
if (NativeLibrary.TryLoad($"{Interop.Libraries.MsQuic}.{MsQuicVersion}", typeof(MsQuicApi).Assembly, DllImportSearchPath.AssemblyDirectory, out msQuicHandle) ||
if (NativeLibrary.TryLoad($"{Interop.Libraries.MsQuic}.{MsQuicVersion.Major}", typeof(MsQuicApi).Assembly, DllImportSearchPath.AssemblyDirectory, out msQuicHandle) ||
NativeLibrary.TryLoad(Interop.Libraries.MsQuic, typeof(MsQuicApi).Assembly, DllImportSearchPath.AssemblyDirectory, out msQuicHandle))
{
try
{
if (NativeLibrary.TryGetExport(msQuicHandle, "MsQuicOpenVersion", out IntPtr msQuicOpenVersionAddress))
{
NativeApi* vtable;
delegate* unmanaged[Cdecl]<uint, NativeApi**, uint> msQuicOpenVersion =
(delegate* unmanaged[Cdecl]<uint, NativeApi**, uint>)msQuicOpenVersionAddress;
uint status = msQuicOpenVersion(MsQuicVersion, &vtable);
if (MsQuicStatusHelper.SuccessfulStatusCode(status))
QUIC_API_TABLE* apiTable;
delegate* unmanaged[Cdecl]<uint, QUIC_API_TABLE**, int> msQuicOpenVersion = (delegate* unmanaged[Cdecl]<uint, QUIC_API_TABLE**, int>)msQuicOpenVersionAddress;
if (StatusSucceeded(msQuicOpenVersion((uint)MsQuicVersion.Major, &apiTable)))
{
IsQuicSupported = true;
Api = new MsQuicApi(vtable);
int arraySize = 4;
uint* libVersion = stackalloc uint[arraySize];
uint size = (uint)arraySize * sizeof(uint);
if (StatusSucceeded(apiTable->GetParam(null, QUIC_PARAM_GLOBAL_LIBRARY_VERSION, &size, libVersion)))
{
var version = new Version((int)libVersion[0], (int)libVersion[1], (int)libVersion[2], (int)libVersion[3]);
if (version >= MsQuicVersion)
{
Api = new MsQuicApi(apiTable);
IsQuicSupported = true;
}
else
{
if (NetEventSource.Log.IsEnabled())
{
NetEventSource.Info(null, $"Incompatible MsQuic library version '{version}', expecting '{MsQuicVersion}'");
}
}
}
}
}
}
Expand Down Expand Up @@ -182,38 +144,5 @@ private static bool IsTls13Disabled()
#endif
return false;
}

// TODO: Consider updating all of these delegates to instead use function pointers.
internal RegistrationOpenDelegate RegistrationOpenDelegate { get; }
internal RegistrationCloseDelegate RegistrationCloseDelegate { get; }

internal ConfigurationOpenDelegate ConfigurationOpenDelegate { get; }
internal ConfigurationCloseDelegate ConfigurationCloseDelegate { get; }
internal ConfigurationLoadCredentialDelegate ConfigurationLoadCredentialDelegate { get; }

internal ListenerOpenDelegate ListenerOpenDelegate { get; }
internal ListenerCloseDelegate ListenerCloseDelegate { get; }
internal ListenerStartDelegate ListenerStartDelegate { get; }
internal ListenerStopDelegate ListenerStopDelegate { get; }

// TODO: missing SendResumptionTicket
internal ConnectionOpenDelegate ConnectionOpenDelegate { get; }
internal ConnectionCloseDelegate ConnectionCloseDelegate { get; }
internal ConnectionShutdownDelegate ConnectionShutdownDelegate { get; }
internal ConnectionStartDelegate ConnectionStartDelegate { get; }
internal ConnectionSetConfigurationDelegate ConnectionSetConfigurationDelegate { get; }

internal StreamOpenDelegate StreamOpenDelegate { get; }
internal StreamCloseDelegate StreamCloseDelegate { get; }
internal StreamStartDelegate StreamStartDelegate { get; }
internal StreamShutdownDelegate StreamShutdownDelegate { get; }
internal StreamSendDelegate StreamSendDelegate { get; }
internal StreamReceiveCompleteDelegate StreamReceiveCompleteDelegate { get; }
internal StreamReceiveSetEnabledDelegate StreamReceiveSetEnabledDelegate { get; }

internal SetCallbackHandlerDelegate SetCallbackHandlerDelegate { get; }

internal SetParamDelegate SetParamDelegate { get; }
internal GetParamDelegate GetParamDelegate { get; }
}
}
Loading