summaryrefslogtreecommitdiffstats
path: root/src/client/connectwindow/connectwindow.cpp
diff options
context:
space:
mode:
authorManuel Schneider2014-05-28 00:37:28 +0200
committerManuel Schneider2014-05-28 00:37:28 +0200
commitafc69ca4ffb0e11d9d06b8ddd31ee40963f86f17 (patch)
treef7284ba33e98d2bb6e099f248c7b127282efa99f /src/client/connectwindow/connectwindow.cpp
parentRemove TODO. User get visual feedback via cam icon. (diff)
downloadpvs2-afc69ca4ffb0e11d9d06b8ddd31ee40963f86f17.tar.gz
pvs2-afc69ca4ffb0e11d9d06b8ddd31ee40963f86f17.tar.xz
pvs2-afc69ca4ffb0e11d9d06b8ddd31ee40963f86f17.zip
Outsource serverDiscovery.
Diffstat (limited to 'src/client/connectwindow/connectwindow.cpp')
-rw-r--r--src/client/connectwindow/connectwindow.cpp233
1 files changed, 72 insertions, 161 deletions
diff --git a/src/client/connectwindow/connectwindow.cpp b/src/client/connectwindow/connectwindow.cpp
index c8f7efd..34087ad 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);
-}
-
-ConnectWindow::~ConnectWindow(){}
+ // React on discovery signal
+ connect(&_serverDiscovery, SIGNAL(serverDetected(QString,quint16,QByteArray,QByteArray)),
+ this, SLOT(onServerDetected(QString,quint16,QByteArray,QByteArray)));
-/**
- * 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(_ui->lineEditName->text().toUtf8());
}
/*
* Slots
*/
-/**
+/***************************************************************************//**
* Handle click on Connect/Disconnect button.
* If already connected --> Stop/disconnect.
* Else scanning for given sessionId.
@@ -258,17 +180,19 @@ 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)
{
// Stop or disconnect
- _timerDiscover = 0;
emit disconnect();
- this->setState(Idle);
+ _state = Idle;
+ this->updateState();
}
else
{
@@ -277,7 +201,7 @@ void ConnectWindow::onBtnConnection()
}
}
-/**
+/***************************************************************************//**
* Handle click on Cancel/Hide Button.
* Just hide the window.
*/
@@ -286,53 +210,24 @@ 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
*/
@@ -341,7 +236,10 @@ void ConnectWindow::onConnectionStateChange(ConnectWindow::ConnectionState state
bool reset = (_state == Scanning);
if (state == InvalidSslHash)
++_hashSslErrorCount;
- this->setState(state);
+
+ _state = state;
+ this->updateState();
+
if (reset)
_state = Scanning;
if (state == Connected)
@@ -349,12 +247,16 @@ void ConnectWindow::onConnectionStateChange(ConnectWindow::ConnectionState state
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 +264,12 @@ void ConnectWindow::onConnectionClosed(QObject* connection)
{
_connection = NULL;
}
+
+/***************************************************************************//**
+ * @brief ConnectWindow::onConnectionDisconnected
+ */
+void ConnectWindow::onConnectionDisconnected()
+{
+ _connected = false;
+ this->updateState();
+}