private Exception LogAndWrapReadError(UvException uvError) { if (uvError.StatusCode == LibuvConstants.ECANCELED) { // The operation was canceled by the server not the client. No need for additional logs. return(new ConnectionAbortedException(uvError.Message, uvError)); } else if (LibuvConstants.IsConnectionReset(uvError.StatusCode)) { // Log connection resets at a lower (Debug) level. LibuvTrace.ConnectionReset(Log, ConnectionId); return(new ConnectionResetException(uvError.Message, uvError)); } else { // This is unexpected. LibuvTrace.ConnectionError(Log, ConnectionId, uvError); return(new IOException(uvError.Message, uvError)); } }
/// <summary> /// Handles an incoming connection /// </summary> /// <param name="listenSocket">Socket being used to listen on</param> /// <param name="status">Connection status</param> private void OnConnection(UvStreamHandle listenSocket, int status) { UvStreamHandle acceptSocket = null; try { acceptSocket = CreateAcceptSocket(); listenSocket.Accept(acceptSocket); DispatchConnection(acceptSocket); } catch (UvException ex) when(LibuvConstants.IsConnectionReset(ex.StatusCode)) { LibuvTrace.ConnectionReset(Log, "(null)"); acceptSocket?.Dispose(); } catch (UvException ex) { Log.LogError(0, ex, "Listener.OnConnection"); acceptSocket?.Dispose(); } }
private void ReadStartCallback(UvStreamHandle handle, int status) { if (status < 0) { if (status != LibuvConstants.EOF) { Thread.Loop.Libuv.Check(status, out var ex); Log.LogError(0, ex, "DispatchPipe.ReadStart"); } DispatchPipe.Dispose(); return; } if (_closed || DispatchPipe.PendingCount() == 0) { return; } var acceptSocket = CreateAcceptSocket(); try { DispatchPipe.Accept(acceptSocket); HandleConnection(acceptSocket); } catch (UvException ex) when(LibuvConstants.IsConnectionReset(ex.StatusCode)) { LibuvTrace.ConnectionReset(Log, "(null)"); acceptSocket.Dispose(); } catch (UvException ex) { Log.LogError(0, ex, "DispatchPipe.Accept"); acceptSocket.Dispose(); } }
private void LogWriteInfo(int status, Exception error) { if (error == null) { LibuvTrace.ConnectionWriteCallback(_log, _connectionId, status); } else { // Log connection resets at a lower (Debug) level. if (status == LibuvConstants.ECANCELED) { // Connection was aborted. } else if (LibuvConstants.IsConnectionReset(status)) { LibuvTrace.ConnectionReset(_log, _connectionId); } else { LibuvTrace.ConnectionError(_log, _connectionId, error); } } }
protected internal void HandleConnection(UvStreamHandle socket) { try { IPEndPoint remoteEndPoint = null; IPEndPoint localEndPoint = null; if (socket is UvTcpHandle tcpHandle) { try { remoteEndPoint = tcpHandle.GetPeerIPEndPoint(); localEndPoint = tcpHandle.GetSockIPEndPoint(); } catch (UvException ex) when(LibuvConstants.IsConnectionReset(ex.StatusCode)) { LibuvTrace.ConnectionReset(TransportContext.Log, "(null)"); socket.Dispose(); return; } } var options = TransportContext.Options; #pragma warning disable CS0618 var connection = new LibuvConnection(socket, TransportContext.Log, Thread, remoteEndPoint, localEndPoint, InputOptions, OutputOptions, options.MaxReadBufferSize, options.MaxWriteBufferSize); #pragma warning restore CS0618 connection.Start(); bool accepted = _acceptQueue.Writer.TryWrite(connection); Debug.Assert(accepted, "The connection was not written to the channel!"); } catch (Exception ex) { TransportContext.Log.LogCritical(ex, $"Unexpected exception in {nameof(ListenerContext)}.{nameof(HandleConnection)}."); } }