Skip to content

Commit e326578

Browse files
Aananth Vdavem330
authored andcommitted
tcp: call tcp_try_undo_recovery when an RTOd TFO SYNACK is ACKed
For passive TCP Fast Open sockets that had SYN/ACK timeout and did not send more data in SYN_RECV, upon receiving the final ACK in 3WHS, the congestion state may awkwardly stay in CA_Loss mode unless the CA state was undone due to TCP timestamp checks. However, if tcp_rcv_synrecv_state_fastopen() decides not to undo, then we should enter CA_Open, because at that point we have received an ACK covering the retransmitted SYNACKs. Currently, the icsk_ca_state is only set to CA_Open after we receive an ACK for a data-packet. This is because tcp_ack does not call tcp_fastretrans_alert (and tcp_process_loss) if !prior_packets Note that tcp_process_loss() calls tcp_try_undo_recovery(), so having tcp_rcv_synrecv_state_fastopen() decide that if we're in CA_Loss we should call tcp_try_undo_recovery() is consistent with that, and low risk. Fixes: dad8cea ("tcp: fix TFO SYNACK undo to avoid double-timestamp-undo") Signed-off-by: Aananth V <[email protected]> Signed-off-by: Neal Cardwell <[email protected]> Signed-off-by: Yuchung Cheng <[email protected]> Reviewed-by: Eric Dumazet <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 50675d8 commit e326578

File tree

1 file changed

+5
-4
lines changed

1 file changed

+5
-4
lines changed

net/ipv4/tcp_input.c

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6444,22 +6444,23 @@ static int tcp_rcv_synsent_state_process(struct sock *sk, struct sk_buff *skb,
64446444

64456445
static void tcp_rcv_synrecv_state_fastopen(struct sock *sk)
64466446
{
6447+
struct tcp_sock *tp = tcp_sk(sk);
64476448
struct request_sock *req;
64486449

64496450
/* If we are still handling the SYNACK RTO, see if timestamp ECR allows
64506451
* undo. If peer SACKs triggered fast recovery, we can't undo here.
64516452
*/
6452-
if (inet_csk(sk)->icsk_ca_state == TCP_CA_Loss)
6453-
tcp_try_undo_loss(sk, false);
6453+
if (inet_csk(sk)->icsk_ca_state == TCP_CA_Loss && !tp->packets_out)
6454+
tcp_try_undo_recovery(sk);
64546455

64556456
/* Reset rtx states to prevent spurious retransmits_timed_out() */
6456-
tcp_sk(sk)->retrans_stamp = 0;
6457+
tp->retrans_stamp = 0;
64576458
inet_csk(sk)->icsk_retransmits = 0;
64586459

64596460
/* Once we leave TCP_SYN_RECV or TCP_FIN_WAIT_1,
64606461
* we no longer need req so release it.
64616462
*/
6462-
req = rcu_dereference_protected(tcp_sk(sk)->fastopen_rsk,
6463+
req = rcu_dereference_protected(tp->fastopen_rsk,
64636464
lockdep_sock_is_held(sk));
64646465
reqsk_fastopen_remove(sk, req, false);
64656466

0 commit comments

Comments
 (0)