Update socket error and documentation

This commit is contained in:
Simon Stürz 2018-08-17 15:54:59 +02:00
parent f6e2d9b3b2
commit f28ac0f4e3
16 changed files with 74 additions and 37 deletions

View File

@ -391,15 +391,15 @@ Once the server is up and running with the dummy authenticator, you can try to c
> *Note:* assuming you are starting the client on the same system as the server: > *Note:* assuming you are starting the client on the same system as the server:
$ nymea-remoteproxy-client -u wss://127.0.0.1:443 -t "dummytoken" $ nymea-remoteproxy-client -i -u wss://127.0.0.1:443 -t "dummytoken"
Open a second terminal and start the same command again. Open a second terminal and start the same command again.
> *Note:* assuming you are starting the client on the same system as the server: > *Note:* assuming you are starting the client on the same system as the server:
$ nymea-remoteproxy-client -u wss://127.0.0.1:443 -t "dummytoken" $ nymea-remoteproxy-client -i -u wss://127.0.0.1:443 -t "dummytoken"
You can follow the connection flow on all parts using the `--very-verbose` option. You can follow the connection flow on both sides using the `--very-verbose` option.
# License # License

View File

@ -80,7 +80,6 @@ void ProxyClient::onRemoteConnectionEstablished()
void ProxyClient::onDataReady(const QByteArray &data) void ProxyClient::onDataReady(const QByteArray &data)
{ {
qCDebug(dcProxyClient()) << "<--" << qUtf8Printable(data); qCDebug(dcProxyClient()) << "<--" << qUtf8Printable(data);
if (m_pingpong) { if (m_pingpong) {
QTimer::singleShot(1000, this, &ProxyClient::sendPing); QTimer::singleShot(1000, this, &ProxyClient::sendPing);
} }

View File

@ -103,7 +103,7 @@ void MonitorServer::onMonitorDisconnected()
} }
void MonitorServer::startServer() void MonitorServer::startServer()
{ {
qCDebug(dcMonitorServer()) << "Starting server on" << m_serverName; qCDebug(dcMonitorServer()) << "Starting server on" << m_serverName;
m_server = new QLocalServer(this); m_server = new QLocalServer(this);
if (!m_server->listen(m_serverName)) { if (!m_server->listen(m_serverName)) {

View File

@ -21,14 +21,17 @@
#include "proxyclient.h" #include "proxyclient.h"
#include <QDateTime>
namespace remoteproxy { namespace remoteproxy {
ProxyClient::ProxyClient(TransportInterface *interface, const QUuid &clientId, QObject *parent) : ProxyClient::ProxyClient(TransportInterface *interface, const QUuid &clientId, const QHostAddress &address, QObject *parent) :
QObject(parent), QObject(parent),
m_interface(interface), m_interface(interface),
m_clientId(clientId) m_clientId(clientId),
m_peerAddress(address)
{ {
m_creationTimeStamp = QDateTime::currentDateTime().toTime_t();
} }
QUuid ProxyClient::clientId() const QUuid ProxyClient::clientId() const
@ -36,6 +39,21 @@ QUuid ProxyClient::clientId() const
return m_clientId; return m_clientId;
} }
QHostAddress ProxyClient::peerAddress() const
{
return m_peerAddress;
}
uint ProxyClient::creationTime() const
{
return m_creationTimeStamp;
}
QString ProxyClient::creationTimeString() const
{
return QDateTime::fromTime_t(creationTime()).toString("dd.MM.yyyy hh:mm:ss");
}
bool ProxyClient::isAuthenticated() const bool ProxyClient::isAuthenticated() const
{ {
return m_authenticated; return m_authenticated;
@ -102,7 +120,9 @@ void ProxyClient::setToken(const QString &token)
QDebug operator<<(QDebug debug, ProxyClient *proxyClient) QDebug operator<<(QDebug debug, ProxyClient *proxyClient)
{ {
debug.nospace() << "ProxyClient(" << proxyClient->interface()->serverName(); debug.nospace() << "ProxyClient(" << proxyClient->interface()->serverName();
debug.nospace() << ", " << proxyClient->clientId().toString() << ") "; debug.nospace() << ", " << proxyClient->clientId().toString();
debug.nospace() << ", " << proxyClient->peerAddress().toString() << ") ";
debug.nospace() << ", " << proxyClient->creationTimeString() << ") ";
return debug; return debug;
} }

View File

@ -25,6 +25,7 @@
#include <QUuid> #include <QUuid>
#include <QDebug> #include <QDebug>
#include <QObject> #include <QObject>
#include <QHostAddress>
#include "transportinterface.h" #include "transportinterface.h"
@ -35,9 +36,13 @@ class ProxyClient : public QObject
Q_OBJECT Q_OBJECT
public: public:
explicit ProxyClient(TransportInterface *interface, const QUuid &clientId, QObject *parent = nullptr); explicit ProxyClient(TransportInterface *interface, const QUuid &clientId, const QHostAddress &address, QObject *parent = nullptr);
QUuid clientId() const; QUuid clientId() const;
QHostAddress peerAddress() const;
uint creationTime() const;
QString creationTimeString() const;
bool isAuthenticated() const; bool isAuthenticated() const;
void setAuthenticated(bool isAuthenticated); void setAuthenticated(bool isAuthenticated);
@ -60,8 +65,13 @@ public:
private: private:
TransportInterface *m_interface = nullptr; TransportInterface *m_interface = nullptr;
QUuid m_clientId; QUuid m_clientId;
QHostAddress m_peerAddress;
uint m_creationTimeStamp = 0;
bool m_authenticated = false; bool m_authenticated = false;
bool m_tunnelConnected = false; bool m_tunnelConnected = false;
QString m_uuid; QString m_uuid;
QString m_name; QString m_name;
QString m_token; QString m_token;

View File

@ -140,13 +140,13 @@ void ProxyServer::establishTunnel(ProxyClient *firstClient, ProxyClient *secondC
Q_ARG(ProxyClient *, tunnel.clientTwo())); Q_ARG(ProxyClient *, tunnel.clientTwo()));
} }
void ProxyServer::onClientConnected(const QUuid &clientId) void ProxyServer::onClientConnected(const QUuid &clientId, const QHostAddress &address)
{ {
TransportInterface *interface = static_cast<TransportInterface *>(sender()); TransportInterface *interface = static_cast<TransportInterface *>(sender());
qCDebug(dcProxyServer()) << "New client connected" << interface->serverName() << clientId.toString(); qCDebug(dcProxyServer()) << "New client connected" << interface->serverName() << clientId.toString() << address.toString();
ProxyClient *proxyClient = new ProxyClient(interface, clientId, this); ProxyClient *proxyClient = new ProxyClient(interface, clientId, address, this);
connect(proxyClient, &ProxyClient::authenticated, this, &ProxyServer::onProxyClientAuthenticated); connect(proxyClient, &ProxyClient::authenticated, this, &ProxyServer::onProxyClientAuthenticated);
connect(proxyClient, &ProxyClient::tunnelConnected, this, &ProxyServer::onProxyClientTunnelConnected); connect(proxyClient, &ProxyClient::tunnelConnected, this, &ProxyServer::onProxyClientTunnelConnected);

View File

@ -71,7 +71,7 @@ signals:
void runningChanged(); void runningChanged();
private slots: private slots:
void onClientConnected(const QUuid &clientId); void onClientConnected(const QUuid &clientId, const QHostAddress &address);
void onClientDisconnected(const QUuid &clientId); void onClientDisconnected(const QUuid &clientId);
void onClientDataAvailable(const QUuid &clientId, const QByteArray &data); void onClientDataAvailable(const QUuid &clientId, const QByteArray &data);

View File

@ -23,6 +23,7 @@
#define TRANSPORTINTERFACE_H #define TRANSPORTINTERFACE_H
#include <QObject> #include <QObject>
#include <QHostAddress>
namespace remoteproxy { namespace remoteproxy {
@ -41,7 +42,7 @@ public:
virtual void killClientConnection(const QUuid &clientId, const QString &killReason) = 0; virtual void killClientConnection(const QUuid &clientId, const QString &killReason) = 0;
signals: signals:
void clientConnected(const QUuid &clientId); void clientConnected(const QUuid &clientId, const QHostAddress &address);
void clientDisconnected(const QUuid &clientId); void clientDisconnected(const QUuid &clientId);
void dataAvailable(const QUuid &clientId, const QByteArray &data); void dataAvailable(const QUuid &clientId, const QByteArray &data);

View File

@ -116,7 +116,7 @@ void WebSocketServer::onClientConnected()
connect(client, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(onClientError(QAbstractSocket::SocketError))); connect(client, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(onClientError(QAbstractSocket::SocketError)));
connect(client, SIGNAL(disconnected()), this, SLOT(onClientDisconnected())); connect(client, SIGNAL(disconnected()), this, SLOT(onClientDisconnected()));
emit clientConnected(clientId); emit clientConnected(clientId, client->peerAddress());
} }
void WebSocketServer::onClientDisconnected() void WebSocketServer::onClientDisconnected()

View File

@ -53,7 +53,7 @@ protected:
signals: signals:
void connectedChanged(bool connected); void connectedChanged(bool connected);
void dataReceived(const QByteArray &data); void dataReceived(const QByteArray &data);
void errorOccured(); void errorOccured(QAbstractSocket::SocketError error);
void sslErrors(const QList<QSslError> &errors); void sslErrors(const QList<QSslError> &errors);
public slots: public slots:

View File

@ -244,8 +244,9 @@ void RemoteProxyConnection::onConnectionDataAvailable(const QByteArray &data)
} }
} }
void RemoteProxyConnection::onConnectionSocketError() void RemoteProxyConnection::onConnectionSocketError(QAbstractSocket::SocketError error)
{ {
emit socketErrorOccured(error);
setError(ErrorSocketError); setError(ErrorSocketError);
} }
@ -305,9 +306,8 @@ void RemoteProxyConnection::onTunnelEstablished(const QString &clientName, const
bool RemoteProxyConnection::connectServer(const QUrl &url) bool RemoteProxyConnection::connectServer(const QUrl &url)
{ {
// Verify url
// FIXME: support also tcp
if (url.scheme() != "wss") { if (url.scheme() != "wss") {
// FIXME: support also tcp
qCWarning(dcRemoteProxyClientConnection()) << "Unsupported connection type" << url.scheme() << "Default to wss"; qCWarning(dcRemoteProxyClientConnection()) << "Unsupported connection type" << url.scheme() << "Default to wss";
m_serverUrl.setScheme("wss"); m_serverUrl.setScheme("wss");
} }

View File

@ -49,7 +49,6 @@ public:
Q_ENUM(ConnectionType) Q_ENUM(ConnectionType)
enum State { enum State {
StateHostLookup,
StateConnecting, StateConnecting,
StateConnected, StateConnected,
StateInitializing, StateInitializing,
@ -137,6 +136,7 @@ signals:
void stateChanged(RemoteProxyConnection::State state); void stateChanged(RemoteProxyConnection::State state);
void errorOccured(RemoteProxyConnection::Error error); void errorOccured(RemoteProxyConnection::Error error);
void socketErrorOccured(QAbstractSocket::SocketError error);
void sslErrors(const QList<QSslError> &errors); void sslErrors(const QList<QSslError> &errors);
void dataReady(const QByteArray &data); void dataReady(const QByteArray &data);
@ -144,7 +144,7 @@ signals:
private slots: private slots:
void onConnectionChanged(bool isConnected); void onConnectionChanged(bool isConnected);
void onConnectionDataAvailable(const QByteArray &data); void onConnectionDataAvailable(const QByteArray &data);
void onConnectionSocketError(); void onConnectionSocketError(QAbstractSocket::SocketError error);
void onHelloFinished(); void onHelloFinished();
void onAuthenticateFinished(); void onAuthenticateFinished();

View File

@ -73,7 +73,7 @@ void WebSocketConnection::onDisconnected()
void WebSocketConnection::onError(QAbstractSocket::SocketError error) void WebSocketConnection::onError(QAbstractSocket::SocketError error)
{ {
qCDebug(dcRemoteProxyClientWebSocket()) << "Socket error occured" << error << m_webSocket->errorString(); qCDebug(dcRemoteProxyClientWebSocket()) << "Socket error occured" << error << m_webSocket->errorString();
emit errorOccured(); emit errorOccured(error);
} }
void WebSocketConnection::onStateChanged(QAbstractSocket::SocketState state) void WebSocketConnection::onStateChanged(QAbstractSocket::SocketState state)

View File

@ -61,6 +61,7 @@ private slots:
public slots: public slots:
void connectServer(const QUrl &serverUrl) override; void connectServer(const QUrl &serverUrl) override;
void disconnectServer() override; void disconnectServer() override;
}; };
} }

View File

@ -287,11 +287,21 @@ void RemoteProxyOfflineTests::remoteConnection()
m_mockAuthenticator->setTimeoutDuration(100); m_mockAuthenticator->setTimeoutDuration(100);
m_mockAuthenticator->setExpectedAuthenticationError(); m_mockAuthenticator->setExpectedAuthenticationError();
QString nameConnectionOne = "Test client one";
QUuid uuidConnectionOne = QUuid::createUuid();
QString nameConnectionTwo = "Test client two";
QUuid uuidConnectionTwo = QUuid::createUuid();
QByteArray dataOne = "Hello from client one :-)";
QByteArray dataTwo = "Hello from client two :-)";
// Create two connection // Create two connection
RemoteProxyConnection *connectionOne = new RemoteProxyConnection(QUuid::createUuid(), "Test client one", this); RemoteProxyConnection *connectionOne = new RemoteProxyConnection(uuidConnectionOne, nameConnectionOne, this);
connect(connectionOne, &RemoteProxyConnection::sslErrors, this, &BaseTest::ignoreConnectionSslError); connect(connectionOne, &RemoteProxyConnection::sslErrors, this, &BaseTest::ignoreConnectionSslError);
RemoteProxyConnection *connectionTwo = new RemoteProxyConnection(QUuid::createUuid(), "Test client two", this); RemoteProxyConnection *connectionTwo = new RemoteProxyConnection(uuidConnectionTwo, nameConnectionTwo, this);
connect(connectionTwo, &RemoteProxyConnection::sslErrors, this, &BaseTest::ignoreConnectionSslError); connect(connectionTwo, &RemoteProxyConnection::sslErrors, this, &BaseTest::ignoreConnectionSslError);
// Connect one // Connect one
@ -336,27 +346,25 @@ void RemoteProxyOfflineTests::remoteConnection()
QVERIFY(connectionOne->state() == RemoteProxyConnection::StateRemoteConnected); QVERIFY(connectionOne->state() == RemoteProxyConnection::StateRemoteConnected);
QVERIFY(connectionTwo->state() == RemoteProxyConnection::StateRemoteConnected); QVERIFY(connectionTwo->state() == RemoteProxyConnection::StateRemoteConnected);
QCOMPARE(connectionOne->tunnelPartnerName(), nameConnectionTwo);
QCOMPARE(connectionOne->tunnelPartnerUuid(), uuidConnectionTwo.toString());
QCOMPARE(connectionTwo->tunnelPartnerName(), nameConnectionOne);
QCOMPARE(connectionTwo->tunnelPartnerUuid(), uuidConnectionOne.toString());
// Pipe data trought the tunnel // Pipe data trought the tunnel
QSignalSpy remoteConnectionDataOne(connectionOne, &RemoteProxyConnection::dataReady); QSignalSpy remoteConnectionDataOne(connectionOne, &RemoteProxyConnection::dataReady);
QSignalSpy remoteConnectionDataTwo(connectionTwo, &RemoteProxyConnection::dataReady); QSignalSpy remoteConnectionDataTwo(connectionTwo, &RemoteProxyConnection::dataReady);
QByteArray dataOne = "Hello from client one :-)";
QByteArray dataTwo = "Hello from client two :-)";
connectionOne->sendData(dataOne); connectionOne->sendData(dataOne);
remoteConnectionDataTwo.wait(500); remoteConnectionDataTwo.wait(500);
QVERIFY(remoteConnectionDataTwo.count() == 1); QVERIFY(remoteConnectionDataTwo.count() == 1);
QCOMPARE(remoteConnectionDataTwo.at(0).at(0).toByteArray(), dataOne); QCOMPARE(remoteConnectionDataTwo.at(0).at(0).toByteArray(), dataOne);
// verify if data is the same
connectionTwo->sendData(dataTwo); connectionTwo->sendData(dataTwo);
remoteConnectionDataOne.wait(500); remoteConnectionDataOne.wait(500);
QVERIFY(remoteConnectionDataOne.count() == 1); QVERIFY(remoteConnectionDataOne.count() == 1);
QCOMPARE(remoteConnectionDataOne.at(0).at(0).toByteArray(), dataTwo); QCOMPARE(remoteConnectionDataOne.at(0).at(0).toByteArray(), dataTwo);
// verify if data is the same
connectionOne->deleteLater(); connectionOne->deleteLater();
connectionTwo->deleteLater(); connectionTwo->deleteLater();
@ -380,7 +388,7 @@ void RemoteProxyOfflineTests::trippleConnection()
RemoteProxyConnection *connectionTwo = new RemoteProxyConnection(QUuid::createUuid(), "Test client two", this); RemoteProxyConnection *connectionTwo = new RemoteProxyConnection(QUuid::createUuid(), "Test client two", this);
connect(connectionTwo, &RemoteProxyConnection::sslErrors, this, &BaseTest::ignoreConnectionSslError); connect(connectionTwo, &RemoteProxyConnection::sslErrors, this, &BaseTest::ignoreConnectionSslError);
RemoteProxyConnection *connectionThree = new RemoteProxyConnection(QUuid::createUuid(), "Token thief ^w^", this); RemoteProxyConnection *connectionThree = new RemoteProxyConnection(QUuid::createUuid(), "Token thief ^v^", this);
connect(connectionThree, &RemoteProxyConnection::sslErrors, this, &BaseTest::ignoreConnectionSslError); connect(connectionThree, &RemoteProxyConnection::sslErrors, this, &BaseTest::ignoreConnectionSslError);
// Connect one // Connect one
@ -479,10 +487,6 @@ void RemoteProxyOfflineTests::timeout()
// Start the server // Start the server
startServer(); startServer();
// Configure result
// Start the server
startServer();
// Configure result // Configure result
m_mockAuthenticator->setExpectedAuthenticationError(); m_mockAuthenticator->setExpectedAuthenticationError();
m_mockAuthenticator->setTimeoutDuration(6000); m_mockAuthenticator->setTimeoutDuration(6000);
@ -495,6 +499,7 @@ void RemoteProxyOfflineTests::timeout()
QVariant response = invokeApiCall("Authentication.Authenticate", params); QVariant response = invokeApiCall("Authentication.Authenticate", params);
qDebug() << qUtf8Printable(QJsonDocument::fromVariant(response).toJson(QJsonDocument::Indented)); qDebug() << qUtf8Printable(QJsonDocument::fromVariant(response).toJson(QJsonDocument::Indented));
// Clean up // Clean up
stopServer(); stopServer();
} }

View File

@ -41,6 +41,7 @@ class RemoteProxyOnlineTests : public BaseTest
Q_OBJECT Q_OBJECT
public: public:
explicit RemoteProxyOnlineTests(QObject *parent = nullptr); explicit RemoteProxyOnlineTests(QObject *parent = nullptr);
~RemoteProxyOnlineTests() = default;
private slots: private slots:
void awsStaticCredentials(); void awsStaticCredentials();