summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFlorin Coras <fcoras@cisco.com>2020-04-24 23:00:11 +0000
committerDave Barach <openvpp@barachs.net>2020-04-25 11:40:25 +0000
commit36d49391aadeb10b9f3626b62c5c019c4fddf5ed (patch)
tree9280b80a3769104f5ab3e8422428190a640c3352
parent5e6222a0332e38316b5a58b23c35cca69bb72025 (diff)
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 <fcoras@cisco.com> Change-Id: I7c3a8245cbbc23728e4408feb63a659a11f718ed
-rw-r--r--src/vcl/vppcom.c11
-rw-r--r--src/vnet/session/application_interface.h1
-rw-r--r--src/vnet/session/session_api.c6
-rw-r--r--src/vnet/session/transport.c7
-rw-r--r--src/vnet/tls/tls.c7
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)