Skip to content

Commit

Permalink
tcp: fix TFO SYN_RECV to not zero retrans_stamp with retransmits out
Browse files Browse the repository at this point in the history
[ Upstream commit 27c80ef ]

Fix tcp_rcv_synrecv_state_fastopen() to not zero retrans_stamp
if retransmits are outstanding.

tcp_fastopen_synack_timer() sets retrans_stamp, so typically we'll
need to zero retrans_stamp here to prevent spurious
retransmits_timed_out(). The logic to zero retrans_stamp is from this
2019 commit:

commit cd736d8 ("tcp: fix retrans timestamp on passive Fast Open")

However, in the corner case where the ACK of our TFO SYNACK carried
some SACK blocks that caused us to enter TCP_CA_Recovery then that
non-zero retrans_stamp corresponds to the active fast recovery, and we
need to leave retrans_stamp with its current non-zero value, for
correct ETIMEDOUT and undo behavior.

Fixes: cd736d8 ("tcp: fix retrans timestamp on passive Fast Open")
Signed-off-by: Neal Cardwell <[email protected]>
Signed-off-by: Yuchung Cheng <[email protected]>
Signed-off-by: Eric Dumazet <[email protected]>
Link: https://patch.msgid.link/[email protected]
Signed-off-by: Jakub Kicinski <[email protected]>
Signed-off-by: Sasha Levin <[email protected]>
  • Loading branch information
nealcardwell authored and gregkh committed Oct 17, 2024
1 parent 718c49f commit 2daffbd
Showing 1 changed file with 9 additions and 2 deletions.
11 changes: 9 additions & 2 deletions net/ipv4/tcp_input.c
Original file line number Diff line number Diff line change
Expand Up @@ -6554,10 +6554,17 @@ static void tcp_rcv_synrecv_state_fastopen(struct sock *sk)
if (inet_csk(sk)->icsk_ca_state == TCP_CA_Loss && !tp->packets_out)
tcp_try_undo_recovery(sk);

/* Reset rtx states to prevent spurious retransmits_timed_out() */
tcp_update_rto_time(tp);
tp->retrans_stamp = 0;
inet_csk(sk)->icsk_retransmits = 0;
/* In tcp_fastopen_synack_timer() on the first SYNACK RTO we set
* retrans_stamp but don't enter CA_Loss, so in case that happened we
* need to zero retrans_stamp here to prevent spurious
* retransmits_timed_out(). However, if the ACK of our SYNACK caused us
* to enter CA_Recovery then we need to leave retrans_stamp as it was
* set entering CA_Recovery, for correct retransmits_timed_out() and
* undo behavior.
*/
tcp_retrans_stamp_cleanup(sk);

/* Once we leave TCP_SYN_RECV or TCP_FIN_WAIT_1,
* we no longer need req so release it.
Expand Down

0 comments on commit 2daffbd

Please sign in to comment.