aboutgitcodebugslistschat
diff options
context:
space:
mode:
authorDavid Gibson <david@gibson.dropbear.id.au>2026-01-30 15:41:02 +1100
committerStefano Brivio <sbrivio@redhat.com>2026-01-31 03:56:50 +0100
commite992b14b405ec4d0f4ea40b447029e23cbc2e30d (patch)
tree224557605c175eed73aadf29bb0d58c4d44be19f
parente3f70c05bad90368a1a89bf31a9015125232b9ae (diff)
downloadpasst-e992b14b405ec4d0f4ea40b447029e23cbc2e30d.tar
passt-e992b14b405ec4d0f4ea40b447029e23cbc2e30d.tar.gz
passt-e992b14b405ec4d0f4ea40b447029e23cbc2e30d.tar.bz2
passt-e992b14b405ec4d0f4ea40b447029e23cbc2e30d.tar.lz
passt-e992b14b405ec4d0f4ea40b447029e23cbc2e30d.tar.xz
passt-e992b14b405ec4d0f4ea40b447029e23cbc2e30d.tar.zst
passt-e992b14b405ec4d0f4ea40b447029e23cbc2e30d.zip
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 <david@gibson.dropbear.id.au> Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
-rw-r--r--tcp.c4
-rw-r--r--tcp_buf.c1
-rw-r--r--tcp_vu.c1
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;