QSslServer: Re-enable read notifications when a client times out

Otherwise new clients will not be handled when they try to connect

Amends 29a1fe72a0888eb1f22a5ae9fe1b3d87257f3246

Change-Id: Ifff052d1bf27682df2782faa285a257c9b41d86f
Reviewed-by: Konrad Kujawa <konrad.kujawa@qt.io>
Reviewed-by: Timur Pocheptsov <timur.pocheptsov@qt.io>
(cherry picked from commit 50f8a9578dd54f74e8a5f99481f7f34d969d867f)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
This commit is contained in:
Mårten Nordheim 2022-08-19 13:23:27 +02:00 committed by Qt Cherry-pick Bot
parent 3eb367095f
commit e70018c814
2 changed files with 18 additions and 6 deletions

View File

@ -396,6 +396,8 @@ void QSslServerPrivate::handleHandshakeTimedOut(QSslSocket *socket)
socket->disconnectFromHost(); socket->disconnectFromHost();
Q_EMIT q->errorOccurred(socket, QAbstractSocket::SocketTimeoutError); Q_EMIT q->errorOccurred(socket, QAbstractSocket::SocketTimeoutError);
socket->deleteLater(); socket->deleteLater();
if (!socketEngine->isReadNotificationEnabled() && totalPendingConnections() < maxConnections)
q->resumeAccepting();
} }
QT_END_NAMESPACE QT_END_NAMESPACE

View File

@ -25,7 +25,7 @@ private slots:
#endif #endif
void plaintextClient(); void plaintextClient();
void quietClient(); void quietClient();
void manyQuietClients(); void twoGoodAndManyBadClients();
private: private:
QString testDataDir; QString testDataDir;
@ -488,22 +488,26 @@ void tst_QSslServer::quietClient()
QCOMPARE(serverPeerPort, clientLocalPort); QCOMPARE(serverPeerPort, clientLocalPort);
} }
void tst_QSslServer::manyQuietClients() void tst_QSslServer::twoGoodAndManyBadClients()
{ {
QSslConfiguration serverConfiguration = selfSignedServerQSslConfiguration(); QSslConfiguration serverConfiguration = selfSignedServerQSslConfiguration();
SslServerSpy server(serverConfiguration); SslServerSpy server(serverConfiguration);
server.server.setHandshakeTimeout(750);
constexpr qsizetype ExpectedConnections = 5; constexpr qsizetype ExpectedConnections = 5;
server.server.setMaxPendingConnections(ExpectedConnections); server.server.setMaxPendingConnections(ExpectedConnections);
QVERIFY(server.server.listen()); QVERIFY(server.server.listen());
auto connectGoodClient = [&server](QSslSocket *socket) {
QObject::connect(socket, &QSslSocket::sslErrors, socket,
qOverload<const QList<QSslError> &>(&QSslSocket::ignoreSslErrors));
socket->connectToHostEncrypted("127.0.0.1", server.server.serverPort());
};
// Connect one socket encrypted so we have a socket in the regular queue // Connect one socket encrypted so we have a socket in the regular queue
QSslSocket tlsSocket; QSslSocket tlsSocket;
QObject::connect(&tlsSocket, &QSslSocket::sslErrors, &tlsSocket, connectGoodClient(&tlsSocket);
qOverload<const QList<QSslError> &>(&QSslSocket::ignoreSslErrors));
tlsSocket.connectToHostEncrypted("127.0.0.1", server.server.serverPort());
// Then we connect a bunch of TCP sockets who will not send any data at all // Then we connect a bunch of TCP sockets who will not send any data at all
std::array<QTcpSocket, size_t(ExpectedConnections) * 4> sockets; std::array<QTcpSocket, size_t(ExpectedConnections) * 2> sockets;
for (QTcpSocket &socket : sockets) for (QTcpSocket &socket : sockets)
socket.connectToHost(QHostAddress::LocalHost, server.server.serverPort()); socket.connectToHost(QHostAddress::LocalHost, server.server.serverPort());
QTest::qWait(500); // some leeway to let connections try to connect... QTest::qWait(500); // some leeway to let connections try to connect...
@ -514,6 +518,12 @@ void tst_QSslServer::manyQuietClients()
QCOMPARE(connectedCount, ExpectedConnections); QCOMPARE(connectedCount, ExpectedConnections);
// 1 socket is ready and pending // 1 socket is ready and pending
QCOMPARE(server.pendingConnectionAvailableSpy.size(), 1); QCOMPARE(server.pendingConnectionAvailableSpy.size(), 1);
// Connect another client to make sure that the server is accepting connections again even after
// all the bad actors tried to connect:
QSslSocket goodClient;
connectGoodClient(&goodClient);
QTRY_COMPARE(server.pendingConnectionAvailableSpy.size(), 2);
} }
QTEST_MAIN(tst_QSslServer) QTEST_MAIN(tst_QSslServer)