session: force session cleanups on app detach 37/40737/6
authorFlorin Coras <fcoras@cisco.com>
Tue, 16 Apr 2024 23:53:14 +0000 (16:53 -0700)
committerDave Barach <vpp@barachs.net>
Wed, 17 Apr 2024 19:03:28 +0000 (19:03 +0000)
Force transport and session cleanup on session detach if transport is
already closing. This should also avoid races between transport
initiated session cleanups and pending session control events.

Type: improvement

Signed-off-by: Florin Coras <fcoras@cisco.com>
Change-Id: I83a947a0c01f5af8ac70aa31fee660276f1d1c60

src/vnet/session/session.c

index e1a93a6..67e7ee3 100644 (file)
@@ -273,7 +273,7 @@ session_cleanup_notify (session_t * s, session_cleanup_ntf_t ntf)
   app_worker_t *app_wrk;
 
   app_wrk = app_worker_get_if_valid (s->app_wrk_index);
-  if (!app_wrk)
+  if (PREDICT_FALSE (!app_wrk))
     {
       if (ntf == SESSION_CLEANUP_TRANSPORT)
        return;
@@ -1600,11 +1600,28 @@ void
 session_detach_app (session_t *s)
 {
   if (s->session_state < SESSION_STATE_TRANSPORT_CLOSING)
-    session_close (s);
-  else if (s->session_state < SESSION_STATE_TRANSPORT_CLOSED)
-    session_set_state (s, SESSION_STATE_APP_CLOSED);
-  else if (s->session_state < SESSION_STATE_CLOSED)
-    session_set_state (s, SESSION_STATE_CLOSED);
+    {
+      session_close (s);
+    }
+  else if (s->session_state < SESSION_STATE_TRANSPORT_DELETED)
+    {
+      transport_connection_t *tc;
+
+      /* Transport is closing but it's not yet deleted. Confirm close and
+       * subsequently detach transport from session and enqueue a session
+       * cleanup notification. Transport closed and cleanup notifications are
+       * going to be dropped by session layer apis */
+      transport_close (session_get_transport_proto (s), s->connection_index,
+                      s->thread_index);
+      tc = session_get_transport (s);
+      tc->s_index = SESSION_INVALID_INDEX;
+      session_set_state (s, SESSION_STATE_TRANSPORT_DELETED);
+      session_cleanup_notify (s, SESSION_CLEANUP_SESSION);
+    }
+  else
+    {
+      session_cleanup_notify (s, SESSION_CLEANUP_SESSION);
+    }
 
   s->flags |= SESSION_F_APP_CLOSED;
   s->app_wrk_index = APP_INVALID_INDEX;