From af61b7312e2701bc89bdb78d6a8d8984c59c673f Mon Sep 17 00:00:00 2001 From: Scott Deboy Date: Thu, 25 Jul 2013 10:22:01 -0700 Subject: Resolve error caused by server-initiated TLS renegotiation Updating the SSL_write code to correctly handle SSL_ERROR_WANT_WRITE and SSL_ERROR_WANT_READ, which are not actual errors. Change-Id: Icd7369b438ef402bf438c3fcc64514a1f9f45452 Reviewed-by: Peter Hartmann Reviewed-by: Lars Knoll Reviewed-by: Richard J. Moore --- src/network/ssl/qsslsocket_openssl.cpp | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) (limited to 'src/network') diff --git a/src/network/ssl/qsslsocket_openssl.cpp b/src/network/ssl/qsslsocket_openssl.cpp index e94df10fed..69b9e53884 100644 --- a/src/network/ssl/qsslsocket_openssl.cpp +++ b/src/network/ssl/qsslsocket_openssl.cpp @@ -796,11 +796,22 @@ void QSslSocketBackendPrivate::transmit() while ((nextDataBlockSize = writeBuffer.nextDataBlockSize()) > 0) { int writtenBytes = q_SSL_write(ssl, writeBuffer.readPointer(), nextDataBlockSize); if (writtenBytes <= 0) { - // ### Better error handling. - q->setErrorString(QSslSocket::tr("Unable to write data: %1").arg(getErrorsFromOpenSsl())); - q->setSocketError(QAbstractSocket::SslInternalError); - emit q->error(QAbstractSocket::SslInternalError); - return; + int error = q_SSL_get_error(ssl, writtenBytes); + //write can result in a want_write_error - not an error - continue transmitting + if (error == SSL_ERROR_WANT_WRITE) { + transmitting = true; + break; + } else if (error == SSL_ERROR_WANT_READ) { + //write can result in a want_read error, possibly due to renegotiation - not an error - stop transmitting + transmitting = false; + break; + } else { + // ### Better error handling. + q->setErrorString(QSslSocket::tr("Unable to write data: %1").arg(getErrorsFromOpenSsl())); + q->setSocketError(QAbstractSocket::SslInternalError); + emit q->error(QAbstractSocket::SslInternalError); + return; + } } #ifdef QSSLSOCKET_DEBUG qDebug() << "QSslSocketBackendPrivate::transmit: encrypted" << writtenBytes << "bytes"; -- cgit v1.2.3