summaryrefslogtreecommitdiffstats
path: root/src/vnet/session
diff options
context:
space:
mode:
Diffstat (limited to 'src/vnet/session')
-rw-r--r--src/vnet/session/application_worker.c2
-rw-r--r--src/vnet/session/session.c79
-rw-r--r--src/vnet/session/session.h2
3 files changed, 73 insertions, 10 deletions
diff --git a/src/vnet/session/application_worker.c b/src/vnet/session/application_worker.c
index fad70c06de3..0b2f1459d9a 100644
--- a/src/vnet/session/application_worker.c
+++ b/src/vnet/session/application_worker.c
@@ -396,7 +396,7 @@ int
app_worker_del_half_open (app_worker_t *app_wrk, session_t *s)
{
application_t *app = application_get (app_wrk->app_index);
- ASSERT (vlib_get_thread_index () == 0);
+ ASSERT (vlib_get_thread_index () <= 1);
pool_put_index (app_wrk->half_open_table, s->ho_index);
if (app->cb_fns.half_open_cleanup_callback)
app->cb_fns.half_open_cleanup_callback (s);
diff --git a/src/vnet/session/session.c b/src/vnet/session/session.c
index 0d2301c5f83..7aadb2188b4 100644
--- a/src/vnet/session/session.c
+++ b/src/vnet/session/session.c
@@ -303,21 +303,82 @@ session_delete (session_t * s)
void
session_cleanup_half_open (session_handle_t ho_handle)
{
- session_t *s = session_get_from_handle (ho_handle);
- transport_cleanup_half_open (session_get_transport_proto (s),
- s->connection_index);
+ session_t *ho = session_get_from_handle (ho_handle);
+
+ /* App transports can migrate their half-opens */
+ if (ho->flags & SESSION_F_IS_MIGRATING)
+ {
+ /* Session still migrating, move to closed state to signal that the
+ * session should be removed. */
+ if (ho->connection_index == ~0)
+ {
+ ho->session_state = SESSION_STATE_CLOSED;
+ return;
+ }
+ /* Migrated transports are no longer half-opens */
+ transport_cleanup (session_get_transport_proto (ho),
+ ho->connection_index, ho->app_index /* overloaded */);
+ return;
+ }
+ transport_cleanup_half_open (session_get_transport_proto (ho),
+ ho->connection_index);
+}
+
+static void
+session_half_open_free (u32 ho_index)
+{
+ app_worker_t *app_wrk;
+ session_t *ho;
+
+ ASSERT (vlib_get_thread_index () <= 1);
+ ho = ho_session_get (ho_index);
+ app_wrk = app_worker_get (ho->app_wrk_index);
+ app_worker_del_half_open (app_wrk, ho);
+ session_free (ho);
+}
+
+static void
+session_half_open_free_rpc (void *args)
+{
+ session_half_open_free (pointer_to_uword (args));
}
void
session_half_open_delete_notify (transport_connection_t *tc)
{
- app_worker_t *app_wrk;
- session_t *s;
+ void *args = uword_to_pointer ((uword) tc->s_index, void *);
+ u32 ctrl_thread = vlib_num_workers () ? 1 : 0;
+ session_send_rpc_evt_to_thread (ctrl_thread, session_half_open_free_rpc,
+ args);
+}
- s = ho_session_get (tc->s_index);
- app_wrk = app_worker_get (s->app_wrk_index);
- app_worker_del_half_open (app_wrk, s);
- session_free (s);
+void
+session_half_open_migrate_notify (transport_connection_t *tc)
+{
+ session_t *ho;
+
+ ho = ho_session_get (tc->s_index);
+ ho->flags |= SESSION_F_IS_MIGRATING;
+ ho->connection_index = ~0;
+}
+
+int
+session_half_open_migrated_notify (transport_connection_t *tc)
+{
+ session_t *ho;
+
+ ho = ho_session_get (tc->s_index);
+
+ /* App probably detached so the half-open must be cleaned up */
+ if (ho->session_state == SESSION_STATE_CLOSED)
+ {
+ session_half_open_delete_notify (tc);
+ return -1;
+ }
+ ho->connection_index = tc->c_index;
+ /* Overload app index for half-open with new thread */
+ ho->app_index = tc->thread_index;
+ return 0;
}
session_t *
diff --git a/src/vnet/session/session.h b/src/vnet/session/session.h
index d14c68971de..bf326811b24 100644
--- a/src/vnet/session/session.h
+++ b/src/vnet/session/session.h
@@ -506,6 +506,8 @@ int session_stream_accept_notify (transport_connection_t * tc);
void session_transport_closing_notify (transport_connection_t * tc);
void session_transport_delete_notify (transport_connection_t * tc);
void session_half_open_delete_notify (transport_connection_t *tc);
+void session_half_open_migrate_notify (transport_connection_t *tc);
+int session_half_open_migrated_notify (transport_connection_t *tc);
void session_transport_closed_notify (transport_connection_t * tc);
void session_transport_reset_notify (transport_connection_t * tc);
int session_stream_accept (transport_connection_t * tc, u32 listener_index,