From 0f7267f220be79e21cf9f96efa01929285e9aa55 Mon Sep 17 00:00:00 2001 From: Riza Sulistyo Date: Wed, 5 Jul 2023 10:38:21 +0700 Subject: [PATCH 303/303] Don't call SSL_shutdown() when receiving SSL_ERROR_SYSCALL or SSL_ERROR_SSL (#3577) --- pjlib/src/pj/ssl_sock_imp_common.c | 1 + pjlib/src/pj/ssl_sock_imp_common.h | 13 +++++++------ pjlib/src/pj/ssl_sock_ossl.c | 17 ++++++++++++----- 3 files changed, 20 insertions(+), 11 deletions(-) diff --git a/pjlib/src/pj/ssl_sock_imp_common.c b/pjlib/src/pj/ssl_sock_imp_common.c index ae2f1136e..c825676c3 100644 --- a/pjlib/src/pj/ssl_sock_imp_common.c +++ b/pjlib/src/pj/ssl_sock_imp_common.c @@ -237,20 +237,21 @@ static void ssl_close_sockets(pj_ssl_sock_t *ssock) #endif /* When handshake completed: * - notify application * - if handshake failed, reset SSL state * - return PJ_FALSE when SSL socket instance is destroyed by application. */ static pj_bool_t on_handshake_complete(pj_ssl_sock_t *ssock, pj_status_t status) { + ssock->handshake_status = status; /* Cancel handshake timer */ if (ssock->timer.id == TIMER_HANDSHAKE_TIMEOUT) { pj_timer_heap_cancel(ssock->param.timer_heap, &ssock->timer); ssock->timer.id = TIMER_NONE; } /* Update certificates info on successful handshake */ if (status == PJ_SUCCESS) ssl_update_certs_info(ssock); diff --git a/pjlib/src/pj/ssl_sock_imp_common.h b/pjlib/src/pj/ssl_sock_imp_common.h index cba28dbd3..8a63faa90 100644 --- a/pjlib/src/pj/ssl_sock_imp_common.h +++ b/pjlib/src/pj/ssl_sock_imp_common.h @@ -99,26 +99,27 @@ struct pj_ssl_sock_t * information allocation. Don't use for * other purposes. */ pj_ssl_sock_t *parent; pj_ssl_sock_param param; pj_ssl_sock_param newsock_param; pj_ssl_cert_t *cert; pj_ssl_cert_info local_cert_info; pj_ssl_cert_info remote_cert_info; - pj_bool_t is_server; - enum ssl_state ssl_state; - pj_ioqueue_op_key_t handshake_op_key; - pj_ioqueue_op_key_t shutdown_op_key; - pj_timer_entry timer; - pj_status_t verify_status; + pj_bool_t is_server; + enum ssl_state ssl_state; + pj_ioqueue_op_key_t handshake_op_key; + pj_ioqueue_op_key_t shutdown_op_key; + pj_timer_entry timer; + pj_status_t verify_status; + pj_status_t handshake_status; pj_bool_t is_closing; unsigned long last_err; pj_sock_t sock; pj_activesock_t *asock; pj_sockaddr local_addr; pj_sockaddr rem_addr; int addr_len; diff --git a/pjlib/src/pj/ssl_sock_ossl.c b/pjlib/src/pj/ssl_sock_ossl.c index 5c8e67b76..8a717e362 100644 --- a/pjlib/src/pj/ssl_sock_ossl.c +++ b/pjlib/src/pj/ssl_sock_ossl.c @@ -1646,27 +1646,34 @@ static void ssl_reset_sock_state(pj_ssl_sock_t *ssock) /* Detach from SSL instance */ if (ossock->ossl_ssl) { SSL_set_ex_data(ossock->ossl_ssl, sslsock_idx, NULL); } /** * Avoid calling SSL_shutdown() if handshake wasn't completed. * OpenSSL 1.0.2f complains if SSL_shutdown() is called during an * SSL handshake, while previous versions always return 0. + * Call SSL_shutdown() when there is a timeout handshake failure or + * the last error is not SSL_ERROR_SYSCALL and not SSL_ERROR_SSL. */ if (ossock->ossl_ssl && SSL_in_init(ossock->ossl_ssl) == 0) { - int ret = SSL_shutdown(ossock->ossl_ssl); - if (ret == 0) { - /* SSL_shutdown will potentially trigger a bunch of - * data to dump to the socket */ - post_unlock_flush_circ_buf = 1; + if (ssock->handshake_status == PJ_ETIMEDOUT || + (ssock->last_err != SSL_ERROR_SYSCALL && + ssock->last_err != SSL_ERROR_SSL)) + { + int ret = SSL_shutdown(ossock->ossl_ssl); + if (ret == 0) { + /* SSL_shutdown will potentially trigger a bunch of + * data to dump to the socket */ + post_unlock_flush_circ_buf = 1; + } } } ssock->ssl_state = SSL_STATE_NULL; pj_lock_release(ssock->write_mutex); if (post_unlock_flush_circ_buf) { /* Flush data to send close notify. */ flush_circ_buf_output(ssock, &ssock->shutdown_op_key, 0, 0); -- 2.41.0