From f6647e0f3653929a0528f5eb97337016bdda01be Mon Sep 17 00:00:00 2001 From: Florin Coras Date: Fri, 23 Mar 2018 22:56:43 -0700 Subject: session: fix local session disconnects Select the right segment manager for local sessions established via global table. Change-Id: I88ad4bf70d0cae160a0c744950098a954dfbc911 Signed-off-by: Florin Coras --- src/vnet/session/application.c | 70 ++++++++++++++++++++++++++------------ src/vnet/session/application.h | 2 ++ src/vnet/session/segment_manager.c | 8 +++++ 3 files changed, 58 insertions(+), 22 deletions(-) (limited to 'src/vnet/session') diff --git a/src/vnet/session/application.c b/src/vnet/session/application.c index 0db52fedcdd..7bc2c11442a 100644 --- a/src/vnet/session/application.c +++ b/src/vnet/session/application.c @@ -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) { diff --git a/src/vnet/session/application.h b/src/vnet/session/application.h index 9f3fc12e486..6f53ea2f94c 100644 --- a/src/vnet/session/application.h +++ b/src/vnet/session/application.h @@ -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 diff --git a/src/vnet/session/segment_manager.c b/src/vnet/session/segment_manager.c index 9304dd70b5d..9dade6ec0d6 100644 --- a/src/vnet/session/segment_manager.c +++ b/src/vnet/session/segment_manager.c @@ -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); -- cgit 1.2.3-korg