diff options
author | Florin Coras <fcoras@cisco.com> | 2023-10-14 15:16:18 -0700 |
---|---|---|
committer | Dave Barach <vpp@barachs.net> | 2023-10-16 20:00:49 +0000 |
commit | da2ae9af61fbdb3b68eb72f8d35294fdb3720303 (patch) | |
tree | a80b9f1883a8e9b32e4ac24c0e69cab5a8d86f06 /src/vnet/tcp/tcp_input.c | |
parent | 61d63e8323d11240edab44ff714def1c573fc987 (diff) |
tcp: allow fins in syns in syn-rcvd
Also make sure connection is properly cleaned up.
Type: fix
Signed-off-by: Florin Coras <fcoras@cisco.com>
Change-Id: I02f83e9a1e17cbbbd2ee74044d02049b2fd2f21c
Diffstat (limited to 'src/vnet/tcp/tcp_input.c')
-rw-r--r-- | src/vnet/tcp/tcp_input.c | 18 |
1 files changed, 11 insertions, 7 deletions
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: |