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; }
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); }
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); }
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); }
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; }
private void Listen() { _listenSocket = new UvTcpHandle(); _listenSocket.Init(_thread.Loop, UvThread._queueCloseCallback); _listenSocket.NoDelay(true); _listenSocket.Bind(_endpoint); _listenSocket.Listen(10, _onConnectionCallback, this); }
public UvTcpConnection(ChannelFactory channelFactory, UvLoopHandle loop, UvTcpHandle handle) { _input = channelFactory.CreateChannel(); _output = channelFactory.CreateChannel(); ProcessReads(handle); _sendingTask = ProcessWrites(loop, handle); }
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); }
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); }
/// <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); }
/// <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); }
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); }
public UvTcpConnection(UvTcpListener listener, UvTcpHandle handle) { _listener = listener; _input = listener.ChannelFactory.CreateChannel(); _output = listener.ChannelFactory.CreateChannel(); ProcessReads(handle); _sendingTask = ProcessWrites(handle); }
/// <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); }
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(); }
public UvTcpConnection(UvThread thread, UvTcpHandle handle) { _thread = thread; _handle = handle; _input = _thread.PipelineFactory.Create(); _output = _thread.PipelineFactory.Create(); StartReading(); _sendingTask = ProcessWrites(); }
public UvTcpConnection(UvThread thread, UvTcpHandle handle) { _thread = thread; _handle = handle; _input = _thread.ChannelFactory.CreateChannel(); _output = _thread.ChannelFactory.CreateChannel(); ProcessReads(); _sendingTask = ProcessWrites(); }
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(); }
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(); }
/// <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); }
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(); } }
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(); }
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(); } }
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(); }
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(); } }
public void tcp_init(UvLoopHandle loop, UvTcpHandle handle) { loop.Validate(); handle.Validate(); ThrowIfErrored(_uv_tcp_init(loop, handle)); }
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); }
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); } } }
public void tcp_open(UvTcpHandle handle, IntPtr hSocket) { handle.Validate(); ThrowIfErrored(_uv_tcp_open(handle, hSocket)); }
public void tcp_nodelay(UvTcpHandle handle, bool enable) { handle.Validate(); ThrowIfErrored(_uv_tcp_nodelay(handle, enable ? 1 : 0)); }
public void tcp_getpeername(UvTcpHandle handle, out SockAddr addr, ref int namelen) { handle.Validate(); ThrowIfErrored(_uv_tcp_getpeername(handle, out addr, ref namelen)); }
public static extern int uv_tcp_bind(UvTcpHandle handle, ref SockAddr addr, int flags);
public static extern int uv_tcp_init(UvLoopHandle loop, UvTcpHandle handle);
public static extern int uv_tcp_open(UvTcpHandle handle, IntPtr hSocket);
public static extern int uv_tcp_nodelay(UvTcpHandle handle, int enable);
public static extern void uv_tcp_connect(UvConnectRequest req, UvTcpHandle handle, ref SockAddr addr, uv_connect_cb cb);
public static extern int uv_tcp_getpeername(UvTcpHandle handle, out SockAddr name, ref int namelen);
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); } }