From mboxrd@z Thu Jan 1 00:00:00 1970 Authentication-Results: passt.top; dmarc=none (p=none dis=none) header.from=gibson.dropbear.id.au Authentication-Results: passt.top; dkim=pass (2048-bit key; secure) header.d=gibson.dropbear.id.au header.i=@gibson.dropbear.id.au header.a=rsa-sha256 header.s=202602 header.b=OxKck+TA; dkim-atps=neutral Received: from mail.ozlabs.org (mail.ozlabs.org [IPv6:2404:9400:2221:ea00::3]) by passt.top (Postfix) with ESMTPS id 9CD605A0271 for ; Thu, 21 May 2026 08:37:52 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gibson.dropbear.id.au; s=202602; t=1779345468; bh=MMRLvU0OUB388T6qyG+kqT0CquQWUUqogH0jAEBGC+E=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=OxKck+TALyiI+M6er3+RPInl6azBM2/W0eMK4XyReLGPoSlpHM381dTZIaYG733d6 pRgQZneFPy/l2/B0URa/c/CI/N7JBKScG51wlJ2pzbCi9lwUV9RPMndLIztFxCZFMl aKCTB0eA+X6XeimuTPglpxjSRFie/kdRSNsQ5w6Z2sW4a2aiSrCSmS3jbxqOeuIlHx JKYgikZt8br1TjnvFTt42KWWm+SnsUg3RZMpFe/u0dKvJeHgCgxlaoNskUPZhOqfpt pvjbUV/pVOTQyL4ontp/1/oCLQhaVi+Hr+5uEafoA4SpFl8klAR8BUTveryqrOdgBf 9bL0C2UEIo6fA== Received: by gandalf.ozlabs.org (Postfix, from userid 1007) id 4gLdy44SFDz4wJp; Thu, 21 May 2026 16:37:48 +1000 (AEST) From: David Gibson To: passt-dev@passt.top, Stefano Brivio Subject: [PATCH v2 2/4] tcp_splice: Avoid missing EOF recognition while forwarding Date: Thu, 21 May 2026 16:37:43 +1000 Message-ID: <20260521063745.1211215-3-david@gibson.dropbear.id.au> X-Mailer: git-send-email 2.54.0 In-Reply-To: <20260521063745.1211215-1-david@gibson.dropbear.id.au> References: <20260521063745.1211215-1-david@gibson.dropbear.id.au> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Message-ID-Hash: 5YTQMIXBLIYNO4GQACQ7TKKX6MVEMJNO X-Message-ID-Hash: 5YTQMIXBLIYNO4GQACQ7TKKX6MVEMJNO X-MailFrom: dgibson@gandalf.ozlabs.org X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; emergency; loop; banned-address; member-moderation; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; digests; suspicious-header CC: Paul Holzinger , David Gibson X-Mailman-Version: 3.3.8 Precedence: list List-Id: Development discussion and patches for passt Archived-At: Archived-At: List-Archive: List-Archive: List-Help: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: tcp_splice_sock_handler() has an optimised path for the common case where the amount we splice(2) into the pipe is exactly the same as the amount we splice(2) out again. If the pipe is empty at that point, we stop forwarding until we get another epoll event. However, via a subtle chain of events, this can cause a bug for a half-closed connection. Suppose the connection is already half-closed in the other direction - that is, we've already called shutdown(SHUT_WR) on the socket for which we're getting the event. In this event we're getting the last batch of data in the other direction, and also a FIN. This can result in EPOLLIN, EPOLLRDHUP and EPOLLHUP events simultaneously. We read the last data from the socket and successfully splice it to the other side. Since there is no data in the pipe, we exit the forwarding loop. However, because we did read data, we don't set the eof flag. Because we don't set eof, we don't (yet) propagate the FIN to the other side, or set FIN_SENT_(!fromsidei). Therefore we don't (yet) recognize this as a clean termination and set the CLOSING flag. We would correct this when we get our next event, however before we can do so we process the EPOLLHUP event. Because we haven't recognized this as a clean close we assume it is an abrupt close and send an RST to the other side. To avoid this, don't stop attempting to forward data on this path. Continue for at least one more loop. If we're at EOF, we'll recognize it on the next splice(2). If not it gives us an opportunity to forward more data without returning to the mail epoll loop. Reported-by: Paul Holzinger Link: https://bugs.passt.top/show_bug.cgi?id=202 Signed-off-by: David Gibson --- tcp_splice.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tcp_splice.c b/tcp_splice.c index 915ac114..762a058e 100644 --- a/tcp_splice.c +++ b/tcp_splice.c @@ -612,7 +612,7 @@ retry: } } - break; + continue; } conn->read[fromsidei] += readlen > 0 ? readlen : 0; -- 2.54.0