예제 #1
0
        public QuicStreamContext(QuicConnectionContext connection, QuicTransportContext context)
        {
            _connection = connection;
            _context    = context;
            _log        = context.Log;
            MemoryPool  = connection.MemoryPool;
            MultiplexedConnectionFeatures = connection.Features;

            RemoteEndPoint = connection.RemoteEndPoint;
            LocalEndPoint  = connection.LocalEndPoint;

            var maxReadBufferSize  = context.Options.MaxReadBufferSize ?? 0;
            var maxWriteBufferSize = context.Options.MaxWriteBufferSize ?? 0;

            // 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);

            _inputPipe  = new Pipe(inputOptions);
            _outputPipe = new Pipe(outputOptions);

            _transportPipeReader = new CompletionPipeReader(_inputPipe.Reader);
            _transportPipeWriter = new CompletionPipeWriter(_outputPipe.Writer);

            _originalApplication = new DuplexPipe(_outputPipe.Reader, _inputPipe.Writer);
            _originalTransport   = new DuplexPipe(_transportPipeReader, _transportPipeWriter);
        }
예제 #2
0
        public QuicStreamContext(QuicStream stream, QuicConnectionContext connection, QuicTransportContext context)
        {
            _stream     = stream;
            _connection = connection;
            _context    = context;
            _log        = context.Log;

            ConnectionClosed = _streamClosedTokenSource.Token;

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

            // 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);

            Features.Set <IStreamDirectionFeature>(this);
            Features.Set <IProtocolErrorCodeFeature>(this);
            Features.Set <IStreamIdFeature>(this);

            // TODO populate the ITlsConnectionFeature (requires client certs).
            Features.Set <ITlsConnectionFeature>(new FakeTlsConnectionFeature());
            CanRead  = stream.CanRead;
            CanWrite = stream.CanWrite;

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

            _processingTask = StartAsync();
        }
        public async ValueTask <MultiplexedConnectionContext?> AcceptAsync(IFeatureCollection?features = null, CancellationToken cancellationToken = default)
        {
            try
            {
                var quicConnection = await _listener.AcceptConnectionAsync(cancellationToken);

                var connectionContext = new QuicConnectionContext(quicConnection, _context);

                _log.AcceptedConnection(connectionContext);

                return(connectionContext);
            }
            catch (QuicOperationAbortedException ex)
            {
                _log.LogDebug($"Listener has aborted with exception: {ex.Message}");
            }
            return(null);
        }