diff options
author | Florin Coras <fcoras@cisco.com> | 2023-10-14 15:16:18 -0700 |
---|---|---|
committer | Andrew Yourtchenko <ayourtch@gmail.com> | 2023-10-25 17:20:00 +0000 |
commit | d20bacd0e5d0872eed025620a15f9dd314d6aca2 (patch) | |
tree | 46dea73288d0fa04cd5f6f4cb8f08b1d36d733a7 /src | |
parent | dcb10ce353316a176b5c1c5475fda5edee588770 (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
(cherry picked from commit da2ae9af61fbdb3b68eb72f8d35294fdb3720303)
Diffstat (limited to 'src')
-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: |