summaryrefslogtreecommitdiffstats
path: root/src/server/net/client.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/server/net/client.cpp')
-rw-r--r--src/server/net/client.cpp90
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();
+}