diff options
| author | Jeremy Lainé <jeremy.laine@m4x.org> | 2012-09-17 12:18:00 +0200 |
|---|---|---|
| committer | Jeremy Lainé <jeremy.laine@m4x.org> | 2012-09-17 12:18:00 +0200 |
| commit | 50e054649befa753d5b41256a67b54d5d9d92256 (patch) | |
| tree | 97aa15f6c2bd70ad3ec95756fedbdc179d66e6e0 /src/server/QXmppServer.cpp | |
| parent | 7b3f1ebe5b11f74f85721870b72f89157b9a79b9 (diff) | |
Enable multiple calls to QXmppServer::listenFor(Clients|Servers)
Make it possible to call listenForClients and listenForServers
multiple times to supported multiple IP address / ports.
Diffstat (limited to 'src/server/QXmppServer.cpp')
| -rw-r--r-- | src/server/QXmppServer.cpp | 118 |
1 files changed, 83 insertions, 35 deletions
diff --git a/src/server/QXmppServer.cpp b/src/server/QXmppServer.cpp index 57f55119..0dd66066 100644 --- a/src/server/QXmppServer.cpp +++ b/src/server/QXmppServer.cpp @@ -89,15 +89,20 @@ public: QXmppPasswordChecker *passwordChecker; // client-to-server - QXmppSslServer *serverForClients; QSet<QXmppIncomingClient*> incomingClients; QHash<QString, QXmppIncomingClient*> incomingClientsByJid; QHash<QString, QSet<QXmppIncomingClient*> > incomingClientsByBareJid; + QSet<QXmppSslServer*> serversForClients; // server-to-server QSet<QXmppIncomingServer*> incomingServers; QSet<QXmppOutgoingServer*> outgoingServers; - QXmppSslServer *serverForServers; + QSet<QXmppSslServer*> serversForServers; + + // ssl + QList<QSslCertificate> caCertificates; + QSslCertificate localCertificate; + QSslKey privateKey; private: bool loaded; @@ -145,7 +150,7 @@ bool QXmppServerPrivate::routeData(const QString &to, const QByteArray &data) QMetaObject::invokeMethod(conn, "sendData", Q_ARG(QByteArray, data)); return !found.isEmpty(); - } else if (serverForServers->isListening()) { + } else if (!serversForServers.isEmpty()) { bool check; Q_UNUSED(check); @@ -302,22 +307,9 @@ void QXmppServerPrivate::stopExtensions() QXmppServer::QXmppServer(QObject *parent) : QXmppLoggable(parent) + , d(new QXmppServerPrivate(this)) { - bool check; - Q_UNUSED(check); - qRegisterMetaType<QDomElement>("QDomElement"); - - d = new QXmppServerPrivate(this); - d->serverForClients = new QXmppSslServer(this); - check = connect(d->serverForClients, SIGNAL(newConnection(QSslSocket*)), - this, SLOT(_q_clientConnection(QSslSocket*))); - Q_ASSERT(check); - - d->serverForServers = new QXmppSslServer(this); - check = connect(d->serverForServers, SIGNAL(newConnection(QSslSocket*)), - this, SLOT(_q_serverConnection(QSslSocket*))); - Q_ASSERT(check); } /// Destroys an XMPP server instance. @@ -452,11 +444,19 @@ QVariantMap QXmppServer::statistics() const void QXmppServer::addCaCertificates(const QString &path) { - if (!path.isEmpty() && !QFileInfo(path).isReadable()) + // load certificates + if (path.isEmpty()) { + d->caCertificates = QList<QSslCertificate>(); + } else if (QFileInfo(path).isReadable()) { + d->caCertificates = QSslCertificate::fromPath(path); + } else { d->warning(QString("SSL CA certificates are not readable %1").arg(path)); - QList<QSslCertificate> certificates = QSslCertificate::fromPath(path); - d->serverForClients->addCaCertificates(certificates); - d->serverForServers->addCaCertificates(certificates); + d->caCertificates = QList<QSslCertificate>(); + } + + // reconfigure servers + foreach (QXmppSslServer *server, d->serversForClients + d->serversForServers) + server->addCaCertificates(d->caCertificates); } /// Sets the path for the local SSL certificate. @@ -465,14 +465,21 @@ void QXmppServer::addCaCertificates(const QString &path) void QXmppServer::setLocalCertificate(const QString &path) { + // load certificate QSslCertificate certificate; QFile file(path); - if (!path.isEmpty() && file.open(QIODevice::ReadOnly | QIODevice::Text)) - certificate = QSslCertificate(file.readAll()); - else + if (path.isEmpty()) { + d->localCertificate = QSslCertificate(); + } else if (file.open(QIODevice::ReadOnly | QIODevice::Text)) { + d->localCertificate = QSslCertificate(file.readAll()); + } else { d->warning(QString("SSL certificate is not readable %1").arg(path)); - d->serverForClients->setLocalCertificate(certificate); - d->serverForServers->setLocalCertificate(certificate); + d->localCertificate = QSslCertificate(); + } + + // reconfigure servers + foreach (QXmppSslServer *server, d->serversForClients + d->serversForServers) + server->setLocalCertificate(d->localCertificate); } /// Sets the path for the local SSL private key. @@ -481,14 +488,21 @@ void QXmppServer::setLocalCertificate(const QString &path) void QXmppServer::setPrivateKey(const QString &path) { + // load key QSslKey key; QFile file(path); - if (!path.isEmpty() && file.open(QIODevice::ReadOnly)) - key = QSslKey(file.readAll(), QSsl::Rsa); - else + if (path.isEmpty()) { + d->privateKey = QSslKey(); + } else if (file.open(QIODevice::ReadOnly)) { + d->privateKey = QSslKey(file.readAll(), QSsl::Rsa); + } else { d->warning(QString("SSL key is not readable %1").arg(path)); - d->serverForClients->setPrivateKey(key); - d->serverForServers->setPrivateKey(key); + d->privateKey = QSslKey(); + } + + // reconfigure servers + foreach (QXmppSslServer *server, d->serversForClients + d->serversForServers) + server->setPrivateKey(d->privateKey); } /// Listen for incoming XMPP client connections. @@ -498,15 +512,30 @@ void QXmppServer::setPrivateKey(const QString &path) bool QXmppServer::listenForClients(const QHostAddress &address, quint16 port) { + bool check; + Q_UNUSED(check); + if (d->domain.isEmpty()) { d->warning("No domain was specified!"); return false; } - if (!d->serverForClients->listen(address, port)) { + // create new server + QXmppSslServer *server = new QXmppSslServer(this); + server->addCaCertificates(d->caCertificates); + server->setLocalCertificate(d->localCertificate); + server->setPrivateKey(d->privateKey); + + check = connect(server, SIGNAL(newConnection(QSslSocket*)), + this, SLOT(_q_clientConnection(QSslSocket*))); + Q_ASSERT(check); + + if (!server->listen(address, port)) { d->warning(QString("Could not start listening for C2S on port %1").arg(QString::number(port))); + delete server; return false; } + d->serversForClients.insert(server); // start extensions d->loadExtensions(this); @@ -520,8 +549,12 @@ bool QXmppServer::listenForClients(const QHostAddress &address, quint16 port) void QXmppServer::close() { // prevent new connections - d->serverForClients->close(); - d->serverForServers->close(); + foreach (QXmppSslServer *server, d->serversForClients + d->serversForServers) { + server->close(); + delete server; + } + d->serversForClients.clear(); + d->serversForServers.clear(); // stop extensions d->stopExtensions(); @@ -542,15 +575,30 @@ void QXmppServer::close() bool QXmppServer::listenForServers(const QHostAddress &address, quint16 port) { + bool check; + Q_UNUSED(check); + if (d->domain.isEmpty()) { d->warning("No domain was specified!"); return false; } - if (!d->serverForServers->listen(address, port)) { + // create new server + QXmppSslServer *server = new QXmppSslServer(this); + server->addCaCertificates(d->caCertificates); + server->setLocalCertificate(d->localCertificate); + server->setPrivateKey(d->privateKey); + + check = connect(server, SIGNAL(newConnection(QSslSocket*)), + this, SLOT(_q_serverConnection(QSslSocket*))); + Q_ASSERT(check); + + if (!server->listen(address, port)) { d->warning(QString("Could not start listening for S2S on port %1").arg(QString::number(port))); + delete server; return false; } + d->serversForServers.insert(server); // start extensions d->loadExtensions(this); |
