git: 239464e99321 - main - tcp: drop SYN ACK segment for listening sockets

From: Michael Tuexen <tuexen_at_FreeBSD.org>
Date: Mon, 03 Nov 2025 14:53:40 UTC
The branch main has been updated by tuexen:

URL: https://cgit.FreeBSD.org/src/commit/?id=239464e99321ede07664782426ec4e54cd8a618d

commit 239464e99321ede07664782426ec4e54cd8a618d
Author:     Michael Tuexen <tuexen@FreeBSD.org>
AuthorDate: 2025-11-03 10:50:49 +0000
Commit:     Michael Tuexen <tuexen@FreeBSD.org>
CommitDate: 2025-11-03 10:50:49 +0000

    tcp: drop SYN ACK segment for listening sockets
    
    When a SYN ACK is received for a listening socket, just drop it
    instead of killing the SYN-cache entry and send a RST.
    This closes the possibility to kill a TCP connection during its
    handling in the SYN-cache.
    
    Reviewed by:            Nick Banks, Peter Lei
    MFC after:              3 days
    Sponsored by:           Netflix, Inc.
    Differential Revision:  https://reviews.freebsd.org/D53540
---
 sys/netinet/tcp_input.c    |  5 ++---
 sys/netinet/tcp_syncache.c | 17 -----------------
 sys/netinet/tcp_syncache.h |  1 -
 3 files changed, 2 insertions(+), 21 deletions(-)

diff --git a/sys/netinet/tcp_input.c b/sys/netinet/tcp_input.c
index 2146b0cac48f..9c58c2815d13 100644
--- a/sys/netinet/tcp_input.c
+++ b/sys/netinet/tcp_input.c
@@ -1192,11 +1192,10 @@ tfo_socket_result:
 		if (thflags & TH_ACK) {
 			if ((s = tcp_log_addrs(&inc, th, NULL, NULL)))
 				log(LOG_DEBUG, "%s; %s: Listen socket: "
-				    "SYN|ACK invalid, segment rejected\n",
+				    "SYN|ACK invalid, segment ignored\n",
 				    s, __func__);
-			syncache_badack(&inc, port);	/* XXX: Not needed! */
 			TCPSTAT_INC(tcps_badsyn);
-			goto dropwithreset;
+			goto dropunlock;
 		}
 		/*
 		 * If the drop_synfin option is enabled, drop all
diff --git a/sys/netinet/tcp_syncache.c b/sys/netinet/tcp_syncache.c
index 3a7755e9f09e..fa7035771714 100644
--- a/sys/netinet/tcp_syncache.c
+++ b/sys/netinet/tcp_syncache.c
@@ -712,23 +712,6 @@ done:
 	SCH_UNLOCK(sch);
 }
 
-void
-syncache_badack(struct in_conninfo *inc, uint16_t port)
-{
-	struct syncache *sc;
-	struct syncache_head *sch;
-
-	if (syncache_cookiesonly())
-		return;
-	sc = syncache_lookup(inc, &sch);	/* returns locked sch */
-	SCH_LOCK_ASSERT(sch);
-	if ((sc != NULL) && (sc->sc_port == port)) {
-		syncache_drop(sc, sch);
-		TCPSTAT_INC(tcps_sc_badack);
-	}
-	SCH_UNLOCK(sch);
-}
-
 void
 syncache_unreach(struct in_conninfo *inc, tcp_seq th_seq, uint16_t port)
 {
diff --git a/sys/netinet/tcp_syncache.h b/sys/netinet/tcp_syncache.h
index 37f6ff3d6ca9..c916b4de6ae0 100644
--- a/sys/netinet/tcp_syncache.h
+++ b/sys/netinet/tcp_syncache.h
@@ -45,7 +45,6 @@ struct socket *	 syncache_add(struct in_conninfo *, struct tcpopt *,
 	     void *, void *, uint8_t, uint16_t);
 void	 syncache_chkrst(struct in_conninfo *, struct tcphdr *, struct mbuf *,
 	     uint16_t);
-void	 syncache_badack(struct in_conninfo *, uint16_t);
 int	 syncache_pcblist(struct sysctl_req *);
 
 struct syncache {