From c31ca95ac73d0da462f7e324e1c3a33b11c39f2c Mon Sep 17 00:00:00 2001 From: Alan Conway Date: Wed, 27 Sep 2017 18:37:24 -0400 Subject: [PATCH] PROTON-1587: fix openssl error handling, causing spurious errors From the SSL_get_error() man page: In addition to ssl and ret, SSL_get_error() inspects the current thread's OpenSSL error queue. Thus, SSL_get_error() must be used in the same thread that performed the TLS/SSL I/O operation, and no other OpenSSL function calls should appear in between. The current thread's error queue must be empty before the TLS/SSL I/O operation is attempted, or SSL_get_error() will not work reliably. Proton was not clearing the error queue, so the "shutdown-during-init" error (which was introduced recently in OpenSSL) was left dangling, and was reported incorrectly when the thread was used to serve another transport. Upstream: https://github.com/apache/qpid-proton/commit/c31ca95ac73d0da462f7e324e1c3a33b11c39f2c Signed-off-by: Matthew Weber --- proton-c/src/ssl/openssl.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/proton-c/src/ssl/openssl.c b/proton-c/src/ssl/openssl.c index 5c750b0..3a4e1a3 100644 --- a/proton-c/src/ssl/openssl.c +++ b/proton-c/src/ssl/openssl.c @@ -206,7 +206,7 @@ static int ssl_failed(pn_transport_t *transport) // fake a shutdown so the i/o processing code will close properly SSL_set_shutdown(ssl->ssl, SSL_SENT_SHUTDOWN|SSL_RECEIVED_SHUTDOWN); // try to grab the first SSL error to add to the failure log - char buf[128] = "Unknown error."; + char buf[256] = "Unknown error"; unsigned long ssl_err = ERR_get_error(); if (ssl_err) { ERR_error_string_n( ssl_err, buf, sizeof(buf) ); @@ -909,6 +909,7 @@ static ssize_t process_input_ssl( pn_transport_t *transport, unsigned int layer, do { work_pending = false; + ERR_clear_error(); // Write to network bio as much as possible, consuming bytes/available @@ -1058,6 +1059,8 @@ static ssize_t process_output_ssl( pn_transport_t *transport, unsigned int layer do { work_pending = false; + ERR_clear_error(); + // first, get any pending application output, if possible if (!ssl->app_output_closed && ssl->out_count < ssl->out_size) { -- 1.9.1