diff options
Diffstat (limited to 'src/server/net/client.cpp')
-rw-r--r-- | src/server/net/client.cpp | 90 |
1 files changed, 53 insertions, 37 deletions
diff --git a/src/server/net/client.cpp b/src/server/net/client.cpp index 977eb84..51ffb61 100644 --- a/src/server/net/client.cpp +++ b/src/server/net/client.cpp @@ -9,46 +9,53 @@ #include "../serverapp/serverapp.h" #include "../../shared/settings.h" #include "../../shared/util.h" + #include <QPixmap> #include <cassert> #include <QNetworkInterface> +#include <QTcpSocket> +#include <QSslSocket> +#include <QTimer> #define CHALLENGE_LEN 20 int Client::_clientIdCounter = 0; -Client::Client(QTcpSocket* socket) : _socket(socket) +Client::Client(QTcpSocket* socket) + : _socket(socket) { assert(socket != nullptr); - _authed = 0; - _projectionSource = 0; _desiredSource = NO_SOURCE; - _isActiveVncClient = false; - _vncPort = 0; - _isTutor = false; - _locked = false; - _wantsAttention = false; - + _socket->setParent(nullptr); _id = ++_clientIdCounter; //_ip = _socket->peerAddress().toString(); qDebug("*** Client %s created.", qPrintable(_socket->peerAddress().toString())); // Connect important signals - connect(_socket, SIGNAL(disconnected()), - this, SLOT(disconnect())); - connect(_socket, SIGNAL(error(QAbstractSocket::SocketError)), - this, SLOT(disconnect())); - connect(_socket, SIGNAL(sslErrors(const QList<QSslError> &)), - this, SLOT(disconnect())); - connect(_socket, SIGNAL(readyRead()), - this, SLOT(onDataArrival())); + connect(_socket, &QTcpSocket::disconnected, + [this]() { + this->disconnect("Client closed connection"); + }); + connect(_socket, QOverload<QAbstractSocket::SocketError>::of(&QTcpSocket::errorOccurred), + [this](QAbstractSocket::SocketError) { + this->disconnect("Client socket error"); + }); + auto *ssl = qobject_cast<QSslSocket*>(_socket); + if (ssl != nullptr) { + connect(ssl, QOverload<const QList<QSslError> &>::of(&QSslSocket::sslErrors), + [this](const QList<QSslError> &) { + this->disconnect("Client SSL Errors"); + }); + } + connect(_socket, &QTcpSocket::readyRead, + this, &Client::onDataArrival); // Send challenge _challenge.resize(CHALLENGE_LEN); for (int i = 0; i < CHALLENGE_LEN; ++i) { - _challenge[i] = char(qrand() & 0xff); + _challenge[i] = char(slxrand() & 0xff); } - NetworkMessage msgChlng; - msgChlng.setField(_ID, _CHALLENGE); - msgChlng.setField(_CHALLENGE, _challenge); - msgChlng.writeMessage(_socket); + NetworkMessage msgChallenge; + msgChallenge.setField(_ID, _CHALLENGE); + msgChallenge.setField(_CHALLENGE, _challenge); + msgChallenge.writeMessage(_socket); // give client 3 seconds to complete handshake _timerIdAuthTimeout = startTimer(3000); _timerPingTimeout = startTimer(3000); @@ -58,22 +65,25 @@ Client::Client(QTcpSocket* socket) : _socket(socket) Client::~Client() { qDebug() << "*** Client" << _host << " destroyed."; - _socket->deleteLater(); + _socket->blockSignals(true); + QTcpSocket *sck = _socket; + QTimer::singleShot(10, [sck]() { + sck->deleteLater(); + }); } void Client::timerEvent(QTimerEvent* event) { if (event->timerId() == _timerPingTimeout) { if (_pingTimeout < QDateTime::currentMSecsSinceEpoch()) { - qDebug() << "Client" << _socket->peerAddress().toString() << "has a ping timeout."; killTimer(_timerPingTimeout); - this->disconnect(); + this->disconnect("Disconnecting client because of ping timeout"); } } else if (event->timerId() == _timerIdAuthTimeout) { // Client did not send login request within 3 seconds killTimer(_timerIdAuthTimeout); _timerIdAuthTimeout = 0; - this->disconnect(); + this->disconnect("Did not authenticate withing three seconds"); } else killTimer(event->timerId()); } @@ -122,7 +132,7 @@ void Client::onDataArrival() while (_socket->bytesAvailable() > 0) { int ret = _fromClient.readMessage(_socket); // let the message read data from socket if (ret == NM_READ_FAILED) { // error parsing msg, disconnect client! - this->disconnect(); + this->disconnect("Malformed message received from client."); return; } if (ret == NM_READ_INCOMPLETE) @@ -210,8 +220,7 @@ void Client::handleMsg() // emit event, see if request is accepted emit authenticating(this, &request); if (!request.accept) { - qDebug("Request denied."); - this->disconnect(); // Nope + this->disconnect("Login request denied."); // Nope return; } // Accepted @@ -236,10 +245,7 @@ void Client::handleMsg() if (genSha1(&serverApp->sessionNameArray(), &_challenge) != hash && !(serverApp->getCurrentRoom()->clientPositions.contains(_socket->peerAddress().toString()))) { // Challenge reply is invalid, drop client - NetworkMessage msgErr; - msgErr.buildErrorMessage("Challenge reply invalid."); - msgErr.writeMessage(_socket); - this->disconnect(); + this->disconnect("Challenge reply invalid."); return; } // Now answer to challenge by client @@ -302,7 +308,7 @@ void Client::stopVncClient() * Checks if client and manager runs on same machine. * @return Return true, if pvsmanager is running on client. */ -bool Client::isManagerMachine() +bool Client::isManagerMachine() const { foreach (const QHostAddress & address, QNetworkInterface::allAddresses()) if (address != QHostAddress(QHostAddress::LocalHost) @@ -326,11 +332,21 @@ void Client::lockScreen(bool lock) emit stateChanged(); } -void Client::disconnect() +void Client::disconnect(const char *errmsg) { - qDebug("*** Client %s disconnected.", qPrintable(_socket->peerAddress().toString())); + qDebug() << "*** Client" << _socket->peerAddress().toString() << "disconnected:" << errmsg; + if (_socket->state() == QAbstractSocket::ConnectedState) { + NetworkMessage msgErr; + msgErr.buildErrorMessage(errmsg); + msgErr.writeMessage(_socket); + _socket->flush(); + } _socket->blockSignals(true); - _socket->abort(); this->deleteLater(); emit disconnected(); } + +QString Client::ip() const +{ + return _socket->peerAddress().toString(); +} |