aboutsummaryrefslogtreecommitdiff
path: root/src/server
diff options
context:
space:
mode:
authorJeremy Lainé <jeremy.laine@m4x.org>2011-09-13 12:08:15 +0000
committerJeremy Lainé <jeremy.laine@m4x.org>2011-09-13 12:08:15 +0000
commit8eaf6c3def32f1aa07fe863d5eab69f44672b3a5 (patch)
treee6950f5dbceeb0e34ac98f7639a63049f8cf7c44 /src/server
parent5d6e2cabfb730fa6b537397db342bed8eec15de1 (diff)
* hide some QXmppServer internals
* improve QXmppServer performance
Diffstat (limited to 'src/server')
-rw-r--r--src/server/mod_disco.cpp4
-rw-r--r--src/server/mod_disco.h2
-rw-r--r--src/server/mod_ping.cpp4
-rw-r--r--src/server/mod_ping.h2
-rw-r--r--src/server/mod_presence.cpp267
-rw-r--r--src/server/mod_presence.h60
-rw-r--r--src/server/mod_proxy65.cpp56
-rw-r--r--src/server/mod_proxy65.h6
-rw-r--r--src/server/mod_stats.cpp57
-rw-r--r--src/server/mod_stats.h6
-rw-r--r--src/server/mod_time.cpp4
-rw-r--r--src/server/mod_time.h2
-rw-r--r--src/server/mod_version.cpp4
-rw-r--r--src/server/mod_version.h2
14 files changed, 391 insertions, 85 deletions
diff --git a/src/server/mod_disco.cpp b/src/server/mod_disco.cpp
index 715511c8..61caf5dc 100644
--- a/src/server/mod_disco.cpp
+++ b/src/server/mod_disco.cpp
@@ -52,10 +52,8 @@ QStringList QXmppServerDiscovery::discoveryItems() const
return m_discoveryItems;
}
-bool QXmppServerDiscovery::handleStanza(QXmppStream *stream, const QDomElement &element)
+bool QXmppServerDiscovery::handleStanza(const QDomElement &element)
{
- Q_UNUSED(stream);
-
if (element.attribute("to") != server()->domain())
return false;
diff --git a/src/server/mod_disco.h b/src/server/mod_disco.h
index 1a0e00c6..41791cf7 100644
--- a/src/server/mod_disco.h
+++ b/src/server/mod_disco.h
@@ -44,7 +44,7 @@ public:
/// \cond
QStringList discoveryFeatures() const;
QStringList discoveryItems() const;
- bool handleStanza(QXmppStream *stream, const QDomElement &element);
+ bool handleStanza(const QDomElement &element);
/// \endcond
private:
diff --git a/src/server/mod_ping.cpp b/src/server/mod_ping.cpp
index 96fb55d9..36622b07 100644
--- a/src/server/mod_ping.cpp
+++ b/src/server/mod_ping.cpp
@@ -36,10 +36,8 @@ QStringList QXmppServerPing::discoveryFeatures() const
return QStringList() << ns_ping;
}
-bool QXmppServerPing::handleStanza(QXmppStream *stream, const QDomElement &element)
+bool QXmppServerPing::handleStanza(const QDomElement &element)
{
- Q_UNUSED(stream);
-
if (element.attribute("to") != server()->domain())
return false;
diff --git a/src/server/mod_ping.h b/src/server/mod_ping.h
index 567cc489..960c17f6 100644
--- a/src/server/mod_ping.h
+++ b/src/server/mod_ping.h
@@ -36,7 +36,7 @@ class QXmppServerPing : public QXmppServerExtension
public:
QStringList discoveryFeatures() const;
- bool handleStanza(QXmppStream *stream, const QDomElement &element);
+ bool handleStanza(const QDomElement &element);
};
#endif
diff --git a/src/server/mod_presence.cpp b/src/server/mod_presence.cpp
new file mode 100644
index 00000000..33e7aa26
--- /dev/null
+++ b/src/server/mod_presence.cpp
@@ -0,0 +1,267 @@
+/*
+ * Copyright (C) 2008-2011 The QXmpp developers
+ *
+ * Author:
+ * Jeremy Lainé
+ *
+ * Source:
+ * http://code.google.com/p/qxmpp
+ *
+ * This file is a part of QXmpp library.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ */
+
+#include <QDomElement>
+
+#include "QXmppConstants.h"
+#include "QXmppPresence.h"
+#include "QXmppServer.h"
+#include "QXmppServerPlugin.h"
+#include "QXmppStream.h"
+#include "QXmppUtils.h"
+
+#include "mod_presence.h"
+
+class QXmppServerPresencePrivate
+{
+public:
+ QXmppServerPresencePrivate(QXmppServerPresence *qq);
+
+ QSet<QString> collectSubscribers(const QString &jid);
+ QSet<QString> collectSubscriptions(const QString &jid);
+
+ QHash<QString, QHash<QString, QXmppPresence> > presences;
+ QHash<QString, QSet<QString> > subscribers;
+
+private:
+ QXmppServerPresence *q;
+};
+
+QXmppServerPresencePrivate::QXmppServerPresencePrivate(QXmppServerPresence *qq)
+ : q(qq)
+{
+}
+
+/// Collect subscribers from the extensions.
+///
+/// \param jid
+
+QSet<QString> QXmppServerPresencePrivate::collectSubscribers(const QString &jid)
+{
+ QSet<QString> recipients;
+ foreach (QXmppServerExtension *extension, q->server()->extensions())
+ recipients += extension->presenceSubscribers(jid);
+ return recipients;
+}
+
+/// Collect subscriptions from the extensions.
+///
+/// \param jid
+
+QSet<QString> QXmppServerPresencePrivate::collectSubscriptions(const QString &jid)
+{
+ QSet<QString> recipients;
+ foreach (QXmppServerExtension *extension, q->server()->extensions())
+ recipients += extension->presenceSubscriptions(jid);
+ return recipients;
+}
+
+QXmppServerPresence::QXmppServerPresence()
+{
+ d = new QXmppServerPresencePrivate(this);
+}
+
+QXmppServerPresence::~QXmppServerPresence()
+{
+ delete d;
+}
+
+/// Returns the list of available resources for the given local JID.
+///
+/// \param bareJid
+
+QList<QXmppPresence> QXmppServerPresence::availablePresences(const QString &bareJid) const
+{
+ return d->presences.value(bareJid).values();
+}
+
+bool QXmppServerPresence::handleStanza(const QDomElement &element)
+{
+ if (element.tagName() != QLatin1String("presence"))
+ return false;
+
+ const QString domain = server()->domain();
+ const QString from = element.attribute("from");
+ const QString type = element.attribute("type");
+ const QString to = element.attribute("to");
+
+ if (to == domain) {
+ // presence to the local domain
+
+ // we only want available or unavailable presences from local users
+ if ((!type.isEmpty() && type != QLatin1String("unavailable"))
+ || (jidToDomain(from) != domain))
+ return true;
+
+ const QString bareFrom = jidToBareJid(from);
+ bool isInitial = false;
+
+ if (type.isEmpty()) {
+ QXmppPresence presence;
+ presence.parse(element);
+
+ // record the presence for future use
+ isInitial = !d->presences.value(bareFrom).contains(from);
+ d->presences[bareFrom][from] = presence;
+ } else {
+ d->presences[bareFrom].remove(from);
+ if (d->presences[bareFrom].isEmpty())
+ d->presences.remove(bareFrom);
+ }
+
+ // broadcast it to subscribers
+ foreach (const QString &subscriber, d->collectSubscribers(from)) {
+ // avoid loop
+ if (subscriber == to)
+ continue;
+ QDomElement changed = element.cloneNode(true).toElement();
+ changed.setAttribute("to", subscriber);
+ server()->handleElement(changed);
+ }
+
+ // get presences from subscriptions
+ if (isInitial) {
+ foreach (const QString &subscription, d->collectSubscriptions(from)) {
+ if (jidToDomain(subscription) != domain) {
+ QXmppPresence probe;
+ probe.setType(QXmppPresence::Probe);
+ probe.setFrom(from);
+ probe.setTo(subscription);
+ server()->sendPacket(probe);
+ } else {
+ QXmppPresence push;
+ foreach (push, availablePresences(subscription)) {
+ push.setTo(from);
+ server()->sendPacket(push);
+ }
+ }
+ }
+ }
+
+ // the presence was for us, stop here
+ return true;
+ } else {
+ // directed presence
+ if ((type.isEmpty() || type == QLatin1String("unavailable")) && jidToDomain(from) == domain) {
+ // available or unavailable presence from local user
+ if (type.isEmpty())
+ d->subscribers[from].insert(to);
+ else {
+ d->subscribers[from].remove(to);
+ if (d->subscribers[from].isEmpty())
+ d->subscribers.remove(from);
+ }
+ } else if (type == QLatin1String("error") && jidToDomain(to) == domain) {
+ // error presence to a local user
+ d->subscribers[to].remove(from);
+ if (d->subscribers[to].isEmpty())
+ d->subscribers.remove(to);
+ }
+
+ // the presence was not for us
+ return false;
+ }
+}
+
+QSet<QString> QXmppServerPresence::presenceSubscribers(const QString &jid)
+{
+ return d->subscribers.value(jid);
+}
+
+QXmppServerPresence* QXmppServerPresence::instance(QXmppServer *server)
+{
+ foreach (QXmppServerExtension *extension, server->extensions()) {
+ QXmppServerPresence *presenceExtension = qobject_cast<QXmppServerPresence*>(extension);
+ if (presenceExtension)
+ return presenceExtension;
+ }
+ return 0;
+}
+
+bool QXmppServerPresence::start()
+{
+ bool check;
+ Q_UNUSED(check);
+
+ check = connect(server(), SIGNAL(clientDisconnected(QString)),
+ this, SLOT(_q_clientDisconnected(QString)));
+ Q_ASSERT(check);
+
+ return true;
+}
+
+void QXmppServerPresence::stop()
+{
+ disconnect(server(), SIGNAL(clientDisconnected(QString)),
+ this, SLOT(_q_clientDisconnected(QString)));
+}
+
+void QXmppServerPresence::_q_clientDisconnected(const QString &jid)
+{
+ Q_ASSERT(!jid.isEmpty());
+
+ // check the user exited cleanly
+ const bool hadPresence = d->presences.value(jidToBareJid(jid)).contains(jid);
+ if (hadPresence) {
+ // the client had sent an initial available presence but did
+ // not sent an unavailable presence, synthesize it
+ QDomDocument doc;
+ QDomElement presence = doc.createElement("presence");
+ presence.setAttribute("from", jid);
+ presence.setAttribute("type", "unavailable");
+ presence.setAttribute("to", server()->domain());
+ server()->handleElement(presence);
+ } else {
+ // synthesize unavailable presence to directed presence receivers
+ foreach (const QString &recipient, presenceSubscribers(jid)) {
+ QDomDocument doc;
+ QDomElement presence = doc.createElement("presence");
+ presence.setAttribute("from", jid);
+ presence.setAttribute("type", "unavailable");
+ presence.setAttribute("to", recipient);
+ server()->handleElement(presence);
+ }
+ }
+}
+
+// PLUGIN
+
+class QXmppServerPresencePlugin : public QXmppServerPlugin
+{
+public:
+ QXmppServerExtension *create(const QString &key)
+ {
+ if (key == QLatin1String("presence"))
+ return new QXmppServerPresence;
+ else
+ return 0;
+ };
+
+ QStringList keys() const
+ {
+ return QStringList() << QLatin1String("presence");
+ };
+};
+
+Q_EXPORT_STATIC_PLUGIN2(mod_presence, QXmppServerPresencePlugin)
+
diff --git a/src/server/mod_presence.h b/src/server/mod_presence.h
new file mode 100644
index 00000000..4424f17d
--- /dev/null
+++ b/src/server/mod_presence.h
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2008-2011 The QXmpp developers
+ *
+ * Author:
+ * Jeremy Lainé
+ *
+ * Source:
+ * http://code.google.com/p/qxmpp
+ *
+ * This file is a part of QXmpp library.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ */
+
+#ifndef QXMPP_SERVER_PRESENCE_H
+#define QXMPP_SERVER_PRESENCE_H
+
+#include "QXmppServerExtension.h"
+
+class QXmppPresence;
+class QXmppServerPresencePrivate;
+
+/// \brief QXmppServer extension for presence handling.
+///
+
+class QXmppServerPresence : public QXmppServerExtension
+{
+ Q_OBJECT
+ Q_CLASSINFO("ExtensionName", "presence");
+
+public:
+ QXmppServerPresence();
+ ~QXmppServerPresence();
+
+ QList<QXmppPresence> availablePresences(const QString &bareJid) const;
+ bool handleStanza(const QDomElement &element);
+ QSet<QString> presenceSubscribers(const QString &jid);
+ bool start();
+ void stop();
+
+ static QXmppServerPresence* instance(QXmppServer *server);
+
+private slots:
+ void _q_clientDisconnected(const QString &jid);
+
+private:
+ friend class QXmppServerPresencePrivate;
+ QXmppServerPresencePrivate *d;
+};
+
+#endif
diff --git a/src/server/mod_proxy65.cpp b/src/server/mod_proxy65.cpp
index 9562eae4..374adc79 100644
--- a/src/server/mod_proxy65.cpp
+++ b/src/server/mod_proxy65.cpp
@@ -160,14 +160,15 @@ class QXmppServerProxy65Private
{
public:
// configuration
+ QString advertisedName;
+ QHostAddress advertisedAddress;
QStringList allowedDomains;
QString jid;
- QHostAddress hostAddress;
QString hostName;
quint16 port;
// state
- QMap<QString, QTcpSocketPair*> pairs;
+ QHash<QString, QTcpSocketPair*> pairs;
QXmppSocksServer *server;
// statistics
@@ -205,6 +206,26 @@ QXmppServerProxy65::~QXmppServerProxy65()
delete d;
}
+/// Returns the host which is advertised to clients for SOCKS5 connections.
+///
+/// You should only care about this if the host which the clients will see is
+/// different from \a host().
+
+QString QXmppServerProxy65::advertisedHost() const
+{
+ return d->advertisedName;
+}
+
+/// Sets the host which is advertised to clients for SOCKS5 connections.
+///
+/// You should only care about this if the host which the clients will see is
+/// different from \a host().
+
+void QXmppServerProxy65::setAdvertisedHost(const QString &advertisedHost)
+{
+ d->advertisedName = advertisedHost;
+}
+
/// Returns the XMPP domains which are allowed to use the proxy.
///
@@ -284,10 +305,8 @@ QStringList QXmppServerProxy65::discoveryItems() const
return QStringList() << d->jid;
}
-bool QXmppServerProxy65::handleStanza(QXmppStream *stream, const QDomElement &element)
+bool QXmppServerProxy65::handleStanza(const QDomElement &element)
{
- Q_UNUSED(stream);
-
if (element.attribute("to") != d->jid)
return false;
@@ -341,7 +360,7 @@ bool QXmppServerProxy65::handleStanza(QXmppStream *stream, const QDomElement &el
QXmppByteStreamIq::StreamHost streamHost;
streamHost.setJid(d->jid);
- streamHost.setHost(d->hostAddress);
+ streamHost.setHost(d->advertisedAddress);
streamHost.setPort(d->port);
streamHosts.append(streamHost);
@@ -389,10 +408,11 @@ bool QXmppServerProxy65::start()
if (d->jid.isEmpty())
d->jid = "proxy." + server()->domain();
- // determine address
+ // determine bind address
if (d->hostName.isEmpty())
d->hostName = server()->domain();
- if (!d->hostAddress.setAddress(d->hostName))
+ QHostAddress bindAddress;
+ if (!bindAddress.setAddress(d->hostName))
{
QHostInfo hostInfo = QHostInfo::fromName(d->hostName);
if (hostInfo.addresses().isEmpty())
@@ -400,11 +420,27 @@ bool QXmppServerProxy65::start()
warning(QString("Could not lookup host %1").arg(d->hostName));
return false;
}
- d->hostAddress = hostInfo.addresses().first();
+ bindAddress = hostInfo.addresses().first();
+ }
+
+ // determine advertised address
+ if (d->advertisedName.isEmpty()) {
+ d->advertisedName = d->hostName;
+ d->advertisedAddress = bindAddress;
+ }
+ else if (!d->advertisedAddress.setAddress(d->advertisedName))
+ {
+ QHostInfo hostInfo = QHostInfo::fromName(d->advertisedName);
+ if (hostInfo.addresses().isEmpty())
+ {
+ warning(QString("Could not lookup host %1").arg(d->hostName));
+ return false;
+ }
+ d->advertisedAddress = hostInfo.addresses().first();
}
// start listening
- if (!d->server->listen(d->hostAddress, d->port))
+ if (!d->server->listen(bindAddress, d->port))
return false;
// start statistics update
diff --git a/src/server/mod_proxy65.h b/src/server/mod_proxy65.h
index 308725f4..e891963b 100644
--- a/src/server/mod_proxy65.h
+++ b/src/server/mod_proxy65.h
@@ -66,6 +66,7 @@ class QXmppServerProxy65 : public QXmppServerExtension
{
Q_OBJECT
Q_CLASSINFO("ExtensionName", "proxy65");
+ Q_PROPERTY(QString advertisedHost READ advertisedHost WRITE setAdvertisedHost);
Q_PROPERTY(QStringList allowedDomains READ allowedDomains WRITE setAllowedDomains);
Q_PROPERTY(QString jid READ jid WRITE setJid);
Q_PROPERTY(QString host READ host WRITE setHost);
@@ -75,6 +76,9 @@ public:
QXmppServerProxy65();
~QXmppServerProxy65();
+ QString advertisedHost() const;
+ void setAdvertisedHost(const QString &advertisedHost);
+
QStringList allowedDomains() const;
void setAllowedDomains(const QStringList &allowedDomains);
@@ -89,7 +93,7 @@ public:
/// \cond
QStringList discoveryItems() const;
- bool handleStanza(QXmppStream *stream, const QDomElement &element);
+ bool handleStanza(const QDomElement &element);
bool start();
void stop();
QVariantMap statistics() const;
diff --git a/src/server/mod_stats.cpp b/src/server/mod_stats.cpp
index 36cea79d..357634aa 100644
--- a/src/server/mod_stats.cpp
+++ b/src/server/mod_stats.cpp
@@ -28,9 +28,6 @@
#include "QXmppConstants.h"
#include "QXmppDiscoveryIq.h"
-#include "QXmppIncomingClient.h"
-#include "QXmppIncomingServer.h"
-#include "QXmppOutgoingServer.h"
#include "QXmppServer.h"
#include "QXmppServerPlugin.h"
#include "QXmppUtils.h"
@@ -173,20 +170,13 @@ QStringList QXmppServerStats::discoveryItems() const
return QStringList() << d->jid;
}
-QVariantMap QXmppServerStats::statistics() const
+QVariantMap QXmppServerStats::statistics()
{
- QVariantMap stats;
- stats["version"] = qApp->applicationVersion();
- stats["incoming-clients"] = d->incomingClients;
- stats["incoming-servers"] = d->incomingServers;
- stats["outgoing-servers"] = d->outgoingServers;
- return stats;
+ return server()->statistics();
}
-bool QXmppServerStats::handleStanza(QXmppStream *stream, const QDomElement &element)
+bool QXmppServerStats::handleStanza(const QDomElement &element)
{
- Q_UNUSED(stream);
-
if (element.attribute("to") != d->jid)
return false;
@@ -280,21 +270,10 @@ bool QXmppServerStats::handleStanza(QXmppStream *stream, const QDomElement &elem
bool QXmppServerStats::start()
{
- bool check;
- Q_UNUSED(check);
-
// determine jid
if (d->jid.isEmpty())
d->jid = "statistics." + server()->domain();
- check = connect(server(), SIGNAL(streamAdded(QXmppStream*)),
- this, SLOT(streamAdded(QXmppStream*)));
- Q_ASSERT(check);
-
- check = connect(server(), SIGNAL(streamRemoved(QXmppStream*)),
- this, SLOT(streamRemoved(QXmppStream*)));
- Q_ASSERT(check);
-
d->statisticsTimer->start();
return true;
@@ -303,36 +282,6 @@ bool QXmppServerStats::start()
void QXmppServerStats::stop()
{
d->statisticsTimer->stop();
-
- disconnect(server(), SIGNAL(streamAdded(QXmppStream*)),
- this, SLOT(streamAdded(QXmppStream*)));
-
- disconnect(server(), SIGNAL(streamRemoved(QXmppStream*)),
- this, SLOT(streamRemoved(QXmppStream*)));
-}
-
-void QXmppServerStats::streamAdded(QXmppStream *stream)
-{
- if (qobject_cast<QXmppIncomingClient*>(stream))
- d->incomingClients++;
- else if (qobject_cast<QXmppIncomingServer*>(stream))
- d->incomingServers++;
- else if (qobject_cast<QXmppOutgoingServer*>(stream))
- d->outgoingServers++;
- else
- return;
-}
-
-void QXmppServerStats::streamRemoved(QXmppStream *stream)
-{
- if (qobject_cast<QXmppIncomingClient*>(stream))
- d->incomingClients--;
- else if (qobject_cast<QXmppIncomingServer*>(stream))
- d->incomingServers--;
- else if (qobject_cast<QXmppOutgoingServer*>(stream))
- d->outgoingServers--;
- else
- return;
}
// PLUGIN
diff --git a/src/server/mod_stats.h b/src/server/mod_stats.h
index d53d60a5..6eff688f 100644
--- a/src/server/mod_stats.h
+++ b/src/server/mod_stats.h
@@ -51,15 +51,13 @@ public:
/// cond
QStringList discoveryItems() const;
- bool handleStanza(QXmppStream *stream, const QDomElement &element);
- QVariantMap statistics() const;
+ bool handleStanza(const QDomElement &element);
+ QVariantMap statistics();
bool start();
void stop();
/// \endcond
private slots:
- void streamAdded(QXmppStream *stream);
- void streamRemoved(QXmppStream *stream);
void writeStatistics();
private:
diff --git a/src/server/mod_time.cpp b/src/server/mod_time.cpp
index 0523eaf0..ec535662 100644
--- a/src/server/mod_time.cpp
+++ b/src/server/mod_time.cpp
@@ -37,10 +37,8 @@ QStringList QXmppServerTime::discoveryFeatures() const
return QStringList() << ns_entity_time;
}
-bool QXmppServerTime::handleStanza(QXmppStream *stream, const QDomElement &element)
+bool QXmppServerTime::handleStanza(const QDomElement &element)
{
- Q_UNUSED(stream);
-
if (element.attribute("to") != server()->domain())
return false;
diff --git a/src/server/mod_time.h b/src/server/mod_time.h
index ecc94b90..2935ac49 100644
--- a/src/server/mod_time.h
+++ b/src/server/mod_time.h
@@ -36,7 +36,7 @@ class QXmppServerTime : public QXmppServerExtension
public:
QStringList discoveryFeatures() const;
- bool handleStanza(QXmppStream *stream, const QDomElement &element);
+ bool handleStanza(const QDomElement &element);
};
#endif
diff --git a/src/server/mod_version.cpp b/src/server/mod_version.cpp
index ec069e0f..500bd173 100644
--- a/src/server/mod_version.cpp
+++ b/src/server/mod_version.cpp
@@ -37,10 +37,8 @@ QStringList QXmppServerVersion::discoveryFeatures() const
return QStringList() << ns_version;
}
-bool QXmppServerVersion::handleStanza(QXmppStream *stream, const QDomElement &element)
+bool QXmppServerVersion::handleStanza(const QDomElement &element)
{
- Q_UNUSED(stream);
-
if (element.attribute("to") != server()->domain())
return false;
diff --git a/src/server/mod_version.h b/src/server/mod_version.h
index d88cbd5b..4dd1ace7 100644
--- a/src/server/mod_version.h
+++ b/src/server/mod_version.h
@@ -36,7 +36,7 @@ class QXmppServerVersion : public QXmppServerExtension
public:
QStringList discoveryFeatures() const;
- bool handleStanza(QXmppStream *stream, const QDomElement &element);
+ bool handleStanza(const QDomElement &element);
};
#endif