From e992b14b405ec4d0f4ea40b447029e23cbc2e30d Mon Sep 17 00:00:00 2001 From: David Gibson Date: Fri, 30 Jan 2026 15:41:02 +1100 Subject: tcp: Retransmit FINs like data segments RFC 9293 doesn't distinguish between regular data segments and FIN segments for the purposes of retransmissions. Our existing retransmission logic will also work for FIN segments, except for one detail: we don't currently set the ACK_FROM_TAP_DUE flag when we send a FIN. Add the flag, so that we'll properly retransmit FIN segments like data segments. Remove the section from the theory of operation comment that describes a different way of handling FIN timeouts which (a) isn't correct behaviour and (b) doesn't appear to be implemented. I've tested this by adding logic to suppress sending the FIN if retries < some non-zero value. We correctly resend the FIN and close normally after the expected timeouts. Link: https://bugs.passt.top/show_bug.cgi?id=195 Signed-off-by: David Gibson Signed-off-by: Stefano Brivio --- tcp.c | 4 ---- tcp_buf.c | 1 + tcp_vu.c | 1 + 3 files changed, 2 insertions(+), 4 deletions(-) diff --git a/tcp.c b/tcp.c index 17e5b00..dbfde2e 100644 --- a/tcp.c +++ b/tcp.c @@ -190,10 +190,6 @@ * - RTO_INIT_AFTER_SYN_RETRIES: if SYN retries happened during handshake and * RTO is less than this, re-initialise RTO to this for data retransmissions * - * - FIN_TIMEOUT: if a FIN segment was sent to tap/guest (flag ACK_FROM_TAP_DUE - * with TAP_FIN_SENT event), and no ACK is received within this time, reset - * the connection - * * - FIN_TIMEOUT: if a FIN segment was acknowledged by tap/guest and a FIN * segment (write shutdown) was sent via socket (events SOCK_FIN_SENT and * TAP_FIN_ACKED), but no socket activity is detected from the socket within diff --git a/tcp_buf.c b/tcp_buf.c index 5d419d3..d292541 100644 --- a/tcp_buf.c +++ b/tcp_buf.c @@ -407,6 +407,7 @@ int tcp_buf_data_from_sock(const struct ctx *c, struct tcp_tap_conn *conn) } conn_event(c, conn, TAP_FIN_SENT); + conn_flag(c, conn, ACK_FROM_TAP_DUE); } return 0; diff --git a/tcp_vu.c b/tcp_vu.c index db9db78..b9e9b55 100644 --- a/tcp_vu.c +++ b/tcp_vu.c @@ -425,6 +425,7 @@ int tcp_vu_data_from_sock(const struct ctx *c, struct tcp_tap_conn *conn) } conn_event(c, conn, TAP_FIN_SENT); + conn_flag(c, conn, ACK_FROM_TAP_DUE); } return 0; -- cgit v1.2.3