Пример #1
0
        public Transport(IPEndPoint listenEndPoint, IConnectionHandler connectionHandler, LinuxTransportOptions transportOptions, ILoggerFactory loggerFactory)
        {
            if (connectionHandler == null)
            {
                throw new ArgumentNullException(nameof(connectionHandler));
            }
            if (transportOptions == null)
            {
                throw new ArgumentException(nameof(transportOptions));
            }
            if (loggerFactory == null)
            {
                throw new ArgumentException(nameof(loggerFactory));
            }
            if (listenEndPoint == null)
            {
                throw new ArgumentException(nameof(listenEndPoint));
            }

            _endPoint          = listenEndPoint;
            _connectionHandler = connectionHandler;
            _transportOptions  = transportOptions;
            _loggerFactory     = loggerFactory;
            _logger            = loggerFactory.CreateLogger <Transport>();
        }
Пример #2
0
        public Transport(IEndPointInformation ipEndPointInformation, IConnectionDispatcher connectionDispatcher, LinuxTransportOptions transportOptions, ILoggerFactory loggerFactory)
        {
            if (connectionDispatcher == null)
            {
                throw new ArgumentNullException(nameof(connectionDispatcher));
            }
            if (transportOptions == null)
            {
                throw new ArgumentException(nameof(transportOptions));
            }
            if (loggerFactory == null)
            {
                throw new ArgumentException(nameof(loggerFactory));
            }
            if (ipEndPointInformation == null)
            {
                throw new ArgumentException(nameof(ipEndPointInformation));
            }

            _endPoint             = ipEndPointInformation;
            _connectionDispatcher = connectionDispatcher;
            _transportOptions     = transportOptions;
            _loggerFactory        = loggerFactory;
            _logger  = loggerFactory.CreateLogger <Transport>();
            _threads = Array.Empty <TransportThread>();
        }
Пример #3
0
 public TransportThread(IPEndPoint endPoint, IConnectionHandler connectionHandler, LinuxTransportOptions options, int threadId, int cpuId, ILoggerFactory loggerFactory)
 {
     if (connectionHandler == null)
     {
         throw new ArgumentNullException(nameof(connectionHandler));
     }
     _connectionHandler = connectionHandler;
     _threadId          = threadId;
     _cpuId             = cpuId;
     _endPoint          = endPoint;
     _transportOptions  = options;
     _loggerFactory     = loggerFactory;
 }
Пример #4
0
 public LinuxTransportFactory(IOptions <LinuxTransportOptions> options, ILoggerFactory loggerFactory)
 {
     if (options == null)
     {
         throw new ArgumentNullException(nameof(options));
     }
     if (loggerFactory == null)
     {
         throw new ArgumentNullException(nameof(loggerFactory));
     }
     _options       = options.Value;
     _loggerFactory = loggerFactory;
 }
            public ThreadContext(TransportThread transportThread, LinuxTransportOptions transportOptions, IConnectionHandler connectionHandler, ILogger logger)
            {
                TransportThread   = transportThread;
                ConnectionHandler = connectionHandler;

                Sockets           = new Dictionary <int, TSocket>();
                Logger            = logger;
                AcceptSockets     = new List <TSocket>();
                _schedulerAdding  = new Queue <ScheduledAction>(1024);
                _schedulerRunning = new Queue <ScheduledAction>(1024);
                _epollState       = EPollBlocked;
                SendScheduler     = transportOptions.DeferSend ? this as IScheduler : InlineScheduler.Default;
            }
 public TransportThread(IPEndPoint endPoint, IConnectionDispatcher connectionDispatcher, LinuxTransportOptions options, AcceptThread acceptThread, int threadId, int cpuId, ILoggerFactory loggerFactory)
 {
     if (connectionDispatcher == null)
     {
         throw new ArgumentNullException(nameof(connectionDispatcher));
     }
     ConnectionDispatcher = connectionDispatcher;
     ThreadId             = threadId;
     CpuId            = cpuId;
     EndPoint         = endPoint;
     TransportOptions = options;
     AcceptThread     = acceptThread;
     LoggerFactory    = loggerFactory;
 }
Пример #7
0
            public unsafe ThreadContext(TransportThread transportThread)
            {
                _transportThread      = transportThread;
                _connectionDispatcher = transportThread.ConnectionDispatcher;
                _sockets              = new Dictionary <int, TSocket>();
                _logger               = _transportThread.LoggerFactory.CreateLogger($"{nameof(RedHatX)}.{nameof(TransportThread)}.{_transportThread.ThreadId}");
                _acceptSockets        = new List <TSocket>();
                _transportOptions     = transportThread.TransportOptions;
                _scheduledSendAdding  = new List <ScheduledSend>(1024);
                _scheduledSendRunning = new List <ScheduledSend>(1024);
                _epollState           = EPollBlocked;
                if (_transportOptions.AioReceive | _transportOptions.AioSend)
                {
                    _aioEventsMemory     = AllocMemory(sizeof(AioEvent) * EventBufferLength);
                    _aioCbsMemory        = AllocMemory(sizeof(AioCb) * EventBufferLength);
                    _aioCbsTableMemory   = AllocMemory(sizeof(AioCb *) * EventBufferLength);
                    _ioVectorTableMemory = AllocMemory(sizeof(IOVector) * IoVectorsPerAioSocket * EventBufferLength);
                    for (int i = 0; i < EventBufferLength; i++)
                    {
                        AioCbsTable[i] = &AioCbs[i];
                    }
                    if (_transportOptions.AioSend)
                    {
                        _aioSendBuffers = new ReadOnlySequence <byte> [EventBufferLength];
                    }
                }
                int maxMemoryHandleCount = TSocket.MaxIOVectorReceiveLength;

                if (_transportOptions.AioReceive || _transportOptions.AioSend)
                {
                    maxMemoryHandleCount = Math.Max(maxMemoryHandleCount, EventBufferLength);
                }
                if (_transportOptions.DeferSend)
                {
                    maxMemoryHandleCount = Math.Max(maxMemoryHandleCount, TSocket.MaxIOVectorSendLength);
                }
                MemoryHandles = new MemoryHandle[maxMemoryHandleCount];

                // These members need to be Disposed
                _epoll     = EPoll.Create();
                _epollFd   = _epoll.DangerousGetHandle().ToInt32();
                MemoryPool = CreateMemoryPool();
                _pipeEnds  = PipeEnd.CreatePair(blocking: false);
                if (_aioEventsMemory != IntPtr.Zero)
                {
                    AioInterop.IoSetup(EventBufferLength, out _aioContext).ThrowOnError();
                }
            }
Пример #8
0
        private static void AcceptOn(IPEndPoint endPoint, int cpuId, LinuxTransportOptions transportOptions, ThreadContext threadContext)
        {
            Socket      acceptSocket = null;
            int         fd           = 0;
            int         port         = endPoint.Port;
            SocketFlags flags        = SocketFlags.TypeAccept;

            try
            {
                bool ipv4 = endPoint.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork;
                acceptSocket = Socket.Create(ipv4 ? AddressFamily.InterNetwork : AddressFamily.InterNetworkV6, SocketType.Stream, ProtocolType.Tcp, blocking: false);
                fd           = acceptSocket.DangerousGetHandle().ToInt32();
                if (!ipv4)
                {
                    // Don't do mapped ipv4
                    acceptSocket.SetSocketOption(SocketOptionLevel.IPv6, SocketOptionName.IPv6Only, 1);
                }
                if (transportOptions.ReceiveOnIncomingCpu)
                {
                    if (cpuId != -1)
                    {
                        if (!acceptSocket.TrySetSocketOption(SocketOptionLevel.Socket, SocketOptionName.IncomingCpu, cpuId))
                        {
                            threadContext.Logger.LogWarning($"Cannot enable nameof{SocketOptionName.IncomingCpu} for {endPoint}");
                        }
                    }
                }
                // Linux: allow bind during linger time
                acceptSocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, 1);
                // Linux: allow concurrent binds and let the kernel do load-balancing
                acceptSocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReusePort, 1);
                if (transportOptions.DeferAccept)
                {
                    // Linux: wait up to 1 sec for data to arrive before accepting socket
                    acceptSocket.SetSocketOption(SocketOptionLevel.Tcp, SocketOptionName.DeferAccept, 1);
                    flags |= SocketFlags.DeferAccept;
                }

                acceptSocket.Bind(endPoint);
                if (port == 0)
                {
                    // When testing we want the OS to select a free port
                    port = acceptSocket.GetLocalIPAddress().Port;
                }

                acceptSocket.Listen(ListenBacklog);
            }
            catch
            {
                acceptSocket?.Dispose();
                throw;
            }

            TSocket tsocket = null;
            var     sockets = threadContext.Sockets;

            try
            {
                tsocket = new TSocket(threadContext)
                {
                    Flags  = flags,
                    Fd     = fd,
                    Socket = acceptSocket
                };
                threadContext.AcceptSockets.Add(tsocket);
                lock (sockets)
                {
                    sockets.Add(tsocket.Fd, tsocket);
                }

                EPollInterop.EPollControl(threadContext.EPollFd,
                                          EPollOperation.Add,
                                          fd,
                                          EPollEvents.Readable,
                                          EPollData(fd));
            }
            catch
            {
                acceptSocket.Dispose();
                threadContext.AcceptSockets.Remove(tsocket);
                lock (sockets)
                {
                    sockets.Remove(fd);
                }
                throw;
            }
            endPoint.Port = port;
        }
Пример #9
0
 public Transport(IEndPointInformation IEndPointInformation, IConnectionHandler connectionHandler, LinuxTransportOptions transportOptions, ILoggerFactory loggerFactory) :
     this(CreateEndPointFromIEndPointInformation(IEndPointInformation), connectionHandler, transportOptions, loggerFactory)
 {
 }