session: fix local sessions disconnects
[vpp.git] / src / vnet / session / application_worker.c
index 44e0d39..3bab356 100644 (file)
@@ -15,6 +15,7 @@
 
 #include <vnet/session/application.h>
 #include <vnet/session/application_interface.h>
+#include <vnet/session/session.h>
 
 /**
  * Pool of workers associated to apps
@@ -159,7 +160,7 @@ void
 app_worker_free (app_worker_t * app_wrk)
 {
   application_t *app = application_get (app_wrk->app_index);
-  vnet_unbind_args_t _a, *a = &_a;
+  vnet_unlisten_args_t _a, *a = &_a;
   u64 handle, *handles = 0;
   segment_manager_t *sm;
   u32 sm_index;
@@ -187,7 +188,7 @@ app_worker_free (app_worker_t * app_wrk)
       a->wrk_map_index = app_wrk->wrk_map_index;
       a->handle = handles[i];
       /* seg manager is removed when unbind completes */
-      vnet_unlisten (a);
+      (void) vnet_unlisten (a);
     }
 
   /*
@@ -254,6 +255,29 @@ app_worker_alloc_segment_manager (app_worker_t * app_wrk)
   return sm;
 }
 
+static int
+app_worker_alloc_session_fifos (segment_manager_t * sm, session_t * s)
+{
+  svm_fifo_t *rx_fifo = 0, *tx_fifo = 0;
+  u32 fifo_segment_index;
+  int rv;
+
+  if ((rv = segment_manager_alloc_session_fifos (sm, &rx_fifo, &tx_fifo,
+                                                &fifo_segment_index)))
+    return rv;
+
+  rx_fifo->master_session_index = s->session_index;
+  rx_fifo->master_thread_index = s->thread_index;
+
+  tx_fifo->master_session_index = s->session_index;
+  tx_fifo->master_thread_index = s->thread_index;
+
+  s->rx_fifo = rx_fifo;
+  s->tx_fifo = tx_fifo;
+  s->svm_segment_index = fifo_segment_index;
+  return 0;
+}
+
 int
 app_worker_start_listen (app_worker_t * app_wrk,
                         app_listener_t * app_listener)
@@ -283,7 +307,7 @@ app_worker_start_listen (app_worker_t * app_wrk,
 
   if (session_transport_service_type (ls) == TRANSPORT_SERVICE_CL)
     {
-      if (!ls->rx_fifo && session_alloc_fifos (sm, ls))
+      if (!ls->rx_fifo && app_worker_alloc_session_fifos (sm, ls))
        return -1;
     }
   return 0;
@@ -338,7 +362,7 @@ app_worker_stop_listen (app_worker_t * app_wrk, app_listener_t * al)
       /* *INDENT-OFF* */
       pool_foreach (ls, app_wrk->local_sessions, ({
         if (ls->listener_index == ll->session_index)
-          app_worker_local_session_disconnect (app_wrk->app_index, ls);
+          app_worker_local_session_disconnect (app_wrk->wrk_index, ls);
       }));
       /* *INDENT-ON* */
     }
@@ -350,6 +374,51 @@ app_worker_stop_listen (app_worker_t * app_wrk, app_listener_t * al)
   return 0;
 }
 
+int
+app_worker_init_accepted (session_t * s)
+{
+  app_worker_t *app_wrk;
+  segment_manager_t *sm;
+  session_t *listener;
+
+  listener = listen_session_get (s->listener_index);
+  app_wrk = application_listener_select_worker (listener);
+  s->app_wrk_index = app_wrk->wrk_index;
+  sm = app_worker_get_listen_segment_manager (app_wrk, listener);
+  return app_worker_alloc_session_fifos (sm, s);
+}
+
+int
+app_worker_accept_notify (app_worker_t * app_wrk, session_t * s)
+{
+  application_t *app = application_get (app_wrk->app_index);
+  return app->cb_fns.session_accept_callback (s);
+}
+
+int
+app_worker_init_connected (app_worker_t * app_wrk, session_t * s)
+{
+  application_t *app = application_get (app_wrk->app_index);
+  segment_manager_t *sm;
+
+  /* Allocate fifos for session, unless the app is a builtin proxy */
+  if (!application_is_builtin_proxy (app))
+    {
+      sm = app_worker_get_connect_segment_manager (app_wrk);
+      if (app_worker_alloc_session_fifos (sm, s))
+       return -1;
+    }
+  return 0;
+}
+
+int
+app_worker_connect_notify (app_worker_t * app_wrk, session_t * s, u32 opaque)
+{
+  application_t *app = application_get (app_wrk->app_index);
+  return app->cb_fns.session_connected_callback (app_wrk->wrk_index, opaque,
+                                                s, s == 0 /* is_fail */ );
+}
+
 int
 app_worker_own_session (app_worker_t * app_wrk, session_t * s)
 {
@@ -371,7 +440,7 @@ app_worker_own_session (app_worker_t * app_wrk, session_t * s)
   s->tx_fifo = 0;
 
   sm = app_worker_get_or_alloc_connect_segment_manager (app_wrk);
-  if (session_alloc_fifos (sm, s))
+  if (app_worker_alloc_session_fifos (sm, s))
     return -1;
 
   if (!svm_fifo_is_empty (rxf))
@@ -897,35 +966,17 @@ app_worker_local_session_connect_notify (local_session_t * ls)
 }
 
 int
-app_worker_local_session_disconnect (u32 app_index, local_session_t * ls)
+app_worker_local_session_disconnect (u32 app_wrk_index, local_session_t * ls)
 {
   app_worker_t *client_wrk, *server_wrk;
-  u8 is_server = 0, is_client = 0;
-  application_t *app;
-
-  app = application_get_if_valid (app_index);
-  if (!app)
-    return 0;
 
   client_wrk = app_worker_get_if_valid (ls->client_wrk_index);
   server_wrk = app_worker_get (ls->app_wrk_index);
 
-  if (server_wrk->app_index == app_index)
-    is_server = 1;
-  else if (client_wrk && client_wrk->app_index == app_index)
-    is_client = 1;
-
-  if (!is_server && !is_client)
-    {
-      clib_warning ("app %u is neither client nor server for session 0x%lx",
-                   app_index, application_local_session_handle (ls));
-      return VNET_API_ERROR_INVALID_VALUE;
-    }
-
   if (ls->session_state == SESSION_STATE_CLOSED)
     return app_worker_local_session_cleanup (client_wrk, server_wrk, ls);
 
-  if (app_index == ls->client_wrk_index)
+  if (app_wrk_index == ls->client_wrk_index)
     {
       mq_send_local_session_disconnected_cb (ls->app_wrk_index, ls);
     }