From: David Gibson <david@gibson.dropbear.id.au>
To: passt-dev@passt.top, Stefano Brivio <sbrivio@redhat.com>
Cc: David Gibson <david@gibson.dropbear.id.au>
Subject: [PATCH 1/2] tcp, tcp_splice: Make helper for setting SO_LINGER socket option
Date: Wed, 13 May 2026 17:18:20 +1000 [thread overview]
Message-ID: <20260513071821.3137329-2-david@gibson.dropbear.id.au> (raw)
In-Reply-To: <20260513071821.3137329-1-david@gibson.dropbear.id.au>
Both spliced and non-spliced TCP in some cases set the SO_LINGER socket
option in order to to force a TCP RST on a socket side connection. In each
case we open code the setsockopt() logic. We're shortly going to add
another place that needs this, so move the setsockopt() and error handling
logic into a shared helper.
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
---
tcp.c | 33 ++++++++++++++++++++-------------
tcp_conn.h | 3 +++
tcp_splice.c | 20 +++-----------------
3 files changed, 26 insertions(+), 30 deletions(-)
diff --git a/tcp.c b/tcp.c
index d6a9ba28..1078bdc3 100644
--- a/tcp.c
+++ b/tcp.c
@@ -1395,29 +1395,36 @@ static int tcp_send_flag(const struct ctx *c, struct tcp_tap_conn *conn,
}
/**
- * tcp_sock_rst() - Close TCP connection forcing RST on socket side
- * @c: Execution context
- * @conn: Connection pointer
+ * tcp_linger0_() - Set SO_LINGER with 0 timeout on socket
+ * @f: Flow header (only for debug logging)
+ * @s: Socket to modify
*/
-static void tcp_sock_rst(const struct ctx *c, struct tcp_tap_conn *conn)
+void tcp_linger0_(const struct flow_common *f, int s)
{
const struct linger linger0 = {
.l_onoff = 1,
.l_linger = 0,
};
- /* Force RST on socket to inform the peer
- *
- * We do this by setting SO_LINGER with 0 timeout, which means that
- * close() will send an RST (unless the connection is already closed in
- * both directions).
+ /* Setting SO_LINGER with 0 timeout, means that close() will send an RST
+ * (unless the connection is already closed in both directions).
*/
- if (setsockopt(conn->sock, SOL_SOCKET,
- SO_LINGER, &linger0, sizeof(linger0)) < 0) {
- flow_dbg_perror(conn,
- "SO_LINGER failed, may not send RST to peer");
+ if (setsockopt(s, SOL_SOCKET, SO_LINGER,
+ &linger0, sizeof(linger0)) < 0) {
+ flow_log_perror_(f, LOG_DEBUG,
+ "SO_LINGER failed, may not send RST to peer");
}
+}
+/**
+ * tcp_sock_rst() - Close TCP connection forcing RST on socket side
+ * @c: Execution context
+ * @conn: Connection pointer
+ */
+static void tcp_sock_rst(const struct ctx *c, struct tcp_tap_conn *conn)
+{
+ /* Force RST on socket to inform the peer */
+ tcp_linger0(conn, conn->sock);
conn_event(c, conn, CLOSED);
}
diff --git a/tcp_conn.h b/tcp_conn.h
index 9f5bee03..5f7af240 100644
--- a/tcp_conn.h
+++ b/tcp_conn.h
@@ -241,6 +241,9 @@ struct tcp_splice_conn {
extern int init_sock_pool4 [TCP_SOCK_POOL_SIZE];
extern int init_sock_pool6 [TCP_SOCK_POOL_SIZE];
+void tcp_linger0_(const struct flow_common *f, int s);
+#define tcp_linger0(flow_, s_) tcp_linger0_(&(flow_)->f, (s_))
+
bool tcp_flow_defer(const struct tcp_tap_conn *conn);
int tcp_flow_repair_on(struct ctx *c, const struct tcp_tap_conn *conn);
diff --git a/tcp_splice.c b/tcp_splice.c
index 42ee8abc..4c18f0c4 100644
--- a/tcp_splice.c
+++ b/tcp_splice.c
@@ -240,28 +240,14 @@ static void conn_event_do(struct tcp_splice_conn *conn, unsigned long event)
*/
static void tcp_splice_rst(struct tcp_splice_conn *conn)
{
- const struct linger linger0 = {
- .l_onoff = 1,
- .l_linger = 0,
- };
unsigned sidei;
if (conn->flags & CLOSING)
return; /* Nothing to do */
- /* Force RST on sockets to inform the peer
- *
- * We do this by setting SO_LINGER with 0 timeout, which means that
- * close() will send an RST (unless the connection is already closed in
- * both directions).
- */
- flow_foreach_sidei(sidei) {
- if (setsockopt(conn->s[sidei], SOL_SOCKET,
- SO_LINGER, &linger0, sizeof(linger0)) < 0) {
- flow_dbg_perror(conn,
-"SO_LINGER failed, may not send RST to peer");
- }
- }
+ /* Force RST on sockets to inform the peer */
+ flow_foreach_sidei(sidei)
+ tcp_linger0(conn, conn->s[sidei]);
conn_flag(conn, CLOSING);
}
--
2.54.0
next prev parent reply other threads:[~2026-05-13 7:18 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-05-13 7:18 [PATCH 0/2] Fix a Coverity reported socket leak David Gibson
2026-05-13 7:18 ` David Gibson [this message]
2026-05-13 7:18 ` [PATCH 2/2] tcp: Don't leak sockets on error paths David Gibson
2026-05-13 7:23 ` [PATCH 0/2] Fix a Coverity reported socket leak Stefano Brivio
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260513071821.3137329-2-david@gibson.dropbear.id.au \
--to=david@gibson.dropbear.id.au \
--cc=passt-dev@passt.top \
--cc=sbrivio@redhat.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
Code repositories for project(s) associated with this public inbox
https://passt.top/passt
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for IMAP folder(s).