On 2026-05-13 03:18, David Gibson wrote:
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 eachs/to to/to> 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
Reviewed-by: Jon Maloy
On 2026-05-13 03:18, David Gibson wrote:
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
s/to to/to/
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
Reviewed-by: Jon Maloy
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); }