From 36d49391aadeb10b9f3626b62c5c019c4fddf5ed Mon Sep 17 00:00:00 2001 From: Florin Coras Date: Fri, 24 Apr 2020 23:00:11 +0000 Subject: [PATCH] session vcl: propagate transport cleanup notifications Type: improvement Can be used to force app to close a connection on which it still waits for data. Signed-off-by: Florin Coras Change-Id: I7c3a8245cbbc23728e4408feb63a659a11f718ed --- src/vcl/vppcom.c | 11 +++++++++++ src/vnet/session/application_interface.h | 1 + src/vnet/session/session_api.c | 6 ++++-- src/vnet/session/transport.c | 7 ++++--- src/vnet/tls/tls.c | 7 ++++++- 5 files changed, 26 insertions(+), 6 deletions(-) diff --git a/src/vcl/vppcom.c b/src/vcl/vppcom.c index a8cebd8c413..0382af45544 100644 --- a/src/vcl/vppcom.c +++ b/src/vcl/vppcom.c @@ -749,6 +749,17 @@ vcl_session_cleanup_handler (vcl_worker_t * wrk, void *data) return; } + if (msg->type == SESSION_CLEANUP_TRANSPORT) + { + /* Transport was cleaned up before we confirmed close. Probably the + * app is still waiting for some data that cannot be delivered. + * Confirm close to make sure everything is cleaned up */ + if (session->session_state == STATE_VPP_CLOSING) + vcl_session_cleanup (wrk, session, vcl_session_handle (session), + 1 /* do_disconnect */ ); + return; + } + vcl_session_table_del_vpp_handle (wrk, msg->handle); /* Should not happen. App did not close the connection so don't free it. */ if (session->session_state != STATE_CLOSED) diff --git a/src/vnet/session/application_interface.h b/src/vnet/session/application_interface.h index d09432d0b52..c5007673851 100644 --- a/src/vnet/session/application_interface.h +++ b/src/vnet/session/application_interface.h @@ -522,6 +522,7 @@ typedef struct session_migrate_msg_ typedef struct session_cleanup_msg_ { session_handle_t handle; + u8 type; } __clib_packed session_cleanup_msg_t; typedef struct app_session_event_ diff --git a/src/vnet/session/session_api.c b/src/vnet/session/session_api.c index 39545375e62..cfeb7bcc349 100644 --- a/src/vnet/session/session_api.c +++ b/src/vnet/session/session_api.c @@ -550,8 +550,9 @@ mq_send_session_cleanup_cb (session_t * s, session_cleanup_ntf_t ntf) session_event_t *evt; app_worker_t *app_wrk; - /* Only propagate session cleanup notification */ - if (ntf == SESSION_CLEANUP_TRANSPORT) + /* Propagate transport cleanup notifications only if app didn't close */ + if (ntf == SESSION_CLEANUP_TRANSPORT + && s->session_state != SESSION_STATE_TRANSPORT_DELETED) return; app_wrk = app_worker_get_if_valid (s->app_wrk_index); @@ -567,6 +568,7 @@ mq_send_session_cleanup_cb (session_t * s, session_cleanup_ntf_t ntf) evt->event_type = SESSION_CTRL_EVT_CLEANUP; mp = (session_cleanup_msg_t *) evt->data; mp->handle = session_handle (s); + mp->type = ntf; svm_msg_q_add_and_unlock (app_mq, msg); } diff --git a/src/vnet/session/transport.c b/src/vnet/session/transport.c index 9dd495c7d61..8e5df3f8418 100644 --- a/src/vnet/session/transport.c +++ b/src/vnet/session/transport.c @@ -94,11 +94,12 @@ format_transport_connection (u8 * s, va_list * args) s = format (s, "%U", tp_vft->format_connection, conn_index, thread_index, verbose); tc = tp_vft->get_connection (conn_index, thread_index); - if (tc && transport_connection_is_tx_paced (tc) && verbose > 1) + if (tc && verbose > 1) { indent = format_get_indent (s) + 1; - s = format (s, "%Upacer: %U\n", format_white_space, indent, - format_transport_pacer, &tc->pacer, tc->thread_index); + if (transport_connection_is_tx_paced (tc)) + s = format (s, "%Upacer: %U\n", format_white_space, indent, + format_transport_pacer, &tc->pacer, tc->thread_index); s = format (s, "%Utransport: flags 0x%x\n", format_white_space, indent, tc->flags); } diff --git a/src/vnet/tls/tls.c b/src/vnet/tls/tls.c index 89dbd36bc44..1af0857d7f2 100644 --- a/src/vnet/tls/tls.c +++ b/src/vnet/tls/tls.c @@ -518,7 +518,12 @@ tls_app_session_cleanup (session_t * s, session_cleanup_ntf_t ntf) tls_ctx_t *ctx; if (ntf == SESSION_CLEANUP_TRANSPORT) - return; + { + /* Allow cleanup of tcp session */ + if (s->session_state == SESSION_STATE_TRANSPORT_DELETED) + session_close (s); + return; + } ctx = tls_ctx_get (s->opaque); if (!ctx->no_app_session) -- 2.16.6