static MsQuicApi() { // TODO: Consider updating all of these delegates to instead use function pointers. if (NativeLibrary.TryLoad(Interop.Libraries.MsQuic, out IntPtr msQuicHandle)) { try { if (NativeLibrary.TryGetExport(msQuicHandle, "MsQuicOpen", out IntPtr msQuicOpenAddress)) { MsQuicOpenDelegate msQuicOpen = Marshal.GetDelegateForFunctionPointer <MsQuicOpenDelegate>(msQuicOpenAddress); uint status = msQuicOpen(out NativeApi * vtable); if (MsQuicStatusHelper.SuccessfulStatusCode(status)) { IsQuicSupported = true; Api = new MsQuicApi(vtable); } } } finally { if (!IsQuicSupported) { NativeLibrary.Free(msQuicHandle); } } } }
internal static void ThrowIfFailed(uint status, string?message = null, Exception?innerException = null) { if (!MsQuicStatusHelper.SuccessfulStatusCode(status)) { throw CreateExceptionForHResult(status, message, innerException); } }
static MsQuicApi() { if (!IsHttp3Enabled()) { if (NetEventSource.Log.IsEnabled()) { NetEventSource.Info(null, $"HTTP/3 and QUIC is not enabled, see 'System.Net.SocketsHttpHandler.Http3Support' AppContext switch."); } return; } if (OperatingSystem.IsWindows() && !IsWindowsVersionSupported()) { if (NetEventSource.Log.IsEnabled()) { NetEventSource.Info(null, $"Current Windows version ({Environment.OSVersion}) is not supported by QUIC. Minimal supported version is {MinWindowsVersion}"); } return; } if (NativeLibrary.TryLoad(Interop.Libraries.MsQuic, typeof(MsQuicApi).Assembly, DllImportSearchPath.AssemblyDirectory, out IntPtr msQuicHandle)) { try { if (NativeLibrary.TryGetExport(msQuicHandle, "MsQuicOpenVersion", out IntPtr msQuicOpenVersionAddress)) { delegate * unmanaged[Cdecl] < uint, out NativeApi *, uint > msQuicOpenVersion = (delegate * unmanaged[Cdecl] < uint, out NativeApi *, uint >)msQuicOpenVersionAddress; uint status = msQuicOpenVersion(MsQuicVersion, out NativeApi * vtable); if (MsQuicStatusHelper.SuccessfulStatusCode(status)) { IsQuicSupported = true; Api = new MsQuicApi(vtable); } } } finally { if (!IsQuicSupported) { NativeLibrary.Free(msQuicHandle); } } } }
static MsQuicApi() { if (OperatingSystem.IsWindows()) { if (!IsWindowsVersionSupported()) { if (NetEventSource.Log.IsEnabled()) { NetEventSource.Info(null, $"Current Windows version ({Environment.OSVersion}) is not supported by QUIC. Minimal supported version is {MinWindowsVersion}"); } return; } Tls13MayBeDisabled = IsTls13Disabled(); } IntPtr msQuicHandle; if (NativeLibrary.TryLoad($"{Interop.Libraries.MsQuic}.{MsQuicVersion}", 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)) { IsQuicSupported = true; Api = new MsQuicApi(vtable); } } } finally { if (!IsQuicSupported) { NativeLibrary.Free(msQuicHandle); } } } }
static unsafe MsQuicApi() { // MsQuicOpen will succeed even if the platform will not support it. It will then fail with unspecified // platform-specific errors in subsequent callbacks. For now, check for the minimum build we've tested it on. // TODO: // - Hopefully, MsQuicOpen will perform this check for us and give us a consistent error code. // - Otherwise, dial this in to reflect actual minimum requirements and add some sort of platform // error code mapping when creating exceptions. // TODO: try to initialize TLS 1.3 in SslStream. // TODO: Consider updating all of these delegates to instead use function pointers. if (NativeLibrary.TryLoad(Interop.Libraries.MsQuic, out IntPtr msQuicHandle)) { try { if (NativeLibrary.TryGetExport(msQuicHandle, "MsQuicOpen", out IntPtr msQuicOpenAddress)) { MsQuicNativeMethods.MsQuicOpenDelegate msQuicOpen = Marshal.GetDelegateForFunctionPointer <MsQuicNativeMethods.MsQuicOpenDelegate>(msQuicOpenAddress); uint status = msQuicOpen(out MsQuicNativeMethods.NativeApi * registration); if (MsQuicStatusHelper.SuccessfulStatusCode(status)) { IsQuicSupported = true; Api = new MsQuicApi(registration); } } } finally { if (!IsQuicSupported) { NativeLibrary.Free(msQuicHandle); } } } }
private unsafe MsQuicApi() { MsQuicNativeMethods.NativeApi *registration; try { uint status = Interop.MsQuic.MsQuicOpen(out registration); if (!MsQuicStatusHelper.SuccessfulStatusCode(status)) { throw new NotSupportedException(SR.net_quic_notsupported); } } catch (DllNotFoundException) { throw new NotSupportedException(SR.net_quic_notsupported); } MsQuicNativeMethods.NativeApi nativeRegistration = *registration; RegistrationOpenDelegate = Marshal.GetDelegateForFunctionPointer <MsQuicNativeMethods.RegistrationOpenDelegate>( nativeRegistration.RegistrationOpen); RegistrationCloseDelegate = Marshal.GetDelegateForFunctionPointer <MsQuicNativeMethods.RegistrationCloseDelegate>( nativeRegistration.RegistrationClose); SecConfigCreateDelegate = Marshal.GetDelegateForFunctionPointer <MsQuicNativeMethods.SecConfigCreateDelegate>( nativeRegistration.SecConfigCreate); SecConfigDeleteDelegate = Marshal.GetDelegateForFunctionPointer <MsQuicNativeMethods.SecConfigDeleteDelegate>( nativeRegistration.SecConfigDelete); SessionOpenDelegate = Marshal.GetDelegateForFunctionPointer <MsQuicNativeMethods.SessionOpenDelegate>( nativeRegistration.SessionOpen); SessionCloseDelegate = Marshal.GetDelegateForFunctionPointer <MsQuicNativeMethods.SessionCloseDelegate>( nativeRegistration.SessionClose); SessionShutdownDelegate = Marshal.GetDelegateForFunctionPointer <MsQuicNativeMethods.SessionShutdownDelegate>( nativeRegistration.SessionShutdown); ListenerOpenDelegate = Marshal.GetDelegateForFunctionPointer <MsQuicNativeMethods.ListenerOpenDelegate>( nativeRegistration.ListenerOpen); ListenerCloseDelegate = Marshal.GetDelegateForFunctionPointer <MsQuicNativeMethods.ListenerCloseDelegate>( nativeRegistration.ListenerClose); ListenerStartDelegate = Marshal.GetDelegateForFunctionPointer <MsQuicNativeMethods.ListenerStartDelegate>( nativeRegistration.ListenerStart); ListenerStopDelegate = Marshal.GetDelegateForFunctionPointer <MsQuicNativeMethods.ListenerStopDelegate>( nativeRegistration.ListenerStop); ConnectionOpenDelegate = Marshal.GetDelegateForFunctionPointer <MsQuicNativeMethods.ConnectionOpenDelegate>( nativeRegistration.ConnectionOpen); ConnectionCloseDelegate = Marshal.GetDelegateForFunctionPointer <MsQuicNativeMethods.ConnectionCloseDelegate>( nativeRegistration.ConnectionClose); ConnectionShutdownDelegate = Marshal.GetDelegateForFunctionPointer <MsQuicNativeMethods.ConnectionShutdownDelegate>( nativeRegistration.ConnectionShutdown); ConnectionStartDelegate = Marshal.GetDelegateForFunctionPointer <MsQuicNativeMethods.ConnectionStartDelegate>( nativeRegistration.ConnectionStart); StreamOpenDelegate = Marshal.GetDelegateForFunctionPointer <MsQuicNativeMethods.StreamOpenDelegate>( nativeRegistration.StreamOpen); StreamCloseDelegate = Marshal.GetDelegateForFunctionPointer <MsQuicNativeMethods.StreamCloseDelegate>( nativeRegistration.StreamClose); StreamStartDelegate = Marshal.GetDelegateForFunctionPointer <MsQuicNativeMethods.StreamStartDelegate>( nativeRegistration.StreamStart); StreamShutdownDelegate = Marshal.GetDelegateForFunctionPointer <MsQuicNativeMethods.StreamShutdownDelegate>( nativeRegistration.StreamShutdown); StreamSendDelegate = Marshal.GetDelegateForFunctionPointer <MsQuicNativeMethods.StreamSendDelegate>( nativeRegistration.StreamSend); StreamReceiveCompleteDelegate = Marshal.GetDelegateForFunctionPointer <MsQuicNativeMethods.StreamReceiveCompleteDelegate>( nativeRegistration.StreamReceiveComplete); StreamReceiveSetEnabledDelegate = Marshal.GetDelegateForFunctionPointer <MsQuicNativeMethods.StreamReceiveSetEnabledDelegate>( nativeRegistration.StreamReceiveSetEnabled); SetContextDelegate = Marshal.GetDelegateForFunctionPointer <MsQuicNativeMethods.SetContextDelegate>( nativeRegistration.SetContext); GetContextDelegate = Marshal.GetDelegateForFunctionPointer <MsQuicNativeMethods.GetContextDelegate>( nativeRegistration.GetContext); SetCallbackHandlerDelegate = Marshal.GetDelegateForFunctionPointer <MsQuicNativeMethods.SetCallbackHandlerDelegate>( nativeRegistration.SetCallbackHandler); SetParamDelegate = Marshal.GetDelegateForFunctionPointer <MsQuicNativeMethods.SetParamDelegate>( nativeRegistration.SetParam); GetParamDelegate = Marshal.GetDelegateForFunctionPointer <MsQuicNativeMethods.GetParamDelegate>( nativeRegistration.GetParam); var registrationConfig = new MsQuicNativeMethods.RegistrationConfig { AppName = "SystemNetQuic", ExecutionProfile = QUIC_EXECUTION_PROFILE.QUIC_EXECUTION_PROFILE_LOW_LATENCY }; RegistrationOpenDelegate(ref registrationConfig, out IntPtr ctx); _registrationContext = ctx; }
private unsafe MsQuicApi() { MsQuicNativeMethods.NativeApi *registration; try { uint status = Interop.MsQuic.MsQuicOpen(version: 1, out registration); if (!MsQuicStatusHelper.SuccessfulStatusCode(status)) { throw new NotSupportedException(SR.net_quic_notsupported); } } catch (DllNotFoundException) { throw new NotSupportedException(SR.net_quic_notsupported); } MsQuicNativeMethods.NativeApi nativeRegistration = *registration; RegistrationOpenDelegate = Marshal.GetDelegateForFunctionPointer <MsQuicNativeMethods.RegistrationOpenDelegate>( nativeRegistration.RegistrationOpen); RegistrationCloseDelegate = Marshal.GetDelegateForFunctionPointer <MsQuicNativeMethods.RegistrationCloseDelegate>( nativeRegistration.RegistrationClose); SecConfigCreateDelegate = Marshal.GetDelegateForFunctionPointer <MsQuicNativeMethods.SecConfigCreateDelegate>( nativeRegistration.SecConfigCreate); SecConfigDeleteDelegate = Marshal.GetDelegateForFunctionPointer <MsQuicNativeMethods.SecConfigDeleteDelegate>( nativeRegistration.SecConfigDelete); SessionOpenDelegate = Marshal.GetDelegateForFunctionPointer <MsQuicNativeMethods.SessionOpenDelegate>( nativeRegistration.SessionOpen); SessionCloseDelegate = Marshal.GetDelegateForFunctionPointer <MsQuicNativeMethods.SessionCloseDelegate>( nativeRegistration.SessionClose); SessionShutdownDelegate = Marshal.GetDelegateForFunctionPointer <MsQuicNativeMethods.SessionShutdownDelegate>( nativeRegistration.SessionShutdown); ListenerOpenDelegate = Marshal.GetDelegateForFunctionPointer <MsQuicNativeMethods.ListenerOpenDelegate>( nativeRegistration.ListenerOpen); ListenerCloseDelegate = Marshal.GetDelegateForFunctionPointer <MsQuicNativeMethods.ListenerCloseDelegate>( nativeRegistration.ListenerClose); ListenerStartDelegate = Marshal.GetDelegateForFunctionPointer <MsQuicNativeMethods.ListenerStartDelegate>( nativeRegistration.ListenerStart); ListenerStopDelegate = Marshal.GetDelegateForFunctionPointer <MsQuicNativeMethods.ListenerStopDelegate>( nativeRegistration.ListenerStop); ConnectionOpenDelegate = Marshal.GetDelegateForFunctionPointer <MsQuicNativeMethods.ConnectionOpenDelegate>( nativeRegistration.ConnectionOpen); ConnectionCloseDelegate = Marshal.GetDelegateForFunctionPointer <MsQuicNativeMethods.ConnectionCloseDelegate>( nativeRegistration.ConnectionClose); ConnectionShutdownDelegate = Marshal.GetDelegateForFunctionPointer <MsQuicNativeMethods.ConnectionShutdownDelegate>( nativeRegistration.ConnectionShutdown); ConnectionStartDelegate = Marshal.GetDelegateForFunctionPointer <MsQuicNativeMethods.ConnectionStartDelegate>( nativeRegistration.ConnectionStart); StreamOpenDelegate = Marshal.GetDelegateForFunctionPointer <MsQuicNativeMethods.StreamOpenDelegate>( nativeRegistration.StreamOpen); StreamCloseDelegate = Marshal.GetDelegateForFunctionPointer <MsQuicNativeMethods.StreamCloseDelegate>( nativeRegistration.StreamClose); StreamStartDelegate = Marshal.GetDelegateForFunctionPointer <MsQuicNativeMethods.StreamStartDelegate>( nativeRegistration.StreamStart); StreamShutdownDelegate = Marshal.GetDelegateForFunctionPointer <MsQuicNativeMethods.StreamShutdownDelegate>( nativeRegistration.StreamShutdown); StreamSendDelegate = Marshal.GetDelegateForFunctionPointer <MsQuicNativeMethods.StreamSendDelegate>( nativeRegistration.StreamSend); StreamReceiveCompleteDelegate = Marshal.GetDelegateForFunctionPointer <MsQuicNativeMethods.StreamReceiveCompleteDelegate>( nativeRegistration.StreamReceiveComplete); StreamReceiveSetEnabledDelegate = Marshal.GetDelegateForFunctionPointer <MsQuicNativeMethods.StreamReceiveSetEnabledDelegate>( nativeRegistration.StreamReceiveSetEnabled); SetContextDelegate = Marshal.GetDelegateForFunctionPointer <MsQuicNativeMethods.SetContextDelegate>( nativeRegistration.SetContext); GetContextDelegate = Marshal.GetDelegateForFunctionPointer <MsQuicNativeMethods.GetContextDelegate>( nativeRegistration.GetContext); SetCallbackHandlerDelegate = Marshal.GetDelegateForFunctionPointer <MsQuicNativeMethods.SetCallbackHandlerDelegate>( nativeRegistration.SetCallbackHandler); SetParamDelegate = Marshal.GetDelegateForFunctionPointer <MsQuicNativeMethods.SetParamDelegate>( nativeRegistration.SetParam); GetParamDelegate = Marshal.GetDelegateForFunctionPointer <MsQuicNativeMethods.GetParamDelegate>( nativeRegistration.GetParam); RegistrationOpenDelegate(Encoding.UTF8.GetBytes("SystemNetQuic"), out IntPtr ctx); _registrationContext = ctx; }