tcp: re-enable persist timer if no data available to send 41/8241/2
authorFlorin Coras <fcoras@cisco.com>
Tue, 29 Aug 2017 21:50:13 +0000 (14:50 -0700)
committerDave Barach <openvpp@barachs.net>
Wed, 30 Aug 2017 13:15:32 +0000 (13:15 +0000)
Additionally, flush rx fifos for closed sessions.

Change-Id: If2cc563fbda0451e7572650e98b15f0a694a0ff9
Signed-off-by: Florin Coras <fcoras@cisco.com>
src/vnet/session/session.c
src/vnet/tcp/tcp_input.c
src/vnet/tcp/tcp_output.c

index ee22ccb..dcd141f 100644 (file)
@@ -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);
index 66e2b88..1d90345 100644 (file)
@@ -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,
index c56eadf..0255551 100644 (file)
@@ -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);