From: Florin Coras Date: Sat, 14 Oct 2023 22:16:18 +0000 (-0700) Subject: tcp: allow fins in syns in syn-rcvd X-Git-Tag: v24.06-rc0~209 X-Git-Url: https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commitdiff_plain;h=da2ae9af61fbdb3b68eb72f8d35294fdb3720303 tcp: allow fins in syns in syn-rcvd Also make sure connection is properly cleaned up. Type: fix Signed-off-by: Florin Coras Change-Id: I02f83e9a1e17cbbbd2ee74044d02049b2fd2f21c --- diff --git a/src/vnet/tcp/tcp_input.c b/src/vnet/tcp/tcp_input.c index 1602b49b910..1494fd84b6b 100644 --- a/src/vnet/tcp/tcp_input.c +++ b/src/vnet/tcp/tcp_input.c @@ -2123,7 +2123,7 @@ tcp46_rcv_process_inline (vlib_main_t *vm, vlib_node_runtime_t *node, case TCP_STATE_SYN_RCVD: /* Make sure the segment is exactly right */ - if (tc->rcv_nxt != vnet_buffer (b[0])->tcp.seq_number || is_fin) + if (tc->rcv_nxt != vnet_buffer (b[0])->tcp.seq_number) { tcp_send_reset_w_pkt (tc, b[0], thread_index, is_ip4); error = TCP_ERROR_SEGMENT_INVALID; @@ -2143,6 +2143,10 @@ tcp46_rcv_process_inline (vlib_main_t *vm, vlib_node_runtime_t *node, goto drop; } + /* Avoid notifying app if connection is about to be closed */ + if (PREDICT_FALSE (is_fin)) + break; + /* Update rtt and rto */ tcp_estimate_initial_rtt (tc); tcp_connection_tx_pacer_update (tc); @@ -2363,15 +2367,15 @@ tcp46_rcv_process_inline (vlib_main_t *vm, vlib_node_runtime_t *node, tcp_cfg.closewait_time); break; case TCP_STATE_SYN_RCVD: - /* Send FIN-ACK, enter LAST-ACK and because the app was not - * notified yet, set a cleanup timer instead of relying on - * disconnect notify and the implicit close call. */ + /* Send FIN-ACK and enter TIME-WAIT, as opposed to LAST-ACK, + * because the app was not notified yet and we want to avoid + * session state transitions to ensure cleanup does not + * propagate to app. */ tcp_connection_timers_reset (tc); tc->rcv_nxt += 1; tcp_send_fin (tc); - tcp_connection_set_state (tc, TCP_STATE_LAST_ACK); - tcp_timer_set (&wrk->timer_wheel, tc, TCP_TIMER_WAITCLOSE, - tcp_cfg.lastack_time); + tcp_connection_set_state (tc, TCP_STATE_TIME_WAIT); + tcp_program_cleanup (wrk, tc); break; case TCP_STATE_CLOSE_WAIT: case TCP_STATE_CLOSING: