session: fix local session disconnects 46/11346/4
authorFlorin Coras <fcoras@cisco.com>
Sat, 24 Mar 2018 05:56:43 +0000 (22:56 -0700)
committerFlorin Coras <florin.coras@gmail.com>
Sun, 25 Mar 2018 21:22:41 +0000 (21:22 +0000)
Select the right segment manager for local sessions established via
global table.

Change-Id: I88ad4bf70d0cae160a0c744950098a954dfbc911
Signed-off-by: Florin Coras <fcoras@cisco.com>
src/vnet/session/application.c
src/vnet/session/application.h
src/vnet/session/segment_manager.c

index 0db52fe..7bc2c11 100644 (file)
@@ -1079,37 +1079,53 @@ application_local_session_connect_notify (local_session_t * ls)
 }
 
 int
-application_local_session_disconnect (u32 app_index, local_session_t * ls)
+application_local_session_cleanup (application_t * client,
+                                  application_t * server,
+                                  local_session_t * ls)
 {
   svm_fifo_segment_private_t *seg;
-  application_t *client, *server;
   segment_manager_t *sm;
   uword client_key;
+  u8 has_transport;
 
-  client = application_get_if_valid (ls->client_index);
-  server = application_get (ls->app_index);
-
-  if (ls->session_state == SESSION_STATE_CLOSED)
-    {
-    cleanup:
-      client_key = application_client_local_connect_key (ls);
-      sm = application_get_local_segment_manager_w_session (server, ls);
-      seg = segment_manager_get_segment (sm, ls->svm_segment_index);
+  has_transport = session_has_transport ((stream_session_t *) ls);
+  client_key = application_client_local_connect_key (ls);
+  if (!has_transport)
+    sm = application_get_local_segment_manager_w_session (server, ls);
+  else
+    sm = application_get_listen_segment_manager (server,
+                                                (stream_session_t *) ls);
 
-      if (client)
-       {
-         hash_unset (client->local_connects, client_key);
-         client->cb_fns.del_segment_callback (client->api_client_index,
-                                              &seg->ssvm);
-       }
+  seg = segment_manager_get_segment (sm, ls->svm_segment_index);
+  if (client)
+    hash_unset (client->local_connects, client_key);
 
+  if (!has_transport)
+    {
       server->cb_fns.del_segment_callback (server->api_client_index,
                                           &seg->ssvm);
+      if (client)
+       client->cb_fns.del_segment_callback (client->api_client_index,
+                                            &seg->ssvm);
       segment_manager_del_segment (sm, seg);
-      application_free_local_session (server, ls);
-      return 0;
     }
 
+  application_free_local_session (server, ls);
+
+  return 0;
+}
+
+int
+application_local_session_disconnect (u32 app_index, local_session_t * ls)
+{
+  application_t *client, *server;
+
+  client = application_get_if_valid (ls->client_index);
+  server = application_get (ls->app_index);
+
+  if (ls->session_state == SESSION_STATE_CLOSED)
+    return application_local_session_cleanup (client, server, ls);
+
   if (app_index == ls->client_index)
     {
       send_local_session_disconnect_callback (ls->app_index, ls);
@@ -1118,7 +1134,7 @@ application_local_session_disconnect (u32 app_index, local_session_t * ls)
     {
       if (!client)
        {
-         goto cleanup;
+         return application_local_session_cleanup (client, server, ls);
        }
       else if (ls->session_state < SESSION_STATE_READY)
        {
@@ -1127,11 +1143,11 @@ application_local_session_disconnect (u32 app_index, local_session_t * ls)
                                                     (stream_session_t *) ls,
                                                     1 /* is_fail */ );
          ls->session_state = SESSION_STATE_CLOSED;
-         goto cleanup;
+         return application_local_session_cleanup (client, server, ls);
        }
       else
        {
-         send_local_session_disconnect_callback (ls->client_index, ls);
+         send_local_session_disconnect_callback (client->index, ls);
        }
     }
 
@@ -1140,6 +1156,16 @@ application_local_session_disconnect (u32 app_index, local_session_t * ls)
   return 0;
 }
 
+int
+application_local_session_disconnect_w_index (u32 app_index, u32 ls_index)
+{
+  application_t *app;
+  local_session_t *ls;
+  app = application_get (app_index);
+  ls = application_get_local_session (app, ls_index);
+  return application_local_session_disconnect (app_index, ls);
+}
+
 void
 application_local_sessions_del (application_t * app)
 {
index 9f3fc12..6f53ea2 100644 (file)
@@ -204,6 +204,8 @@ int application_local_session_connect (u32 table_index,
 int application_local_session_connect_notify (local_session_t * ls);
 int application_local_session_disconnect (u32 app_index,
                                          local_session_t * ls);
+int application_local_session_disconnect_w_index (u32 app_index,
+                                                 u32 ls_index);
 void application_local_sessions_del (application_t * app);
 
 always_inline u32
index 9304dd7..9dade6e 100644 (file)
@@ -366,6 +366,14 @@ segment_manager_del_sessions (segment_manager_t * sm)
      */
     while (fifo)
       {
+       if (fifo->master_thread_index == 255)
+         {
+           svm_fifo_t *next = fifo->next;
+           application_local_session_disconnect_w_index (sm->app_index,
+                                                         fifo->master_session_index);
+           fifo = next;
+           continue;
+         }
        session = session_get (fifo->master_session_index,
                               fifo->master_thread_index);
        stream_session_disconnect (session);