Example #1
0
        public async ValueTask <MsQuicConnection> ConnectionOpenAsync(IPEndPoint endpoint, MsQuicTransportContext context)
        {
            var status = _registration.ConnectionOpenDelegate(
                _nativeObjPtr,
                MsQuicConnection.NativeCallbackHandler,
                IntPtr.Zero,
                out var connectionPtr);

            MsQuicStatusException.ThrowIfFailed(status);

            var msQuicConnection = new MsQuicConnection(_registration, context, connectionPtr);

            await msQuicConnection.StartAsync((ushort)endpoint.AddressFamily, endpoint.Address.ToString(), (ushort)endpoint.Port);

            return(msQuicConnection);
        }
Example #2
0
        public MsQuicStream(MsQuicApi api, MsQuicConnection connection, MsQuicTransportContext context, QUIC_STREAM_OPEN_FLAG flags, IntPtr nativeObjPtr)
        {
            Debug.Assert(connection != null);

            Api           = api;
            _nativeObjPtr = nativeObjPtr;

            _connection = connection;
            MemoryPool  = context.Options.MemoryPoolFactory();
            _log        = context.Log;

            ConnectionClosed = _streamClosedTokenSource.Token;

            var maxReadBufferSize  = context.Options.MaxReadBufferSize.Value;
            var maxWriteBufferSize = context.Options.MaxWriteBufferSize.Value;

            _resettableCompletion = new ResettableCompletionSource(this);

            // TODO should we allow these PipeScheduler to be configurable here?
            var inputOptions  = new PipeOptions(MemoryPool, PipeScheduler.ThreadPool, PipeScheduler.Inline, maxReadBufferSize, maxReadBufferSize / 2, useSynchronizationContext: false);
            var outputOptions = new PipeOptions(MemoryPool, PipeScheduler.Inline, PipeScheduler.ThreadPool, maxWriteBufferSize, maxWriteBufferSize / 2, useSynchronizationContext: false);

            var pair = DuplexPipe.CreateConnectionPair(inputOptions, outputOptions);

            // TODO when stream is unidirectional, don't create an output pipe.
            if (flags.HasFlag(QUIC_STREAM_OPEN_FLAG.UNIDIRECTIONAL))
            {
                Features.Set <IUnidirectionalStreamFeature>(this);
            }

            // TODO populate the ITlsConnectionFeature (requires client certs).
            var feature = new FakeTlsConnectionFeature();

            Features.Set <ITlsConnectionFeature>(feature);

            Transport   = pair.Transport;
            Application = pair.Application;

            SetCallbackHandler();

            _processingTask = ProcessSends();

            // Concatenate stream id with ConnectionId.
            _log.NewStream(ConnectionId);
        }
        internal uint ListenerCallbackHandler(
            ref ListenerEvent evt)
        {
            switch (evt.Type)
            {
            case QUIC_LISTENER_EVENT.NEW_CONNECTION:
            {
                evt.Data.NewConnection.SecurityConfig = _secConfig.NativeObjPtr;
                var msQuicConnection = new MsQuicConnection(_api, _transportContext, evt.Data.NewConnection.Connection);
                _acceptConnectionQueue.Writer.TryWrite(msQuicConnection);
            }
            break;

            default:
                return(MsQuicConstants.InternalError);
            }

            return(MsQuicConstants.Success);
        }