From 8f9bdcce1336a6851296e429b675e1df343d0f82 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20St=C3=BCrz?= Date: Fri, 30 Jul 2021 18:35:54 +0200 Subject: [PATCH] Start implementing client library tunnel classes --- .../libnymea-remoteproxyclient.pri | 8 +- .../proxyjsonrpcclient.cpp | 13 + .../proxyjsonrpcclient.h | 6 + .../tunnelproxy/tunnelproxyjsonrpcclient.cpp | 37 --- .../tunnelproxy/tunnelproxyjsonrpcclient.h | 48 --- .../tunnelproxyremoteconnection.cpp | 6 + .../tunnelproxy/tunnelproxyremoteconnection.h | 16 + .../tunnelproxy/tunnelproxyserver.cpp | 84 ------ .../tunnelproxy/tunnelproxysocketserver.cpp | 277 ++++++++++++++++++ ...roxyserver.h => tunnelproxysocketserver.h} | 60 +++- tests/test-proxy/remoteproxytestsproxy.cpp | 46 +-- .../remoteproxyteststunnelproxy.cpp | 42 +++ .../remoteproxyteststunnelproxy.h | 6 +- tests/testbase/basetest.cpp | 4 +- tests/testbase/basetest.h | 8 +- 15 files changed, 447 insertions(+), 214 deletions(-) delete mode 100644 libnymea-remoteproxyclient/tunnelproxy/tunnelproxyjsonrpcclient.cpp delete mode 100644 libnymea-remoteproxyclient/tunnelproxy/tunnelproxyjsonrpcclient.h create mode 100644 libnymea-remoteproxyclient/tunnelproxy/tunnelproxyremoteconnection.cpp create mode 100644 libnymea-remoteproxyclient/tunnelproxy/tunnelproxyremoteconnection.h delete mode 100644 libnymea-remoteproxyclient/tunnelproxy/tunnelproxyserver.cpp create mode 100644 libnymea-remoteproxyclient/tunnelproxy/tunnelproxysocketserver.cpp rename libnymea-remoteproxyclient/tunnelproxy/{tunnelproxyserver.h => tunnelproxysocketserver.h} (59%) diff --git a/libnymea-remoteproxyclient/libnymea-remoteproxyclient.pri b/libnymea-remoteproxyclient/libnymea-remoteproxyclient.pri index 92e3a0e..199675b 100644 --- a/libnymea-remoteproxyclient/libnymea-remoteproxyclient.pri +++ b/libnymea-remoteproxyclient/libnymea-remoteproxyclient.pri @@ -1,24 +1,24 @@ INCLUDEPATH += $$PWD HEADERS += \ - $$PWD/tunnelproxy/tunnelproxyjsonrpcclient.h \ + $$PWD/tunnelproxy/tunnelproxyremoteconnection.h \ $$PWD/tunnelproxy/tunnelproxysocket.h \ - $$PWD/tunnelproxy/tunnelproxyserver.h \ $$PWD/tcpsocketconnection.h \ $$PWD/proxyjsonrpcclient.h \ $$PWD/jsonreply.h \ $$PWD/remoteproxyconnection.h \ $$PWD/proxyconnection.h \ + $$PWD/tunnelproxy/tunnelproxysocketserver.h \ $$PWD/websocketconnection.h SOURCES += \ - $$PWD/tunnelproxy/tunnelproxyjsonrpcclient.cpp \ + $$PWD/tunnelproxy/tunnelproxyremoteconnection.cpp \ $$PWD/tunnelproxy/tunnelproxysocket.cpp \ - $$PWD/tunnelproxy/tunnelproxyserver.cpp \ $$PWD/tcpsocketconnection.cpp \ $$PWD/proxyjsonrpcclient.cpp \ $$PWD/jsonreply.cpp \ $$PWD/remoteproxyconnection.cpp \ $$PWD/proxyconnection.cpp \ + $$PWD/tunnelproxy/tunnelproxysocketserver.cpp \ $$PWD/websocketconnection.cpp diff --git a/libnymea-remoteproxyclient/proxyjsonrpcclient.cpp b/libnymea-remoteproxyclient/proxyjsonrpcclient.cpp index 962d7e7..c2e04db 100644 --- a/libnymea-remoteproxyclient/proxyjsonrpcclient.cpp +++ b/libnymea-remoteproxyclient/proxyjsonrpcclient.cpp @@ -66,6 +66,19 @@ JsonReply *JsonRpcClient::callAuthenticate(const QUuid &clientUuid, const QStrin return reply; } +JsonReply *JsonRpcClient::callRegisterServer(const QUuid &serverUuid, const QString &serverName) +{ + QVariantMap params; + params.insert("serverName", serverName); + params.insert("serverUuid", serverUuid.toString()); + + JsonReply *reply = new JsonReply(m_commandId, "TunnelProxy", "RegisterServer", params, this); + qCDebug(dcRemoteProxyClientJsonRpc()) << "Calling" << QString("%1.%2").arg(reply->nameSpace()).arg(reply->method()); + sendRequest(reply->requestMap()); + m_replies.insert(m_commandId, reply); + return reply; +} + void JsonRpcClient::sendRequest(const QVariantMap &request) { QByteArray data = QJsonDocument::fromVariant(request).toJson(QJsonDocument::Compact); diff --git a/libnymea-remoteproxyclient/proxyjsonrpcclient.h b/libnymea-remoteproxyclient/proxyjsonrpcclient.h index b16488b..b3cb0bf 100644 --- a/libnymea-remoteproxyclient/proxyjsonrpcclient.h +++ b/libnymea-remoteproxyclient/proxyjsonrpcclient.h @@ -47,9 +47,15 @@ class JsonRpcClient : public QObject public: explicit JsonRpcClient(ProxyConnection *connection, QObject *parent = nullptr); + // General JsonReply *callHello(); + + // Proxy JsonReply *callAuthenticate(const QUuid &clientUuid, const QString &clientName, const QString &token, const QString &nonce); + // Tunnel proxy + JsonReply *callRegisterServer(const QUuid &serverUuid, const QString &serverName); + private: ProxyConnection *m_connection = nullptr; diff --git a/libnymea-remoteproxyclient/tunnelproxy/tunnelproxyjsonrpcclient.cpp b/libnymea-remoteproxyclient/tunnelproxy/tunnelproxyjsonrpcclient.cpp deleted file mode 100644 index 83a1778..0000000 --- a/libnymea-remoteproxyclient/tunnelproxy/tunnelproxyjsonrpcclient.cpp +++ /dev/null @@ -1,37 +0,0 @@ -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * -* -* Copyright 2013 - 2021, nymea GmbH -* Contact: contact@nymea.io -* -* This file is part of nymea. -* This project including source code and documentation is protected by copyright law, and -* remains the property of nymea GmbH. All rights, including reproduction, publication, -* editing and translation, are reserved. The use of this project is subject to the terms of a -* license agreement to be concluded with nymea GmbH in accordance with the terms -* of use of nymea GmbH, available under https://nymea.io/license -* -* GNU Lesser General Public License Usage -* Alternatively, this project may be redistributed and/or modified under the terms of the GNU -* Lesser General Public License as published by the Free Software Foundation; version 3. -* this project 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. -* -* You should have received a copy of the GNU Lesser General Public License along with this project. -* If not, see . -* -* For any further details and any questions please contact us under contact@nymea.io -* or see our FAQ/Licensing Information on https://nymea.io/license/faq -* -* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ - -#include "tunnelproxyjsonrpcclient.h" - -namespace remoteproxyclient { - -TunnelProxyJsonRpcClient::TunnelProxyJsonRpcClient(QObject *parent) : QObject(parent) -{ - -} - -} diff --git a/libnymea-remoteproxyclient/tunnelproxy/tunnelproxyjsonrpcclient.h b/libnymea-remoteproxyclient/tunnelproxy/tunnelproxyjsonrpcclient.h deleted file mode 100644 index 0c4b0b0..0000000 --- a/libnymea-remoteproxyclient/tunnelproxy/tunnelproxyjsonrpcclient.h +++ /dev/null @@ -1,48 +0,0 @@ -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * -* -* Copyright 2013 - 2021, nymea GmbH -* Contact: contact@nymea.io -* -* This file is part of nymea. -* This project including source code and documentation is protected by copyright law, and -* remains the property of nymea GmbH. All rights, including reproduction, publication, -* editing and translation, are reserved. The use of this project is subject to the terms of a -* license agreement to be concluded with nymea GmbH in accordance with the terms -* of use of nymea GmbH, available under https://nymea.io/license -* -* GNU Lesser General Public License Usage -* Alternatively, this project may be redistributed and/or modified under the terms of the GNU -* Lesser General Public License as published by the Free Software Foundation; version 3. -* this project 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. -* -* You should have received a copy of the GNU Lesser General Public License along with this project. -* If not, see . -* -* For any further details and any questions please contact us under contact@nymea.io -* or see our FAQ/Licensing Information on https://nymea.io/license/faq -* -* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ - -#ifndef TUNNELPROXYJSONRPCCLIENT_H -#define TUNNELPROXYJSONRPCCLIENT_H - -#include - -namespace remoteproxyclient { - -class TunnelProxyJsonRpcClient : public QObject -{ - Q_OBJECT - -public: - explicit TunnelProxyJsonRpcClient(QObject *parent = nullptr); - -signals: - -}; - -} - -#endif // TUNNELPROXYJSONRPCCLIENT_H diff --git a/libnymea-remoteproxyclient/tunnelproxy/tunnelproxyremoteconnection.cpp b/libnymea-remoteproxyclient/tunnelproxy/tunnelproxyremoteconnection.cpp new file mode 100644 index 0000000..7a2e44b --- /dev/null +++ b/libnymea-remoteproxyclient/tunnelproxy/tunnelproxyremoteconnection.cpp @@ -0,0 +1,6 @@ +#include "tunnelproxyremoteconnection.h" + +TunnelProxyRemoteConnection::TunnelProxyRemoteConnection(QObject *parent) : QObject(parent) +{ + +} diff --git a/libnymea-remoteproxyclient/tunnelproxy/tunnelproxyremoteconnection.h b/libnymea-remoteproxyclient/tunnelproxy/tunnelproxyremoteconnection.h new file mode 100644 index 0000000..c649e74 --- /dev/null +++ b/libnymea-remoteproxyclient/tunnelproxy/tunnelproxyremoteconnection.h @@ -0,0 +1,16 @@ +#ifndef TUNNELPROXYREMOTECONNECTION_H +#define TUNNELPROXYREMOTECONNECTION_H + +#include + +class TunnelProxyRemoteConnection : public QObject +{ + Q_OBJECT +public: + explicit TunnelProxyRemoteConnection(QObject *parent = nullptr); + +signals: + +}; + +#endif // TUNNELPROXYREMOTECONNECTION_H diff --git a/libnymea-remoteproxyclient/tunnelproxy/tunnelproxyserver.cpp b/libnymea-remoteproxyclient/tunnelproxy/tunnelproxyserver.cpp deleted file mode 100644 index c0f22f2..0000000 --- a/libnymea-remoteproxyclient/tunnelproxy/tunnelproxyserver.cpp +++ /dev/null @@ -1,84 +0,0 @@ -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * -* -* Copyright 2013 - 2021, nymea GmbH -* Contact: contact@nymea.io -* -* This file is part of nymea. -* This project including source code and documentation is protected by copyright law, and -* remains the property of nymea GmbH. All rights, including reproduction, publication, -* editing and translation, are reserved. The use of this project is subject to the terms of a -* license agreement to be concluded with nymea GmbH in accordance with the terms -* of use of nymea GmbH, available under https://nymea.io/license -* -* GNU Lesser General Public License Usage -* Alternatively, this project may be redistributed and/or modified under the terms of the GNU -* Lesser General Public License as published by the Free Software Foundation; version 3. -* this project 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. -* -* You should have received a copy of the GNU Lesser General Public License along with this project. -* If not, see . -* -* For any further details and any questions please contact us under contact@nymea.io -* or see our FAQ/Licensing Information on https://nymea.io/license/faq -* -* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ - -#include "tunnelproxyserver.h" -#include "proxyconnection.h" -#include "tcpsocketconnection.h" -#include "websocketconnection.h" - -namespace remoteproxyclient { - -TunnelProxyServer::TunnelProxyServer(const QUuid &serverUuid, const QString &serverName, QObject *parent) : - QObject(parent), - m_serverUuid(serverUuid), - m_serverName(serverName) -{ - -} - -TunnelProxyServer::TunnelProxyServer(const QUuid &serverUuid, const QString &serverName, ConnectionType connectionType, QObject *parent) : - QObject(parent), - m_serverUuid(serverUuid), - m_serverName(serverName), - m_connectionType(connectionType) -{ - -} - -TunnelProxyServer::~TunnelProxyServer() -{ - -} - -bool TunnelProxyServer::running() const -{ - return m_running; -} - -void TunnelProxyServer::ignoreSslErrors() -{ - m_connection->ignoreSslErrors(); - -} - -void TunnelProxyServer::ignoreSslErrors(const QList &errors) -{ - m_connection->ignoreSslErrors(errors); -} - -void remoteproxyclient::TunnelProxyServer::startServer(const QUrl &serverUrl) -{ - // Register as server to the remote proxy - m_serverUrl = serverUrl; -} - -void remoteproxyclient::TunnelProxyServer::stopServer() -{ - // Close the server connection and all related sockets -} - -} diff --git a/libnymea-remoteproxyclient/tunnelproxy/tunnelproxysocketserver.cpp b/libnymea-remoteproxyclient/tunnelproxy/tunnelproxysocketserver.cpp new file mode 100644 index 0000000..67576c2 --- /dev/null +++ b/libnymea-remoteproxyclient/tunnelproxy/tunnelproxysocketserver.cpp @@ -0,0 +1,277 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +* +* Copyright 2013 - 2021, nymea GmbH +* Contact: contact@nymea.io +* +* This file is part of nymea. +* This project including source code and documentation is protected by copyright law, and +* remains the property of nymea GmbH. All rights, including reproduction, publication, +* editing and translation, are reserved. The use of this project is subject to the terms of a +* license agreement to be concluded with nymea GmbH in accordance with the terms +* of use of nymea GmbH, available under https://nymea.io/license +* +* GNU Lesser General Public License Usage +* Alternatively, this project may be redistributed and/or modified under the terms of the GNU +* Lesser General Public License as published by the Free Software Foundation; version 3. +* this project 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. +* +* You should have received a copy of the GNU Lesser General Public License along with this project. +* If not, see . +* +* For any further details and any questions please contact us under contact@nymea.io +* or see our FAQ/Licensing Information on https://nymea.io/license/faq +* +* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +#include "tunnelproxysocketserver.h" +#include "proxyconnection.h" +#include "tcpsocketconnection.h" +#include "websocketconnection.h" +#include "proxyjsonrpcclient.h" + +Q_LOGGING_CATEGORY(dcTunnelProxySocketServer, "dcTunnelProxySocketServer") + +namespace remoteproxyclient { + +TunnelProxySocketServer::TunnelProxySocketServer(const QUuid &serverUuid, const QString &serverName, QObject *parent) : + QObject(parent), + m_serverUuid(serverUuid), + m_serverName(serverName) +{ + +} + +TunnelProxySocketServer::TunnelProxySocketServer(const QUuid &serverUuid, const QString &serverName, ConnectionType connectionType, QObject *parent) : + QObject(parent), + m_serverUuid(serverUuid), + m_serverName(serverName), + m_connectionType(connectionType) +{ + +} + +TunnelProxySocketServer::~TunnelProxySocketServer() +{ + +} + +bool TunnelProxySocketServer::running() const +{ + return m_running; +} + +QAbstractSocket::SocketError TunnelProxySocketServer::error() const +{ + return m_error; +} + +void TunnelProxySocketServer::ignoreSslErrors() +{ + m_connection->ignoreSslErrors(); + +} + +void TunnelProxySocketServer::ignoreSslErrors(const QList &errors) +{ + m_connection->ignoreSslErrors(errors); +} + +void TunnelProxySocketServer::startServer(const QUrl &serverUrl) +{ + m_serverUrl = serverUrl; + m_error = QAbstractSocket::UnknownSocketError; + + cleanUp(); + + switch (m_connectionType) { + case ConnectionTypeWebSocket: + qCDebug(dcTunnelProxySocketServer()) << "Creating a web socket connection to" << m_serverUrl.toString(); + m_connection = qobject_cast(new WebSocketConnection(this)); + break; + case ConnectionTypeTcpSocket: + qCDebug(dcTunnelProxySocketServer()) << "Creating a TCP socket connection to" << m_serverUrl.toString(); + m_connection = qobject_cast(new TcpSocketConnection(this)); + break; + } + + connect(m_connection, &ProxyConnection::connectedChanged, this, &TunnelProxySocketServer::onConnectionChanged); + connect(m_connection, &ProxyConnection::dataReceived, this, &TunnelProxySocketServer::onConnectionDataAvailable); + connect(m_connection, &ProxyConnection::errorOccured, this, &TunnelProxySocketServer::onConnectionSocketError); + connect(m_connection, &ProxyConnection::stateChanged, this, &TunnelProxySocketServer::onConnectionStateChanged); + connect(m_connection, &ProxyConnection::sslErrors, this, &TunnelProxySocketServer::sslErrors); + + m_jsonClient = new JsonRpcClient(m_connection, this); +// connect(m_jsonClient, &JsonRpcClient::tunnelEstablished, this, &RemoteProxyConnection::onTunnelEstablished); + + qCDebug(dcTunnelProxySocketServer()) << "Connecting to" << m_serverUrl.toString(); + m_connection->connectServer(m_serverUrl); +} + +void TunnelProxySocketServer::stopServer() +{ + // Close the server connection and all related sockets +} + +void TunnelProxySocketServer::onConnectionChanged(bool connected) +{ + if (connected) { + qCDebug(dcTunnelProxySocketServer()) << "Connected to remote proxy server."; + setState(StateConnected); + + setState(StateInitializing); + JsonReply *reply = m_jsonClient->callHello(); + connect(reply, &JsonReply::finished, this, &TunnelProxySocketServer::onHelloFinished); + } else { + qCDebug(dcTunnelProxySocketServer()) << "Disconnected from remote proxy server."; + setState(StateDisconnected); + cleanUp(); + } +} + +void TunnelProxySocketServer::onConnectionDataAvailable(const QByteArray &data) +{ + if (m_state != StateRunning) { + m_jsonClient->processData(data); + return; + } + + // Parse SLIP +} + +void TunnelProxySocketServer::onConnectionSocketError(QAbstractSocket::SocketError error) +{ + setError(error); +} + +void TunnelProxySocketServer::onConnectionStateChanged(QAbstractSocket::SocketState state) +{ + // Process the actuall socket state + switch (state) { + case QAbstractSocket::UnconnectedState: + setState(StateDisconnected); + break; + case QAbstractSocket::HostLookupState: + setState(StateHostLookup); + break; + case QAbstractSocket::ConnectingState: + setState(StateConnecting); + break; + case QAbstractSocket::ConnectedState: + setState(StateConnected); + break; + case QAbstractSocket::ClosingState: + setState(StateDiconnecting); + break; + case QAbstractSocket::BoundState: + case QAbstractSocket::ListeningState: + break; + } +} + +void TunnelProxySocketServer::onHelloFinished() +{ + JsonReply *reply = static_cast(sender()); + reply->deleteLater(); + + QVariantMap response = reply->response(); + qCDebug(dcTunnelProxySocketServer()) << "Hello response ready" << reply->commandId() << response; + + if (response.value("status").toString() != "success") { + qCWarning(dcTunnelProxySocketServer()) << "Could not get initial information from proxy server."; + m_connection->disconnectServer(); + return; + } + + QVariantMap responseParams = response.value("params").toMap(); + m_remoteProxyServer = responseParams.value("server").toString(); + m_remoteProxyServerName = responseParams.value("name").toString(); + m_remoteProxyServerVersion = responseParams.value("version").toString(); + m_remoteProxyApiVersion = responseParams.value("apiVersion").toString(); + + setState(StateRegister); + + JsonReply *registerReply = m_jsonClient->callRegisterServer(m_serverUuid, m_serverName); + connect(registerReply, &JsonReply::finished, this, &TunnelProxySocketServer::onServerRegistrationFinished); +} + +void TunnelProxySocketServer::onServerRegistrationFinished() +{ + JsonReply *reply = static_cast(sender()); + reply->deleteLater(); + + QVariantMap response = reply->response(); + qCDebug(dcTunnelProxySocketServer()) << "RegisterServer response ready" << reply->commandId() << response; + + if (response.value("status").toString() != "success") { + qCWarning(dcTunnelProxySocketServer()) << "JSON RPC error. Failed to register as tunnel server on the remote proxy server."; + m_connection->disconnectServer(); + return; + } + + QVariantMap responseParams = response.value("params").toMap(); + if (responseParams.value("tunnelProxyError").toString() != "TunnelProxyErrorNoError") { + qCWarning(dcTunnelProxySocketServer()) << "Failed to register as tunnel server on the remote proxy server:" << responseParams.value("tunnelProxyError").toString(); + m_connection->disconnectServer(); + return; + } + + qCDebug(dcTunnelProxySocketServer()) << "Registered successfully as tunnel server on the remote proxy server."; + setState(StateRunning); +} + +void TunnelProxySocketServer::setState(State state) +{ + if (m_state == state) + return; + + m_state = state; + qCDebug(dcTunnelProxySocketServer()) << "State changed" << m_state; + emit stateChanged(m_state); + + setRunning(m_state == StateRunning); +} + +void TunnelProxySocketServer::setRunning(bool running) +{ + if (m_running == running) + return; + + qCDebug(dcTunnelProxySocketServer()) << "The TunnelProxy server" << (running ? "is now up and running. Listening for remote clients" : "not running any more."); + m_running = running; + emit runningChanged(m_running); +} + +void TunnelProxySocketServer::setError(QAbstractSocket::SocketError error) +{ + if (m_error == error) + return; + + m_error = error; + qCDebug(dcTunnelProxySocketServer()) << "Error occured" << m_error; + emit errorOccured(m_error); +} + +void TunnelProxySocketServer::cleanUp() +{ + // TODO: cleanup client connections + + + if (m_jsonClient) { + m_jsonClient->deleteLater(); + m_jsonClient = nullptr; + } + + if (m_connection) { + m_connection->deleteLater(); + m_connection = nullptr; + } + +// m_serverName = QString(); +// m_serverUuid = QUuid(); + + setState(StateDisconnected); +} + +} diff --git a/libnymea-remoteproxyclient/tunnelproxy/tunnelproxyserver.h b/libnymea-remoteproxyclient/tunnelproxy/tunnelproxysocketserver.h similarity index 59% rename from libnymea-remoteproxyclient/tunnelproxy/tunnelproxyserver.h rename to libnymea-remoteproxyclient/tunnelproxy/tunnelproxysocketserver.h index 6dba0af..15b4926 100644 --- a/libnymea-remoteproxyclient/tunnelproxy/tunnelproxyserver.h +++ b/libnymea-remoteproxyclient/tunnelproxy/tunnelproxysocketserver.h @@ -25,14 +25,14 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -#ifndef TUNNELPROXYSERVER_H -#define TUNNELPROXYSERVER_H +#ifndef TUNNELPROXYSOCKETSERVER_H +#define TUNNELPROXYSOCKETSERVER_H #include #include #include -Q_DECLARE_LOGGING_CATEGORY(dcRemoteProxyTunnelProxyServer) +Q_DECLARE_LOGGING_CATEGORY(dcTunnelProxySocketServer) #include "proxyconnection.h" #include "tunnelproxysocket.h" @@ -40,21 +40,33 @@ Q_DECLARE_LOGGING_CATEGORY(dcRemoteProxyTunnelProxyServer) namespace remoteproxyclient { class ProxyConnection; -class TunnelProxyJsonRpcClient; +class JsonRpcClient; -class TunnelProxyServer : public QObject +class TunnelProxySocketServer : public QObject { Q_OBJECT public: + enum State { + StateConnecting, + StateHostLookup, + StateConnected, + StateInitializing, + StateRegister, + StateRunning, + StateDiconnecting, + StateDisconnected, + }; + Q_ENUM(State) + enum ConnectionType { ConnectionTypeWebSocket, ConnectionTypeTcpSocket }; Q_ENUM(ConnectionType) - explicit TunnelProxyServer(const QUuid &serverUuid, const QString &serverName, QObject *parent = nullptr); - explicit TunnelProxyServer(const QUuid &serverUuid, const QString &serverName, ConnectionType connectionType, QObject *parent = nullptr); - ~TunnelProxyServer(); + explicit TunnelProxySocketServer(const QUuid &serverUuid, const QString &serverName, QObject *parent = nullptr); + explicit TunnelProxySocketServer(const QUuid &serverUuid, const QString &serverName, ConnectionType connectionType, QObject *parent = nullptr); + ~TunnelProxySocketServer(); bool running() const; @@ -69,22 +81,50 @@ public slots: signals: void runningChanged(bool running); + + void stateChanged(TunnelProxySocketServer::State state); + void errorOccured(QAbstractSocket::SocketError error); void sslErrors(const QList &errors); + +private slots: + void onConnectionChanged(bool connected); + void onConnectionDataAvailable(const QByteArray &data); + + void onConnectionSocketError(QAbstractSocket::SocketError error); + void onConnectionStateChanged(QAbstractSocket::SocketState state); + + // Initialization calls + void onHelloFinished(); + void onServerRegistrationFinished(); + private: + // This server information QUuid m_serverUuid; QString m_serverName; ConnectionType m_connectionType = ConnectionTypeTcpSocket; + // Remote proxy server information + QString m_remoteProxyServer; + QString m_remoteProxyServerName; + QString m_remoteProxyServerVersion; + QString m_remoteProxyApiVersion; + bool m_running = false; QUrl m_serverUrl; QAbstractSocket::SocketError m_error = QAbstractSocket::UnknownSocketError; + State m_state = StateDisconnected; ProxyConnection *m_connection = nullptr; - TunnelProxyJsonRpcClient *m_jsonClient = nullptr; + JsonRpcClient *m_jsonClient = nullptr; + void setState(State state); + void setRunning(bool running); + void setError(QAbstractSocket::SocketError error); + + void cleanUp(); }; } -#endif // TUNNELPROXYSERVER_H +#endif // TUNNELPROXYSOCKETSERVER_H diff --git a/tests/test-proxy/remoteproxytestsproxy.cpp b/tests/test-proxy/remoteproxytestsproxy.cpp index 9a57216..2c6f164 100644 --- a/tests/test-proxy/remoteproxytestsproxy.cpp +++ b/tests/test-proxy/remoteproxytestsproxy.cpp @@ -128,14 +128,14 @@ void RemoteProxyTestsProxy::monitorServer() // Connect one QSignalSpy connectionOneReadySpy(connectionOne, &RemoteProxyConnection::ready); - QVERIFY(connectionOne->connectServer(m_serverUrl)); + QVERIFY(connectionOne->connectServer(m_serverUrlProxyWebSocket)); connectionOneReadySpy.wait(); QVERIFY(connectionOneReadySpy.count() == 1); QVERIFY(connectionOne->isConnected()); // Connect two QSignalSpy connectionTwoReadySpy(connectionTwo, &RemoteProxyConnection::ready); - QVERIFY(connectionTwo->connectServer(m_serverUrl)); + QVERIFY(connectionTwo->connectServer(m_serverUrlProxyWebSocket)); connectionTwoReadySpy.wait(); QVERIFY(connectionTwoReadySpy.count() == 1); QVERIFY(connectionTwo->isConnected()); @@ -597,14 +597,14 @@ void RemoteProxyTestsProxy::authenticateNonce() // Connect one QSignalSpy connectionOneReadySpy(connectionOne, &RemoteProxyConnection::ready); - QVERIFY(connectionOne->connectServer(m_serverUrl)); + QVERIFY(connectionOne->connectServer(m_serverUrlProxyWebSocket)); connectionOneReadySpy.wait(); QVERIFY(connectionOneReadySpy.count() == 1); QVERIFY(connectionOne->isConnected()); // Connect two QSignalSpy connectionTwoReadySpy(connectionTwo, &RemoteProxyConnection::ready); - QVERIFY(connectionTwo->connectServer(m_serverUrl)); + QVERIFY(connectionTwo->connectServer(m_serverUrlProxyWebSocket)); connectionTwoReadySpy.wait(); QVERIFY(connectionTwoReadySpy.count() == 1); QVERIFY(connectionTwo->isConnected()); @@ -724,14 +724,14 @@ void RemoteProxyTestsProxy::clientConnectionWebSocket() // Connect to server (insecue enabled for testing) QSignalSpy readySpy(connection, &RemoteProxyConnection::ready); - QVERIFY(connection->connectServer(m_serverUrl)); + QVERIFY(connection->connectServer(m_serverUrlProxyWebSocket)); readySpy.wait(); QVERIFY(readySpy.count() == 1); QVERIFY(connection->isConnected()); QVERIFY(!connection->isRemoteConnected()); QVERIFY(connection->state() == RemoteProxyConnection::StateReady); QVERIFY(connection->error() == QAbstractSocket::UnknownSocketError); - QVERIFY(connection->serverUrl() == m_serverUrl); + QVERIFY(connection->serverUrl() == m_serverUrlProxyWebSocket); QVERIFY(connection->connectionType() == RemoteProxyConnection::ConnectionTypeWebSocket); QVERIFY(connection->serverName() == SERVER_NAME_STRING); QVERIFY(connection->proxyServerName() == Engine::instance()->serverName()); @@ -774,14 +774,14 @@ void RemoteProxyTestsProxy::clientConnectionTcpSocket() // Connect to server (insecue enabled for testing) QSignalSpy readySpy(connection, &RemoteProxyConnection::ready); - QVERIFY(connection->connectServer(m_serverUrlTcp)); + QVERIFY(connection->connectServer(m_serverUrlProxyTcp)); readySpy.wait(); QVERIFY(readySpy.count() == 1); QVERIFY(connection->isConnected()); QVERIFY(!connection->isRemoteConnected()); QVERIFY(connection->state() == RemoteProxyConnection::StateReady); QVERIFY(connection->error() == QAbstractSocket::UnknownSocketError); - QVERIFY(connection->serverUrl() == m_serverUrlTcp); + QVERIFY(connection->serverUrl() == m_serverUrlProxyTcp); QVERIFY(connection->connectionType() == RemoteProxyConnection::ConnectionTypeTcpSocket); QVERIFY(connection->serverName() == SERVER_NAME_STRING); QVERIFY(connection->proxyServerName() == Engine::instance()->serverName()); @@ -836,14 +836,14 @@ void RemoteProxyTestsProxy::remoteConnection() // Connect one QSignalSpy connectionOneReadySpy(connectionOne, &RemoteProxyConnection::ready); - QVERIFY(connectionOne->connectServer(m_serverUrl)); + QVERIFY(connectionOne->connectServer(m_serverUrlProxyWebSocket)); connectionOneReadySpy.wait(); QVERIFY(connectionOneReadySpy.count() == 1); QVERIFY(connectionOne->isConnected()); // Connect two QSignalSpy connectionTwoReadySpy(connectionTwo, &RemoteProxyConnection::ready); - QVERIFY(connectionTwo->connectServer(m_serverUrl)); + QVERIFY(connectionTwo->connectServer(m_serverUrlProxyWebSocket)); connectionTwoReadySpy.wait(); QVERIFY(connectionTwoReadySpy.count() == 1); QVERIFY(connectionTwo->isConnected()); @@ -955,14 +955,14 @@ void RemoteProxyTestsProxy::trippleConnection() // Connect one QSignalSpy connectionOneReadySpy(connectionOne, &RemoteProxyConnection::ready); - QVERIFY(connectionOne->connectServer(m_serverUrl)); + QVERIFY(connectionOne->connectServer(m_serverUrlProxyWebSocket)); connectionOneReadySpy.wait(); QVERIFY(connectionOneReadySpy.count() == 1); QVERIFY(connectionOne->isConnected()); // Connect two QSignalSpy connectionTwoReadySpy(connectionTwo, &RemoteProxyConnection::ready); - QVERIFY(connectionTwo->connectServer(m_serverUrl)); + QVERIFY(connectionTwo->connectServer(m_serverUrlProxyWebSocket)); connectionTwoReadySpy.wait(); QVERIFY(connectionTwoReadySpy.count() == 1); QVERIFY(connectionTwo->isConnected()); @@ -995,7 +995,7 @@ void RemoteProxyTestsProxy::trippleConnection() // Connect three QSignalSpy connectionThreeReadySpy(connectionThree, &RemoteProxyConnection::ready); QSignalSpy connectionThreeDisconnectedSpy(connectionThree, &RemoteProxyConnection::disconnected); - QVERIFY(connectionThree->connectServer(m_serverUrl)); + QVERIFY(connectionThree->connectServer(m_serverUrlProxyWebSocket)); connectionThreeReadySpy.wait(); QVERIFY(connectionThreeReadySpy.count() == 1); QVERIFY(connectionThree->isConnected()); @@ -1040,14 +1040,14 @@ void RemoteProxyTestsProxy::duplicateUuid() // Connect one QSignalSpy connectionOneReadySpy(connectionOne, &RemoteProxyConnection::ready); - QVERIFY(connectionOne->connectServer(m_serverUrl)); + QVERIFY(connectionOne->connectServer(m_serverUrlProxyWebSocket)); connectionOneReadySpy.wait(); QVERIFY(connectionOneReadySpy.count() == 1); QVERIFY(connectionOne->isConnected()); // Connect two QSignalSpy connectionTwoReadySpy(connectionTwo, &RemoteProxyConnection::ready); - QVERIFY(connectionTwo->connectServer(m_serverUrl)); + QVERIFY(connectionTwo->connectServer(m_serverUrlProxyWebSocket)); connectionTwoReadySpy.wait(); QVERIFY(connectionTwoReadySpy.count() == 1); QVERIFY(connectionTwo->isConnected()); @@ -1087,7 +1087,7 @@ void RemoteProxyTestsProxy::sslConfigurations() // Connect to the server (insecure disabled) RemoteProxyConnection *connector = new RemoteProxyConnection(QUuid::createUuid(), "Test client one", this); QSignalSpy spyError(connector, &RemoteProxyConnection::errorOccured); - QVERIFY(connector->connectServer(m_serverUrl)); + QVERIFY(connector->connectServer(m_serverUrlProxyWebSocket)); spyError.wait(); QVERIFY(spyError.count() == 1); qDebug() << connector->error(); @@ -1097,7 +1097,7 @@ void RemoteProxyTestsProxy::sslConfigurations() // Connect to server (insecue enabled) QSignalSpy spyConnected(connector, &RemoteProxyConnection::connected); connect(connector, &RemoteProxyConnection::sslErrors, this, &BaseTest::ignoreConnectionSslError); - connector->connectServer(m_serverUrl); + connector->connectServer(m_serverUrlProxyWebSocket); spyConnected.wait(); QVERIFY(connector->isConnected()); @@ -1152,7 +1152,7 @@ void RemoteProxyTestsProxy::inactiveTimeout() // Connect one QSignalSpy connectionReadySpy(connection, &RemoteProxyConnection::ready); QSignalSpy connectionDisconnectedSpy(connection, &RemoteProxyConnection::disconnected); - QVERIFY(connection->connectServer(m_serverUrl)); + QVERIFY(connection->connectServer(m_serverUrlProxyWebSocket)); connectionReadySpy.wait(); QVERIFY(connectionReadySpy.count() == 1); @@ -1209,7 +1209,7 @@ void RemoteProxyTestsProxy::authenticationReplyConnection() // Connect one QSignalSpy connectionReadySpy(connection, &RemoteProxyConnection::ready); - QVERIFY(connection->connectServer(m_serverUrl)); + QVERIFY(connection->connectServer(m_serverUrlProxyWebSocket)); connectionReadySpy.wait(); QVERIFY(connectionReadySpy.count() == 1); @@ -1251,14 +1251,14 @@ void RemoteProxyTestsProxy::tcpRemoteConnection() // Connect one QSignalSpy connectionOneReadySpy(connectionOne, &RemoteProxyConnection::ready); - QVERIFY(connectionOne->connectServer(m_serverUrlTcp)); + QVERIFY(connectionOne->connectServer(m_serverUrlProxyTcp)); connectionOneReadySpy.wait(); QVERIFY(connectionOneReadySpy.count() == 1); QVERIFY(connectionOne->isConnected()); // Connect two QSignalSpy connectionTwoReadySpy(connectionTwo, &RemoteProxyConnection::ready); - QVERIFY(connectionTwo->connectServer(m_serverUrlTcp)); + QVERIFY(connectionTwo->connectServer(m_serverUrlProxyTcp)); connectionTwoReadySpy.wait(); QVERIFY(connectionTwoReadySpy.count() == 1); QVERIFY(connectionTwo->isConnected()); @@ -1345,14 +1345,14 @@ void RemoteProxyTestsProxy::tcpWebsocketRemoteConnection() // Connect one QSignalSpy connectionOneReadySpy(connectionOne, &RemoteProxyConnection::ready); - QVERIFY(connectionOne->connectServer(m_serverUrl)); + QVERIFY(connectionOne->connectServer(m_serverUrlProxyWebSocket)); connectionOneReadySpy.wait(); QVERIFY(connectionOneReadySpy.count() == 1); QVERIFY(connectionOne->isConnected()); // Connect two QSignalSpy connectionTwoReadySpy(connectionTwo, &RemoteProxyConnection::ready); - QVERIFY(connectionTwo->connectServer(m_serverUrlTcp)); + QVERIFY(connectionTwo->connectServer(m_serverUrlProxyTcp)); connectionTwoReadySpy.wait(); QVERIFY(connectionTwoReadySpy.count() == 1); QVERIFY(connectionTwo->isConnected()); diff --git a/tests/test-tunnelproxy/remoteproxyteststunnelproxy.cpp b/tests/test-tunnelproxy/remoteproxyteststunnelproxy.cpp index 6d049b7..f8217bf 100644 --- a/tests/test-tunnelproxy/remoteproxyteststunnelproxy.cpp +++ b/tests/test-tunnelproxy/remoteproxyteststunnelproxy.cpp @@ -31,6 +31,9 @@ #include "loggingcategories.h" #include "remoteproxyconnection.h" +// Client +#include "tunnelproxy/tunnelproxysocketserver.h" + #include #include #include @@ -541,5 +544,44 @@ void RemoteProxyTestsTunnelProxy::crossRegisterServerClient() stopServer(); } +void RemoteProxyTestsTunnelProxy::testTunnelProxyServer() +{ + // Start the server + startServer(); + + resetDebugCategories(); + addDebugCategory("TunnelProxyServer.debug=true"); + addDebugCategory("JsonRpcTraffic.debug=true"); + addDebugCategory("TunnelProxySocketServer.debug=true"); + + // Tunnel proxy socket server + QString serverName = "SuperDuper server name"; + QUuid serverUuid = QUuid::createUuid(); + + TunnelProxySocketServer *tunnelProxyServer = new TunnelProxySocketServer(serverUuid, serverName, this); + connect(tunnelProxyServer, &TunnelProxySocketServer::sslErrors, this, [=](const QList &errors){ + tunnelProxyServer->ignoreSslErrors(errors); + }); + + tunnelProxyServer->startServer(m_serverUrlTunnelProxyTcp); + + QSignalSpy serverRunningSpy(tunnelProxyServer, &TunnelProxySocketServer::runningChanged); + serverRunningSpy.wait(); + QVERIFY(serverRunningSpy.count() == 1); + QList arguments = serverRunningSpy.takeFirst(); + QVERIFY(arguments.at(0).toBool() == true); + QVERIFY(tunnelProxyServer->running()); + + + // Tunnel proxy client connection + + + + resetDebugCategories(); + + // Clean up + stopServer(); +} + QTEST_MAIN(RemoteProxyTestsTunnelProxy) diff --git a/tests/test-tunnelproxy/remoteproxyteststunnelproxy.h b/tests/test-tunnelproxy/remoteproxyteststunnelproxy.h index 022036a..c4d40cb 100644 --- a/tests/test-tunnelproxy/remoteproxyteststunnelproxy.h +++ b/tests/test-tunnelproxy/remoteproxyteststunnelproxy.h @@ -44,7 +44,7 @@ private slots: // Basic stuff void startStopServer(); - // WebSocket connection API + // Raw api calls void getIntrospect(); void getHello(); @@ -60,11 +60,13 @@ private slots: void registerClient_data(); void registerClient(); - void registerServerDuplicated(); void registerClientDuplicated(); void crossRegisterServerClient(); + // Client classes + void testTunnelProxyServer(); + }; #endif // REMOTEPROXYTESTSTUNNELPROXY_H diff --git a/tests/testbase/basetest.cpp b/tests/testbase/basetest.cpp index 320444f..cd55fef 100644 --- a/tests/testbase/basetest.cpp +++ b/tests/testbase/basetest.cpp @@ -322,7 +322,7 @@ bool BaseTest::createRemoteConnection(const QString &token, const QString &nonce // Connect one QSignalSpy connectionOneReadySpy(connectionOne, &RemoteProxyConnection::ready); - if (!connectionOne->connectServer(m_serverUrl)) { + if (!connectionOne->connectServer(m_serverUrlProxyWebSocket)) { qWarning() << "Could not connect client one"; return false; } @@ -340,7 +340,7 @@ bool BaseTest::createRemoteConnection(const QString &token, const QString &nonce // Connect two QSignalSpy connectionTwoReadySpy(connectionTwo, &RemoteProxyConnection::ready); - if (!connectionTwo->connectServer(m_serverUrl)) { + if (!connectionTwo->connectServer(m_serverUrlProxyWebSocket)) { qWarning() << "Could not connect client two"; return false; } diff --git a/tests/testbase/basetest.h b/tests/testbase/basetest.h index a3c07d1..5d321e2 100644 --- a/tests/testbase/basetest.h +++ b/tests/testbase/basetest.h @@ -56,11 +56,11 @@ public: protected: ProxyConfiguration *m_configuration = nullptr; - QUrl m_serverUrl = QUrl("wss://127.0.0.1:1212"); - QUrl m_serverUrlTcp = QUrl("ssl://127.0.0.1:1213"); + QUrl m_serverUrlProxyWebSocket = QUrl("wss://127.0.0.1:1212"); + QUrl m_serverUrlProxyTcp = QUrl("ssl://127.0.0.1:1213"); - QUrl m_serverUrlTunnel = QUrl("wss://127.0.0.1:2212"); - QUrl m_serverUrlTunnelTcp = QUrl("ssl://127.0.0.1:2213"); + QUrl m_serverUrlTunnelProxyWebSocket = QUrl("wss://127.0.0.1:2212"); + QUrl m_serverUrlTunnelProxyTcp = QUrl("ssl://127.0.0.1:2213"); QSslConfiguration m_sslConfiguration;