281void QSslServer::incomingConnection(qintptr socket)
283 QSslSocket *pSslSocket =
new QSslSocket(
this);
285 pSslSocket->setSslConfiguration(sslConfiguration());
287 if (Q_LIKELY(pSslSocket->setSocketDescriptor(socket))) {
288 connect(pSslSocket, &QSslSocket::peerVerifyError,
this,
289 [
this, pSslSocket](
const QSslError &error) {
290 Q_EMIT peerVerifyError(pSslSocket, error);
292 connect(pSslSocket, &QSslSocket::sslErrors,
this,
293 [
this, pSslSocket](
const QList<QSslError> &errors) {
294 Q_EMIT sslErrors(pSslSocket, errors);
296 connect(pSslSocket, &QAbstractSocket::errorOccurred,
this,
297 [
this, pSslSocket](QAbstractSocket::SocketError error) {
298 Q_EMIT errorOccurred(pSslSocket, error);
299 if (!pSslSocket->isEncrypted())
300 pSslSocket->deleteLater();
302 connect(pSslSocket, &QSslSocket::encrypted,
this, [
this, pSslSocket]() {
304 d->removeSocketData(quintptr(pSslSocket));
305 pSslSocket->disconnect(
this);
306 addPendingConnection(pSslSocket);
308 connect(pSslSocket, &QSslSocket::preSharedKeyAuthenticationRequired,
this,
309 [
this, pSslSocket](QSslPreSharedKeyAuthenticator *authenticator) {
310 Q_EMIT preSharedKeyAuthenticationRequired(pSslSocket, authenticator);
312 connect(pSslSocket, &QSslSocket::alertSent,
this,
313 [
this, pSslSocket](QSsl::AlertLevel level, QSsl::AlertType type,
314 const QString &description) {
315 Q_EMIT alertSent(pSslSocket, level, type, description);
317 connect(pSslSocket, &QSslSocket::alertReceived,
this,
318 [
this, pSslSocket](QSsl::AlertLevel level, QSsl::AlertType type,
319 const QString &description) {
320 Q_EMIT alertReceived(pSslSocket, level, type, description);
322 connect(pSslSocket, &QSslSocket::handshakeInterruptedOnError,
this,
323 [
this, pSslSocket](
const QSslError &error) {
324 Q_EMIT handshakeInterruptedOnError(pSslSocket, error);
327 d_func()->initializeHandshakeProcess(pSslSocket);
331void QSslServerPrivate::initializeHandshakeProcess(QSslSocket *socket)
334 QMetaObject::Connection readyRead = QObject::connect(
335 socket, &QSslSocket::readyRead, q, [
this]() { checkClientHelloAndContinue(); });
337 QMetaObject::Connection destroyed =
338 QObject::connect(socket, &QSslSocket::destroyed, q, [
this](QObject *obj) {
341 removeSocketData(quintptr(obj));
343 const auto [it, ins] = socketData.try_emplace(quintptr(socket), std::move(readyRead),
344 std::move(destroyed), std::make_shared<QTimer>());
346 qFatal(
"if this fires, we have an ABA problem");
347 auto &e = it->second;
348 e.timeoutTimer->setSingleShot(
true);
349 e.timeoutTimer->callOnTimeout(q, [
this, socket]() { handleHandshakeTimedOut(socket); });
350 e.timeoutTimer->setInterval(handshakeTimeout);
351 e.timeoutTimer->start();
371void QSslServerPrivate::checkClientHelloAndContinue()
374 QSslSocket *socket = qobject_cast<QSslSocket *>(q->sender());
375 if (Q_UNLIKELY(!socket) || socket->bytesAvailable() <= 0)
379 if (socket->peek(&byte, 1) != 1) {
380 socket->deleteLater();
384 auto it = socketData.find(quintptr(socket));
385 const bool foundData = it != socketData.end();
386 if (foundData && it->readyReadConnection)
387 QObject::disconnect(std::exchange(it->readyReadConnection, {}));
389 constexpr char CLIENT_HELLO = 0x16;
390 if (byte != CLIENT_HELLO) {
391 socket->disconnectFromHost();
392 socket->deleteLater();
398 it->timeoutTimer->start();
400 socket->startServerEncryption();
401 Q_EMIT q->startedEncryptionHandshake(socket);
404void QSslServerPrivate::handleHandshakeTimedOut(QSslSocket *socket)
407 removeSocketData(quintptr(socket));
408 socket->disconnectFromHost();
409 Q_EMIT q->errorOccurred(socket, QAbstractSocket::SocketTimeoutError);
410 socket->deleteLater();
411 if (!socketEngine->isReadNotificationEnabled() && totalPendingConnections() < maxConnections)
412 q->resumeAccepting();