summaryrefslogtreecommitdiffstats
path: root/src/network/ssl
diff options
context:
space:
mode:
authorPeter Hartmann <phartmann@blackberry.com>2013-04-04 11:30:43 +0200
committerThe Qt Project <gerrit-noreply@qt-project.org>2013-04-23 23:22:43 +0200
commite145b67fbd54f147dab0f8e460280a9c8533aa7b (patch)
tree957a2fbba25b66036cc415e5964ec8f3ad772b77 /src/network/ssl
parent34673203788dad6817fe1aaa21ca7432a32330d3 (diff)
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 should not send one as well, as it results in an error. Change-Id: Ie7a56cf3008b6ead912aade18dbec67846e2a87e Reviewed-by: Richard J. Moore <rich@kde.org>
Diffstat (limited to 'src/network/ssl')
-rw-r--r--src/network/ssl/qsslsocket.cpp2
-rw-r--r--src/network/ssl/qsslsocket_openssl.cpp14
-rw-r--r--src/network/ssl/qsslsocket_p.h1
3 files changed, 13 insertions, 4 deletions
diff --git a/src/network/ssl/qsslsocket.cpp b/src/network/ssl/qsslsocket.cpp
index a8bf8f83b8..f2310356df 100644
--- a/src/network/ssl/qsslsocket.cpp
+++ b/src/network/ssl/qsslsocket.cpp
@@ -1908,6 +1908,7 @@ QSslSocketPrivate::QSslSocketPrivate()
, mode(QSslSocket::UnencryptedMode)
, autoStartHandshake(false)
, connectionEncrypted(false)
+ , shutdown(false)
, ignoreAllSslErrors(false)
, readyReadEmittedPointer(0)
, allowRootCertOnDemandLoading(true)
@@ -1933,6 +1934,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 3b2de7a05b..d515f27865 100644
--- a/src/network/ssl/qsslsocket_openssl.cpp
+++ b/src/network/ssl/qsslsocket_openssl.cpp
@@ -934,8 +934,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,
@@ -1369,8 +1372,11 @@ void QWindowsCaRootFetcher::start()
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 72117353ac..d1d79ae09c 100644
--- a/src/network/ssl/qsslsocket_p.h
+++ b/src/network/ssl/qsslsocket_p.h
@@ -109,6 +109,7 @@ public:
QSslSocket::SslMode mode;
bool autoStartHandshake;
bool connectionEncrypted;
+ bool shutdown;
bool ignoreAllSslErrors;
QList<QSslError> ignoreErrorsList;
bool* readyReadEmittedPointer;