From 50e53fbe5395ef698d1ca78ac6308533dd3c6c15 Mon Sep 17 00:00:00 2001 From: Max-Wilhelm Bruker Date: Sun, 26 Feb 2012 21:00:05 +0100 Subject: [PATCH] initial commit for server network support --- servatrice/src/main.cpp | 9 +++++- servatrice/src/servatrice.cpp | 56 +++++++++++++++++++++++++++++++---- servatrice/src/servatrice.h | 22 ++++++++++++-- 3 files changed, 77 insertions(+), 10 deletions(-) diff --git a/servatrice/src/main.cpp b/servatrice/src/main.cpp index a0e1e26b..026aae1b 100644 --- a/servatrice/src/main.cpp +++ b/servatrice/src/main.cpp @@ -87,6 +87,12 @@ void myMessageOutput(QtMsgType /*type*/, const char *msg) logger->logMessage(msg); } +void myMessageOutput2(QtMsgType /*type*/, const char *msg) +{ + logger->logMessage(msg); + std::cerr << msg << std::endl; +} + #ifdef Q_OS_UNIX void sigSegvHandler(int sig) { @@ -120,7 +126,7 @@ int main(int argc, char *argv[]) loggerThread->waitForInit(); logger = loggerThread->getLogger(); - qInstallMsgHandler(myMessageOutput); + qInstallMsgHandler(myMessageOutput2); #ifdef Q_OS_UNIX struct sigaction hup; hup.sa_handler = ServerLogger::hupSignalHandler; @@ -152,6 +158,7 @@ int main(int argc, char *argv[]) std::cerr << "-------------------------" << std::endl; std::cerr << "Server initialized." << std::endl; + qInstallMsgHandler(myMessageOutput); int retval = app.exec(); std::cerr << "Server quit." << std::endl; diff --git a/servatrice/src/servatrice.cpp b/servatrice/src/servatrice.cpp index b0c07f6f..246f4272 100644 --- a/servatrice/src/servatrice.cpp +++ b/servatrice/src/servatrice.cpp @@ -21,6 +21,7 @@ #include #include #include +#include #include "servatrice.h" #include "server_room.h" #include "serversocketinterface.h" @@ -33,7 +34,7 @@ #include "pb/event_server_shutdown.pb.h" #include "pb/event_connection_closed.pb.h" -void Servatrice_TcpServer::incomingConnection(int socketDescriptor) +void Servatrice_GameServer::incomingConnection(int socketDescriptor) { if (threaded) { ServerSocketThread *sst = new ServerSocketThread(socketDescriptor, server, this); @@ -46,6 +47,17 @@ void Servatrice_TcpServer::incomingConnection(int socketDescriptor) } } +void Servatrice_NetworkServer::incomingConnection(int socketDescriptor) +{ + QSslSocket *socket = new QSslSocket; + socket->setLocalCertificate(cert); + socket->setPrivateKey(privateKey); + socket->setSocketDescriptor(socketDescriptor); + socket->startServerEncryption(); +// SocketInterface *ssi = new ServerSocketInterface(server, socket); +// logger->logMessage(QString("Incoming server network connection: %1").arg(socket->peerAddress().toString()), ssi); +} + Servatrice::Servatrice(QSettings *_settings, QObject *parent) : Server(parent), dbMutex(QMutex::Recursive), settings(_settings), uptime(0), shutdownTimer(0) { @@ -64,13 +76,13 @@ Servatrice::Servatrice(QSettings *_settings, QObject *parent) } threaded = settings->value("server/threaded", false).toInt(); - tcpServer = new Servatrice_TcpServer(this, threaded, this); - int port = settings->value("server/port", 4747).toInt(); - qDebug() << "Starting server on port" << port; - if (tcpServer->listen(QHostAddress::Any, port)) + gameServer = new Servatrice_GameServer(this, threaded, this); + const int gamePort = settings->value("server/port", 4747).toInt(); + qDebug() << "Starting server on port" << gamePort; + if (gameServer->listen(QHostAddress::Any, gamePort)) qDebug() << "Server listening."; else - qDebug() << "tcpServer->listen(): Error."; + qDebug() << "gameServer->listen(): Error."; const QString authenticationMethodStr = settings->value("authentication/method").toString(); if (authenticationMethodStr == "sql") @@ -87,6 +99,38 @@ Servatrice::Servatrice(QSettings *_settings, QObject *parent) if (databaseType != DatabaseNone) openDatabase(); + try { if (settings->value("servernetwork/active", 0).toInt()) { + qDebug() << "Connecting to server network."; + const QString certFileName = settings->value("servernetwork/ssl_cert").toString(); + const QString keyFileName = settings->value("servernetwork/ssl_key").toString(); + const QString passphrase = settings->value("servernetwork/ssl_passphrase").toString(); + qDebug() << "Loading certificate..."; + QFile certFile(certFileName); + if (!certFile.open(QIODevice::ReadOnly)) + throw QString("Error opening certificate file: %1").arg(certFileName); + QSslCertificate cert(&certFile); + if (!cert.isValid()) + throw(QString("Invalid certificate.")); + qDebug() << "Loading private key..."; + QFile keyFile(keyFileName); + if (!keyFile.open(QIODevice::ReadOnly)) + throw QString("Error opening private key file: %1").arg(keyFileName); + QSslKey key(&keyFile, QSsl::Rsa, QSsl::Pem, QSsl::PrivateKey, passphrase.toAscii()); + if (key.isNull()) + throw QString("Invalid private key."); + + const int networkPort = settings->value("servernetwork/port", 14747).toInt(); + qDebug() << "Starting network server on port" << networkPort; + + networkServer = new Servatrice_NetworkServer(this, cert, key, this); + if (networkServer->listen(QHostAddress::Any, networkPort)) + qDebug() << "Network server listening."; + else + throw QString("networkServer->listen(): Error."); + } } catch (QString error) { + qDebug() << "ERROR --" << error; + } + int size = settings->beginReadArray("rooms"); for (int i = 0; i < size; ++i) { settings->setArrayIndex(i); diff --git a/servatrice/src/servatrice.h b/servatrice/src/servatrice.h index 8aa84fef..780d3a9c 100644 --- a/servatrice/src/servatrice.h +++ b/servatrice/src/servatrice.h @@ -22,6 +22,8 @@ #include #include +#include +#include #include "server.h" class QSqlDatabase; @@ -33,18 +35,31 @@ class GameReplay; class Servatrice; class ServerSocketInterface; -class Servatrice_TcpServer : public QTcpServer { +class Servatrice_GameServer : public QTcpServer { Q_OBJECT private: Servatrice *server; bool threaded; public: - Servatrice_TcpServer(Servatrice *_server, bool _threaded, QObject *parent = 0) + Servatrice_GameServer(Servatrice *_server, bool _threaded, QObject *parent = 0) : QTcpServer(parent), server(_server), threaded(_threaded) { } protected: void incomingConnection(int socketDescriptor); }; +class Servatrice_NetworkServer : public QTcpServer { + Q_OBJECT +private: + Servatrice *server; + QSslCertificate cert; + QSslKey privateKey; +public: + Servatrice_NetworkServer(Servatrice *_server, const QSslCertificate &_cert, const QSslKey &_privateKey, QObject *parent = 0) + : QTcpServer(parent), server(_server), cert(_cert), privateKey(_privateKey) { } +protected: + void incomingConnection(int socketDescriptor); +}; + class Servatrice : public Server { Q_OBJECT @@ -94,7 +109,8 @@ private: AuthenticationMethod authenticationMethod; DatabaseType databaseType; QTimer *pingClock, *statusUpdateClock; - QTcpServer *tcpServer; + Servatrice_GameServer *gameServer; + Servatrice_NetworkServer *networkServer; QString serverName; QString loginMessage; QString dbPrefix;