summaryrefslogtreecommitdiffstats
path: root/src/plugins/tlsopenssl
diff options
context:
space:
mode:
authorFlorin Coras <fcoras@cisco.com>2019-08-07 11:14:56 -0700
committerDave Barach <openvpp@barachs.net>2019-08-08 22:02:17 +0000
commitef2b3357b4b2a682ef81ffa2c71cec14f83101d6 (patch)
treebc881e13c2d2ab7c086d24803cc5bc99744c2c19 /src/plugins/tlsopenssl
parentd1ba3d257788f1a65016a50a53d85f2b905874bb (diff)
tls: fix close with data
Type:fix Also changes the way the ctx is freed. TLS now waits for tcp delete notification before freeing the ctx. Change-Id: I2f606a9ce7b3755ae9d11d6fe714fe11b65dcb98 Signed-off-by: Florin Coras <fcoras@cisco.com>
Diffstat (limited to 'src/plugins/tlsopenssl')
-rw-r--r--src/plugins/tlsopenssl/tls_openssl.c55
1 files changed, 43 insertions, 12 deletions
diff --git a/src/plugins/tlsopenssl/tls_openssl.c b/src/plugins/tlsopenssl/tls_openssl.c
index 6cb8ff08b7f..ee6b0e3172e 100644
--- a/src/plugins/tlsopenssl/tls_openssl.c
+++ b/src/plugins/tlsopenssl/tls_openssl.c
@@ -233,6 +233,29 @@ openssl_ctx_handshake_rx (tls_ctx_t * ctx, session_t * tls_session)
rv = SSL_do_handshake (oc->ssl);
err = SSL_get_error (oc->ssl, rv);
+
+ if (err == SSL_ERROR_SSL)
+ {
+ char buf[512];
+ ERR_error_string (ERR_get_error (), buf);
+ clib_warning ("Err: %s", buf);
+
+ /*
+ * Cleanup pre-allocated app session and close transport
+ */
+ if (SSL_is_server (oc->ssl))
+ {
+ session_free (session_get (ctx->c_s_index,
+ ctx->c_thread_index));
+ ctx->no_app_session = 1;
+ ctx->c_s_index = SESSION_INVALID_INDEX;
+ tls_disconnect_transport (ctx);
+ }
+ else
+ tls_notify_app_connected (ctx, /* is failed */ 1);
+ return -1;
+ }
+
openssl_try_handshake_write (oc, tls_session);
#ifdef HAVE_OPENSSL_ASYNC
if (err == SSL_ERROR_WANT_ASYNC)
@@ -247,15 +270,7 @@ openssl_ctx_handshake_rx (tls_ctx_t * ctx, session_t * tls_session)
#endif
if (err != SSL_ERROR_WANT_WRITE)
- {
- if (err == SSL_ERROR_SSL)
- {
- char buf[512];
- ERR_error_string (ERR_get_error (), buf);
- clib_warning ("Err: %s", buf);
- }
- break;
- }
+ break;
}
TLS_DBG (2, "tls state for %u is %s", oc->openssl_ctx_index,
SSL_state_string_long (oc->ssl));
@@ -297,6 +312,13 @@ openssl_ctx_handshake_rx (tls_ctx_t * ctx, session_t * tls_session)
return rv;
}
+static void
+openssl_confirm_app_close (tls_ctx_t * ctx)
+{
+ tls_disconnect_transport (ctx);
+ session_transport_closed_notify (&ctx->connection);
+}
+
static inline int
openssl_ctx_write (tls_ctx_t * ctx, session_t * app_session)
{
@@ -374,6 +396,8 @@ check_tls_fifo:
if (BIO_ctrl_pending (oc->rbio) > 0)
tls_add_vpp_q_builtin_tx_evt (app_session);
+ else if (ctx->app_closed)
+ openssl_confirm_app_close (ctx);
return wrote;
}
@@ -744,9 +768,16 @@ openssl_transport_close (tls_ctx_t * ctx)
static int
openssl_app_close (tls_ctx_t * ctx)
{
- tls_disconnect_transport (ctx);
- session_transport_delete_notify (&ctx->connection);
- openssl_ctx_free (ctx);
+ openssl_ctx_t *oc = (openssl_ctx_t *) ctx;
+ session_t *app_session;
+
+ /* Wait for all data to be written to tcp */
+ app_session = session_get_from_handle (ctx->app_session_handle);
+ if (BIO_ctrl_pending (oc->rbio) <= 0
+ && !svm_fifo_max_dequeue_cons (app_session->tx_fifo))
+ openssl_confirm_app_close (ctx);
+ else
+ ctx->app_closed = 1;
return 0;
}