summaryrefslogtreecommitdiffstats
path: root/src/server
diff options
context:
space:
mode:
authorSimon Rettberg2018-07-24 14:39:25 +0200
committerSimon Rettberg2018-07-24 14:39:25 +0200
commit5a2f79450f5de00dab58b41e39810a8212781828 (patch)
tree5b8c459d809b15ea63edf46c135f32114a06389c /src/server
parentUpdate code style, fix compiler warnings (diff)
downloadpvs2-5a2f79450f5de00dab58b41e39810a8212781828.tar.gz
pvs2-5a2f79450f5de00dab58b41e39810a8212781828.tar.xz
pvs2-5a2f79450f5de00dab58b41e39810a8212781828.zip
[server] Cleanup and simplify SslServer
Diffstat (limited to 'src/server')
-rw-r--r--src/server/net/sslserver.cpp102
-rw-r--r--src/server/net/sslserver.h20
2 files changed, 38 insertions, 84 deletions
diff --git a/src/server/net/sslserver.cpp b/src/server/net/sslserver.cpp
index c11f0ae..9e1e82d 100644
--- a/src/server/net/sslserver.cpp
+++ b/src/server/net/sslserver.cpp
@@ -17,17 +17,35 @@
#include "sslserver.h"
#include <QtNetwork/QSslCipher>
#include <QtNetwork/QSslSocket>
+#include <QTimer>
#include "certmanager.h"
#include <unistd.h>
-SslServer::SslServer() : QTcpServer(nullptr)
+SslServer::SslServer() : QTcpServer(nullptr), _timer(new QTimer(this))
{
- _tmr = startTimer(5123);
+ connect(_timer, &QTimer::timeout, [=]() {
+ if (_pending.empty())
+ return;
+ const qint64 deadline = QDateTime::currentSecsSinceEpoch() - 10;
+ QMutableHashIterator<QSslSocket*, qint64> it(_pending);
+ while (it.hasNext()) { // Remove lingering connections after 10s
+ it.next();
+ if (it.value() < deadline) {
+ it.key()->blockSignals(true);
+ it.key()->deleteLater();
+ it.remove();
+ }
+ }
+ });
+ _timer->start(10000);
}
SslServer::~SslServer()
{
- killTimer(_tmr);
+ _timer->stop();
+ for (QSslSocket *sock : _pending.keys()) {
+ sock->deleteLater();
+ }
}
/**
@@ -47,93 +65,37 @@ void SslServer::incomingConnection(qintptr socketDescriptor)
return;
}
QSslSocket *serverSocket = new QSslSocket(nullptr);
- connect(serverSocket, SIGNAL(sslErrors(const QList<QSslError> &)), this, SLOT(sslErrors(const QList<QSslError> &)));
- connect(serverSocket, SIGNAL(disconnected()), this, SLOT(sock_closed()));
- connect(serverSocket, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(sock_error(QAbstractSocket::SocketError)));
+ connect(serverSocket, QOverload<const QList<QSslError> &>::of(&QSslSocket::sslErrors), this, &SslServer::sslErrors);
serverSocket->setPrivateKey(key);
serverSocket->setLocalCertificate(cert);
serverSocket->setPeerVerifyMode(QSslSocket::VerifyNone);
serverSocket->setProtocol(QSsl::SecureProtocols);
if (serverSocket->setSocketDescriptor(socketDescriptor)) {
+ _pending.insert(serverSocket, QDateTime::currentSecsSinceEpoch());
// Once the connection is successfully encrypted, raise our newConnection event
connect(serverSocket, &QSslSocket::encrypted, [=]() {
- disconnect(serverSocket, SIGNAL(sslErrors(const QList<QSslError> &)), this, SLOT(sslErrors(const QList<QSslError> &)));
- disconnect(serverSocket, SIGNAL(disconnected()), this, SLOT(sock_closed()));
- disconnect(serverSocket, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(sock_error(QAbstractSocket::SocketError)));
+ serverSocket->disconnect(this);
+ if (_pending.remove(serverSocket) == 0) {
+ // Should never happen, so better log...
+ qDebug() << "Encryption event for socket that is not pending!?";
+ } else {
+ this->addPendingConnection(serverSocket);
+ emit newConnection();
+ }
});
- connect(serverSocket, SIGNAL(encrypted()), this, SIGNAL(newConnection()));
serverSocket->startServerEncryption();
- _pending.push_back(serverSocket);
} else {
qDebug() << "Failed to setSocketDescriptor on new SSL Socket";
serverSocket->deleteLater();
}
}
-void SslServer::sslErrors(const QList<QSslError>& /* errors */)
+void SslServer::sslErrors(const QList<QSslError>& errors)
{
- /*
qDebug() << "Client caused sslErrors before connection:";
for (QList<QSslError>::const_iterator it = errors.begin(); it != errors.end(); it++) {
qDebug() << it->errorString();
}
- */
-}
-
-void SslServer::sock_closed()
-{
- qDebug() << "Client closed connection before SSL handshake completed.";
- sender()->deleteLater();
-}
-
-void SslServer::sock_error(QAbstractSocket::SocketError err)
-{
- qDebug() << "Client error before SSL handshake completed: " << err;
- sender()->deleteLater();
-}
-
-void SslServer::timerEvent(QTimerEvent* /* event */ )
-{
- // Remove all sockets marked for deletion
- while (!_delete.isEmpty()) {
- QSslSocket *sock = _delete.takeFirst();
- sock->blockSignals(true);
- sock->deleteLater();
- }
- _delete = _pending;
- _pending.clear();
-}
-
-bool SslServer::hasPendingConnections() const
-{
- for (QList<QSslSocket*>::const_iterator it(_pending.begin()); it != _pending.end(); it++) {
- qDebug("State: %d - Encrypted: %d", (int)(*it)->state(), (*it)->isEncrypted());
- if ((*it)->state() == QAbstractSocket::ConnectedState && (*it)->isEncrypted())
- return true;
- }
- return false;
-}
-QTcpSocket* SslServer::nextPendingConnection()
-{
- for (QList<QSslSocket*>::iterator it(_pending.begin()); it != _pending.end(); it++) {
- if ((*it)->state() == QAbstractSocket::ConnectedState && (*it)->isEncrypted()) {
- QSslSocket *sock = *it;
- QObject::disconnect(sock, SIGNAL(encrypted()), this, SIGNAL(newConnection()));
- _pending.removeAll(sock);
- _delete.removeAll(sock);
- return sock;
- }
- }
- for (QList<QSslSocket*>::iterator it(_delete.begin()); it != _delete.end(); it++) {
- if ((*it)->state() == QAbstractSocket::ConnectedState && (*it)->isEncrypted()) {
- QSslSocket *sock = *it;
- QObject::disconnect(sock, SIGNAL(encrypted()), this, SIGNAL(newConnection()));
- _pending.removeAll(sock);
- _delete.removeAll(sock);
- return sock;
- }
- }
- return nullptr;
}
diff --git a/src/server/net/sslserver.h b/src/server/net/sslserver.h
index 6e8f26e..03d947a 100644
--- a/src/server/net/sslserver.h
+++ b/src/server/net/sslserver.h
@@ -17,11 +17,12 @@
#ifndef SSLSERVER_H_
#define SSLSERVER_H_
-#include <QtCore/QList>
+#include <QHash>
#include <QtNetwork/QTcpServer>
#include <QtNetwork/QSslError>
class QSslSocket;
+class QTimer;
/**
* Class for handling ssl server connections.
@@ -30,26 +31,17 @@ class SslServer : public QTcpServer
{
Q_OBJECT
-private Q_SLOTS:
+private slots:
void sslErrors ( const QList<QSslError> & errors );
- void sock_closed();
- void sock_error(QAbstractSocket::SocketError err);
public:
- SslServer();
+ explicit SslServer();
virtual ~SslServer();
- virtual bool hasPendingConnections () const;
- // This one has to return a TcpSocket as we're overwriting from the base class
- // just cast it to QSslSocket later
- virtual QTcpSocket* nextPendingConnection();
-
protected:
void incomingConnection(qintptr handle);
- void timerEvent(QTimerEvent* event);
- QList<QSslSocket*> _pending;
- QList<QSslSocket*> _delete;
- int _tmr;
+ QHash<QSslSocket*, qint64> _pending; // Queue for connected but unencrypted connections
+ QTimer* _timer;
};
#endif /* SSLSERVER_H_ */