Details
-
Bug
-
Resolution: Unresolved
-
P3: Somewhat important
-
None
-
5.11.2
-
None
Description
If there's an error during the SSL handshake phase and QSslSocket::disconnectFromHost is called from the error handler, the socket gets stuck in QAbstractSocket::ClosingState forever. In my case I was trying to handle a self-signed certificate error when I encountered this. Here's a small snippet to reproduce:
#include <QApplication> #include <QDebug> #include <QSslSocket> #include <QSslError> int main(int argc, char ** argv) { QApplication app(argc, argv); QSslSocket * socket = new QSslSocket(); QObject::connect(socket, &QSslSocket::stateChanged, [] (QAbstractSocket::SocketState state) -> void { qDebug() << state; }); QObject::connect(socket, &QSslSocket::encrypted, [] () -> void { qDebug() << "Encrypted!"; }); QObject::connect(socket, &QSslSocket::peerVerifyError, [socket] (const QSslError & error) -> void { qDebug() << error.errorString(); qDebug() << "Pending write (ecrypted): " << socket->bytesToWrite(); qDebug() << "Pending write: " << socket->QTcpSocket::bytesToWrite(); qDebug() << "Pending read (ecrypted): " << socket->bytesAvailable(); qDebug() << "Pending read: " << socket->QTcpSocket::bytesAvailable(); socket->disconnectFromHost(); }); socket->setPauseMode(QSslSocket::PauseNever); socket->connectToHostEncrypted("127.0.0.1", 7778); return QApplication::exec(); }
Which produces the following debug output:
QAbstractSocket::HostLookupState
QAbstractSocket::ConnectingState
QAbstractSocket::ConnectedState
"The certificate is self-signed, and untrusted"
Pending write (ecrypted): 0
Pending write: 0
Pending read (ecrypted): 0
Pending read: 0
QAbstractSocket::ClosingState
The only way to actually close the socket is to call QSslSocket::abort instead of QSslSocket::disconnectFromHost.