Exemplo n.º 1
0
 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);
             }
         }
     }
 }
Exemplo n.º 2
0
 internal static void ThrowIfFailed(uint status, string?message = null, Exception?innerException = null)
 {
     if (!MsQuicStatusHelper.SuccessfulStatusCode(status))
     {
         throw CreateExceptionForHResult(status, message, innerException);
     }
 }
Exemplo n.º 3
0
        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);
                    }
                }
            }
        }
Exemplo n.º 4
0
        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);
                    }
                }
            }
        }
Exemplo n.º 5
0
        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);
                    }
                }
            }
        }
Exemplo n.º 6
0
        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;
        }
Exemplo n.º 7
0
        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;
        }