session: cleanup ho lookup table on close

Make sure half-open table is cleaned up on close and cleanup of
half-open.

Type: fix

Signed-off-by: Florin Coras <fcoras@cisco.com>
Change-Id: Id7ad177f364d6395f7379dc927e449a40547510e
diff --git a/src/vnet/session/session.c b/src/vnet/session/session.c
index 93bdf6c..1b9f9de 100644
--- a/src/vnet/session/session.c
+++ b/src/vnet/session/session.c
@@ -307,8 +307,19 @@
 			 ho->connection_index, ho->app_index /* overloaded */);
     }
   else
-    transport_cleanup_half_open (session_get_transport_proto (ho),
-				 ho->connection_index);
+    {
+      /* Cleanup half-open session lookup table if need be */
+      if (ho->session_state != SESSION_STATE_TRANSPORT_CLOSING)
+	{
+	  transport_connection_t *tc;
+	  tc = transport_get_half_open (session_get_transport_proto (ho),
+					ho->connection_index);
+	  if (tc && !(tc->flags & TRANSPORT_CONNECTION_F_NO_LOOKUP))
+	    session_lookup_del_half_open (tc);
+	}
+      transport_cleanup_half_open (session_get_transport_proto (ho),
+				   ho->connection_index);
+    }
   session_free (ho);
 }
 
@@ -317,9 +328,10 @@
 {
   app_worker_t *app_wrk;
 
-  ASSERT (vlib_get_thread_index () <= 1);
-  app_wrk = app_worker_get (ho->app_wrk_index);
-  app_worker_del_half_open (app_wrk, ho);
+  ASSERT (vlib_get_thread_index () <= transport_cl_thread ());
+  app_wrk = app_worker_get_if_valid (ho->app_wrk_index);
+  if (app_wrk)
+    app_worker_del_half_open (app_wrk, ho);
   session_free (ho);
 }
 
@@ -333,10 +345,19 @@
 void
 session_half_open_delete_notify (transport_connection_t *tc)
 {
+  session_t *ho = ho_session_get (tc->s_index);
+
+  /* Cleanup half-open lookup table if need be */
+  if (ho->session_state != SESSION_STATE_TRANSPORT_CLOSING)
+    {
+      if (!(tc->flags & TRANSPORT_CONNECTION_F_NO_LOOKUP))
+	session_lookup_del_half_open (tc);
+    }
+
   /* Notification from ctrl thread accepted without rpc */
   if (tc->thread_index == transport_cl_thread ())
     {
-      session_half_open_free (ho_session_get (tc->s_index));
+      session_half_open_free (ho);
     }
   else
     {
@@ -351,6 +372,9 @@
 {
   session_t *ho;
 
+  /* Support half-open migrations only for transports with no lookup */
+  ASSERT (tc->flags & TRANSPORT_CONNECTION_F_NO_LOOKUP);
+
   ho = ho_session_get (tc->s_index);
   ho->flags |= SESSION_F_IS_MIGRATING;
   ho->connection_index = ~0;
@@ -887,6 +911,7 @@
   session_lookup_del_half_open (tc);
 
   ho = ho_session_get (tc->s_index);
+  session_set_state (ho, SESSION_STATE_TRANSPORT_CLOSING);
   opaque = ho->opaque;
   app_wrk = app_worker_get_if_valid (ho->app_wrk_index);
   if (!app_wrk)
diff --git a/src/vnet/tcp/tcp.c b/src/vnet/tcp/tcp.c
index d0d8158..977eda3 100644
--- a/src/vnet/tcp/tcp.c
+++ b/src/vnet/tcp/tcp.c
@@ -489,6 +489,14 @@
 {
   tcp_connection_t *tc;
   tc = tcp_connection_get (conn_index, thread_index);
+
+  /* For half-opens just cleanup */
+  if (tc->state == TCP_STATE_SYN_SENT)
+    {
+      tcp_connection_cleanup (tc);
+      return;
+    }
+
   tcp_send_reset (tc);
   tcp_connection_timers_reset (tc);
   tcp_cong_recovery_off (tc);