From: Qingfang Deng <qingfang.deng@linux.dev>
To: Eric Dumazet <edumazet@kernel.org>,
Neal Cardwell <ncardwell@google.com>,
Kuniyuki Iwashima <kuniyu@google.com>,
"David S. Miller" <davem@davemloft.net>,
Jakub Kicinski <kuba@kernel.org>, Paolo Abeni <pabeni@redhat.com>,
Simon Horman <horms@kernel.org>,
Yuchung Cheng <ycheng@google.com>, Wei Wang <weiwan@google.com>,
netdev@vger.kernel.org, linux-kernel@vger.kernel.org
Cc: Qingfang Deng <qingfang.deng@linux.dev>
Subject: [PATCH net] tcp: initialize send sequence numbers before deferring TFO
Date: Mon, 2 Nov 2026 11:59:43 +0800 [thread overview]
Message-ID: <20261102035943.9700-1-qingfang.deng@linux.dev> (raw)
TCP_FASTOPEN_CONNECT can return from connect() before tcp_connect_init()
when a cached cookie or cookieless Fast Open allows deferring the SYN.
At this point write_seq contains the initial sequence number, while
snd_una and snd_nxt have not been initialized to that sequence number.
Consequently, inet_diag and /proc/net/tcp{,6} report the initial
sequence number as the send queue length despite no SYN or payload being
queued.
Initialize snd_una and snd_nxt to write_seq before marking the
connection as deferred. Both sequence-based queue lengths then remain
zero until the first write starts the connection and runs
tcp_connect_init().
Fixes: 19f6d3f3c842 ("net/tcp-fastopen: Add new API support")
Signed-off-by: Qingfang Deng <qingfang.deng@linux.dev>
---
Reproducer:
#define _GNU_SOURCE
#include <netinet/in.h>
#include <netinet/tcp.h>
#include <stdio.h>
#include <sys/socket.h>
#include <unistd.h>
int main(void)
{
struct sockaddr_in dst = {
.sin_family = AF_INET,
.sin_port = htons(9),
.sin_addr.s_addr = htonl(INADDR_LOOPBACK),
};
struct tcp_info info = {0};
socklen_t len = sizeof(info);
int fd = socket(AF_INET, SOCK_STREAM, 0), one = 1;
if (fd < 0 ||
setsockopt(fd, IPPROTO_TCP, TCP_FASTOPEN_CONNECT, &one, sizeof(one)) < 0 ||
setsockopt(fd, IPPROTO_TCP, TCP_FASTOPEN_NO_COOKIE, &one, sizeof(one)) < 0 ||
connect(fd, (struct sockaddr *)&dst, sizeof(dst)) < 0 ||
getsockopt(fd, IPPROTO_TCP, TCP_INFO, &info, &len) < 0) {
perror("TFO setup");
return 1;
}
if (info.tcpi_state != TCP_SYN_SENT) {
fprintf(stderr, "Expected SYN_SENT, got state %u\n", info.tcpi_state);
return 1;
}
printf("PID %ld: deferred SYN_SENT; no SYN or payload sent\n", (long)getpid());
fflush(stdout);
for (;;)
pause();
}
`ss -ntp state syn-sent` will show a bogus Send-Q number, which is the
initial sequence number interpreted as signed 32-bit:
Recv-Q Send-Q Local Address:Port Peer Address:Port Process
0 -1405690727 127.0.0.1:57290 127.0.0.1:9 users:(("a.out",pid=63363,fd=3))
Diagnosis and implementation were assisted by GPT Codex.
---
net/ipv4/tcp_fastopen.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/net/ipv4/tcp_fastopen.c b/net/ipv4/tcp_fastopen.c
index 6dfe40322fb5..ff81e663ac61 100644
--- a/net/ipv4/tcp_fastopen.c
+++ b/net/ipv4/tcp_fastopen.c
@@ -545,6 +545,8 @@ bool tcp_fastopen_defer_connect(struct sock *sk, int *err)
if (tp->fastopen_connect && !tp->fastopen_req) {
if (tcp_fastopen_cookie_check(sk, &mss, &cookie)) {
+ WRITE_ONCE(tp->snd_una, tp->write_seq);
+ WRITE_ONCE(tp->snd_nxt, tp->write_seq);
inet_set_bit(DEFER_CONNECT, sk);
return true;
}
--
2.43.0
next reply other threads:[~2026-11-02 3:59 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-11-02 3:59 Qingfang Deng [this message]
2026-11-02 6:11 ` [PATCH net] tcp: initialize send sequence numbers before deferring TFO Jiayuan Chen
2026-11-02 7:40 ` Qingfang Deng
2026-11-02 8:00 ` Eric Dumazet
2026-11-02 8:13 ` Qingfang Deng
2026-11-02 8:20 ` Eric Dumazet
2026-11-03 5:31 ` Kuniyuki Iwashima
2026-11-03 14:52 ` Neal Cardwell
2026-11-03 5:06 ` Kuniyuki Iwashima
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=20261102035943.9700-1-qingfang.deng@linux.dev \
--to=qingfang.deng@linux.dev \
--cc=davem@davemloft.net \
--cc=edumazet@kernel.org \
--cc=horms@kernel.org \
--cc=kuba@kernel.org \
--cc=kuniyu@google.com \
--cc=linux-kernel@vger.kernel.org \
--cc=ncardwell@google.com \
--cc=netdev@vger.kernel.org \
--cc=pabeni@redhat.com \
--cc=weiwan@google.com \
--cc=ycheng@google.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.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.