diff options
| author | Sebastian | 2010-05-12 19:42:27 +0200 |
|---|---|---|
| committer | Sebastian | 2010-05-12 19:42:27 +0200 |
| commit | ce3329047d378a14006ce74ec273ac59e3375303 (patch) | |
| tree | 782430f270b4c7aca1b35d5b7813518e3797c555 /src/net/pvsServiceDiscovery.cpp | |
| download | pvs-ce3329047d378a14006ce74ec273ac59e3375303.tar.gz pvs-ce3329047d378a14006ce74ec273ac59e3375303.tar.xz pvs-ce3329047d378a14006ce74ec273ac59e3375303.zip | |
initial import of latest svn version
Diffstat (limited to 'src/net/pvsServiceDiscovery.cpp')
| -rw-r--r-- | src/net/pvsServiceDiscovery.cpp | 181 |
1 files changed, 181 insertions, 0 deletions
diff --git a/src/net/pvsServiceDiscovery.cpp b/src/net/pvsServiceDiscovery.cpp new file mode 100644 index 0000000..0a99802 --- /dev/null +++ b/src/net/pvsServiceDiscovery.cpp @@ -0,0 +1,181 @@ +/* +# Copyright (c) 2009 - OpenSLX Project, Computer Center University of Freiburg +# +# This program is free software distributed under the GPL version 2. +# See http://openslx.org/COPYING +# +# If you have any feedback please consult http://openslx.org/feedback and +# send your suggestions, praise, or complaints to feedback@openslx.org +# +# General information about OpenSLX can be found at http://openslx.org/ +# ----------------------------------------------------------------------------- +# src/net/pvsServiceDiscovery.cpp +# - handle console broadcasts, tell client to connect on match +# ----------------------------------------------------------------------------- +*/ + +#include <QtCore/QHash> +#include "src/pvs.h" +#include "pvsServiceDiscovery.h" +#include "pvsDiscoveredServer.h" +#include "src/setup.h" +#include "src/util/serviceDiscoveryUtil.h" +#include <cassert> + + + +PVSServiceDiscovery::PVSServiceDiscovery(PVS* client) +{ + assert(client); + bool ret = _sock.bind(SD_PORT_CLIENT); + if (!ret) + { + printf("Could not open SERVICE DISCOVERY port\n"); + exit(1); + } + connect(&_sock, SIGNAL(readyRead()), this, SLOT(sock_dataArrival())); + _currentServer = 0; + _last = QDateTime::currentDateTime(); + _client = client; + _timerId = startTimer(10000); +} + +PVSServiceDiscovery::~PVSServiceDiscovery() +{ + killTimer(_timerId); +} + +void PVSServiceDiscovery::connectToSession(QString name, QString passwd) +{ + _sessionName = name; + _sessionPasswd = passwd; + if (name.length() == 0) return; + for (tServerList::iterator it = _servers.begin(); it != _servers.end(); it++) + { + PVSDiscoveredServer *ds = *it; + if (ds->isValid() && ds->getName() == name) + { + _client->connectToHost(ds, _sessionPasswd); + } + } +} + +void PVSServiceDiscovery::sock_dataArrival() +{ + int len; + while ((len = _sock.pendingDatagramSize()) > -1) + { + if (len == 0) continue; + char *data = new char[len]; + QHostAddress host; + len = _sock.readDatagram(data, len, &host); + SdFields fields = parseSdFields((unsigned char*)data, len); + QDateTime now = QDateTime::currentDateTime(); + if (fields.contains("hsh") && fields.contains("prt") && fields.contains("aut")) + { + if (fields["aut"] == "SHA1") + { + this->handleDiscovery( + host, + atoi(fields["prt"].toUtf8().data()), + QByteArray::fromBase64(fields["hsh"].toAscii()) + ); + } + } + /* + // DEBUG ONLY: connect to any host without matching the session name + if (_last.secsTo(now) > 9 && fields.contains("prt")) + { + _last = now; + int port = atoi(fields["prt"].toUtf8().data()); + _client->connectToHost(host, QByteArray(), port); + } + // ^^^^^^^^^^ + */ + } +} + +void PVSServiceDiscovery::handleDiscovery(QHostAddress host, int port, QByteArray hash) +{ + int numhosts = 0; ///< while iterating we count how many entries have the same host + for (tServerList::iterator it = _servers.begin(); it != _servers.end(); it++) + { + if ((**it).hasHost(host)) + { + ConsoleLog writeNetwork(host.toString() + " == " + (**it).getHost().toString()); + if (++numhosts >= 5) return; // ddos through faked service broadcasts? ignore... + if ((**it).hasFingerprint(hash) && (**it).getPort() == port) // known entry... + { + if ((*it)->isValid() && (*it)->getName() == _sessionName && _sessionName.length() > 0) + { + ConsoleLog writeNetwork(QString("Connecting to ").append(_sessionName)); + _client->connectToHost((*it), _sessionPasswd); + } + (**it).update(port); + return; + } + } + } + if (_servers.length() >= 30) return; // !? + QString oname = sha1ToReadable(hash); + QString name = oname; + int dup = 0; + while (nameExists(name)) + { + name = "(" + QString::number(++dup) + ") " + oname; + } + PVSDiscoveredServer *ds = new PVSDiscoveredServer(this, host, port, hash, name); + connect(ds, SIGNAL(validated(PVSDiscoveredServer*)), this, SLOT(sendServerToGui(PVSDiscoveredServer*))); + _servers.push_back(ds); + setTimerInterval(); +} + +bool PVSServiceDiscovery::nameExists(QString name) +{ + for (tServerList::iterator it = _servers.begin(); it != _servers.end(); it++) + { + if ((**it).getName() == name) return true; + } + return false; +} + +QStringList PVSServiceDiscovery::getAllServers() +{ + QStringList hosts; + for (tServerList::iterator it = _servers.begin(); it != _servers.end(); it++) + { + if ((**it).isValid()) hosts.append((**it).getName()); + } + return hosts; +} + +void PVSServiceDiscovery::sendServerToGui(PVSDiscoveredServer* ds) +{ + _client->guiAddHost(ds->getName()); +} + +void PVSServiceDiscovery::timerEvent(QTimerEvent *event) +{ + if (_servers.size() == 0) return; + if (_currentServer >= _servers.size()) _currentServer = 0; + PVSDiscoveredServer *ds = _servers.at(_currentServer); + if (ds->getAge() >= SB_INTERVAL*2 + 1) // Entry too old? + { + disconnect(ds, SIGNAL(validated(PVSDiscoveredServer*)), this, SLOT(sendServerToGui(PVSDiscoveredServer*))); + _client->guiDelHost(ds->getName()); + delete ds; + _servers.removeAt(_currentServer); // Clean it up + setTimerInterval(); + } + else + { + ds->validateCertificate(); + } + ++_currentServer; +} + +void PVSServiceDiscovery::setTimerInterval() +{ + killTimer(_timerId); + _timerId = startTimer(10000 / (_servers.size() + 1)); +} |
