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