git: 5050df3f4aa4 - main - tcp: fix counter leak for SYN_RCVD state when syncache_socket() fails
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Wed, 14 Dec 2022 03:32:02 UTC
The branch main has been updated by glebius:
URL: https://cgit.FreeBSD.org/src/commit/?id=5050df3f4aa4867ef8ab49e3116ade64442a5f21
commit 5050df3f4aa4867ef8ab49e3116ade64442a5f21
Author: Gleb Smirnoff <glebius@FreeBSD.org>
AuthorDate: 2022-12-14 03:31:05 +0000
Commit: Gleb Smirnoff <glebius@FreeBSD.org>
CommitDate: 2022-12-14 03:31:05 +0000
tcp: fix counter leak for SYN_RCVD state when syncache_socket() fails
The SYN_RCVD state count is tricky here due to default code path and TFO
being so different. In the default case the count is incremented when a
syncache entry is added to the the database in syncache_insert(). Later
when connection transitions from syncache entry to a socket in
syncache_expand(), this counter is inherited by the tcpcb. If socket or
tcpcb allocation failed in syncache_socket() failed the syncache_expand()
is responsible for decrement. In the TFO case the syncache entry is not
inserted into database and count of SYN_RCVD is first incremented in the
syncache_tfo_expand() after successful socket allocation. Thus, inside
syncache_socket() we can't tell whether we need to decrement in a case of
a failure or not. The caller is responsible for this book keeping.
Fixes: 07285bb4c22c026a50f69149d5dae03169b15fe4
Differential revision: https://reviews.freebsd.org/D37610
---
sys/netinet/tcp_syncache.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/sys/netinet/tcp_syncache.c b/sys/netinet/tcp_syncache.c
index 00d0ac2fa9d5..1a4cde642d4a 100644
--- a/sys/netinet/tcp_syncache.c
+++ b/sys/netinet/tcp_syncache.c
@@ -1313,9 +1313,10 @@ syncache_expand(struct in_conninfo *inc, struct tcpopt *to, struct tcphdr *th,
*lsop = syncache_socket(sc, *lsop, m);
- if (*lsop == NULL)
+ if (__predict_false(*lsop == NULL)) {
TCPSTAT_INC(tcps_sc_aborted);
- else
+ TCPSTATES_DEC(TCPS_SYN_RECEIVED);
+ } else
TCPSTAT_INC(tcps_sc_completed);
/* how do we find the inp for the new socket? */