Пример #1
0
        private UvTcpHandle ListenTcp(bool useFileHandle)
        {
            var socket = new UvTcpHandle(Log);

            try
            {
                socket.Init(Thread.Loop, Thread.QueueCloseHandle);
                socket.NoDelay(EndPointInformation.NoDelay);

                if (!useFileHandle)
                {
                    socket.Bind(EndPointInformation.IPEndPoint);

                    // If requested port was "0", replace with assigned dynamic port.
                    EndPointInformation.IPEndPoint = socket.GetSockIPEndPoint();
                }
                else
                {
                    socket.Open((IntPtr)EndPointInformation.FileHandle);
                }
            }
            catch
            {
                socket.Dispose();
                throw;
            }

            return(socket);
        }
        public async Task SocketCanListenAndAccept()
        {
            var loop = new UvLoopHandle(_logger);

            loop.Init(_uv);
            var tcp = new UvTcpHandle(_logger);

            tcp.Init(loop, (a, b) => { });
            var address = ServerAddress.FromUrl($"http://127.0.0.1:0/");

            tcp.Bind(address);
            var port = tcp.GetSockIPEndPoint().Port;

            tcp.Listen(10, (stream, status, error, state) =>
            {
                var tcp2 = new UvTcpHandle(_logger);
                tcp2.Init(loop, (a, b) => { });
                stream.Accept(tcp2);
                tcp2.Dispose();
                stream.Dispose();
            }, null);
            var t = Task.Run(() =>
            {
                var socket = TestConnection.CreateConnectedLoopbackSocket(port);
                socket.Dispose();
            });

            loop.Run();
            loop.Dispose();
            await t;
        }
Пример #3
0
        private UvTcpHandle ListenTcp(bool useFileHandle)
        {
            var socket = new UvTcpHandle(Log);

            try
            {
                socket.Init(Thread.Loop, Thread.QueueCloseHandle);
#pragma warning disable CS0618
                socket.NoDelay(TransportContext.Options.NoDelay);
#pragma warning restore CS0618

                if (!useFileHandle)
                {
                    socket.Bind((IPEndPoint)EndPoint);

                    // If requested port was "0", replace with assigned dynamic port.
                    EndPoint = socket.GetSockIPEndPoint();
                }
                else
                {
                    socket.Open((IntPtr)((FileHandleEndPoint)EndPoint).FileHandle);
                }
            }
            catch
            {
                socket.Dispose();
                throw;
            }

            return(socket);
        }
        /// <summary>
        /// Creates a socket which can be used to accept an incoming connection
        /// </summary>
        protected override UvStreamHandle CreateAcceptSocket()
        {
            var acceptSocket = new UvTcpHandle(Log);

            acceptSocket.Init(Thread.Loop, Thread.QueueCloseHandle);
            return(acceptSocket);
        }
Пример #5
0
        public Task StartAsync(
            string scheme,
            string host,
            int port,
            KestrelThread thread,
            Func <Frame, Task> application)
        {
            Thread      = thread;
            Application = application;

            var tcs = new TaskCompletionSource <int>();

            Thread.Post(_ =>
            {
                try
                {
                    ListenSocket = new UvTcpHandle();
                    ListenSocket.Init(Thread.Loop, Thread.QueueCloseHandle);
                    ListenSocket.Bind(new IPEndPoint(IPAddress.Any, port));
                    ListenSocket.Listen(10, _connectionCallback, this);
                    tcs.SetResult(0);
                }
                catch (Exception ex)
                {
                    tcs.SetException(ex);
                }
            }, null);
            return(tcs.Task);
        }
Пример #6
0
        public void Connect(
            UvTcpHandle socket,
            IPEndPoint endpoint,
            Action<UvConnectRequest, int, Exception, object> callback,
            object state)
        {
            _callback = callback;
            _state = state;

            SockAddr addr;
            var addressText = endpoint.Address.ToString();

            Exception error1;
            _uv.ip4_addr(addressText, endpoint.Port, out addr, out error1);

            if (error1 != null)
            {
                Exception error2;
                _uv.ip6_addr(addressText, endpoint.Port, out addr, out error2);
                if (error2 != null)
                {
                    throw error1;
                }
            }

            Pin();
            Libuv.tcp_connect(this, socket, ref addr, _uv_connect_cb);
        }
Пример #7
0
        public void Dispose()
        {
            // Ensure the event loop is still running.
            // If the event loop isn't running and we try to wait on this Post
            // to complete, then KestrelEngine will never be disposed and
            // the exception that stopped the event loop will never be surfaced.
            if (Thread.FatalError == null)
            {
                var tcs = new TaskCompletionSource <int>();
                Thread.Post(
                    _ =>
                {
                    try
                    {
                        ListenSocket.Dispose();
                        tcs.SetResult(0);
                    }
                    catch (Exception ex)
                    {
                        tcs.SetException(ex);
                    }
                },
                    null);

                // REVIEW: Should we add a timeout here to be safe?
                tcs.Task.Wait();
            }

            ListenSocket = null;
        }
Пример #8
0
 private void Listen()
 {
     _listenSocket = new UvTcpHandle();
     _listenSocket.Init(_thread.Loop, UvThread._queueCloseCallback);
     _listenSocket.NoDelay(true);
     _listenSocket.Bind(_endpoint);
     _listenSocket.Listen(10, _onConnectionCallback, this);
 }
Пример #9
0
        public UvTcpConnection(ChannelFactory channelFactory, UvLoopHandle loop, UvTcpHandle handle)
        {
            _input  = channelFactory.CreateChannel();
            _output = channelFactory.CreateChannel();

            ProcessReads(handle);
            _sendingTask = ProcessWrites(loop, handle);
        }
Пример #10
0
        public UvServerChannelBus()
        {
            _uvLoop = new UvLoopHandle();
            _uvLoop.Init();

            _listenUvTcpHandle = new UvTcpHandle();
            _listenUvTcpHandle.Init(_uvLoop);
        }
        [InlineData("*", "::")]          // "::" is IPAddress.IPv6Any
        public void CorrectIPEndpointsAreCreated(string host, string expectedAddress)
        {
            var endpoint = UvTcpHandle.CreateIPEndpoint(ServerAddress.FromUrl($"http://{host}:5000/"));

            Assert.NotNull(endpoint);
            Assert.Equal(IPAddress.Parse(expectedAddress), endpoint.Address);
            Assert.Equal(5000, endpoint.Port);
        }
Пример #12
0
        public async Task SocketCanRead()
        {
            int bytesRead = 0;
            var loop      = new UvLoopHandle();

            loop.Init(_uv);
            var tcp = new UvTcpHandle();

            tcp.Init(loop);
            tcp.Bind(new IPEndPoint(IPAddress.Loopback, 54321));
            tcp.Listen(10, (_, status, error, state) =>
            {
                Console.WriteLine("Connected");
                var tcp2 = new UvTcpHandle();
                tcp2.Init(loop);
                tcp.Accept(tcp2);
                var data = Marshal.AllocCoTaskMem(500);
                tcp2.ReadStart(
                    (a, b, c) => _uv.buf_init(data, 500),
                    (__, nread, error2, state2) =>
                {
                    bytesRead += nread;
                    if (nread == 0)
                    {
                        tcp2.Dispose();
                    }
                },
                    null);
                tcp.Dispose();
            }, null);
            Console.WriteLine("Task.Run");
            var t = Task.Run(async() =>
            {
                var socket = new Socket(
                    AddressFamily.InterNetwork,
                    SocketType.Stream,
                    ProtocolType.Tcp);
                await Task.Factory.FromAsync(
                    socket.BeginConnect,
                    socket.EndConnect,
                    new IPEndPoint(IPAddress.Loopback, 54321),
                    null,
                    TaskCreationOptions.None);
                await Task.Factory.FromAsync(
                    socket.BeginSend,
                    socket.EndSend,
                    new[] { new ArraySegment <byte>(new byte[] { 1, 2, 3, 4, 5 }) },
                    SocketFlags.None,
                    null,
                    TaskCreationOptions.None);
                socket.Dispose();
            });

            loop.Run();
            loop.Dispose();
            await t;
        }
        public void CorrectIPEndpointsAreCreated(string host, string expectedAddress)
        {
            // "0.0.0.0" is IPAddress.Any
            var endpoint = UvTcpHandle.CreateIPEndpoint(host, 5000);

            Assert.NotNull(endpoint);
            Assert.Equal(IPAddress.Parse(expectedAddress), endpoint.Address);
            Assert.Equal(5000, endpoint.Port);
        }
Пример #14
0
        /// <summary>
        /// Creates the socket used to listen for incoming connections
        /// </summary>
        protected override UvStreamHandle CreateListenSocket(string host, int port)
        {
            var socket = new UvTcpHandle(Log);

            socket.Init(Thread.Loop, Thread.QueueCloseHandle);
            socket.Bind(host, port);
            socket.Listen(Constants.ListenBacklog, ConnectionCallback, this);
            return(socket);
        }
Пример #15
0
        /// <summary>
        /// Creates a socket which can be used to accept an incoming connection
        /// </summary>
        protected override UvStreamHandle CreateAcceptSocket()
        {
            var acceptSocket = new UvTcpHandle();

            acceptSocket.Init(Thread.Loop, Thread.QueueCloseHandle);
            acceptSocket.NoDelay(true);
            acceptSocket.KeepAlive(true);
            return(acceptSocket);
        }
Пример #16
0
        private void DoConnect()
        {
            _connectSocket = new UvTcpHandle();
            _connectSocket.Init(_thread.Loop, null);

            var connectReq = new UvConnectRequest();
            connectReq.Init(_thread.Loop);
            connectReq.Connect(_connectSocket, _ipEndPoint, _connectCallback, this);
        }
Пример #17
0
        public UvTcpConnection(UvTcpListener listener, UvTcpHandle handle)
        {
            _listener = listener;

            _input  = listener.ChannelFactory.CreateChannel();
            _output = listener.ChannelFactory.CreateChannel();

            ProcessReads(handle);
            _sendingTask = ProcessWrites(handle);
        }
Пример #18
0
        private void DoConnect()
        {
            _connectSocket = new UvTcpHandle();
            _connectSocket.Init(_thread.Loop, null);

            var connectReq = new UvConnectRequest();

            connectReq.Init(_thread.Loop);
            connectReq.Connect(_connectSocket, _ipEndPoint, _connectCallback, this);
        }
Пример #19
0
        /// <summary>
        /// Creates the socket used to listen for incoming connections
        /// </summary>
        protected override UvStreamHandle CreateListenSocket()
        {
            var socket = new UvTcpHandle(Log);

            socket.Init(Thread.Loop, Thread.QueueCloseHandle);
            socket.NoDelay(NoDelay);
            socket.Bind(ServerAddress);
            socket.Listen(Constants.ListenBacklog, (stream, status, error, state) => ConnectionCallback(stream, status, error, state), this);
            return(socket);
        }
Пример #20
0
        private void OnConnection(UvStreamHandle listenSocket, int status)
        {
            var acceptSocket = new UvTcpHandle();

            acceptSocket.Init(Thread.Loop, Thread.QueueCloseHandle);
            listenSocket.Accept(acceptSocket);

            var connection = new Connection(this, acceptSocket);

            connection.Start();
        }
Пример #21
0
        public UvTcpConnection(UvThread thread, UvTcpHandle handle)
        {
            _thread = thread;
            _handle = handle;

            _input  = _thread.PipelineFactory.Create();
            _output = _thread.PipelineFactory.Create();

            StartReading();
            _sendingTask = ProcessWrites();
        }
Пример #22
0
        public UvTcpConnection(UvThread thread, UvTcpHandle handle)
        {
            _thread = thread;
            _handle = handle;

            _input  = _thread.ChannelFactory.CreateChannel();
            _output = _thread.ChannelFactory.CreateChannel();

            ProcessReads();
            _sendingTask = ProcessWrites();
        }
Пример #23
0
        public UvTcpConnection(UvThread thread, UvTcpHandle handle)
        {
            _thread = thread;
            _handle = handle;

            _input = _thread.PipelineFactory.Create();
            _output = _thread.PipelineFactory.Create();

            StartReading();
            _sendingTask = ProcessWrites();
        }
Пример #24
0
        private void Listen()
        {
            // TODO: Error handling
            _listenSocket = new UvTcpHandle();
            _listenSocket.Init(_thread.Loop, null);
            _listenSocket.NoDelay(true);
            _listenSocket.Bind(_endpoint);
            _listenSocket.Listen(10, _onConnectionCallback, this);

            // Don't complete the task on the UV thread
            Task.Run(() => _startedTcs.TrySetResult(null));
        }
Пример #25
0
        private void Listen()
        {
            // TODO: Error handling
            _listenSocket = new UvTcpHandle();
            _listenSocket.Init(_thread.Loop, null);
            _listenSocket.NoDelay(true);
            _listenSocket.Bind(_endpoint);
            _listenSocket.Listen(10, _onConnectionCallback, this);

            // Don't complete the task on the UV thread
            Task.Run(() => _startedTcs.TrySetResult(null));
        }
        public async Task SocketCanRead()
        {
            var loop = new UvLoopHandle(_logger);

            loop.Init(_uv);
            var tcp = new UvTcpHandle(_logger);

            tcp.Init(loop, (a, b) => { });
            var address = ServerAddress.FromUrl($"http://127.0.0.1:0/");

            tcp.Bind(address);
            var port = tcp.GetSockIPEndPoint().Port;

            tcp.Listen(10, (_, status, error, state) =>
            {
                var tcp2 = new UvTcpHandle(_logger);
                tcp2.Init(loop, (a, b) => { });
                tcp.Accept(tcp2);
                var data = Marshal.AllocCoTaskMem(500);
                tcp2.ReadStart(
                    (a, b, c) => _uv.buf_init(data, 500),
                    (__, nread, state2) =>
                {
                    if (nread <= 0)
                    {
                        tcp2.Dispose();
                    }
                },
                    null);
                tcp.Dispose();
            }, null);
            var t = Task.Run(async() =>
            {
                var socket = TestConnection.CreateConnectedLoopbackSocket(port);
#if NET451
                await Task.Factory.FromAsync(
                    socket.BeginSend,
                    socket.EndSend,
                    new[] { new ArraySegment <byte>(new byte[] { 1, 2, 3, 4, 5 }) },
                    SocketFlags.None,
                    null,
                    TaskCreationOptions.None);
#else
                await socket.SendAsync(new[] { new ArraySegment <byte>(new byte[] { 1, 2, 3, 4, 5 }) },
                                       SocketFlags.None);
#endif
                socket.Dispose();
            });

            loop.Run();
            loop.Dispose();
            await t;
        }
        public void SocketCanBeInitAndClose()
        {
            var loop = new UvLoopHandle(_logger);

            loop.Init(_uv);
            var tcp = new UvTcpHandle(_logger);

            tcp.Init(loop);
            tcp.Bind("localhost", 0);
            tcp.Dispose();
            loop.Run();
            loop.Dispose();
        }
Пример #28
0
        public async Task SocketCanBeInitAndClose()
        {
            var loop = new UvLoopHandle();

            loop.Init(_uv);
            var tcp = new UvTcpHandle();

            tcp.Init(loop);
            tcp.Bind(new IPEndPoint(IPAddress.Loopback, 0));
            tcp.Dispose();
            loop.Run();
            loop.Dispose();
        }
Пример #29
0
        /// <summary>
        /// Creates the socket used to listen for incoming connections
        /// </summary>
        protected override UvStreamHandle CreateListenSocket()
        {
            var socket = new UvTcpHandle(Log);

            socket.Init(Thread.Loop, Thread.QueueCloseHandle);
            socket.NoDelay(ServerOptions.NoDelay);
            socket.Bind(ServerAddress);

            // If requested port was "0", replace with assigned dynamic port.
            ServerAddress.Port = socket.GetSockIPEndPoint().Port;

            socket.Listen(Constants.ListenBacklog, (stream, status, error, state) => ConnectionCallback(stream, status, error, state), this);
            return(socket);
        }
Пример #30
0
        public void ReadStopIsIdempotent()
        {
            var libuvTrace = new TestApplicationErrorLogger();

            using (var uvLoopHandle = new UvLoopHandle(libuvTrace))
            using (var uvTcpHandle = new UvTcpHandle(libuvTrace))
            {
                uvLoopHandle.Init(new MockLibuv());
                uvTcpHandle.Init(uvLoopHandle, null);

                UvStreamHandle uvStreamHandle = uvTcpHandle;
                uvStreamHandle.ReadStop();
                uvStreamHandle.ReadStop();
            }
        }
Пример #31
0
        public void SocketCanBeInitAndClose()
        {
            var loop = new UvLoopHandle(_logger);

            loop.Init(_uv);
            var tcp = new UvTcpHandle(_logger);

            tcp.Init(loop, (a, b) => { });
            var endPoint = new IPEndPoint(IPAddress.Loopback, 0);

            tcp.Bind(endPoint);
            tcp.Dispose();
            loop.Run();
            loop.Dispose();
        }
        public void SocketCanBeInitAndClose()
        {
            var loop = new UvLoopHandle(_logger);

            loop.Init(_uv);
            var tcp = new UvTcpHandle(_logger);

            tcp.Init(loop, (a, b) => { });
            var address = ServerAddress.FromUrl("http://127.0.0.1:0/");

            tcp.Bind(address);
            tcp.Dispose();
            loop.Run();
            loop.Dispose();
        }
Пример #33
0
        private async Task ProcessWrites(UvLoopHandle loop, UvTcpHandle handle)
        {
            var writeReq = new UvWriteReq();

            writeReq.Init(loop);

            try
            {
                while (true)
                {
                    await _output;

                    var buffer = _output.BeginRead();

                    if (buffer.IsEmpty && _output.Completion.IsCompleted)
                    {
                        break;
                    }

                    // Up the reference count of the buffer so that we own the disposal of it
                    var cloned = buffer.Clone();
                    _outgoing.Enqueue(cloned);
                    writeReq.Write(handle, ref cloned, _writeCallback, this);

                    _output.EndRead(buffer);
                }
            }
            catch (Exception ex)
            {
                _output.CompleteReading(ex);
            }
            finally
            {
                _output.CompleteReading();

                // There's pending writes happening
                if (_outgoing.Count > 0)
                {
                    _connectionCompleted = new TaskCompletionSource <object>();

                    await _connectionCompleted.Task;
                }

                writeReq.Dispose();

                handle.Dispose();
            }
        }
Пример #34
0
        public UvTcpConnection(UvThread thread, UvTcpHandle handle)
        {
            _thread = thread;
            _handle = handle;

            _input = new Pipe(new PipeOptions(thread.Pool,
                                              // resume from back pressure on the uv thread
                                              writerScheduler: thread));

            _output = new Pipe(new PipeOptions(thread.Pool,
                                               // user code will dispatch back to the uv thread for writes,
                                               readerScheduler: thread));

            StartReading();
            _sendingTask = ProcessWrites();
        }
Пример #35
0
        private static void OnConnectionCallback(UvStreamHandle listenSocket, int status, Exception error, object state)
        {
            var listener = (UvTcpListener)state;

            var acceptSocket = new UvTcpHandle();

            try
            {
                acceptSocket.Init(listener._thread.Loop, null);
                acceptSocket.NoDelay(true);
                listenSocket.Accept(acceptSocket);
                var connection = new UvTcpConnection(listener._thread, acceptSocket);
                ExecuteCallback(listener, connection);
            }
            catch (UvException)
            {
                acceptSocket.Dispose();
            }
        }
Пример #36
0
 public void tcp_init(UvLoopHandle loop, UvTcpHandle handle)
 {
     loop.Validate();
     handle.Validate();
     ThrowIfErrored(_uv_tcp_init(loop, handle));
 }
Пример #37
0
 public void tcp_connect(UvConnectRequest req, UvTcpHandle handle, ref SockAddr addr, uv_connect_cb cb)
 {
     req.Validate();
     handle.Validate();
     _uv_tcp_connect(req, handle, ref addr, cb);
 }
Пример #38
0
        private unsafe void tcp_bind_windows_extras(UvTcpHandle handle)
        {
            const int SIO_LOOPBACK_FAST_PATH = -1744830448; // IOC_IN | IOC_WS2 | 16;
            const int WSAEOPNOTSUPP = 10000 + 45; // (WSABASEERR+45)
            const int SOCKET_ERROR = -1;

            var socket = IntPtr.Zero;
            ThrowIfErrored(_uv_fileno(handle, ref socket));

            // Enable loopback fast-path for lower latency for localhost comms, like HttpPlatformHandler fronting
            // http://blogs.technet.com/b/wincat/archive/2012/12/05/fast-tcp-loopback-performance-and-low-latency-with-windows-server-2012-tcp-loopback-fast-path.aspx
            // https://github.com/libuv/libuv/issues/489
            var optionValue = 1;
            uint dwBytes = 0u;

            var result = NativeMethods.WSAIoctl(socket, SIO_LOOPBACK_FAST_PATH, &optionValue, sizeof(int), null, 0, out dwBytes, IntPtr.Zero, IntPtr.Zero);
            if (result == SOCKET_ERROR)
            {
                var errorId = NativeMethods.WSAGetLastError();
                if (errorId == WSAEOPNOTSUPP)
                {
                    // This system is not >= Windows Server 2012, and the call is not supported.
                }
                else
                {
                    ThrowIfErrored(errorId);
                }
            }
        }
Пример #39
0
 public void tcp_open(UvTcpHandle handle, IntPtr hSocket)
 {
     handle.Validate();
     ThrowIfErrored(_uv_tcp_open(handle, hSocket));
 }
Пример #40
0
 public void tcp_nodelay(UvTcpHandle handle, bool enable)
 {
     handle.Validate();
     ThrowIfErrored(_uv_tcp_nodelay(handle, enable ? 1 : 0));
 }
Пример #41
0
 public void tcp_getpeername(UvTcpHandle handle, out SockAddr addr, ref int namelen)
 {
     handle.Validate();
     ThrowIfErrored(_uv_tcp_getpeername(handle, out addr, ref namelen));
 }
Пример #42
0
 public static extern int uv_tcp_bind(UvTcpHandle handle, ref SockAddr addr, int flags);
Пример #43
0
 public static extern int uv_tcp_init(UvLoopHandle loop, UvTcpHandle handle);
Пример #44
0
 public static extern int uv_tcp_open(UvTcpHandle handle, IntPtr hSocket);
Пример #45
0
 public static extern int uv_tcp_nodelay(UvTcpHandle handle, int enable);
Пример #46
0
 public static extern void uv_tcp_connect(UvConnectRequest req, UvTcpHandle handle, ref SockAddr addr, uv_connect_cb cb);
Пример #47
0
 public static extern int uv_tcp_getpeername(UvTcpHandle handle, out SockAddr name, ref int namelen);
Пример #48
0
 public void tcp_bind(UvTcpHandle handle, ref SockAddr addr, int flags)
 {
     handle.Validate();
     ThrowIfErrored(_uv_tcp_bind(handle, ref addr, flags));
     if (PlatformApis.IsWindows)
     {
         tcp_bind_windows_extras(handle);
     }
 }