diff options
Diffstat (limited to 'src/vnet/session')
-rw-r--r-- | src/vnet/session/application_worker.c | 2 | ||||
-rw-r--r-- | src/vnet/session/session.c | 79 | ||||
-rw-r--r-- | src/vnet/session/session.h | 2 |
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, |