FS-10395: [mod_sofia] Fix ssl error handling in tls sip traffic

Clears SSL error state.

Updates tport_tls.c to clear the SSL error state after an error occurs.

OpenSSL puts errors into a queue that is kept in thread local storage.
In some cases, such as when SSL_ERROR_SSL is returned by SSL_get_errror(),
OpenSSL will queue multiple errors for a single event. When this occurs,
OpenSSL will report an error the next time I/O is performed if the queue
is not cleared first, which can result in TLS connections being torn down
prematurely.
This commit is contained in:
trevora 2016-08-02 13:11:02 +00:00 committed by Mike Jerris
parent 719937ff8f
commit 74f5b5675e
1 changed files with 5 additions and 7 deletions

View File

@ -769,6 +769,7 @@ int tls_error(tls_t *tls, int ret, char const *who,
return 0;
case SSL_ERROR_SYSCALL:
ERR_clear_error();
if (SSL_get_shutdown(tls->con) & SSL_RECEIVED_SHUTDOWN)
return 0; /* EOS */
if (errno == 0)
@ -897,7 +898,7 @@ ssize_t tls_write(tls_t *tls, void *buf, size_t size)
tls->write_events = 0;
ret = SSL_write(tls->con, buf, size);
if (ret < 0)
if (ret <= 0)
return tls_error(tls, ret, "tls_write: SSL_write", buf, size);
return ret;
@ -1020,6 +1021,8 @@ int tls_connect(su_root_magic_t *magic, su_wait_t *w, tport_t *self)
if ((su_wait_create(wait, self->tp_socket, self->tp_events) == -1) ||
((self->tp_index = su_root_register(mr->mr_root, wait, tport_wakeup,
self, 0)) == -1)) {
tls_log_errors(3, "TLS post handshake error", status);
tport_close(self);
tport_set_secondary_timer(self);
return 0;
@ -1041,12 +1044,7 @@ int tls_connect(su_root_magic_t *magic, su_wait_t *w, tport_t *self)
break;
default:
{
char errbuf[64];
ERR_error_string_n(status, errbuf, 64);
SU_DEBUG_3(("%s(%p): TLS setup failed (%s)\n",
__func__, (void *)self, errbuf));
}
tls_log_errors(3, "TLS setup failed", status);
break;
}
}