git: c55c8a899edc - stable/14 - tcp: apply rate limits to challenge ACKs
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Fri, 03 Oct 2025 08:32:10 UTC
The branch stable/14 has been updated by tuexen:
URL: https://cgit.FreeBSD.org/src/commit/?id=c55c8a899edcb5736df46058ac57e8d20f653991
commit c55c8a899edcb5736df46058ac57e8d20f653991
Author: Michael Tuexen <tuexen@FreeBSD.org>
AuthorDate: 2025-09-30 20:06:33 +0000
Commit: Michael Tuexen <tuexen@FreeBSD.org>
CommitDate: 2025-10-03 08:31:41 +0000
tcp: apply rate limits to challenge ACKs
When sending challenge ACKs from the SYN-cache, apply the same rate
limiting as in other states.
Reviewed by: cc, rrs
Sponsored by: Netflix, Inc.
Differential Revision: https://reviews.freebsd.org/D52754
(cherry picked from commit c2900b6e8255ba4f54dbd897cf42427db577ed3d)
---
sys/netinet/tcp_syncache.c | 28 ++++++++++++++++++++++++----
sys/netinet/tcp_syncache.h | 2 ++
2 files changed, 26 insertions(+), 4 deletions(-)
diff --git a/sys/netinet/tcp_syncache.c b/sys/netinet/tcp_syncache.c
index 9d2c5dd5098e..012240f46ffb 100644
--- a/sys/netinet/tcp_syncache.c
+++ b/sys/netinet/tcp_syncache.c
@@ -130,6 +130,7 @@ static void syncache_drop(struct syncache *, struct syncache_head *);
static void syncache_free(struct syncache *);
static void syncache_insert(struct syncache *, struct syncache_head *);
static int syncache_respond(struct syncache *, const struct mbuf *, int);
+static int syncache_send_challenge_ack(struct syncache *, struct mbuf *);
static struct socket *syncache_socket(struct syncache *, struct socket *,
struct mbuf *m);
static void syncache_timeout(struct syncache *sc, struct syncache_head *sch,
@@ -702,10 +703,7 @@ syncache_chkrst(struct in_conninfo *inc, struct tcphdr *th, struct mbuf *m,
"sending challenge ACK\n",
s, __func__,
th->th_seq, sc->sc_irs + 1, sc->sc_wnd);
- if (syncache_respond(sc, m, TH_ACK) == 0) {
- TCPSTAT_INC(tcps_sndacks);
- TCPSTAT_INC(tcps_sndtotal);
- } else {
+ if (syncache_send_challenge_ack(sc, m) != 0) {
syncache_drop(sc, sch);
TCPSTAT_INC(tcps_sc_dropped);
}
@@ -976,6 +974,10 @@ syncache_socket(struct syncache *sc, struct socket *lso, struct mbuf *m)
if (sc->sc_rxmits > 1)
tp->snd_cwnd = 1;
+ /* Copy over the challenge ACK state. */
+ tp->t_challenge_ack_end = sc->sc_challenge_ack_end;
+ tp->t_challenge_ack_cnt = sc->sc_challenge_ack_cnt;
+
#ifdef TCP_OFFLOAD
/*
* Allow a TOE driver to install its hooks. Note that we hold the
@@ -2060,6 +2062,24 @@ syncache_respond(struct syncache *sc, const struct mbuf *m0, int flags)
return (error);
}
+static int
+syncache_send_challenge_ack(struct syncache *sc, struct mbuf *m)
+{
+ int error;
+
+ if (tcp_challenge_ack_check(&sc->sc_challenge_ack_end,
+ &sc->sc_challenge_ack_cnt)) {
+ error = syncache_respond(sc, m, TH_ACK);
+ if (error == 0) {
+ TCPSTAT_INC(tcps_sndacks);
+ TCPSTAT_INC(tcps_sndtotal);
+ }
+ } else {
+ error = 0;
+ }
+ return (error);
+}
+
/*
* The purpose of syncookies is to handle spoofed SYN flooding DoS attacks
* that exceed the capacity of the syncache by avoiding the storage of any
diff --git a/sys/netinet/tcp_syncache.h b/sys/netinet/tcp_syncache.h
index 219cddee0b1d..9445940bcec5 100644
--- a/sys/netinet/tcp_syncache.h
+++ b/sys/netinet/tcp_syncache.h
@@ -69,6 +69,8 @@ struct syncache {
u_int8_t sc_requested_s_scale:4,
sc_requested_r_scale:4;
u_int16_t sc_flags;
+ u_int32_t sc_challenge_ack_cnt; /* chall. ACKs sent in epoch */
+ sbintime_t sc_challenge_ack_end; /* End of chall. ack epoch */
#if defined(TCP_OFFLOAD) || !defined(TCP_OFFLOAD_DISABLE)
struct toedev *sc_tod; /* entry added by this TOE */
void *sc_todctx; /* TOE driver context */