Beispiel #1
0
        private unsafe IPEndPoint Start(QuicListenerOptions options)
        {
            List <SslApplicationProtocol> applicationProtocols = options.ServerAuthenticationOptions !.ApplicationProtocols !;
            IPEndPoint listenEndPoint = options.ListenEndPoint !;

            SOCKADDR_INET address = MsQuicAddressHelpers.IPEndPointToINet(listenEndPoint);

            uint status;

            Debug.Assert(_stateHandle.IsAllocated);

            MemoryHandle[]? handles = null;
            QuicBuffer[]? buffers   = null;
            try
            {
                MsQuicAlpnHelper.Prepare(applicationProtocols, out handles, out buffers);
                status = MsQuicApi.Api.ListenerStartDelegate(_state.Handle, (QuicBuffer *)Marshal.UnsafeAddrOfPinnedArrayElement(buffers, 0), (uint)applicationProtocols.Count, ref address);
            }
            catch
            {
                _stateHandle.Free();
                throw;
            }
            finally
            {
                MsQuicAlpnHelper.Return(ref handles, ref buffers);
            }

            QuicExceptionHelpers.ThrowIfFailed(status, "ListenerStart failed.");

            SOCKADDR_INET inetAddress = MsQuicParameterHelpers.GetINetParam(MsQuicApi.Api, _state.Handle, QUIC_PARAM_LEVEL.LISTENER, (uint)QUIC_PARAM_LISTENER.LOCAL_ADDRESS);

            return(MsQuicAddressHelpers.INetToIPEndPoint(ref inetAddress));
        }
Beispiel #2
0
        internal override unsafe void Start()
        {
            ThrowIfDisposed();

            SOCKADDR_INET address = MsQuicAddressHelpers.IPEndPointToINet(_listenEndPoint);

            uint status;

            MemoryHandle[]? handles = null;
            QuicBuffer[]? buffers   = null;
            try
            {
                MsQuicAlpnHelper.Prepare(_applicationProtocols, out handles, out buffers);
                status = MsQuicApi.Api.ListenerStartDelegate(_state.Handle, (QuicBuffer *)Marshal.UnsafeAddrOfPinnedArrayElement(buffers, 0), (uint)_applicationProtocols.Count, ref address);
            }
            finally
            {
                MsQuicAlpnHelper.Return(ref handles, ref buffers);
            }

            QuicExceptionHelpers.ThrowIfFailed(status, "ListenerStart failed.");

            SOCKADDR_INET inetAddress = MsQuicParameterHelpers.GetINetParam(MsQuicApi.Api, _state.Handle, QUIC_PARAM_LEVEL.LISTENER, (uint)QUIC_PARAM_LISTENER.LOCAL_ADDRESS);

            _listenEndPoint = MsQuicAddressHelpers.INetToIPEndPoint(ref inetAddress);
        }
Beispiel #3
0
        internal unsafe uint ListenerCallbackHandler(
            ref ListenerEvent evt)
        {
            try
            {
                switch (evt.Type)
                {
                case QUIC_LISTENER_EVENT.NEW_CONNECTION:
                {
                    NewConnectionInfo connectionInfo   = *(NewConnectionInfo *)evt.Data.NewConnection.Info;
                    IPEndPoint        localEndPoint    = MsQuicAddressHelpers.INetToIPEndPoint(*(SOCKADDR_INET *)connectionInfo.LocalAddress);
                    IPEndPoint        remoteEndPoint   = MsQuicAddressHelpers.INetToIPEndPoint(*(SOCKADDR_INET *)connectionInfo.RemoteAddress);
                    MsQuicConnection  msQuicConnection = new MsQuicConnection(localEndPoint, remoteEndPoint, evt.Data.NewConnection.Connection);
                    _acceptConnectionQueue.Writer.TryWrite(msQuicConnection);
                }
                    // Always pend the new connection to wait for the security config to be resolved
                    // TODO this doesn't need to be async always
                    return(MsQuicStatusCodes.Pending);

                default:
                    return(MsQuicStatusCodes.InternalError);
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
                return(MsQuicStatusCodes.InternalError);
            }
        }
Beispiel #4
0
        internal override void Start()
        {
            ThrowIfDisposed();

            SetCallbackHandler();

            SOCKADDR_INET address = MsQuicAddressHelpers.IPEndPointToINet(_listenEndPoint);

            MsQuicStatusException.ThrowIfFailed(MsQuicApi.Api.ListenerStartDelegate(
                                                    _ptr,
                                                    ref address));

            SetListenPort();
        }
Beispiel #5
0
        private uint HandleEventConnected(ConnectionEvent connectionEvent)
        {
            SOCKADDR_INET inetAddress = MsQuicParameterHelpers.GetINetParam(MsQuicApi.Api, _ptr, (uint)QUIC_PARAM_LEVEL.CONNECTION, (uint)QUIC_PARAM_CONN.LOCAL_ADDRESS);

            _localEndPoint = MsQuicAddressHelpers.INetToIPEndPoint(inetAddress);

            _connected = true;
            // I don't believe we need to lock here because
            // handle event connected will not be called at the same time as
            // handle event shutdown initiated by transport
            _connectTcs.Complete(MsQuicStatusCodes.Success);

            return(MsQuicStatusCodes.Success);
        }
Beispiel #6
0
        private static uint HandleEventConnected(State state, ref ConnectionEvent connectionEvent)
        {
            if (state.Connected)
            {
                return(MsQuicStatusCodes.Success);
            }

            if (state.IsServer)
            {
                state.Connected = true;
                MsQuicListener.State?listenerState = state.ListenerState;
                state.ListenerState = null;

                if (listenerState != null)
                {
                    if (listenerState.PendingConnections.TryRemove(state.Handle.DangerousGetHandle(), out MsQuicConnection? connection))
                    {
                        // Move connection from pending to Accept queue and hand it out.
                        if (listenerState.AcceptConnectionQueue.Writer.TryWrite(connection))
                        {
                            return(MsQuicStatusCodes.Success);
                        }
                        // Listener is closed
                        connection.Dispose();
                    }
                }

                return(MsQuicStatusCodes.UserCanceled);
            }
            else
            {
                // Connected will already be true for connections accepted from a listener.
                Debug.Assert(!Monitor.IsEntered(state));
                SOCKADDR_INET inetAddress = MsQuicParameterHelpers.GetINetParam(MsQuicApi.Api, state.Handle, QUIC_PARAM_LEVEL.CONNECTION, (uint)QUIC_PARAM_CONN.LOCAL_ADDRESS);

                Debug.Assert(state.Connection != null);
                state.Connection._localEndPoint = MsQuicAddressHelpers.INetToIPEndPoint(ref inetAddress);
                state.Connection.SetNegotiatedAlpn(connectionEvent.Data.Connected.NegotiatedAlpn, connectionEvent.Data.Connected.NegotiatedAlpnLength);
                state.Connection = null;

                state.Connected = true;
                state.ConnectTcs !.SetResult(MsQuicStatusCodes.Success);
                state.ConnectTcs = null;
            }

            return(MsQuicStatusCodes.Success);
        }
Beispiel #7
0
        private uint HandleEventConnected(ref ConnectionEvent connectionEvent)
        {
            if (!_connected)
            {
                // _connected will already be true for connections accepted from a listener.

                SOCKADDR_INET inetAddress = MsQuicParameterHelpers.GetINetParam(MsQuicApi.Api, _ptr, (uint)QUIC_PARAM_LEVEL.CONNECTION, (uint)QUIC_PARAM_CONN.LOCAL_ADDRESS);
                _localEndPoint = MsQuicAddressHelpers.INetToIPEndPoint(ref inetAddress);

                SetNegotiatedAlpn(connectionEvent.Data.Connected.NegotiatedAlpn, connectionEvent.Data.Connected.NegotiatedAlpnLength);

                _connected = true;
                _connectTcs.SetResult(MsQuicStatusCodes.Success);
            }

            return(MsQuicStatusCodes.Success);
        }
Beispiel #8
0
        private static unsafe uint NativeCallbackHandler(
            IntPtr listener,
            IntPtr context,
            ref ListenerEvent evt)
        {
            if (evt.Type != QUIC_LISTENER_EVENT.NEW_CONNECTION)
            {
                return(MsQuicStatusCodes.InternalError);
            }

            GCHandle gcHandle = GCHandle.FromIntPtr(context);

            Debug.Assert(gcHandle.IsAllocated);
            Debug.Assert(gcHandle.Target is not null);
            var state = (State)gcHandle.Target;

            SafeMsQuicConnectionHandle?connectionHandle = null;

            try
            {
                ref NewConnectionInfo connectionInfo = ref *evt.Data.NewConnection.Info;

                IPEndPoint localEndPoint  = MsQuicAddressHelpers.INetToIPEndPoint(ref *(SOCKADDR_INET *)connectionInfo.LocalAddress);
                IPEndPoint remoteEndPoint = MsQuicAddressHelpers.INetToIPEndPoint(ref *(SOCKADDR_INET *)connectionInfo.RemoteAddress);

                connectionHandle = new SafeMsQuicConnectionHandle(evt.Data.NewConnection.Connection);

                uint status = MsQuicApi.Api.ConnectionSetConfigurationDelegate(connectionHandle, state.ConnectionConfiguration);
                QuicExceptionHelpers.ThrowIfFailed(status, "ConnectionSetConfiguration failed.");

                var msQuicConnection = new MsQuicConnection(localEndPoint, remoteEndPoint, connectionHandle, state.RemoteCertificateRequired, state.RevocationMode, state.RemoteCertificateValidationCallback);
                msQuicConnection.SetNegotiatedAlpn(connectionInfo.NegotiatedAlpn, connectionInfo.NegotiatedAlpnLength);

                if (!state.AcceptConnectionQueue.Writer.TryWrite(msQuicConnection))
                {
                    // This handle will be cleaned up by MsQuic.
                    connectionHandle.SetHandleAsInvalid();
                    msQuicConnection.Dispose();
                    return(MsQuicStatusCodes.InternalError);
                }

                return(MsQuicStatusCodes.Success);
            }
Beispiel #9
0
        private static uint HandleEventConnected(State state, ref ConnectionEvent connectionEvent)
        {
            if (!state.Connected)
            {
                // Connected will already be true for connections accepted from a listener.
                Debug.Assert(!Monitor.IsEntered(state));
                SOCKADDR_INET inetAddress = MsQuicParameterHelpers.GetINetParam(MsQuicApi.Api, state.Handle, QUIC_PARAM_LEVEL.CONNECTION, (uint)QUIC_PARAM_CONN.LOCAL_ADDRESS);

                Debug.Assert(state.Connection != null);
                state.Connection._localEndPoint = MsQuicAddressHelpers.INetToIPEndPoint(ref inetAddress);
                state.Connection.SetNegotiatedAlpn(connectionEvent.Data.Connected.NegotiatedAlpn, connectionEvent.Data.Connected.NegotiatedAlpnLength);
                state.Connection = null;

                state.Connected = true;
                state.ConnectTcs !.SetResult(MsQuicStatusCodes.Success);
                state.ConnectTcs = null;
            }

            return(MsQuicStatusCodes.Success);
        }
Beispiel #10
0
        internal unsafe uint ListenerCallbackHandler(ref ListenerEvent evt)
        {
            try
            {
                switch (evt.Type)
                {
                case QUIC_LISTENER_EVENT.NEW_CONNECTION:
                {
                    ref NewConnectionInfo connectionInfo = ref *(NewConnectionInfo *)evt.Data.NewConnection.Info;

                    IPEndPoint localEndPoint  = MsQuicAddressHelpers.INetToIPEndPoint(ref *(SOCKADDR_INET *)connectionInfo.LocalAddress);
                    IPEndPoint remoteEndPoint = MsQuicAddressHelpers.INetToIPEndPoint(ref *(SOCKADDR_INET *)connectionInfo.RemoteAddress);

                    MsQuicConnection msQuicConnection = new MsQuicConnection(localEndPoint, remoteEndPoint, evt.Data.NewConnection.Connection, _options.IdleTimeout);
                    msQuicConnection.SetNegotiatedAlpn(connectionInfo.NegotiatedAlpn, connectionInfo.NegotiatedAlpnLength);

                    _acceptConnectionQueue.Writer.TryWrite(msQuicConnection);
                }
                    // Always pend the new connection to wait for the security config to be resolved
                    // TODO this doesn't need to be async always
                    return(MsQuicStatusCodes.Pending);
Beispiel #11
0
        internal override void Start()
        {
            ThrowIfDisposed();

            // protect against double starts.
            if (_started)
            {
                throw new QuicException("Cannot start Listener multiple times");
            }

            _started = true;
            SetCallbackHandler();

            SOCKADDR_INET address = MsQuicAddressHelpers.IPEndPointToINet(_listenEndPoint);

            QuicExceptionHelpers.ThrowIfFailed(MsQuicApi.Api.ListenerStartDelegate(
                                                   _ptr,
                                                   ref address),
                                               "Failed to start listener.");

            SetListenPort();
        }
Beispiel #12
0
        internal override ValueTask ConnectAsync(CancellationToken cancellationToken = default)
        {
            ThrowIfDisposed();

            if (_configuration is null)
            {
                throw new Exception($"{nameof(ConnectAsync)} must not be called on a connection obtained from a listener.");
            }

            QUIC_ADDRESS_FAMILY af = _remoteEndPoint.AddressFamily switch
            {
                AddressFamily.Unspecified => QUIC_ADDRESS_FAMILY.UNSPEC,
                AddressFamily.InterNetwork => QUIC_ADDRESS_FAMILY.INET,
                AddressFamily.InterNetworkV6 => QUIC_ADDRESS_FAMILY.INET6,
                _ => throw new Exception(SR.Format(SR.net_quic_unsupported_address_family, _remoteEndPoint.AddressFamily))
            };

            Debug.Assert(_state.StateGCHandle.IsAllocated);

            _state.Connection = this;
            uint   status;
            string targetHost;
            int    port;

            if (_remoteEndPoint is IPEndPoint)
            {
                SOCKADDR_INET address = MsQuicAddressHelpers.IPEndPointToINet((IPEndPoint)_remoteEndPoint);
                unsafe
                {
                    Debug.Assert(!Monitor.IsEntered(_state));
                    status = MsQuicApi.Api.SetParamDelegate(_state.Handle, QUIC_PARAM_LEVEL.CONNECTION, (uint)QUIC_PARAM_CONN.REMOTE_ADDRESS, (uint)sizeof(SOCKADDR_INET), (byte *)&address);
                    QuicExceptionHelpers.ThrowIfFailed(status, "Failed to connect to peer.");
                }

                targetHost = _state.TargetHost ?? ((IPEndPoint)_remoteEndPoint).Address.ToString();
                port       = ((IPEndPoint)_remoteEndPoint).Port;
            }
            else if (_remoteEndPoint is DnsEndPoint)
            {
                // We don't have way how to set separate SNI and name for connection at this moment.
                targetHost = ((DnsEndPoint)_remoteEndPoint).Host;
                port       = ((DnsEndPoint)_remoteEndPoint).Port;
            }
            else
            {
                throw new Exception($"Unsupported remote endpoint type '{_remoteEndPoint.GetType()}'.");
            }

            // We store TCS to local variable to avoid NRE if callbacks finish fast and set _state.ConnectTcs to null.
            var tcs = _state.ConnectTcs = new TaskCompletionSource <uint>(TaskCreationOptions.RunContinuationsAsynchronously);

            try
            {
                Debug.Assert(!Monitor.IsEntered(_state));
                status = MsQuicApi.Api.ConnectionStartDelegate(
                    _state.Handle,
                    _configuration,
                    af,
                    targetHost,
                    (ushort)port);

                QuicExceptionHelpers.ThrowIfFailed(status, "Failed to connect to peer.");

                // this handle is ref counted by MsQuic, so safe to dispose here.
                _configuration.Dispose();
                _configuration = null;
            }
            catch
            {
                _state.StateGCHandle.Free();
                _state.Connection = null;
                throw;
            }

            return(new ValueTask(tcs.Task));
        }
Beispiel #13
0
        private void SetListenPort()
        {
            SOCKADDR_INET inetAddress = MsQuicParameterHelpers.GetINetParam(MsQuicApi.Api, _ptr, (uint)QUIC_PARAM_LEVEL.LISTENER, (uint)QUIC_PARAM_LISTENER.LOCAL_ADDRESS);

            _listenEndPoint = MsQuicAddressHelpers.INetToIPEndPoint(ref inetAddress);
        }
Beispiel #14
0
        private static unsafe uint NativeCallbackHandler(
            IntPtr listener,
            IntPtr context,
            ListenerEvent *evt)
        {
            GCHandle gcHandle = GCHandle.FromIntPtr(context);

            Debug.Assert(gcHandle.IsAllocated);
            Debug.Assert(gcHandle.Target is not null);
            var state = (State)gcHandle.Target;

            if (evt->Type != QUIC_LISTENER_EVENT.NEW_CONNECTION)
            {
                return(MsQuicStatusCodes.InternalError);
            }

            SafeMsQuicConnectionHandle?connectionHandle = null;
            MsQuicConnection?          msQuicConnection = null;

            try
            {
                ref NewConnectionInfo connectionInfo = ref *evt->Data.NewConnection.Info;

                IPEndPoint localEndPoint  = MsQuicAddressHelpers.INetToIPEndPoint(ref *(SOCKADDR_INET *)connectionInfo.LocalAddress);
                IPEndPoint remoteEndPoint = MsQuicAddressHelpers.INetToIPEndPoint(ref *(SOCKADDR_INET *)connectionInfo.RemoteAddress);
                string     targetHost     = string.Empty; // compat with SslStream
                if (connectionInfo.ServerNameLength > 0 && connectionInfo.ServerName != IntPtr.Zero)
                {
                    // TBD We should figure out what to do with international names.
                    targetHost = Marshal.PtrToStringAnsi(connectionInfo.ServerName, connectionInfo.ServerNameLength);
                }

                SafeMsQuicConfigurationHandle?connectionConfiguration = state.ConnectionConfiguration;

                if (connectionConfiguration == null)
                {
                    Debug.Assert(state.AuthenticationOptions.ServerCertificateSelectionCallback != null);
                    try
                    {
                        // ServerCertificateSelectionCallback is synchronous. We will call it as needed when building configuration
                        connectionConfiguration = SafeMsQuicConfigurationHandle.Create(state.ConnectionOptions, state.AuthenticationOptions, targetHost);
                    }
                    catch (Exception ex)
                    {
                        if (NetEventSource.Log.IsEnabled())
                        {
                            NetEventSource.Error(state, $"[Listener#{state.GetHashCode()}] Exception occurred during creating configuration in connection callback: {ex}");
                        }
                    }

                    if (connectionConfiguration == null)
                    {
                        // We don't have safe handle yet so MsQuic will cleanup new connection.
                        return(MsQuicStatusCodes.InternalError);
                    }
                }

                connectionHandle = new SafeMsQuicConnectionHandle(evt->Data.NewConnection.Connection);

                uint status = MsQuicApi.Api.ConnectionSetConfigurationDelegate(connectionHandle, connectionConfiguration);
                if (MsQuicStatusHelper.SuccessfulStatusCode(status))
                {
                    msQuicConnection = new MsQuicConnection(localEndPoint, remoteEndPoint, state, connectionHandle, state.AuthenticationOptions.ClientCertificateRequired, state.AuthenticationOptions.CertificateRevocationCheckMode, state.AuthenticationOptions.RemoteCertificateValidationCallback);
                    msQuicConnection.SetNegotiatedAlpn(connectionInfo.NegotiatedAlpn, connectionInfo.NegotiatedAlpnLength);

                    if (!state.PendingConnections.TryAdd(connectionHandle.DangerousGetHandle(), msQuicConnection))
                    {
                        msQuicConnection.Dispose();
                    }

                    return(MsQuicStatusCodes.Success);
                }

                // If we fall-through here something wrong happened.
            }
Beispiel #15
0
        internal override ValueTask ConnectAsync(CancellationToken cancellationToken = default)
        {
            ThrowIfDisposed();

            if (_configuration is null)
            {
                throw new InvalidOperationException($"{nameof(ConnectAsync)} must not be called on a connection obtained from a listener.");
            }

            QUIC_ADDRESS_FAMILY af = _remoteEndPoint.AddressFamily switch
            {
                AddressFamily.Unspecified => QUIC_ADDRESS_FAMILY.UNSPEC,
                AddressFamily.InterNetwork => QUIC_ADDRESS_FAMILY.INET,
                AddressFamily.InterNetworkV6 => QUIC_ADDRESS_FAMILY.INET6,
                _ => throw new ArgumentException(SR.Format(SR.net_quic_unsupported_address_family, _remoteEndPoint.AddressFamily))
            };

            Debug.Assert(_state.StateGCHandle.IsAllocated);

            _state.Connection = this;
            uint   status;
            string targetHost;
            int    port;

            if (_remoteEndPoint is IPEndPoint)
            {
                SOCKADDR_INET address = MsQuicAddressHelpers.IPEndPointToINet((IPEndPoint)_remoteEndPoint);
                unsafe
                {
                    Debug.Assert(!Monitor.IsEntered(_state));
                    status = MsQuicApi.Api.SetParamDelegate(_state.Handle, QUIC_PARAM_LEVEL.CONNECTION, (uint)QUIC_PARAM_CONN.REMOTE_ADDRESS, (uint)sizeof(SOCKADDR_INET), (byte *)&address);
                    QuicExceptionHelpers.ThrowIfFailed(status, "Failed to connect to peer.");
                }

                targetHost = _state.TargetHost ?? ((IPEndPoint)_remoteEndPoint).Address.ToString();
                port       = ((IPEndPoint)_remoteEndPoint).Port;
            }
            else if (_remoteEndPoint is DnsEndPoint)
            {
                port = ((DnsEndPoint)_remoteEndPoint).Port;
                string dnsHost = ((DnsEndPoint)_remoteEndPoint).Host !;

                // We don't have way how to set separate SNI and name for connection at this moment.
                // If the name is actually IP address we can use it to make at least some cases work for people
                // who want to bypass DNS but connect to specific virtual host.
                if (!string.IsNullOrEmpty(_state.TargetHost) && !dnsHost.Equals(_state.TargetHost, StringComparison.InvariantCultureIgnoreCase) && IPAddress.TryParse(dnsHost, out IPAddress? address))
                {
                    // This is form of IPAddress and _state.TargetHost is set to different string
                    SOCKADDR_INET quicAddress = MsQuicAddressHelpers.IPEndPointToINet(new IPEndPoint(address, port));
                    unsafe
                    {
                        Debug.Assert(!Monitor.IsEntered(_state));
                        status = MsQuicApi.Api.SetParamDelegate(_state.Handle, QUIC_PARAM_LEVEL.CONNECTION, (uint)QUIC_PARAM_CONN.REMOTE_ADDRESS, (uint)sizeof(SOCKADDR_INET), (byte *)&quicAddress);
                        QuicExceptionHelpers.ThrowIfFailed(status, "Failed to connect to peer.");
                    }
                    targetHost = _state.TargetHost !;
                }
                else
                {
                    targetHost = dnsHost;
                }
            }
            else
            {
                throw new ArgumentException($"Unsupported remote endpoint type '{_remoteEndPoint.GetType()}'.");
            }

            // We store TCS to local variable to avoid NRE if callbacks finish fast and set _state.ConnectTcs to null.
            var tcs = _state.ConnectTcs = new TaskCompletionSource <uint>(TaskCreationOptions.RunContinuationsAsynchronously);

            try
            {
                Debug.Assert(!Monitor.IsEntered(_state));
                status = MsQuicApi.Api.ConnectionStartDelegate(
                    _state.Handle,
                    _configuration,
                    af,
                    targetHost,
                    (ushort)port);

                QuicExceptionHelpers.ThrowIfFailed(status, "Failed to connect to peer.");

                // this handle is ref counted by MsQuic, so safe to dispose here.
                _configuration.Dispose();
                _configuration = null;
            }
            catch
            {
                _state.StateGCHandle.Free();
                _state.Connection = null;
                throw;
            }

            return(new ValueTask(tcs.Task));
        }
Beispiel #16
0
#pragma warning restore CS3016
        private static unsafe int NativeCallback(QUIC_HANDLE *listener, void *context, QUIC_LISTENER_EVENT *listenerEvent)
        {
            GCHandle gcHandle = GCHandle.FromIntPtr((IntPtr)context);

            Debug.Assert(gcHandle.IsAllocated);
            Debug.Assert(gcHandle.Target is not null);
            var state = (State)gcHandle.Target;


            if (listenerEvent->Type == QUIC_LISTENER_EVENT_TYPE.STOP_COMPLETE)
            {
                state.StopCompletion.TrySetResult();
                return(QUIC_STATUS_SUCCESS);
            }

            if (listenerEvent->Type != QUIC_LISTENER_EVENT_TYPE.NEW_CONNECTION)
            {
                return(QUIC_STATUS_INTERNAL_ERROR);
            }

            SafeMsQuicConnectionHandle?connectionHandle = null;
            MsQuicConnection?          msQuicConnection = null;

            try
            {
                ref QUIC_NEW_CONNECTION_INFO connectionInfo = ref *listenerEvent->NEW_CONNECTION.Info;

                IPEndPoint localEndPoint  = MsQuicAddressHelpers.INetToIPEndPoint((IntPtr)connectionInfo.LocalAddress);
                IPEndPoint remoteEndPoint = MsQuicAddressHelpers.INetToIPEndPoint((IntPtr)connectionInfo.RemoteAddress);

                string targetHost = string.Empty;   // compat with SslStream
                if (connectionInfo.ServerNameLength > 0 && (IntPtr)connectionInfo.ServerName != IntPtr.Zero)
                {
                    // TBD We should figure out what to do with international names.
                    targetHost = Marshal.PtrToStringAnsi((IntPtr)connectionInfo.ServerName, connectionInfo.ServerNameLength);
                }

                SafeMsQuicConfigurationHandle?connectionConfiguration = state.ConnectionConfiguration;

                if (connectionConfiguration == null)
                {
                    Debug.Assert(state.AuthenticationOptions.ServerCertificateSelectionCallback != null);
                    try
                    {
                        // ServerCertificateSelectionCallback is synchronous. We will call it as needed when building configuration
                        connectionConfiguration = SafeMsQuicConfigurationHandle.Create(state.ConnectionOptions, state.AuthenticationOptions, targetHost);
                    }
                    catch (Exception ex)
                    {
                        if (NetEventSource.Log.IsEnabled())
                        {
                            NetEventSource.Error(state, $"[Listener#{state.GetHashCode()}] Exception occurred during creating configuration in connection callback: {ex}");
                        }
                    }

                    if (connectionConfiguration == null)
                    {
                        // We don't have safe handle yet so MsQuic will cleanup new connection.
                        return(QUIC_STATUS_INTERNAL_ERROR);
                    }
                }

                connectionHandle = new SafeMsQuicConnectionHandle(listenerEvent->NEW_CONNECTION.Connection);

                Debug.Assert(!Monitor.IsEntered(state), "!Monitor.IsEntered(state)");
                int status = MsQuicApi.Api.ApiTable->ConnectionSetConfiguration(connectionHandle.QuicHandle, connectionConfiguration.QuicHandle);
                if (StatusSucceeded(status))
                {
                    msQuicConnection = new MsQuicConnection(localEndPoint, remoteEndPoint, state, connectionHandle, state.AuthenticationOptions.ClientCertificateRequired, state.AuthenticationOptions.CertificateRevocationCheckMode, state.AuthenticationOptions.RemoteCertificateValidationCallback);
                    msQuicConnection.SetNegotiatedAlpn((IntPtr)connectionInfo.NegotiatedAlpn, connectionInfo.NegotiatedAlpnLength);

                    if (!state.PendingConnections.TryAdd(connectionHandle.DangerousGetHandle(), msQuicConnection))
                    {
                        msQuicConnection.Dispose();
                    }

                    return(QUIC_STATUS_SUCCESS);
                }

                // If we fall-through here something wrong happened.
            }