summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/client/connectwindow/connectwindow.cpp243
-rw-r--r--src/client/connectwindow/connectwindow.h53
-rw-r--r--src/client/net/serverdiscovery.cpp181
-rw-r--r--src/client/net/serverdiscovery.h51
-rw-r--r--src/client/toolbar/toolbar.cpp4
-rw-r--r--src/client/vnc/vncserver.cpp70
-rw-r--r--src/server/mainwindow/mainwindow.cpp41
-rw-r--r--src/server/mainwindow/mainwindow.h1
-rw-r--r--src/server/net/client.cpp5
-rw-r--r--src/server/net/discoverylistener.cpp54
10 files changed, 448 insertions, 255 deletions
diff --git a/src/client/connectwindow/connectwindow.cpp b/src/client/connectwindow/connectwindow.cpp
index c8f7efd..7f24281 100644
--- a/src/client/connectwindow/connectwindow.cpp
+++ b/src/client/connectwindow/connectwindow.cpp
@@ -16,16 +16,19 @@
#define UDPBUFSIZ 9000
#define SALT_LEN 18
-/**
+/***************************************************************************//**
* Initialize Connection Window.
* @param parent
*/
-ConnectWindow::ConnectWindow(QWidget *parent) :
- QWidget(parent), _ui(new Ui::ConnectWindow), _connected(false),
- _timerDiscover(0), _timerHide(0), _connection(NULL), _state(Idle),
- _hashErrorCount(0), _hashSslErrorCount(0), _certErrorCount(0),
- _ipErrorCount(0), _discoveryInterval(800)
-{
+ConnectWindow::ConnectWindow(QWidget *parent) : QWidget(parent)
+{
+ _ui = new Ui::ConnectWindow;
+ _connected = false;
+ _timerHide = 0;
+ _connection = NULL;
+ _state = Idle;
+ _hashSslErrorCount = 0;
+
// Initialize the GUI
_ui->setupUi(this);
@@ -39,53 +42,21 @@ ConnectWindow::ConnectWindow(QWidget *parent) :
connect(_ui->btn_connection, SIGNAL(clicked()), this, SLOT(onBtnConnection()));
connect(_ui->btn_hide, SIGNAL(clicked()), this, SLOT(onBtnHide()));
- int tries = 10;
- while (tries-- != 0)
- {
- const quint16 port = (quint16)(qrand() % 10000) + 10000;
- if (_discoverySocket.bind(QHostAddress::Any, port))
- break;
- if (tries == 0)
- qFatal("Could not bind to any UDP port for server discovery.");
- }
- connect(&_discoverySocket, SIGNAL(readyRead()), this, SLOT(onUdpReadyRead()));
- this->setState(Idle);
-}
+ // React on discovery signal
+ connect(&_serverDiscovery, SIGNAL(serverDetected(QString,quint16,QByteArray,QByteArray)),
+ this, SLOT(onServerDetected(QString,quint16,QByteArray,QByteArray)));
-ConnectWindow::~ConnectWindow(){}
-
-/**
- * Set Client as Connected (true) or Disconnected (false).
- * After settings updateState() is called.
- * @param connected
- */
-void ConnectWindow::setConnected(const bool connected)
-{
- _connected = connected;
this->updateState();
- if (_state == Scanning)
- {
- killTimer(_timerDiscover);
- _discoveryInterval = 1000;
- _timerDiscover = startTimer(_discoveryInterval);
- }
}
-/**
- * Set current state of Client.
- * After setting state updateState() is called.
- * @param state
+/***************************************************************************//**
+ * @brief ConnectWindow::~ConnectWindow
*/
-void ConnectWindow::setState(const ConnectionState state)
-{
- if (_state != state)
- {
- _state = state;
- this->updateState();
- }
-}
+ConnectWindow::~ConnectWindow(){}
+
+
-/**
+/***************************************************************************//**
* Handle changes in state and update window.
* Also changing TextLabel which shows the user what the program is doing.
*/
@@ -115,7 +86,6 @@ void ConnectWindow::updateState()
break;
case Scanning:
_ui->lblStatus->setText(tr("Scanning for session %1.").arg(_ui->lineEditName->text()));
- _timerDiscover = startTimer(_discoveryInterval);
break;
case Connecting:
_ui->lblStatus->setText(tr("Found session, connecting..."));
@@ -132,12 +102,11 @@ void ConnectWindow::updateState()
case Connected:
_ui->lblStatus->setText(tr("Connection established!"));
break;
- case InvalidIpList:
- case InvalidHash:
case InvalidCert:
+ _ui->lblStatus->setText(tr("Invalid certificate."));
+ break;
case InvalidSslHash:
- _ui->lblStatus->setText(tr("Invalid hash: %1; invalid cert: %2; invalid iplist: %3; invalid sslhash: %4")
- .arg(_hashErrorCount).arg(_certErrorCount).arg(_ipErrorCount).arg(_hashSslErrorCount));
+ _ui->lblStatus->setText(tr("Invalid Ssl hash: %1.").arg(_hashSslErrorCount));
break;
}
}
@@ -146,57 +115,13 @@ void ConnectWindow::updateState()
* Overrides
*/
-/**
+/***************************************************************************//**
* Called when a Qt timer fires; used for server discovery and
* auto-hiding the connect dialog.
*/
void ConnectWindow::timerEvent(QTimerEvent* event)
{
- if (event->timerId() == _timerDiscover)
- {
- killTimer(_timerDiscover);
- if (_connected || _state != Scanning) // Not scanning, bail out
- return;
- if (_discoveryInterval < 30000)
- _discoveryInterval += 100;
- _timerDiscover = startTimer(_discoveryInterval);
- // Don't send packet if we're trying to connect
- if (_connection != NULL)
- return;
- // Send discovery
- _packet.reset();
- QByteArray iplist(Network::interfaceAddressesToString().toUtf8());
- QByteArray salt1(SALT_LEN, 0);
- if (_salt2.size() < SALT_LEN)
- _salt2.resize(SALT_LEN);
- for (int i = 0; i < SALT_LEN; ++i)
- {
- salt1[i] = qrand() & 0xff;
- _salt2[i] = qrand() & 0xff;
- }
- _packet.reset();
- _packet.setField(_HASH, genSha1(&_sessionNameBytes, &salt1, &iplist));
- _packet.setField(_SALT1, salt1);
- _packet.setField(_SALT2, _salt2);
- _packet.setField(_IPLIST, iplist);
- foreach (QNetworkInterface interface, QNetworkInterface::allInterfaces())
- {
- foreach (QNetworkAddressEntry entry, interface.addressEntries())
- {
- if (!entry.broadcast().isNull() && entry.ip() != QHostAddress::LocalHost && entry.ip() != QHostAddress::LocalHostIPv6)
- {
- qDebug() << "Broadcasting to " << entry.broadcast().toString();
- if (!_packet.writeMessage(&_discoverySocket, entry.broadcast(), SERVICE_DISCOVERY_PORT))
- qDebug("FAILED");
- }
- }
- }
- qDebug("Broadcasting to 255.255.255.255");
- if (!_packet.writeMessage(&_discoverySocket, QHostAddress::Broadcast, SERVICE_DISCOVERY_PORT))
- qDebug("FAILED");
- // End send discovery
- }
- else if(event->timerId() == _timerHide)
+ if(event->timerId() == _timerHide)
{
killTimer(_timerHide);
_timerHide = 0;
@@ -204,11 +129,11 @@ void ConnectWindow::timerEvent(QTimerEvent* event)
_ui->stackedWidget->setCurrentIndex(0);
}
else
- // Unknown/Old timer id, kill it
+ // Unknown/Old timer id, kill it ??? PALM -> FACE
killTimer(event->timerId());
}
-/**
+/***************************************************************************//**
* Handle incoming closeEvent and hide window.
* @param e
*/
@@ -218,7 +143,7 @@ void ConnectWindow::closeEvent(QCloseEvent *e)
this->hide();
}
-/**
+/***************************************************************************//**
* Gives the keyboard input focus to the input line.
* @param event
*/
@@ -227,7 +152,7 @@ void ConnectWindow::showEvent(QShowEvent* event)
_ui->lineEditName->setFocus();
}
-/**
+/***************************************************************************//**
* Public function connect to session.
* Check if currently connected to server,
* if not --> connect to given sessionName.
@@ -237,19 +162,16 @@ void ConnectWindow::connectToSession(const QByteArray sessionName)
{
if (_connected || _state != Idle)
return;
-
- _discoveryInterval = 800;
- _sessionNameBytes = sessionName;
- _timerDiscover = startTimer(_discoveryInterval);
- _hashErrorCount = _hashSslErrorCount = _certErrorCount = _ipErrorCount = 0;
- this->setState(Scanning);
+ _state = Scanning;
+ this->updateState();
+ _serverDiscovery.start(sessionName);
}
/*
* Slots
*/
-/**
+/***************************************************************************//**
* Handle click on Connect/Disconnect button.
* If already connected --> Stop/disconnect.
* Else scanning for given sessionId.
@@ -258,26 +180,30 @@ void ConnectWindow::onBtnConnection()
{
if (_timerHide){
killTimer(_timerHide);
+ _timerHide = 0;
_ui->stackedWidget->setCurrentIndex(0);
}
- _timerHide = 0;
- if (_timerDiscover)
- killTimer(_timerDiscover);
+
+ if (_serverDiscovery.isActive())
+ _serverDiscovery.stop();
+
if (_connected || _state != Idle)
{
+ _tryReconnect = false;
// Stop or disconnect
- _timerDiscover = 0;
emit disconnect();
- this->setState(Idle);
+ _state = Idle;
+ this->updateState();
}
else
{
// Connect (scan for session)
+ _tryReconnect = true;
connectToSession(_ui->lineEditName->text().toUtf8());
}
}
-/**
+/***************************************************************************//**
* Handle click on Cancel/Hide Button.
* Just hide the window.
*/
@@ -286,75 +212,56 @@ void ConnectWindow::onBtnHide()
this->hide();
}
-/**
- * Handle incoming service discovery packets.
+
+/***************************************************************************//**
+ * @brief ConnectWindow::onServerDetected
+ * @param host
+ * @param port
+ * @param sessionName
+ * @param certHash
*/
-void ConnectWindow::onUdpReadyRead()
+void ConnectWindow::onServerDetected(const QString& host, const quint16 port, const QByteArray& sessionName, const QByteArray& certHash)
{
- char data[UDPBUFSIZ];
- QHostAddress addr;
- quint16 port;
- while (_discoverySocket.hasPendingDatagrams())
- {
- const qint64 size = _discoverySocket.readDatagram(data, UDPBUFSIZ, &addr, &port);
- if (size <= 0 || _connection != NULL)
- continue;
-
- _packet.reset();
- if (!_packet.readMessage(data, (quint32)size))
- continue;
- // Valid packet, process it:
- const QByteArray hash(_packet.getFieldBytes(_HASH));
- const QByteArray iplist(_packet.getFieldBytes(_IPLIST));
- const QByteArray port(_packet.getFieldBytes(_PORT));
- const QByteArray cert(_packet.getFieldBytes(_CERT));
- // Check if the source IP of the packet matches any of the addresses given in the IP list
- if (!Network::isAddressInList(QString::fromUtf8(iplist), addr.toString()))
- {
- ++_ipErrorCount;
- this->setState(InvalidIpList);
- this->setState(Scanning);
- continue;
- }
- // If so, check if the submitted hash seems valid
- if (genSha1(&_sessionNameBytes, &_salt2, &iplist, &port, &cert) != hash)
- {
- // did not match local session name, or other data was spoofed
- ++_hashErrorCount;
- this->setState(InvalidHash);
- this->setState(Scanning);
- continue;
- }
- // Otherwise it's a valid reply, try to connect
- _connection = new ServerConnection(addr.toString(), (quint16)QString::fromUtf8(port).toInt(), _sessionNameBytes, cert);
- connect(_connection, SIGNAL(stateChange(ConnectWindow::ConnectionState)), this, SLOT(onConnectionStateChange(ConnectWindow::ConnectionState)));
- connect(_connection, SIGNAL(destroyed(QObject*)), this, SLOT(onConnectionClosed(QObject*)));
- }
+ _connection = new ServerConnection(host, port, sessionName, certHash);
+ connect(_connection, SIGNAL(stateChange(ConnectWindow::ConnectionState)), this, SLOT(onConnectionStateChange(ConnectWindow::ConnectionState)));
+ connect(_connection, SIGNAL(destroyed(QObject*)), this, SLOT(onConnectionClosed(QObject*)));
+ connect(_connection, SIGNAL(disconnected()), this, SLOT(onConnectionDisconnected()));
}
-/**
+
+/***************************************************************************//**
* Handle connection state changes and update member variables describing state.
* @param state
*/
void ConnectWindow::onConnectionStateChange(ConnectWindow::ConnectionState state)
{
+ qDebug() << "STATE!"<< state;
bool reset = (_state == Scanning);
if (state == InvalidSslHash)
++_hashSslErrorCount;
- this->setState(state);
- if (reset)
+
+ _state = state;
+ this->updateState();
+
+ if (reset) {
+ qDebug() << "RESET!!"<< state;
_state = Scanning;
+ }
if (state == Connected)
{
QObject::disconnect(_connection, SIGNAL(stateChange(ConnectWindow::ConnectionState)), this, SLOT(onConnectionStateChange(ConnectWindow::ConnectionState)));
QObject::disconnect(_connection, SIGNAL(destroyed(QObject*)), this, SLOT(onConnectionClosed(QObject*)));
emit connected(_connection);
+
+ _connected = true;
+ this->updateState();
+
_connection = NULL;
_timerHide = startTimer(2000);
}
}
-/**
+/***************************************************************************//**
* If connection is closed set _connection = NULL.
* @param connection
*/
@@ -362,3 +269,15 @@ void ConnectWindow::onConnectionClosed(QObject* connection)
{
_connection = NULL;
}
+
+/***************************************************************************//**
+ * @brief ConnectWindow::onConnectionDisconnected
+ */
+void ConnectWindow::onConnectionDisconnected()
+{
+ _connected = false;
+ _state = Idle;
+ this->updateState();
+ if (_tryReconnect)
+ connectToSession(_ui->lineEditName->text().toUtf8());
+}
diff --git a/src/client/connectwindow/connectwindow.h b/src/client/connectwindow/connectwindow.h
index 9319e45..df112fe 100644
--- a/src/client/connectwindow/connectwindow.h
+++ b/src/client/connectwindow/connectwindow.h
@@ -20,6 +20,7 @@
#include <QUdpSocket>
#include <QSslSocket>
#include "../../shared/networkmessage.h"
+#include "../net/serverdiscovery.h"
namespace Ui{
class ConnectWindow;
@@ -38,54 +39,37 @@ class ConnectWindow : public QWidget
Q_OBJECT
public:
- enum ConnectionState
- {
+ enum ConnectionState {
Idle,
Scanning,
Connecting,
AwaitingChallenge,
AwaitingChallengeResponse,
LoggingIn,
- InvalidIpList,
- InvalidHash, // Hash of UDP reply invalid
InvalidSslHash, // Hash of challenge inside SSL connection invalid
InvalidCert,
Connected
};
-private:
- Ui::ConnectWindow *_ui;
-
- bool _connected;
- int _timerDiscover, _timerHide;
- ServerConnection *_connection;
- ConnectionState _state;
- int _hashErrorCount, _hashSslErrorCount, _certErrorCount, _ipErrorCount;
- int _discoveryInterval;
-
- QByteArray _sessionNameBytes;
- QByteArray _salt2;
- QUdpSocket _discoverySocket;
- NetworkMessage _packet;
-
- void setState(const ConnectionState state);
- void updateState();
-
-public:
explicit ConnectWindow(QWidget *parent = NULL);
virtual ~ConnectWindow();
- void setConnected(const bool connected);
void connectToSession(const QByteArray sessionName);
+private:
+ Ui::ConnectWindow *_ui;
+ ServerConnection *_connection;
+ int _hashSslErrorCount;
+ ServerDiscovery _serverDiscovery;
+ ConnectionState _state;
+ QByteArray _sessionNameBytes;
+ NetworkMessage _packet;
+ bool _connected, _tryReconnect;
+ int _timerHide;
+
+ void updateState();
+
protected:
- /*
- void enterEvent(QEvent *e);
- void leaveEvent(QEvent *e);
- void mousePressEvent(QMouseEvent *event);
- void mouseReleaseEvent(QMouseEvent *event);
- void mouseMoveEvent(QMouseEvent *event);
- */
void timerEvent(QTimerEvent* event);
void closeEvent(QCloseEvent *e);
void showEvent(QShowEvent* event);
@@ -93,15 +77,16 @@ protected:
protected slots:
void onBtnConnection();
void onBtnHide();
- void onUdpReadyRead();
+
void onConnectionStateChange(ConnectWindow::ConnectionState state);
void onConnectionClosed(QObject* connection);
- //void onSsl
+ void onConnectionDisconnected();
+ // void onUdpReadyRead();
+ void onServerDetected(const QString& host, const quint16 port, const QByteArray& sessionName, const QByteArray& certHash);
signals:
void disconnect();
void connected(ServerConnection* connection);
-
};
#endif
diff --git a/src/client/net/serverdiscovery.cpp b/src/client/net/serverdiscovery.cpp
new file mode 100644
index 0000000..a4edb46
--- /dev/null
+++ b/src/client/net/serverdiscovery.cpp
@@ -0,0 +1,181 @@
+
+#include <QNetworkInterface>
+#include "../../shared/settings.h"
+#include "../../shared/network.h"
+#include "../../shared/util.h"
+#include "serverdiscovery.h"
+#include <assert.h>
+
+
+/***************************************************************************//**
+ * Ctor
+ */
+ServerDiscovery::ServerDiscovery(QObject *parent) : QObject(parent)
+{
+ _hashErrorCount = 0;
+ _ipErrorCount = 0;
+
+ /* Try to get a UDP port for server discovery */
+ int tries = 10;
+ while (tries-- != 0)
+ {
+ const quint16 port = (quint16)(qrand() % 10000) + 10000;
+ if (_discoverySocket.bind(QHostAddress::Any, port))
+ break;
+ if (tries == 0)
+ qFatal("Could not bind to any UDP port for server discovery.");
+ }
+ // Handle incoming messages
+ connect(&_discoverySocket, SIGNAL(readyRead()), this, SLOT(onUdpReadyRead()));
+
+ /* Setup the discovery timer */
+ _discoveryTimer.setInterval(500);
+ _discoveryTimer.setSingleShot(true);
+ //
+ connect(&_discoveryTimer, SIGNAL(timeout()), this, SLOT(doDiscovery()));
+}
+
+/***************************************************************************//**
+ * Dtor
+ */
+ServerDiscovery::~ServerDiscovery()
+{
+}
+
+/***************************************************************************//**
+ * @brief start
+ */
+void ServerDiscovery::start(const QByteArray& sessionName)
+{
+ //assert(!this->isActive());
+
+ // Set the session which is searched
+ _nameBytes = sessionName;
+
+ // Enable signal emittance
+ this->blockSignals(false);
+
+ // Reset the error counters
+ _hashErrorCount = _ipErrorCount = 0;
+
+ // reset anbd start the discovery timer
+ _discoveryTimer.setInterval(500);
+ _discoveryTimer.start();
+}
+
+/***************************************************************************//**
+ * @brief stop
+ */
+void ServerDiscovery::stop()
+{
+ assert(this->isActive());
+
+ //Bock further signal emittance
+ this->blockSignals(true);
+ _discoveryTimer.stop();
+}
+
+/*******************************************************************************
+ * SLOTS
+ ***************************************************************************//**
+ * @brief ConnectWindow::doDiscovery
+ */
+void ServerDiscovery::doDiscovery()
+{
+ // Send discovery
+ _packet.reset();
+ QByteArray iplist(Network::interfaceAddressesToString().toUtf8());
+ // qDebug
+ QByteArray salt1(SALT_LEN, 0);
+ if (_salt2.size() < SALT_LEN)
+ _salt2.resize(SALT_LEN);
+ for (int i = 0; i < SALT_LEN; ++i) {
+ salt1[i] = qrand() & 0xff;
+ _salt2[i] = qrand() & 0xff;
+ }
+ _packet.reset();
+ _packet.setField(_HASH, genSha1(&_nameBytes, &salt1, &iplist));
+ _packet.setField(_SALT1, salt1);
+ _packet.setField(_SALT2, _salt2);
+ _packet.setField(_IPLIST, iplist);
+ foreach (QNetworkInterface interface, QNetworkInterface::allInterfaces())
+ {
+ foreach (QNetworkAddressEntry entry, interface.addressEntries())
+ {
+ if (!entry.broadcast().isNull() && entry.ip() != QHostAddress::LocalHost && entry.ip() != QHostAddress::LocalHostIPv6)
+ {
+ qDebug() << "Broadcasting to " << entry.broadcast().toString();
+ if (!_packet.writeMessage(&_discoverySocket, entry.broadcast(), SERVICE_DISCOVERY_PORT))
+ qDebug("FAILED");
+ }
+ }
+ }
+ qDebug("Broadcasting to 255.255.255.255");
+ if (!_packet.writeMessage(&_discoverySocket, QHostAddress::Broadcast, SERVICE_DISCOVERY_PORT))
+ qDebug("FAILED");
+
+ // Start the timer again with a larger interval
+ if (_discoveryTimer.interval() < 5000)
+ _discoveryTimer.setInterval(_discoveryTimer.interval() * 2);
+ _discoveryTimer.start();
+}
+
+
+/***************************************************************************//**
+ * Handle incoming service discovery packets.
+ */
+void ServerDiscovery::onUdpReadyRead()
+{
+ char data[UDPBUFSIZ];
+ QHostAddress addr;
+ quint16 port;
+ while (_discoverySocket.hasPendingDatagrams())
+ {
+ // Discard any packets if discovery is stopped
+ if (!this->isActive()){
+ _discoverySocket.readDatagram(NULL, 0);
+ continue;
+ }
+
+ const qint64 size = _discoverySocket.readDatagram(data, UDPBUFSIZ, &addr, &port);
+ if (size <= 0) //|| _connection != NULL) // TODO CHECK
+ continue;
+
+ _packet.reset();
+ if (!_packet.readMessage(data, (quint32)size))
+ continue;
+
+ // Valid packet, process it:
+ const QByteArray hash(_packet.getFieldBytes(_HASH));
+ const QByteArray iplist(_packet.getFieldBytes(_IPLIST));
+ const QByteArray port(_packet.getFieldBytes(_PORT));
+ const QByteArray cert(_packet.getFieldBytes(_CERT));
+
+ // Check if the source IP of the packet matches any of the addresses given in the IP list
+ if (!Network::isAddressInList(QString::fromUtf8(iplist), addr.toString()))
+ {
+ ++_ipErrorCount;
+ emit error(ErrorType::InvalidIpList, _hashErrorCount);
+ continue;
+ }
+
+ // If so, check if the submitted hash seems valid
+ if (genSha1(&_nameBytes, &_salt2, &iplist, &port, &cert) != hash)
+ {
+ // did not match local session name, or other data was spoofed
+ ++_hashErrorCount;
+ emit error(ErrorType::InvalidHash, _ipErrorCount);
+ continue;
+ }
+
+ /* Otherwise it's a valid reply */
+ qDebug() << "Server detected:"
+ << addr.toString() + ":" + QString::fromUtf8(port) + "/" + _nameBytes;
+
+ // Tell that a server hs been found
+ emit serverDetected(addr.toString(), (quint16)QString::fromUtf8(port).toInt(), _nameBytes, cert);
+
+ // Stop the discovery
+ this->stop();
+ }
+}
diff --git a/src/client/net/serverdiscovery.h b/src/client/net/serverdiscovery.h
new file mode 100644
index 0000000..093b841
--- /dev/null
+++ b/src/client/net/serverdiscovery.h
@@ -0,0 +1,51 @@
+#ifndef SERVERDISCOVERY_H
+#define SERVERDISCOVERY_H
+
+#include <QObject>
+#include <QUdpSocket>
+#include <QTimer>
+#include "../../shared/networkmessage.h"
+
+class ServerDiscovery : public QObject
+{
+ Q_OBJECT
+
+ public:
+ enum class ErrorType{
+ InvalidIpList,
+ InvalidHash
+ };
+
+ explicit ServerDiscovery(QObject *parent = 0);
+ ~ServerDiscovery();
+
+ void start(const QByteArray& sessionName);
+ void stop();
+ inline bool isActive(){ return _discoveryTimer.isActive(); }
+
+ private:
+ QTimer _discoveryTimer;
+ int _hashErrorCount;
+ int _ipErrorCount;
+ QByteArray _nameBytes;
+ QByteArray _salt2;
+ QUdpSocket _discoverySocket;
+ NetworkMessage _packet;
+
+ static const int UDPBUFSIZ = 9000;
+ static const int SALT_LEN = 18;
+
+public:
+ signals:
+ void serverDetected(const QString& host, const quint16 port, const QByteArray& sessionName, const QByteArray& certHash);
+ void error(ErrorType e, int count);
+
+ public slots:
+
+ private slots:
+ void doDiscovery();
+ void onUdpReadyRead();
+
+};
+
+#endif // SERVERDISCOVERY_H
diff --git a/src/client/toolbar/toolbar.cpp b/src/client/toolbar/toolbar.cpp
index 88d4b2a..9bc5998 100644
--- a/src/client/toolbar/toolbar.cpp
+++ b/src/client/toolbar/toolbar.cpp
@@ -174,8 +174,7 @@ void Toolbar::onVncServerIsRunning(int port)
*/
void Toolbar::onDisconnected()
{
- _connectWindow->setConnected(false);
- if (_connection != NULL)
+ if (_connection != NULL)
_connection->blockSignals(true);
_connection = NULL;
_ui->lblStatus->setStyleSheet("color:red");
@@ -205,7 +204,6 @@ void Toolbar::onConnected(ServerConnection* connection)
_vnc, SLOT(open(const QString&, int, const QString&, bool, bool, const QString&, const int)));
connect(_connection, SIGNAL(closeVnc()), _vnc, SLOT(close()));
connect(_vnc, SIGNAL(running(const bool, const int)), _connection, SLOT(onVncViewerStartStop(const bool, const int)));
- _connectWindow->setConnected(true);
}
/***************************************************************************//**
diff --git a/src/client/vnc/vncserver.cpp b/src/client/vnc/vncserver.cpp
index 2b341fb..77beda2 100644
--- a/src/client/vnc/vncserver.cpp
+++ b/src/client/vnc/vncserver.cpp
@@ -12,12 +12,12 @@
#include "vncserver.h"
#include "../util/util.h"
-/*******************************************
- * STATIC
- *******************************************/
-
VncServer* VncServer::me = NULL;
+/***************************************************************************//**
+ * @brief VncServer::instance
+ * @return
+ */
VncServer* VncServer::instance()
{
if (me == NULL)
@@ -25,7 +25,11 @@ VncServer* VncServer::instance()
return me;
}
-//
+/***************************************************************************//**
+ * @brief makePassword
+ * @param len
+ * @return
+ */
static QString makePassword(int len = 10)
{
char pass[len];
@@ -34,27 +38,27 @@ static QString makePassword(int len = 10)
return QString::fromUtf8(pass, len);
}
-// Ugly hack to get an el-cheapo platform independent sleep
+/***************************************************************************//**
+ * @brief Ugly hack to get an el-cheapo platform independent sleep
+ */
struct Sleeper : public QThread
{
-static void msleep(unsigned long msecs) { QThread::msleep(msecs); }
+ static void msleep(unsigned long msecs) { QThread::msleep(msecs); }
};
-/*******************************************
- * INSTANCE
- *******************************************/
-
-VncServer::VncServer() :
- _process(NULL), _port(0), _timerId(0)
-{
- // TODO Auto-generated constructor stub
-}
+/***************************************************************************//**
+ * @brief VncServer::VncServer
+ */
+VncServer::VncServer() : _process(NULL), _port(0), _timerId(0){}
-VncServer::~VncServer()
-{
- // TODO Auto-generated destructor stub
-}
+/***************************************************************************//**
+ * @brief VncServer::~VncServer
+ */
+VncServer::~VncServer(){}
+/***************************************************************************//**
+ * @brief VncServer::start
+ */
void VncServer::start()
{
// Keep things clean
@@ -117,6 +121,9 @@ void VncServer::start()
_process->start("x11vnc", args, QIODevice::ReadOnly);
}
+/***************************************************************************//**
+ * @brief VncServer::stop
+ */
void VncServer::stop()
{
if (_timerId != 0)
@@ -142,13 +149,16 @@ void VncServer::stop()
process->deleteLater();
}
+
/*
* Overrides
*/
-/**
- * Timer event, currently only used to assume VNC server setup failed
+
+/***************************************************************************//**
+ * @brief Timer event, currently only used to assume VNC server setup failed
* after 3 seconds...
+ * @param event
*/
void VncServer::timerEvent(QTimerEvent *event)
{
@@ -157,10 +167,15 @@ void VncServer::timerEvent(QTimerEvent *event)
emit started(0, _ropass, _rwpass);
}
+
/*
* Slots
*/
+
+/***************************************************************************//**
+ * @brief VncServer::onStdOut
+ */
void VncServer::onStdOut()
{
if (_process == NULL)
@@ -188,6 +203,9 @@ void VncServer::onStdOut()
}
}
+/***************************************************************************//**
+ * @brief VncServer::onStdErr
+ */
void VncServer::onStdErr()
{
if (_process == NULL)
@@ -198,12 +216,20 @@ void VncServer::onStdErr()
QByteArray data(_process->readAllStandardError());
}
+/***************************************************************************//**
+ * @brief VncServer::onError
+ * @param error
+ */
void VncServer::onError(QProcess::ProcessError error)
{
this->stop();
emit started(0, _ropass, _rwpass);
}
+/***************************************************************************//**
+ * @brief VncServer::onFinished
+ * @param exitCode
+ */
void VncServer::onFinished(int exitCode)
{
this->stop();
diff --git a/src/server/mainwindow/mainwindow.cpp b/src/server/mainwindow/mainwindow.cpp
index 590d5ab..21cde86 100644
--- a/src/server/mainwindow/mainwindow.cpp
+++ b/src/server/mainwindow/mainwindow.cpp
@@ -364,6 +364,20 @@ void MainWindow::mouseReleaseEvent(QMouseEvent* e)
}
}
+/***************************************************************************//**
+ * @brief reset
+ */
+void MainWindow::reset()
+{
+ // Unlock all clients
+ for (QList<ConnectionFrame*>::iterator it(_clientFrames.begin()); it != _clientFrames.end(); ++it)
+ if ((*it)->client() != NULL)
+ (*it)->client()->lockScreen(false);
+
+ // Stop server (Clients get stopped on ACK)
+ if (_streamingSource != NULL)
+ _streamingSource->stopVncServer();
+}
/*
* Slots
@@ -529,6 +543,8 @@ void MainWindow::onButtonHelp()
*/
void MainWindow::onButtonTutorToAll()
{
+ ui->action_Lock->setChecked(false);
+
if (_tutorFrame == NULL)
QMessageBox::critical(this, tr("Projection"), sStrTutorNdef);
else if (_tutorFrame->client() == NULL)
@@ -544,6 +560,8 @@ void MainWindow::onButtonTutorToAll()
*/
void MainWindow::onButtonStudentToAll()
{
+ ui->action_Lock->setChecked(false);
+
if (_selectedFrame == NULL)
QMessageBox::critical(this, tr("Projection"), sStrSourceNdef);
if (_selectedFrame->client() == NULL)
@@ -558,6 +576,8 @@ void MainWindow::onButtonStudentToAll()
*/
void MainWindow::onButtonTutorToStudent()
{
+ ui->action_Lock->setChecked(false);
+
if (_selectedFrame == NULL)
QMessageBox::critical(this, tr("Projection"), sStrDestNdef);
else if (_tutorFrame == NULL)
@@ -578,6 +598,8 @@ void MainWindow::onButtonTutorToStudent()
*/
void MainWindow::onButtonStudentToTutor()
{
+ ui->action_Lock->setChecked(false);
+
if (_selectedFrame == NULL)
QMessageBox::critical(this, tr("Projection"), sStrSourceNdef);
else if (_tutorFrame == NULL)
@@ -598,6 +620,8 @@ void MainWindow::onButtonStudentToTutor()
*/
void MainWindow::onButtonStudentToTutorExclusive()
{
+ ui->action_Lock->setChecked(false);
+
if (_selectedFrame == NULL)
QMessageBox::critical(this, tr("Projection"), sStrSourceNdef);
else if (_tutorFrame == NULL)
@@ -609,7 +633,7 @@ void MainWindow::onButtonStudentToTutorExclusive()
else if (_tutorFrame->client() == NULL)
QMessageBox::critical(this, tr("Projection"), sStrTutorOffline);
else
- changeProjection(_tutorFrame->client(), Mode::LockedMulticast, _selectedFrame->client());
+ changeProjection(_selectedFrame->client(), Mode::LockedMulticast, _tutorFrame->client());
}
@@ -620,14 +644,8 @@ void MainWindow::onButtonStudentToTutorExclusive()
*/
void MainWindow::onButtonStopProjection()
{
- // Unlock all clients
- for (QList<ConnectionFrame*>::iterator it(_clientFrames.begin()); it != _clientFrames.end(); ++it)
- if ((*it)->client() != NULL)
- (*it)->client()->lockScreen(false);
-
- // Stop server (Clients get stopped on ACK)
- if (_streamingSource != NULL)
- _streamingSource->startVncServer();
+ ui->action_Lock->setChecked(false);
+ reset();
}
/***************************************************************************//**
@@ -638,6 +656,9 @@ void MainWindow::onButtonStopProjection()
*/
void MainWindow::onButtonLock(bool checked)
{
+ // Stop all projections
+ reset();
+
for (QList<ConnectionFrame*>::iterator it(_clientFrames.begin()); it != _clientFrames.end(); ++it)
{
// Check if client is Tutor or the manager is also running on this machine.
@@ -662,6 +683,8 @@ void MainWindow::onButtonExit()
*/
void MainWindow::onButtonSetAsTutor()
{
+ ui->action_Lock->setChecked(false);
+
// If no frame is selected, warning.
if (_selectedFrame == NULL)
{
diff --git a/src/server/mainwindow/mainwindow.h b/src/server/mainwindow/mainwindow.h
index 3866db5..0d0d650 100644
--- a/src/server/mainwindow/mainwindow.h
+++ b/src/server/mainwindow/mainwindow.h
@@ -79,6 +79,7 @@ private:
void changeProjection(Client *from, Mode mode = Mode::Broadcast, Client *to = NULL);
void tellClientCurrentSituation(Client* client);
bool isManagerMachine(Client* client);
+ void reset();
void closeEvent(QCloseEvent *e);
void changeEvent(QEvent *e);
diff --git a/src/server/net/client.cpp b/src/server/net/client.cpp
index abd739d..135157c 100644
--- a/src/server/net/client.cpp
+++ b/src/server/net/client.cpp
@@ -46,8 +46,8 @@ Client::Client(QSslSocket* socket) : _socket(socket)
msgChlng.setField(_CHALLENGE, _challenge);
msgChlng.writeMessage(_socket);
// give client 3 seconds to complete handshake
- _timerIdAuthTimeout = startTimer(3000);
- _timerPingTimeout = startTimer(600000); // for debugging purposes 10min
+ _timerIdAuthTimeout = startTimer(600000);// TODO undo, for debugging purposes 10min
+ _timerPingTimeout = startTimer(600000); // TODO undo, for debugging purposes 10min
_pingTimeout = QDateTime::currentMSecsSinceEpoch() + PING_TIMEOUT_MS;
}
@@ -169,7 +169,6 @@ void Client::handleMsg()
if (_vncPort <= 0)
{
qDebug() << "Starting VNC server on client" << _name << " (" << _socket->peerAddress().toString()+_vncPort << ") failed.";
- // TODO: Show message on manager
}
else
{
diff --git a/src/server/net/discoverylistener.cpp b/src/server/net/discoverylistener.cpp
index b308a09..f3d7d39 100644
--- a/src/server/net/discoverylistener.cpp
+++ b/src/server/net/discoverylistener.cpp
@@ -25,6 +25,33 @@
// +++ static ++++ hash ip address +++
+
+/***************************************************************************//**
+ * @brief DiscoveryListener::DiscoveryListener
+ */
+DiscoveryListener::DiscoveryListener() :
+ _socket(this), _counterResetPos(0)
+{
+ if (!_socket.bind(SERVICE_DISCOVERY_PORT))
+ qFatal("Could not bind to service discovery port %d", (int)SERVICE_DISCOVERY_PORT);
+ connect(&_socket, SIGNAL(readyRead()), this, SLOT(onReadyRead()));
+ for (int i = 0; i < SD_PACKET_TABLE_SIZE; ++i)
+ _packetCounter[i] = 0;
+ startTimer((SPAM_MODERATE_AT_ONCE * SPAM_MODERATE_INTERVAL) / SD_PACKET_TABLE_SIZE + 1);
+}
+
+/***************************************************************************//**
+ * @brief DiscoveryListener::~DiscoveryListener
+ */
+DiscoveryListener::~DiscoveryListener()
+{
+}
+
+/***************************************************************************//**
+ * @brief hash
+ * @param host
+ * @return
+ */
static quint16 hash(const QHostAddress& host)
{
static quint16 seed1 = 0, seed2 = 0;
@@ -70,30 +97,13 @@ static quint16 hash(const QHostAddress& host)
return result;
}
-// +++++++++++++++++++++++++++++++++++
-
-DiscoveryListener::DiscoveryListener() :
- _socket(this), _counterResetPos(0)
-{
- if (!_socket.bind(SERVICE_DISCOVERY_PORT))
- qFatal("Could not bind to service discovery port %d", (int)SERVICE_DISCOVERY_PORT);
- connect(&_socket, SIGNAL(readyRead()), this, SLOT(onReadyRead()));
- for (int i = 0; i < SD_PACKET_TABLE_SIZE; ++i)
- _packetCounter[i] = 0;
- startTimer((SPAM_MODERATE_AT_ONCE * SPAM_MODERATE_INTERVAL) / SD_PACKET_TABLE_SIZE + 1);
-}
-
-DiscoveryListener::~DiscoveryListener()
-{
- // TODO Auto-generated destructor stub
-}
-
/*
* Overrides
*/
-/**
- * Decrease packet counters per source IP in our "spam protection" table.
+/***************************************************************************//**
+ * @brief Decrease packet counters per source IP in our "spam protection" table.
+ * @param event
*/
void DiscoveryListener::timerEvent(QTimerEvent* event)
{
@@ -112,8 +122,8 @@ void DiscoveryListener::timerEvent(QTimerEvent* event)
* Slots
*/
-/**
- * Incoming UDP packet on service discovery port - handle.
+/***************************************************************************//**
+ * @brief Incoming UDP packet on service discovery port - handle.
*/
void DiscoveryListener::onReadyRead()
{