From ef2b3357b4b2a682ef81ffa2c71cec14f83101d6 Mon Sep 17 00:00:00 2001 From: Florin Coras Date: Wed, 7 Aug 2019 11:14:56 -0700 Subject: 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 --- src/plugins/tlsopenssl/tls_openssl.c | 55 ++++++++++++++++++++++++++++-------- 1 file changed, 43 insertions(+), 12 deletions(-) (limited to 'src/plugins/tlsopenssl/tls_openssl.c') 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; } -- cgit 1.2.3-korg