From 5f58c0ce3a336a87ad0222da03fe8c5aa54cf3d7 Mon Sep 17 00:00:00 2001 From: Jan Klass Date: Tue, 29 Apr 2025 17:19:09 +0200 Subject: [PATCH 1/2] fix: Ignore remote peer closed on write (ConnectionReset) During writing to a connection stream a socket exception (SocketException) may be thrown. The socket error SocketError.ConnectionReset (10054 WSAECONNRESET) indicates that the remote peer closed the connection. This lead to unhandled exceptions being thrown and logged. Given that this is a client initiated abort, there is no issue on the server side. A debug log level log message is appropriate for that, instead of warning or throwing (unhandled) exceptions. --- This is reproducible with mass-connects. In my test scenario I create (sequentially) 20 times (concurrently) 400 TCP connect Tasks. Co-authored-by: Jan Klass --- .../Networking/StreamPipeWriterService.cs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/FubarDev.FtpServer/Networking/StreamPipeWriterService.cs b/src/FubarDev.FtpServer/Networking/StreamPipeWriterService.cs index 1d300fb9..5ecf318b 100644 --- a/src/FubarDev.FtpServer/Networking/StreamPipeWriterService.cs +++ b/src/FubarDev.FtpServer/Networking/StreamPipeWriterService.cs @@ -6,6 +6,7 @@ using System.Buffers; using System.IO; using System.IO.Pipelines; +using System.Net.Sockets; using System.Threading; using System.Threading.Tasks; @@ -72,6 +73,11 @@ protected override async Task ExecuteAsync(CancellationToken cancellationToken) await SendDataToStream(readResult.Buffer, CancellationToken.None) .ConfigureAwait(false); } + catch (SocketException ex) when (ex.SocketErrorCode == SocketError.ConnectionReset) + { + Logger?.LogDebug(ex, "Sending data failed. The remote peer closed the connection."); + return; + } catch (Exception ex) { Logger?.LogWarning(ex, "Sending data failed {ErrorMessage}", ex.Message); From 133ea52977813f7892e5a8b09fe558a5fadbc88f Mon Sep 17 00:00:00 2001 From: Jan Klass Date: Thu, 8 May 2025 20:21:31 +0200 Subject: [PATCH 2/2] fix: Use correct catch ex structure Co-authored-by: Jan Klass --- src/FubarDev.FtpServer/Networking/StreamPipeWriterService.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/FubarDev.FtpServer/Networking/StreamPipeWriterService.cs b/src/FubarDev.FtpServer/Networking/StreamPipeWriterService.cs index 5ecf318b..3a067118 100644 --- a/src/FubarDev.FtpServer/Networking/StreamPipeWriterService.cs +++ b/src/FubarDev.FtpServer/Networking/StreamPipeWriterService.cs @@ -73,7 +73,7 @@ protected override async Task ExecuteAsync(CancellationToken cancellationToken) await SendDataToStream(readResult.Buffer, CancellationToken.None) .ConfigureAwait(false); } - catch (SocketException ex) when (ex.SocketErrorCode == SocketError.ConnectionReset) + catch (IOException ex) when (ex.InnerException is SocketException { SocketErrorCode: SocketError.ConnectionReset }) { Logger?.LogDebug(ex, "Sending data failed. The remote peer closed the connection."); return;