aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/vnet/session/application.c70
-rw-r--r--src/vnet/session/application.h2
-rw-r--r--src/vnet/session/segment_manager.c8
3 files changed, 58 insertions, 22 deletions
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);