From 172138c0b005fe92e8f0220b38912685b63a5882 Mon Sep 17 00:00:00 2001 From: Pietro De Domenico Date: Thu, 12 Nov 2026 16:56:44 +0100 Subject: [PATCH 1/2] tcp: Don't add peers to low RTT table before RTT is measured The kernel initialises the minimum RTT of a socket to ~0U (see tcp_init_sock() and tcp_create_openreq_child()), and tcpi_min_rtt keeps that value until the first RTT sample. For a passively opened socket, the handshake gives no sample if the SYN-ACK was retransmitted (Karn's algorithm, see tcp_synack_rtt_meas()), and the only fallback is the timestamp echo, which isn't there if the peer didn't negotiate TCP timestamps. Windows clients don't, by default. tcp_rtt_dst_check() casts tcpi_min_rtt to int, so ~0U becomes -1, the peer passes the threshold check, and it's added to the low RTT table, which it never leaves: from then on, every connection with that peer advertises an unclamped window to the guest and stalls on retransmissions. Skip the check while the minimum RTT hasn't been measured yet. Reproduced on Linux 6.18.57 by dropping SYN-ACKs at a client with net.ipv4.tcp_timestamps set to 0, for two seconds: tcpi_min_rtt of the accepted socket is 0xffffffff, with tcpi_total_retrans 3, and pasta would have added the client to the table. Link: https://archives.passt.top/passt-dev/CAJPNJUuUYSkW776P0hKmweHnKOqXtsXqwm4HXP-+jorXrSfFFg@mail.gmail.com/ Suggested-by: Stefano Brivio Co-Authored-By: Claude Opus 5.5 Signed-off-by: Pietro De Domenico --- tcp.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tcp.c b/tcp.c index 95f4f3e..d88ebd4 100644 --- a/tcp.c +++ b/tcp.c @@ -758,7 +758,8 @@ static void tcp_rtt_dst_check(const struct tcp_tap_conn *conn, int i, hole = -1; if (!min_rtt_cap || - (int)tinfo->tcpi_min_rtt > LOW_RTT_THRESHOLD) + (int)tinfo->tcpi_min_rtt > LOW_RTT_THRESHOLD || + tinfo->tcpi_min_rtt == ~0U /* not measured yet */) return; for (i = 0; i < LOW_RTT_TABLE_SIZE; i++) { -- 2.56.0