diff options
author | Peter Hartmann <phartmann@blackberry.com> | 2013-04-04 09:30:43 (GMT) |
---|---|---|
committer | The Qt Project <gerrit-noreply@qt-project.org> | 2013-04-24 16:03:42 (GMT) |
commit | 488cb662604437b31db0667dd9e17772395f16c2 (patch) | |
tree | c9ce430944173b17dff5a77d64f5479d9a00c17f /src | |
parent | 1df30fbd1e9ce54dd1076649162121b99700dc98 (diff) | |
download | Qt-488cb662604437b31db0667dd9e17772395f16c2.zip Qt-488cb662604437b31db0667dd9e17772395f16c2.tar.gz Qt-488cb662604437b31db0667dd9e17772395f16c2.tar.bz2 |
SSL internals: do not write after shutting down the socket
... but rather throw an error, so the HTTP layer can recover from a SSL
shutdown gracefully. In case the other side sent us a shutdown, we tried
to send one as well, which results in an error.
(backport of commit e145b67fbd54f147dab0f8e460280a9c8533aa7b)
Change-Id: I57291a5363cb0f6585dbd6aaa521c748766a1fdf
Reviewed-by: Richard J. Moore <rich@kde.org>
Diffstat (limited to 'src')
-rw-r--r-- | src/network/ssl/qsslsocket.cpp | 2 | ||||
-rw-r--r-- | src/network/ssl/qsslsocket_openssl.cpp | 14 | ||||
-rw-r--r-- | src/network/ssl/qsslsocket_p.h | 1 |
3 files changed, 13 insertions, 4 deletions
diff --git a/src/network/ssl/qsslsocket.cpp b/src/network/ssl/qsslsocket.cpp index 6ec8f6e..454a52a 100644 --- a/src/network/ssl/qsslsocket.cpp +++ b/src/network/ssl/qsslsocket.cpp @@ -1851,6 +1851,7 @@ QSslSocketPrivate::QSslSocketPrivate() , mode(QSslSocket::UnencryptedMode) , autoStartHandshake(false) , connectionEncrypted(false) + , shutdown(false) , ignoreAllSslErrors(false) , readyReadEmittedPointer(0) , allowRootCertOnDemandLoading(true) @@ -1875,6 +1876,7 @@ void QSslSocketPrivate::init() autoStartHandshake = false; connectionEncrypted = false; ignoreAllSslErrors = false; + shutdown = false; // we don't want to clear the ignoreErrorsList, so // that it is possible setting it before connecting diff --git a/src/network/ssl/qsslsocket_openssl.cpp b/src/network/ssl/qsslsocket_openssl.cpp index 37dea2b..4b0a9ec 100644 --- a/src/network/ssl/qsslsocket_openssl.cpp +++ b/src/network/ssl/qsslsocket_openssl.cpp @@ -1163,8 +1163,11 @@ void QSslSocketBackendPrivate::transmit() #ifdef QSSLSOCKET_DEBUG qDebug() << "QSslSocketBackendPrivate::transmit: remote disconnect"; #endif - plainSocket->disconnectFromHost(); - break; + shutdown = true; // the other side shut down, make sure we do not send shutdown ourselves + q->setErrorString(QSslSocket::tr("The TLS/SSL connection has been closed")); + q->setSocketError(QAbstractSocket::RemoteHostClosedError); + emit q->error(QAbstractSocket::RemoteHostClosedError); + return; case SSL_ERROR_SYSCALL: // some IO error case SSL_ERROR_SSL: // error in the SSL library // we do not know exactly what the error is, nor whether we can recover from it, @@ -1447,8 +1450,11 @@ bool QSslSocketBackendPrivate::startHandshake() void QSslSocketBackendPrivate::disconnectFromHost() { if (ssl) { - q_SSL_shutdown(ssl); - transmit(); + if (!shutdown) { + q_SSL_shutdown(ssl); + shutdown = true; + transmit(); + } } plainSocket->disconnectFromHost(); } diff --git a/src/network/ssl/qsslsocket_p.h b/src/network/ssl/qsslsocket_p.h index 5044c72..f8967d0 100644 --- a/src/network/ssl/qsslsocket_p.h +++ b/src/network/ssl/qsslsocket_p.h @@ -108,6 +108,7 @@ public: QSslSocket::SslMode mode; bool autoStartHandshake; bool connectionEncrypted; + bool shutdown; bool ignoreAllSslErrors; QList<QSslError> ignoreErrorsList; bool* readyReadEmittedPointer; |