blob: bbd3c7b8104a85fda18b95cbd8e2cfdbcbcd2eab [file] [log] [blame]
From c31ca95ac73d0da462f7e324e1c3a33b11c39f2c Mon Sep 17 00:00:00 2001
From: Alan Conway <aconway@redhat.com>
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 <matthew.weber@rockwellcollins.com>
---
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