aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Tuexen <tuexen@FreeBSD.org>2024-09-05 01:33:13 +0000
committerMichael Tuexen <tuexen@FreeBSD.org>2024-10-31 16:36:46 +0000
commit0567f7cc1a4669085f29a8d8e9175eaf83f9877d (patch)
tree1292fb9193c3ab9730a9f0742bf63329e58c5d0c
parent3e8226cb8c8333c4e0a1118fe09d0a7b6e5711cd (diff)
tcp: improve consistency of syncache_respond() failure handling
When the initial sending of the SYN ACK segment using syncache_respond() fails, it is handled as a permanent error. To improve consistency, apply this policy in all cases, where syncache_respond() is called. These include * timer based retransmissions of the SYN ACK * retransmitting a SYN ACK in response to a SYN retransmission * sending of challenge ACKs in response to received RST segments In these cases, fall back to SYN cookies, if enabled. While there, also improve consistency of the TCP stats counters. Reviewed by: cc, glebius (earlier version) Sponsored by: Netflix, Inc. Differential Revision: https://reviews.freebsd.org/D46428 (cherry picked from commit ef438f7706be48f1cf7fd4c8a60329e1619cfe30)
-rw-r--r--sys/netinet/tcp_syncache.c23
1 files changed, 19 insertions, 4 deletions
diff --git a/sys/netinet/tcp_syncache.c b/sys/netinet/tcp_syncache.c
index 86df6c747ea4..111f591c5851 100644
--- a/sys/netinet/tcp_syncache.c
+++ b/sys/netinet/tcp_syncache.c
@@ -531,10 +531,16 @@ syncache_timer(void *xsch)
}
NET_EPOCH_ENTER(et);
- syncache_respond(sc, NULL, TH_SYN|TH_ACK);
+ if (syncache_respond(sc, NULL, TH_SYN|TH_ACK) == 0) {
+ syncache_timeout(sc, sch, 0);
+ TCPSTAT_INC(tcps_sndacks);
+ TCPSTAT_INC(tcps_sndtotal);
+ TCPSTAT_INC(tcps_sc_retransmitted);
+ } else {
+ syncache_drop(sc, sch);
+ TCPSTAT_INC(tcps_sc_dropped);
+ }
NET_EPOCH_EXIT(et);
- TCPSTAT_INC(tcps_sc_retransmitted);
- syncache_timeout(sc, sch, 0);
}
if (!TAILQ_EMPTY(&(sch)->sch_bucket))
callout_reset(&(sch)->sch_timer, (sch)->sch_nextc - tick,
@@ -692,7 +698,13 @@ 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);
- syncache_respond(sc, m, TH_ACK);
+ if (syncache_respond(sc, m, TH_ACK) == 0) {
+ TCPSTAT_INC(tcps_sndacks);
+ TCPSTAT_INC(tcps_sndtotal);
+ } else {
+ syncache_drop(sc, sch);
+ TCPSTAT_INC(tcps_sc_dropped);
+ }
}
} else {
if ((s = tcp_log_addrs(inc, th, NULL, NULL)))
@@ -1589,6 +1601,9 @@ syncache_add(struct in_conninfo *inc, struct tcpopt *to, struct tcphdr *th,
syncache_timeout(sc, sch, 1);
TCPSTAT_INC(tcps_sndacks);
TCPSTAT_INC(tcps_sndtotal);
+ } else {
+ syncache_drop(sc, sch);
+ TCPSTAT_INC(tcps_sc_dropped);
}
SCH_UNLOCK(sch);
goto donenoprobe;