tcp: fix detection of bad RTOs

If timestamps are enabled, the actions performed by a retransmission
timeout were rolled back, when they should not.
It is needed to make sure the incoming segment advances SND.UNA.
To do this, remove the incorrect upfront check and extend the check in
the fast path to handle also the case of timestamps.

PR:			282605
Reviewed by:		cc, rscheff, Peter Lei
MFC after:		3 days
Sponsored by:		Netflix, Inc.
Differential Revision:	https://reviews.freebsd.org/D49414
This commit is contained in:
Michael Tuexen 2025-03-20 16:17:40 +01:00
parent fdc4db5722
commit fbcf3b74e8

View file

@ -1635,11 +1635,6 @@ tcp_do_segment(struct tcpcb *tp, struct mbuf *m, struct tcphdr *th,
to.to_tsecr -= tp->ts_offset;
if (TSTMP_GT(to.to_tsecr, tcp_ts_getticks())) {
to.to_tsecr = 0;
} else if (tp->t_rxtshift == 1 &&
tp->t_flags & TF_PREVVALID &&
tp->t_badrxtwin != 0 &&
TSTMP_LT(to.to_tsecr, tp->t_badrxtwin)) {
cc_cong_signal(tp, th, CC_RTO_ERR);
}
}
/*
@ -1792,15 +1787,17 @@ tcp_do_segment(struct tcpcb *tp, struct mbuf *m, struct tcphdr *th,
TCPSTAT_INC(tcps_predack);
/*
* "bad retransmit" recovery without timestamps.
* "bad retransmit" recovery.
*/
if ((to.to_flags & TOF_TS) == 0 &&
tp->t_rxtshift == 1 &&
if (tp->t_rxtshift == 1 &&
tp->t_flags & TF_PREVVALID &&
tp->t_badrxtwin != 0 &&
TSTMP_LT(ticks, tp->t_badrxtwin)) {
(((to.to_flags & TOF_TS) != 0 &&
to.to_tsecr != 0 &&
TSTMP_LT(to.to_tsecr, tp->t_badrxtwin)) ||
((to.to_flags & TOF_TS) == 0 &&
TSTMP_LT(ticks, tp->t_badrxtwin))))
cc_cong_signal(tp, th, CC_RTO_ERR);
}
/*
* Recalculate the transmit timer / rtt.