Beispiel #1
0
        internal SocketTransport(
            IEndPointInformation endPointInformation,
            IConnectionDispatcher dispatcher,
            IApplicationLifetime applicationLifetime,
            int ioQueueCount,
            ISocketsTrace trace)
        {
            Debug.Assert(endPointInformation != null);
            Debug.Assert(endPointInformation.Type == ListenType.IPEndPoint);
            Debug.Assert(dispatcher != null);
            Debug.Assert(applicationLifetime != null);
            Debug.Assert(trace != null);

            _endPointInformation = endPointInformation;
            _dispatcher          = dispatcher;
            _appLifetime         = applicationLifetime;
            _trace = trace;

            if (ioQueueCount > 0)
            {
                _numSchedulers = ioQueueCount;
                _schedulers    = new IOQueue[_numSchedulers];

                for (var i = 0; i < _numSchedulers; i++)
                {
                    _schedulers[i] = new IOQueue();
                }
            }
            else
            {
                _numSchedulers = ThreadPoolSchedulerArray.Length;
                _schedulers    = ThreadPoolSchedulerArray;
            }
        }
        internal SocketConnection(Socket socket, MemoryPool <byte> memoryPool, PipeScheduler scheduler, ISocketsTrace trace)
        {
            Debug.Assert(socket != null);
            Debug.Assert(memoryPool != null);
            Debug.Assert(trace != null);

            _socket    = socket;
            MemoryPool = memoryPool;
            _scheduler = scheduler;
            _trace     = trace;

            var localEndPoint  = (IPEndPoint)_socket.LocalEndPoint;
            var remoteEndPoint = (IPEndPoint)_socket.RemoteEndPoint;

            LocalAddress = localEndPoint.Address;
            LocalPort    = localEndPoint.Port;

            RemoteAddress = remoteEndPoint.Address;
            RemotePort    = remoteEndPoint.Port;

            // On *nix platforms, Sockets already dispatches to the ThreadPool.
            var awaiterScheduler = IsWindows ? _scheduler : PipeScheduler.Inline;

            _receiver = new SocketReceiver(_socket, awaiterScheduler);
            _sender   = new SocketSender(_socket, awaiterScheduler);
        }
        internal SocketConnection(Socket socket, MemoryPool <byte> memoryPool, PipeScheduler scheduler, ISocketsTrace trace)
        {
            Debug.Assert(socket != null);
            Debug.Assert(memoryPool != null);
            Debug.Assert(trace != null);

            _socket    = socket;
            MemoryPool = memoryPool;
            _scheduler = scheduler;
            _trace     = trace;

            var localEndPoint  = (IPEndPoint)_socket.LocalEndPoint;
            var remoteEndPoint = (IPEndPoint)_socket.RemoteEndPoint;

            LocalAddress = localEndPoint.Address;
            LocalPort    = localEndPoint.Port;

            RemoteAddress = remoteEndPoint.Address;
            RemotePort    = remoteEndPoint.Port;

            ConnectionClosed = _connectionClosedTokenSource.Token;

            _receiver = new SocketReceiver(_socket, _scheduler);
            _sender   = new SocketSender(_socket, _scheduler);
        }
        internal SocketConnection(Socket socket, MemoryPool <byte> memoryPool, PipeScheduler scheduler, ISocketsTrace trace)
        {
            Debug.Assert(socket != null);
            Debug.Assert(memoryPool != null);
            Debug.Assert(trace != null);

            _socket    = socket;
            MemoryPool = memoryPool;
            _scheduler = scheduler;
            _trace     = trace;

            var localEndPoint  = (IPEndPoint)_socket.LocalEndPoint;
            var remoteEndPoint = (IPEndPoint)_socket.RemoteEndPoint;

            LocalAddress = localEndPoint.Address;
            LocalPort    = localEndPoint.Port;

            RemoteAddress = remoteEndPoint.Address;
            RemotePort    = remoteEndPoint.Port;

            ConnectionClosed = _connectionClosedTokenSource.Token;

            // On *nix platforms, Sockets already dispatches to the ThreadPool.
            // Yes, the IOQueues are still used for the PipeSchedulers. This is intentional.
            // https://github.com/aspnet/KestrelHttpServer/issues/2573
            var awaiterScheduler = IsWindows ? _scheduler : PipeScheduler.Inline;

            _receiver = new SocketReceiver(_socket, awaiterScheduler);
            _sender   = new SocketSender(_socket, awaiterScheduler);
        }
        internal SocketConnectionListener(
            EndPoint endpoint,
            SocketTransportOptions options,
            ISocketsTrace trace)
        {
            EndPoint    = endpoint;
            _trace      = trace;
            _options    = options;
            _memoryPool = _options.MemoryPoolFactory();
            var ioQueueCount = options.IOQueueCount;

            if (ioQueueCount > 0)
            {
                _numSchedulers = ioQueueCount;
                _schedulers    = new IOQueue[_numSchedulers];

                for (var i = 0; i < _numSchedulers; i++)
                {
                    _schedulers[i] = new IOQueue();
                }
            }
            else
            {
                var directScheduler = new PipeScheduler[] { PipeScheduler.ThreadPool };
                _numSchedulers = directScheduler.Length;
                _schedulers    = directScheduler;
            }
        }
Beispiel #6
0
        internal SocketConnectionListener(
            EndPoint endpoint,
            SocketTransportOptions options,
            ISocketsTrace trace)
        {
            EndPoint     = endpoint;
            this.trace   = trace;
            this.options = options;
            memoryPool   = MemoryPool <byte> .Shared;
            var ioQueueCount = options.IOQueueCount;

            if (ioQueueCount > 0)
            {
                numSchedulers = ioQueueCount;
                schedulers    = new IOQueue[numSchedulers];

                for (var i = 0; i < numSchedulers; i++)
                {
                    schedulers[i] = new IOQueue();
                }
            }
            else
            {
                var directScheduler = new PipeScheduler[] { PipeScheduler.ThreadPool };
                numSchedulers = directScheduler.Length;
                schedulers    = directScheduler;
            }
        }
Beispiel #7
0
        internal SocketConnection(Socket socket)
        {
            Debug.Assert(socket != null);

            _socket = socket;
            _trace  = new EmptySocketsTrace();

            var localEndPoint  = (IPEndPoint)_socket.LocalEndPoint;
            var remoteEndPoint = (IPEndPoint)_socket.RemoteEndPoint;

            LocalAddress = localEndPoint.Address;
            LocalPort    = localEndPoint.Port;

            RemoteAddress = remoteEndPoint.Address;
            RemotePort    = remoteEndPoint.Port;

            ConnectionClosed = _connectionClosedTokenSource.Token;

            var pair = DuplexPipe.CreateConnectionPair();

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

            PipeScheduler scheduler = MultiIOQueueGroup.GetIOQueue();

            _receiver = new SocketReceiver(_socket, scheduler);
            _sender   = new SocketSender(_socket, scheduler);
        }
        /// <summary>
        /// Creates the <see cref="SocketConnectionContextFactory"/>.
        /// </summary>
        /// <param name="options">The options.</param>
        /// <param name="logger">The logger.</param>
        public SocketConnectionContextFactory(SocketConnectionFactoryOptions options, ILogger logger)
        {
            if (options == null)
            {
                throw new ArgumentNullException(nameof(options));
            }

            if (logger == null)
            {
                throw new ArgumentNullException(nameof(logger));
            }

            _options       = options;
            _trace         = new SocketsTrace(logger);
            _memoryPool    = _options.MemoryPoolFactory();
            _settingsCount = _options.IOQueueCount;

            var maxReadBufferSize    = _options.MaxReadBufferSize ?? 0;
            var maxWriteBufferSize   = _options.MaxWriteBufferSize ?? 0;
            var applicationScheduler = options.UnsafePreferInlineScheduling ? PipeScheduler.Inline : PipeScheduler.ThreadPool;

            if (_settingsCount > 0)
            {
                _settings = new QueueSettings[_settingsCount];

                for (var i = 0; i < _settingsCount; i++)
                {
                    var transportScheduler = options.UnsafePreferInlineScheduling ? PipeScheduler.Inline : new IOQueue();
                    // https://github.com/aspnet/KestrelHttpServer/issues/2573
                    var awaiterScheduler = OperatingSystem.IsWindows() ? transportScheduler : PipeScheduler.Inline;

                    _settings[i] = new QueueSettings()
                    {
                        Scheduler        = transportScheduler,
                        InputOptions     = new PipeOptions(_memoryPool, applicationScheduler, transportScheduler, maxReadBufferSize, maxReadBufferSize / 2, useSynchronizationContext: false),
                        OutputOptions    = new PipeOptions(_memoryPool, transportScheduler, applicationScheduler, maxWriteBufferSize, maxWriteBufferSize / 2, useSynchronizationContext: false),
                        SocketSenderPool = new SocketSenderPool(awaiterScheduler)
                    };
                }
            }
            else
            {
                var transportScheduler = options.UnsafePreferInlineScheduling ? PipeScheduler.Inline : PipeScheduler.ThreadPool;
                // https://github.com/aspnet/KestrelHttpServer/issues/2573
                var awaiterScheduler = OperatingSystem.IsWindows() ? transportScheduler : PipeScheduler.Inline;
                _settings = new QueueSettings[]
                {
                    new QueueSettings()
                    {
                        Scheduler        = transportScheduler,
                        InputOptions     = new PipeOptions(_memoryPool, applicationScheduler, transportScheduler, maxReadBufferSize, maxReadBufferSize / 2, useSynchronizationContext: false),
                        OutputOptions    = new PipeOptions(_memoryPool, transportScheduler, applicationScheduler, maxWriteBufferSize, maxWriteBufferSize / 2, useSynchronizationContext: false),
                        SocketSenderPool = new SocketSenderPool(awaiterScheduler)
                    }
                };
                _settingsCount = 1;
            }
        }
        internal SocketConnection(Socket socket,
                                  MemoryPool <byte> memoryPool,
                                  PipeScheduler scheduler,
                                  ISocketsTrace trace,
                                  long?maxReadBufferSize  = null,
                                  long?maxWriteBufferSize = null,
                                  bool deferSends         = true,
                                  bool deferReceives      = true,
                                  SocketContinuationScheduler socketScheduler = SocketContinuationScheduler.ThreadPool,
                                  InputScheduler inputScheduler             = InputScheduler.ThreadPool,
                                  bool dontAllocateMemoryForIdleConnections = true,
                                  OutputScheduler outputScheduler           = OutputScheduler.IOQueue)
        {
            Debug.Assert(socket != null);
            Debug.Assert(memoryPool != null);
            Debug.Assert(trace != null);

            _socket              = socket;
            MemoryPool           = memoryPool;
            _trace               = trace;
            _waitForReceiveReady = dontAllocateMemoryForIdleConnections;

            LocalEndPoint  = _socket.LocalEndPoint;
            RemoteEndPoint = _socket.RemoteEndPoint;

            ConnectionClosed = _connectionClosedTokenSource.Token;

            // On *nix platforms, Sockets already dispatches to the ThreadPool.
            // Yes, the IOQueues are still used for the PipeSchedulers. This is intentional.
            // https://github.com/aspnet/KestrelHttpServer/issues/2573
            var awaiterScheduler = IsWindows ? scheduler : PipeScheduler.Inline;

            _receiver = new SocketReceiver(_socket, awaiterScheduler, runContinuationsAsynchronously: socketScheduler == SocketContinuationScheduler.ThreadPool, preferSynchronousCompletion: !deferReceives);
            _sender   = new SocketSender(_socket, awaiterScheduler, runContinuationsAsynchronously: socketScheduler == SocketContinuationScheduler.ThreadPool, preferSynchronousCompletion: !deferSends);

            maxReadBufferSize ??= 0;
            maxWriteBufferSize ??= 0;

            PipeScheduler pipeScheduler = outputScheduler switch
            {
                OutputScheduler.Inline => PipeScheduler.Inline,
                OutputScheduler.IOQueue => scheduler,
                OutputScheduler.IOThread => _socket.IOThreadScheduler,
                OutputScheduler.ThreadPool => PipeScheduler.ThreadPool,
                _ => throw new IndexOutOfRangeException()
            };

            var appScheduler  = inputScheduler == InputScheduler.Inline ? PipeScheduler.Inline : PipeScheduler.ThreadPool;
            var inputOptions  = new PipeOptions(MemoryPool, appScheduler, scheduler, maxReadBufferSize.Value, maxReadBufferSize.Value / 2, useSynchronizationContext: false);
            var outputOptions = new PipeOptions(MemoryPool, pipeScheduler, appScheduler, maxWriteBufferSize.Value, maxWriteBufferSize.Value / 2, useSynchronizationContext: false);

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

            // Set the transport and connection id
            Transport   = pair.Transport;
            Application = pair.Application;
        }
Beispiel #10
0
        internal SocketConnectionListener(
            EndPoint endpoint,
            SocketTransportOptions options,
            ISocketsTrace trace)
        {
            EndPoint    = endpoint;
            _trace      = trace;
            _options    = options;
            _memoryPool = _options.MemoryPoolFactory();
            var ioQueueCount = options.IOQueueCount;

            var maxReadBufferSize    = _options.MaxReadBufferSize ?? 0;
            var maxWriteBufferSize   = _options.MaxWriteBufferSize ?? 0;
            var applicationScheduler = options.UnsafePreferInlineScheduling ? PipeScheduler.Inline : PipeScheduler.ThreadPool;

            if (ioQueueCount > 0)
            {
                _settingsCount = ioQueueCount;
                _settings      = new Settings[_settingsCount];

                for (var i = 0; i < _settingsCount; i++)
                {
                    var transportScheduler = options.UnsafePreferInlineScheduling ? PipeScheduler.Inline : new IOQueue();
                    // https://github.com/aspnet/KestrelHttpServer/issues/2573
                    var awaiterScheduler = OperatingSystem.IsWindows() ? transportScheduler : PipeScheduler.Inline;

                    _settings[i] = new Settings
                    {
                        Scheduler        = transportScheduler,
                        InputOptions     = new PipeOptions(_memoryPool, applicationScheduler, transportScheduler, maxReadBufferSize, maxReadBufferSize / 2, useSynchronizationContext: false),
                        OutputOptions    = new PipeOptions(_memoryPool, transportScheduler, applicationScheduler, maxWriteBufferSize, maxWriteBufferSize / 2, useSynchronizationContext: false),
                        SocketSenderPool = new SocketSenderPool(awaiterScheduler)
                    };
                }
            }
            else
            {
                var transportScheduler = options.UnsafePreferInlineScheduling ? PipeScheduler.Inline : PipeScheduler.ThreadPool;
                // https://github.com/aspnet/KestrelHttpServer/issues/2573
                var awaiterScheduler = OperatingSystem.IsWindows() ? transportScheduler : PipeScheduler.Inline;

                var directScheduler = new Settings[]
                {
                    new Settings
                    {
                        Scheduler        = transportScheduler,
                        InputOptions     = new PipeOptions(_memoryPool, applicationScheduler, transportScheduler, maxReadBufferSize, maxReadBufferSize / 2, useSynchronizationContext: false),
                        OutputOptions    = new PipeOptions(_memoryPool, transportScheduler, applicationScheduler, maxWriteBufferSize, maxWriteBufferSize / 2, useSynchronizationContext: false),
                        SocketSenderPool = new SocketSenderPool(awaiterScheduler)
                    }
                };

                _settingsCount = directScheduler.Length;
                _settings      = directScheduler;
            }
        }
Beispiel #11
0
        internal SocketConnectionListener(
            EndPoint endpoint,
            SocketTransportOptions options,
            ILoggerFactory loggerFactory)
        {
            EndPoint = endpoint;
            _options = options;
            var logger = loggerFactory.CreateLogger("Microsoft.AspNetCore.Server.Kestrel.Transport.Sockets");

            _trace   = new SocketsTrace(logger);
            _factory = new SocketConnectionContextFactory(new SocketConnectionFactoryOptions(options), logger);
        }
Beispiel #12
0
        internal SocketConnection(Socket socket,
                                  MemoryPool <byte> memoryPool,
                                  PipeScheduler transportScheduler,
                                  ISocketsTrace trace,
                                  long?maxReadBufferSize   = null,
                                  long?maxWriteBufferSize  = null,
                                  bool waitForData         = true,
                                  bool useInlineSchedulers = false)
        {
            Debug.Assert(socket != null);
            Debug.Assert(memoryPool != null);
            Debug.Assert(trace != null);

            _socket      = socket;
            MemoryPool   = memoryPool;
            _trace       = trace;
            _waitForData = waitForData;

            LocalEndPoint  = _socket.LocalEndPoint;
            RemoteEndPoint = _socket.RemoteEndPoint;

            ConnectionClosed = _connectionClosedTokenSource.Token;

            // On *nix platforms, Sockets already dispatches to the ThreadPool.
            // Yes, the IOQueues are still used for the PipeSchedulers. This is intentional.
            // https://github.com/aspnet/KestrelHttpServer/issues/2573
            var awaiterScheduler = IsWindows ? transportScheduler : PipeScheduler.Inline;

            var applicationScheduler = PipeScheduler.ThreadPool;

            if (useInlineSchedulers)
            {
                transportScheduler   = PipeScheduler.Inline;
                awaiterScheduler     = PipeScheduler.Inline;
                applicationScheduler = PipeScheduler.Inline;
            }

            _receiver = new SocketReceiver(_socket, awaiterScheduler);
            _sender   = new SocketSender(_socket, awaiterScheduler);

            maxReadBufferSize ??= 0;
            maxWriteBufferSize ??= 0;

            var inputOptions  = new PipeOptions(MemoryPool, applicationScheduler, transportScheduler, maxReadBufferSize.Value, maxReadBufferSize.Value / 2, useSynchronizationContext: false);
            var outputOptions = new PipeOptions(MemoryPool, transportScheduler, applicationScheduler, maxWriteBufferSize.Value, maxWriteBufferSize.Value / 2, useSynchronizationContext: false);

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

            // Set the transport and connection id
            Transport   = pair.Transport;
            Application = pair.Application;
        }
Beispiel #13
0
        public SocketTransport(IEndPointInformation endPointInformation,
                               IConnectionDispatcher dispatcher,
                               int listenBacklog,
                               int ioQueueCount,
                               MemoryPool <byte> pool = null,
                               ILogger logger         = null)
        {
            if (endPointInformation == null)
            {
                throw new ArgumentNullException(nameof(endPointInformation));
            }
            if (endPointInformation.Type != ListenType.IPEndPoint)
            {
                throw new InvalidOperationException(nameof(endPointInformation.IPEndPoint));
            }
            if (dispatcher == null)
            {
                throw new ArgumentNullException(nameof(dispatcher));
            }
            if (listenBacklog < 0)
            {
                throw new InvalidOperationException(nameof(listenBacklog));
            }

            _endPointInformation = endPointInformation;
            _dispatcher          = dispatcher;
            _backlog             = listenBacklog;
            _pool   = pool;
            _logger = logger ?? NullLoggerFactory.Instance.CreateLogger("NetGear.Core.SocketTransport");
            _trace  = new TraceDebugger(_logger);

            if (ioQueueCount > 0)
            {
                _numSchedulers  = ioQueueCount;
                _cachedPipeOpts = new PipeOptionsPair[_numSchedulers];

                for (var i = 0; i < _numSchedulers; i++)
                {
                    _cachedPipeOpts[i] = new PipeOptionsPair(
                        GetSendPipeOptions(_pool, new IOQueue()),
                        GetReceivePipeOptions(_pool, new IOQueue()));
                }
            }
            else
            {
                _numSchedulers  = 1;
                _cachedPipeOpts = new PipeOptionsPair[] { new PipeOptionsPair(
                                                              GetSendPipeOptions(_pool, new IOQueue()),
                                                              GetReceivePipeOptions(_pool, new IOQueue())) };
            }
        }
        internal SocketConnectionListener(
            EndPoint endpoint,
            SocketTransportOptions options,
            ISocketsTrace trace)
        {
            EndPoint    = endpoint;
            _trace      = trace;
            _options    = options;
            _memoryPool = _options.MemoryPoolFactory();
            var ioQueueCount = options.IOQueueCount;

            var maxReadBufferSize    = _options.MaxReadBufferSize ?? 0;
            var maxWriteBufferSize   = _options.MaxWriteBufferSize ?? 0;
            var applicationScheduler = options.UnsafePreferInlineScheduling ? PipeScheduler.Inline : PipeScheduler.ThreadPool;

            if (ioQueueCount > 0)
            {
                _settingsCount = ioQueueCount;
                _settings      = new Settings[_settingsCount];

                for (var i = 0; i < _settingsCount; i++)
                {
                    var transportScheduler = options.UnsafePreferInlineScheduling ? PipeScheduler.Inline : new IOQueue();

                    _settings[i] = new Settings
                    {
                        Scheduler     = transportScheduler,
                        InputOptions  = new PipeOptions(_memoryPool, applicationScheduler, transportScheduler, maxReadBufferSize, maxReadBufferSize / 2, useSynchronizationContext: false),
                        OutputOptions = new PipeOptions(_memoryPool, transportScheduler, applicationScheduler, maxWriteBufferSize, maxWriteBufferSize / 2, useSynchronizationContext: false)
                    };
                }
            }
            else
            {
                var transportScheduler = options.UnsafePreferInlineScheduling ? PipeScheduler.Inline : PipeScheduler.ThreadPool;

                var directScheduler = new Settings[]
                {
                    new Settings
                    {
                        Scheduler     = transportScheduler,
                        InputOptions  = new PipeOptions(_memoryPool, applicationScheduler, transportScheduler, maxReadBufferSize, maxReadBufferSize / 2, useSynchronizationContext: false),
                        OutputOptions = new PipeOptions(_memoryPool, transportScheduler, applicationScheduler, maxWriteBufferSize, maxWriteBufferSize / 2, useSynchronizationContext: false)
                    }
                };

                _settingsCount = directScheduler.Length;
                _settings      = directScheduler;
            }
        }
Beispiel #15
0
        internal SocketConnectionListener(
            EndPoint endpoint,
            SocketConnectionOptions options,
            ISocketsTrace trace,
            SocketSchedulers schedulers)
        {
            Debug.Assert(endpoint != null);
            Debug.Assert(endpoint is IPEndPoint);
            Debug.Assert(trace != null);

            EndPoint    = endpoint;
            _trace      = trace;
            _schedulers = schedulers;
            _options    = options;
            _memoryPool = options.MemoryPoolFactory();
        }
        internal SocketTransport(
            IEndPointInformation endPointInformation,
            IConnectionHandler handler,
            IApplicationLifetime applicationLifetime,
            ISocketsTrace trace)
        {
            Debug.Assert(endPointInformation != null);
            Debug.Assert(endPointInformation.Type == ListenType.IPEndPoint);
            Debug.Assert(handler != null);
            Debug.Assert(applicationLifetime != null);
            Debug.Assert(trace != null);

            _endPointInformation = endPointInformation;
            _handler             = handler;
            _appLifetime         = applicationLifetime;
            _trace = trace;
        }
        internal SocketTransport(
            IEndPointInformation endPointInformation,
            IConnectionHandler handler,
            ISocketsTrace trace)
        {
            Debug.Assert(endPointInformation != null);
            Debug.Assert(endPointInformation.Type == ListenType.IPEndPoint);
            Debug.Assert(handler != null);
            Debug.Assert(trace != null);

            _endPointInformation = endPointInformation;
            _handler             = handler;
            _trace = trace;

            _listenSocket = null;
            _listenTask   = null;
        }
Beispiel #18
0
        private SocketConnection(Socket socket, PipeOptions sendPipeOptions, PipeOptions receivePipeOptions,
                                 SocketConnectionOptions socketConnectionOptions, string name, ILogger logger)
        {
            if (socket == null)
            {
                throw new ArgumentNullException(nameof(socket));
            }
            if (string.IsNullOrWhiteSpace(name))
            {
                Name = GetType().Name.Trim();
            }
            if (sendPipeOptions == null)
            {
                sendPipeOptions = PipeOptions.Default;
            }
            if (receivePipeOptions == null)
            {
                receivePipeOptions = PipeOptions.Default;
            }

            Socket  = socket;
            _logger = logger ?? NullLoggerFactory.Instance.CreateLogger("NetGear.Core.SocketConnection");
            _trace  = new TraceDebugger(_logger);
            var localEndPoint  = (IPEndPoint)Socket.LocalEndPoint;
            var remoteEndPoint = (IPEndPoint)Socket.RemoteEndPoint;

            LocalAddress  = localEndPoint.Address;
            LocalPort     = localEndPoint.Port;
            RemoteAddress = remoteEndPoint.Address;
            RemotePort    = remoteEndPoint.Port;

            SocketConnectionOptions = socketConnectionOptions;
            _sendOptions            = sendPipeOptions;
            _receiveOptions         = receivePipeOptions;
            _sendToSocket           = new Pipe(_sendOptions);    // read from this pipe and send to socket
            _receiveFromSocket      = new Pipe(_receiveOptions); // recv from socket and push to this pipe

            _output = new WrappedWriter(_sendToSocket.Writer, this);
            _input  = new WrappedReader(_receiveFromSocket.Reader, this);

            _sendOptions.ReaderScheduler.Schedule(s_DoSendAsync, this);
            _receiveOptions.WriterScheduler.Schedule(s_DoReceiveAsync, this);
        }
        internal SocketConnection(Socket socket, PipeFactory pipeFactory, ISocketsTrace trace)
        {
            Debug.Assert(socket != null);
            Debug.Assert(pipeFactory != null);
            Debug.Assert(trace != null);

            _socket     = socket;
            PipeFactory = pipeFactory;
            _trace      = trace;

            var localEndPoint  = (IPEndPoint)_socket.LocalEndPoint;
            var remoteEndPoint = (IPEndPoint)_socket.RemoteEndPoint;

            LocalAddress = localEndPoint.Address;
            LocalPort    = localEndPoint.Port;

            RemoteAddress = remoteEndPoint.Address;
            RemotePort    = remoteEndPoint.Port;
        }
        internal SocketConnection(Socket socket,
                                  MemoryPool <byte> memoryPool,
                                  PipeScheduler scheduler,
                                  ISocketsTrace trace,
                                  long?maxReadBufferSize  = null,
                                  long?maxWriteBufferSize = null)
        {
            Debug.Assert(socket != null);
            Debug.Assert(memoryPool != null);
            Debug.Assert(trace != null);

            this.socket     = socket;
            this.MemoryPool = memoryPool;
            this.trace      = trace;

            this.LocalEndPoint  = this.socket.LocalEndPoint;
            this.RemoteEndPoint = this.socket.RemoteEndPoint;

            this.ConnectionClosed = connectionClosedTokenSource.Token;

            // On *nix platforms, Sockets already dispatches to the ThreadPool.
            // Yes, the IOQueues are still used for the PipeSchedulers. This is intentional.
            // https://github.com/aspnet/KestrelHttpServer/issues/2573
            var awaiterScheduler = IsWindows ? scheduler : PipeScheduler.Inline;

            this.receiver = new SocketReceiver(this.socket, awaiterScheduler);
            this.sender   = new SocketSender(this.socket, awaiterScheduler);

            maxReadBufferSize ??= 0;
            maxWriteBufferSize ??= 0;

            var inputOptions  = new PipeOptions(MemoryPool, PipeScheduler.ThreadPool, scheduler, maxReadBufferSize.Value, maxReadBufferSize.Value / 2, useSynchronizationContext: false);
            var outputOptions = new PipeOptions(MemoryPool, scheduler, PipeScheduler.ThreadPool, maxWriteBufferSize.Value, maxWriteBufferSize.Value / 2, useSynchronizationContext: false);

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

            // Set the transport and connection id
            this.Transport    = pair.Transport;
            this.Input        = pair.Application.Output;
            this.Output       = pair.Application.Input;
            this.ConnectionId = Guid.NewGuid().ToString();
        }
Beispiel #21
0
    public KestrelStackTransport(
        KestrelServerWithStack server,
        IEndPointInformation endPointInformation,
        IConnectionDispatcher dispatcher,
        IApplicationLifetime applicationLifetime,
        int ioQueueCount,
        ISocketsTrace trace)
    {
        Debug.Assert(endPointInformation != null);
        Debug.Assert(endPointInformation.Type == ListenType.IPEndPoint);
        Debug.Assert(dispatcher != null);
        Debug.Assert(applicationLifetime != null);
        Debug.Assert(trace != null);

        EndPointInformation = endPointInformation;
        Dispatcher          = dispatcher;
        AppLifetime         = applicationLifetime;
        Trace = trace;

        this.Server = server;
    }
Beispiel #22
0
        internal SocketConnection(Socket socket,
                                  MemoryPool <byte> memoryPool,
                                  PipeScheduler transportScheduler,
                                  ISocketsTrace trace,
                                  SocketSenderPool socketSenderPool,
                                  PipeOptions inputOptions,
                                  PipeOptions outputOptions,
                                  bool waitForData = true)
        {
            Debug.Assert(socket != null);
            Debug.Assert(memoryPool != null);
            Debug.Assert(trace != null);

            _socket           = socket;
            MemoryPool        = memoryPool;
            _trace            = trace;
            _waitForData      = waitForData;
            _socketSenderPool = socketSenderPool;

            LocalEndPoint  = _socket.LocalEndPoint;
            RemoteEndPoint = _socket.RemoteEndPoint;

            ConnectionClosed = _connectionClosedTokenSource.Token;

            // On *nix platforms, Sockets already dispatches to the ThreadPool.
            // Yes, the IOQueues are still used for the PipeSchedulers. This is intentional.
            // https://github.com/aspnet/KestrelHttpServer/issues/2573
            var awaiterScheduler = OperatingSystem.IsWindows() ? transportScheduler : PipeScheduler.Inline;

            _receiver = new SocketReceiver(awaiterScheduler);

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

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

            Transport = new SocketDuplexPipe(this);

            InitializeFeatures();
        }
        internal SocketConnection(Socket socket, MemoryPool memoryPool, ISocketsTrace trace)
        {
            Debug.Assert(socket != null);
            Debug.Assert(memoryPool != null);
            Debug.Assert(trace != null);

            _socket    = socket;
            MemoryPool = memoryPool;
            _trace     = trace;

            var localEndPoint  = (IPEndPoint)_socket.LocalEndPoint;
            var remoteEndPoint = (IPEndPoint)_socket.RemoteEndPoint;

            LocalAddress = localEndPoint.Address;
            LocalPort    = localEndPoint.Port;

            RemoteAddress = remoteEndPoint.Address;
            RemotePort    = remoteEndPoint.Port;

            _receiver = new SocketReceiver(_socket);
            _sender   = new SocketSender(_socket);
        }
Beispiel #24
0
        internal SocketTransport(
            IEndPointInformation endPointInformation,
            IConnectionDispatcher dispatcher,
            IHostApplicationLifetime applicationLifetime,
            int ioQueueCount,
            ISocketsTrace trace,
            MemoryPool <byte> memoryPool)
        {
            Debug.Assert(endPointInformation != null);
            Debug.Assert(endPointInformation.Type == ListenType.IPEndPoint);
            Debug.Assert(dispatcher != null);
            Debug.Assert(applicationLifetime != null);
            Debug.Assert(trace != null);

            _endPointInformation = endPointInformation;
            _dispatcher          = dispatcher;
            _appLifetime         = applicationLifetime;
            _trace      = trace;
            _memoryPool = memoryPool;

            if (ioQueueCount > 0)
            {
                _numSchedulers = ioQueueCount;
                _schedulers    = new IOQueue[_numSchedulers];

                for (var i = 0; i < _numSchedulers; i++)
                {
                    _schedulers[i] = new IOQueue();
                }
            }
            else
            {
                var directScheduler = new PipeScheduler[] { PipeScheduler.ThreadPool };
                _numSchedulers = directScheduler.Length;
                _schedulers    = directScheduler;
            }
        }