aboutsummaryrefslogtreecommitdiff
path: root/src/server/mod_proxy65.cpp
diff options
context:
space:
mode:
authorJeremy Lainé <jeremy.laine@m4x.org>2012-03-26 19:12:45 +0000
committerJeremy Lainé <jeremy.laine@m4x.org>2012-03-26 19:12:45 +0000
commit494ea46f004f493b1158b545c679b8e8d80abdec (patch)
tree6936b0edb623a737e16a73fe800fc553dd2bd1fe /src/server/mod_proxy65.cpp
parent18e9af256bdd9f3c9e90fea540bdfdb8890de278 (diff)
downloadqxmpp-494ea46f004f493b1158b545c679b8e8d80abdec.tar.gz
remove some plugins, they are too specialised
Diffstat (limited to 'src/server/mod_proxy65.cpp')
-rw-r--r--src/server/mod_proxy65.cpp582
1 files changed, 0 insertions, 582 deletions
diff --git a/src/server/mod_proxy65.cpp b/src/server/mod_proxy65.cpp
deleted file mode 100644
index 374adc79..00000000
--- a/src/server/mod_proxy65.cpp
+++ /dev/null
@@ -1,582 +0,0 @@
-/*
- * 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 <QCoreApplication>
-#include <QCryptographicHash>
-#include <QDomElement>
-#include <QHostInfo>
-#include <QSettings>
-#include <QTimer>
-
-#include "QXmppByteStreamIq.h"
-#include "QXmppConfiguration.h"
-#include "QXmppConstants.h"
-#include "QXmppDiscoveryIq.h"
-#include "QXmppPingIq.h"
-#include "QXmppServer.h"
-#include "QXmppServerPlugin.h"
-#include "QXmppSocks.h"
-#include "QXmppStream.h"
-#include "QXmppUtils.h"
-
-#include "mod_proxy65.h"
-
-const int blockSize = 16384;
-
-static QString streamHash(const QString &sid, const QString &initiatorJid, const QString &targetJid)
-{
- QCryptographicHash hash(QCryptographicHash::Sha1);
- QString str = sid + initiatorJid + targetJid;
- hash.addData(str.toAscii());
- return hash.result().toHex();
-}
-
-QTcpSocketPair::QTcpSocketPair(const QString &hash, QObject *parent)
- : QXmppLoggable(parent),
- key(hash),
- transfer(0),
- target(0),
- source(0)
-{
-}
-
-bool QTcpSocketPair::activate()
-{
- if (!source || !target) {
- warning("Both source and target sockets are needed to activate " + key);
- return false;
- }
- time.start();
- connect(target, SIGNAL(bytesWritten(qint64)), this, SLOT(sendData()));
- connect(source, SIGNAL(readyRead()), this, SLOT(sendData()));
- return true;
-}
-
-void QTcpSocketPair::addSocket(QTcpSocket *socket)
-{
- if (source)
- {
- warning("Unexpected connection for " + key);
- socket->deleteLater();
- return;
- }
-
- if (target)
- {
- debug(QString("Opened source connection for %1 %2:%3").arg(
- key,
- socket->peerAddress().toString(),
- QString::number(socket->peerPort())));
- source = socket;
- source->setReadBufferSize(4 * blockSize);
- connect(source, SIGNAL(disconnected()), this, SLOT(disconnected()));
- }
- else
- {
- debug(QString("Opened target connection for %1 %2:%3").arg(
- key,
- socket->peerAddress().toString(),
- QString::number(socket->peerPort())));
- target = socket;
- connect(target, SIGNAL(disconnected()), this, SLOT(disconnected()));
- }
- socket->setParent(this);
-}
-
-void QTcpSocketPair::disconnected()
-{
- QTcpSocket *socket = qobject_cast<QTcpSocket*>(sender());
- if (!socket)
- return;
-
- if (target == socket)
- {
- debug("Closed target connection for " + key);
- emit finished();
- } else if (source == socket) {
- debug("Closed source connection for " + key);
- if (!target || !target->isOpen())
- emit finished();
- }
-}
-
-void QTcpSocketPair::sendData()
-{
- // don't saturate the outgoing socket
- if (target->bytesToWrite() >= 2 * blockSize)
- return;
-
- // check for completion
- if (!source->isOpen())
- {
- if (!target->bytesToWrite())
- target->close();
- return;
- }
-
- char buffer[blockSize];
- qint64 length = source->read(buffer, blockSize);
- if (length < 0)
- {
- if (!target->bytesToWrite())
- target->close();
- return;
- }
- if (length > 0)
- {
- target->write(buffer, length);
- transfer += length;
- }
-}
-
-struct TransferStats
-{
- QDateTime date;
- qint64 size;
- int elapsed;
-};
-
-class QXmppServerProxy65Private
-{
-public:
- // configuration
- QString advertisedName;
- QHostAddress advertisedAddress;
- QStringList allowedDomains;
- QString jid;
- QString hostName;
- quint16 port;
-
- // state
- QHash<QString, QTcpSocketPair*> pairs;
- QXmppSocksServer *server;
-
- // statistics
- QList<TransferStats> recent;
- QTimer *statisticsTimer;
- quint64 totalBytes;
- quint64 totalTransfers;
-};
-
-QXmppServerProxy65::QXmppServerProxy65()
- : d(new QXmppServerProxy65Private)
-{
- bool check;
- Q_UNUSED(check);
-
- d->port = 7777;
- d->server = new QXmppSocksServer(this);
-
- d->statisticsTimer = new QTimer(this);
- d->statisticsTimer->setInterval(300 * 1000);
- d->totalBytes = 0;
- d->totalTransfers = 0;
-
- check = connect(d->server, SIGNAL(newConnection(QTcpSocket*,QString,quint16)),
- this, SLOT(slotSocketConnected(QTcpSocket*,QString,quint16)));
- Q_ASSERT(check);
-
- check = connect(d->statisticsTimer, SIGNAL(timeout()),
- this, SLOT(slotUpdateStatistics()));
- Q_ASSERT(check);
-}
-
-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.
-///
-
-QStringList QXmppServerProxy65::allowedDomains() const
-{
- return d->allowedDomains;
-}
-
-/// Sets the XMPP domains which are allowed to use the proxy.
-///
-/// If not defined, defaults to the server's domain.
-///
-/// \param allowedDomains
-
-void QXmppServerProxy65::setAllowedDomains(const QStringList &allowedDomains)
-{
- d->allowedDomains = allowedDomains;
-}
-
-/// Returns the proxy server's JID.
-///
-
-QString QXmppServerProxy65::jid() const
-{
- return d->jid;
-}
-
-/// Set the proxy server's JID.
-///
-/// \param jid
-
-void QXmppServerProxy65::setJid(const QString &jid)
-{
- d->jid = jid;
-}
-
-/// Returns the host on which to listen for SOCKS5 connections.
-///
-
-QString QXmppServerProxy65::host() const
-{
- return d->hostName;
-}
-
-/// Sets the host on which to listen for SOCKS5 connections.
-///
-/// If not defined, defaults to the server's domain.
-///
-/// \param host
-
-void QXmppServerProxy65::setHost(const QString &host)
-{
- d->hostName = host;
-}
-
-/// Returns the port on which to listen for SOCKS5 connections.
-///
-
-quint16 QXmppServerProxy65::port() const
-{
- return d->port;
-}
-
-/// Sets the port on which to listen for SOCKS5 connections.
-///
-/// If not defined, defaults to 7777.
-///
-/// \param port
-
-void QXmppServerProxy65::setPort(quint16 port)
-{
- d->port = port;
-}
-
-QStringList QXmppServerProxy65::discoveryItems() const
-{
- return QStringList() << d->jid;
-}
-
-bool QXmppServerProxy65::handleStanza(const QDomElement &element)
-{
- if (element.attribute("to") != d->jid)
- return false;
-
- if (element.tagName() == "iq" && QXmppDiscoveryIq::isDiscoveryIq(element))
- {
- QXmppDiscoveryIq discoIq;
- discoIq.parse(element);
-
- if (discoIq.type() == QXmppIq::Get)
- {
- QXmppDiscoveryIq responseIq;
- responseIq.setTo(discoIq.from());
- responseIq.setFrom(discoIq.to());
- responseIq.setId(discoIq.id());
- responseIq.setType(QXmppIq::Result);
- responseIq.setQueryType(discoIq.queryType());
-
- if (discoIq.queryType() == QXmppDiscoveryIq::InfoQuery)
- {
- QStringList features = QStringList() << ns_disco_info << ns_disco_items << ns_bytestreams;
-
- QList<QXmppDiscoveryIq::Identity> identities;
- QXmppDiscoveryIq::Identity identity;
- identity.setCategory("proxy");
- identity.setType("bytestreams");
- identity.setName("SOCKS5 Bytestreams");
- identities.append(identity);
-
- responseIq.setFeatures(features);
- responseIq.setIdentities(identities);
- }
-
- server()->sendPacket(responseIq);
- return true;
- }
- }
- else if (element.tagName() == "iq" && QXmppByteStreamIq::isByteStreamIq(element))
- {
- QXmppByteStreamIq bsIq;
- bsIq.parse(element);
-
- if (bsIq.type() == QXmppIq::Get)
- {
- QXmppByteStreamIq responseIq;
- responseIq.setType(QXmppIq::Result);
- responseIq.setTo(bsIq.from());
- responseIq.setFrom(bsIq.to());
- responseIq.setId(bsIq.id());
-
- QList<QXmppByteStreamIq::StreamHost> streamHosts;
-
- QXmppByteStreamIq::StreamHost streamHost;
- streamHost.setJid(d->jid);
- streamHost.setHost(d->advertisedAddress);
- streamHost.setPort(d->port);
- streamHosts.append(streamHost);
-
- responseIq.setStreamHosts(streamHosts);
- server()->sendPacket(responseIq);
- }
- else if (bsIq.type() == QXmppIq::Set)
- {
- QString hash = streamHash(bsIq.sid(), bsIq.from(), bsIq.activate());
- QTcpSocketPair *pair = d->pairs.value(hash);
-
- QXmppIq responseIq;
- responseIq.setTo(bsIq.from());
- responseIq.setFrom(bsIq.to());
- responseIq.setId(bsIq.id());
-
- if (pair &&
- d->allowedDomains.contains(jidToDomain(bsIq.from())))
- {
- if (pair->activate()) {
- info(QString("Activated connection %1 by %2").arg(hash, bsIq.from()));
- responseIq.setType(QXmppIq::Result);
- } else {
- warning(QString("Failed to activate connection %1 by %2").arg(hash, bsIq.from()));
- responseIq.setType(QXmppIq::Error);
- }
- } else {
- warning(QString("Not activating connection %1 by %2").arg(hash, bsIq.from()));
- responseIq.setType(QXmppIq::Error);
- }
- server()->sendPacket(responseIq);
- }
- return true;
- }
- return false;
-}
-
-bool QXmppServerProxy65::start()
-{
- // determine allowed domains
- if (d->allowedDomains.isEmpty())
- d->allowedDomains << server()->domain();
-
- // determine jid
- if (d->jid.isEmpty())
- d->jid = "proxy." + server()->domain();
-
- // determine bind address
- if (d->hostName.isEmpty())
- d->hostName = server()->domain();
- QHostAddress bindAddress;
- if (!bindAddress.setAddress(d->hostName))
- {
- QHostInfo hostInfo = QHostInfo::fromName(d->hostName);
- if (hostInfo.addresses().isEmpty())
- {
- warning(QString("Could not lookup host %1").arg(d->hostName));
- return false;
- }
- 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(bindAddress, d->port))
- return false;
-
- // start statistics update
- d->statisticsTimer->start();
- return true;
-}
-
-void QXmppServerProxy65::stop()
-{
- // refuse incoming connections
- d->server->close();
-
- // close socket pairs
- foreach (QTcpSocketPair *pair, d->pairs)
- delete pair;
- d->pairs.clear();
-
- // stop statistics update
- d->statisticsTimer->stop();
-}
-
-QVariantMap QXmppServerProxy65::statistics() const
-{
- // calculate stats
- qint64 minimumSpeed = -1;
- qint64 maximumSpeed = 0;
- qint64 totalSize = 0;
- qint64 totalElapsed = 0;
- for (int i = d->recent.size() - 1; i >= 0; --i)
- {
- if (d->recent[i].elapsed > 0)
- {
- qint64 speed = (1000 * d->recent[i].size) / d->recent[i].elapsed;
- if (speed > maximumSpeed)
- maximumSpeed = speed;
- if (minimumSpeed < 0 || speed < minimumSpeed)
- minimumSpeed = speed;
- }
- totalSize += d->recent[i].size;
- totalElapsed += d->recent[i].elapsed;
- }
- if (minimumSpeed < 0)
- minimumSpeed = 0;
- qint64 averageSpeed = totalElapsed > 0 ? (1000 * totalSize) / totalElapsed : 0;
-
- // store stats
- QVariantMap stats;
- stats["total-bytes"] = d->totalBytes;
- stats["total-transfers"] = d->totalTransfers;
- stats["hourly-bytes"] = totalSize;
- stats["hourly-transfers"] = d->recent.size();
- stats["hourly-average-speed"] = averageSpeed;
- stats["hourly-minimum-speed"] = minimumSpeed;
- stats["hourly-maximum-speed"] = maximumSpeed;
- return stats;
-}
-
-void QXmppServerProxy65::setStatistics(const QVariantMap &statistics)
-{
- d->totalBytes = statistics.value("total-bytes").toULongLong();
- d->totalTransfers = statistics.value("total-transfers").toULongLong();
-}
-
-void QXmppServerProxy65::slotSocketConnected(QTcpSocket *socket, const QString &hostName, quint16 port)
-{
- Q_UNUSED(port);
-
- QTcpSocketPair *pair = d->pairs.value(hostName);
- if (!pair)
- {
- bool check;
- Q_UNUSED(check);
-
- pair = new QTcpSocketPair(hostName, this);
- check = connect(pair, SIGNAL(finished()),
- this, SLOT(slotPairFinished()));
- Q_ASSERT(check);
- d->pairs.insert(hostName, pair);
- }
- pair->addSocket(socket);
-}
-
-void QXmppServerProxy65::slotPairFinished()
-{
- QTcpSocketPair *pair = qobject_cast<QTcpSocketPair*>(sender());
- if (!pair)
- return;
-
- info(QString("Data transfered for %1 %2").arg(pair->key, QString::number(pair->transfer)));
-
- // store information for speed statistics
- TransferStats stats;
- stats.date = QDateTime::currentDateTime();
- stats.size = pair->transfer;
- stats.elapsed = pair->time.elapsed();
- d->recent.prepend(stats);
- slotUpdateStatistics();
-
- // update totals
- d->totalBytes += pair->transfer;
- d->totalTransfers++;
-
- // remove socket pair
- d->pairs.remove(pair->key);
- pair->deleteLater();
-}
-
-/// Prune obsolete statistics.
-///
-
-void QXmppServerProxy65::slotUpdateStatistics()
-{
- QDateTime cutoff = QDateTime::currentDateTime().addSecs(-3600);
- for (int i = d->recent.size() - 1; i >= 0; --i)
- if (d->recent[i].date < cutoff)
- d->recent.removeAt(i);
-}
-
-// PLUGIN
-
-class QXmppServerProxy65Plugin : public QXmppServerPlugin
-{
-public:
- QXmppServerExtension *create(const QString &key)
- {
- if (key == QLatin1String("proxy65"))
- return new QXmppServerProxy65;
- else
- return 0;
- };
-
- QStringList keys() const
- {
- return QStringList() << QLatin1String("proxy65");
- };
-};
-
-Q_EXPORT_STATIC_PLUGIN2(mod_proxy65, QXmppServerProxy65Plugin)
-