aboutsummaryrefslogtreecommitdiff
path: root/src/server
diff options
context:
space:
mode:
authorJeremy Lainé <jeremy.laine@m4x.org>2012-09-17 12:18:00 +0200
committerJeremy Lainé <jeremy.laine@m4x.org>2012-09-17 12:18:00 +0200
commit50e054649befa753d5b41256a67b54d5d9d92256 (patch)
tree97aa15f6c2bd70ad3ec95756fedbdc179d66e6e0 /src/server
parent7b3f1ebe5b11f74f85721870b72f89157b9a79b9 (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')
-rw-r--r--src/server/QXmppServer.cpp118
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);