From 50958959b57c9c2d3fc72ae7588c53d1804aeb86 Mon Sep 17 00:00:00 2001 From: Florin Coras Date: Tue, 29 Aug 2017 14:50:13 -0700 Subject: tcp: re-enable persist timer if no data available to send Additionally, flush rx fifos for closed sessions. Change-Id: If2cc563fbda0451e7572650e98b15f0a694a0ff9 Signed-off-by: Florin Coras --- src/vnet/session/session.c | 8 +++++++- src/vnet/tcp/tcp_input.c | 1 + src/vnet/tcp/tcp_output.c | 22 ++++++++++++++++++---- 3 files changed, 26 insertions(+), 5 deletions(-) (limited to 'src/vnet') diff --git a/src/vnet/session/session.c b/src/vnet/session/session.c index ee22ccbe..dcd141f1 100644 --- a/src/vnet/session/session.c +++ b/src/vnet/session/session.c @@ -330,7 +330,13 @@ stream_session_enqueue_notify (stream_session_t * s, u8 block) static u32 serial_number; if (PREDICT_FALSE (s->session_state == SESSION_STATE_CLOSED)) - return 0; + { + /* Session is closed so app will never clean up. Flush rx fifo */ + u32 to_dequeue = svm_fifo_max_dequeue (s->server_rx_fifo); + if (to_dequeue) + svm_fifo_dequeue_drop (s->server_rx_fifo, to_dequeue); + return 0; + } /* Get session's server */ app = application_get_if_valid (s->app_index); diff --git a/src/vnet/tcp/tcp_input.c b/src/vnet/tcp/tcp_input.c index 66e2b88f..1d903453 100644 --- a/src/vnet/tcp/tcp_input.c +++ b/src/vnet/tcp/tcp_input.c @@ -3073,6 +3073,7 @@ do { \ _(TIME_WAIT, TCP_FLAG_FIN | TCP_FLAG_ACK, TCP_INPUT_NEXT_RCV_PROCESS, TCP_ERROR_NONE); _(TIME_WAIT, TCP_FLAG_RST, TCP_INPUT_NEXT_RCV_PROCESS, TCP_ERROR_NONE); + _(TIME_WAIT, TCP_FLAG_ACK, TCP_INPUT_NEXT_RCV_PROCESS, TCP_ERROR_NONE); _(CLOSED, TCP_FLAG_ACK, TCP_INPUT_NEXT_RESET, TCP_ERROR_CONNECTION_CLOSED); _(CLOSED, TCP_FLAG_RST, TCP_INPUT_NEXT_DROP, TCP_ERROR_CONNECTION_CLOSED); _(CLOSED, TCP_FLAG_FIN | TCP_FLAG_ACK, TCP_INPUT_NEXT_RESET, diff --git a/src/vnet/tcp/tcp_output.c b/src/vnet/tcp/tcp_output.c index c56eadf8..02555513 100644 --- a/src/vnet/tcp/tcp_output.c +++ b/src/vnet/tcp/tcp_output.c @@ -1452,15 +1452,29 @@ tcp_timer_persist_handler (u32 index) /* Make sure timer handle is set to invalid */ tc->timers[TCP_TIMER_PERSIST] = TCP_TIMER_HANDLE_INVALID; - offset = tc->snd_una_max - tc->snd_una; /* Problem already solved or worse */ - available_bytes = stream_session_tx_fifo_max_dequeue (&tc->connection); if (tc->state == TCP_STATE_CLOSED || tc->state > TCP_STATE_ESTABLISHED - || tc->snd_wnd > tc->snd_mss || tcp_in_recovery (tc) - || !available_bytes || available_bytes <= offset) + || tc->snd_wnd > tc->snd_mss || tcp_in_recovery (tc)) return; + available_bytes = stream_session_tx_fifo_max_dequeue (&tc->connection); + offset = tc->snd_una_max - tc->snd_una; + + /* Reprogram persist if no new bytes available to send. We may have data + * next time */ + if (!available_bytes) + { + tcp_persist_timer_set (tc); + return; + } + + if (available_bytes <= offset) + { + ASSERT (tcp_timer_is_active (tc, TCP_TIMER_RETRANSMIT)); + return; + } + /* Increment RTO backoff */ tc->rto_boff += 1; tc->rto = clib_min (tc->rto << 1, TCP_RTO_MAX); -- cgit 1.2.3-korg