diff --git a/common/slipdataprocessor.cpp b/common/slipdataprocessor.cpp index c02709d..083a386 100644 --- a/common/slipdataprocessor.cpp +++ b/common/slipdataprocessor.cpp @@ -54,6 +54,9 @@ QByteArray SlipDataProcessor::deserializeData(const QByteArray &data) // If escape byte, the next byte has to be a modified byte if (byte == ProtocolByteEsc) { escaped = true; + } else if (byte == ProtocolByteEnd) { + // We are done...lets skip the rest of the data since we got the end byte + break; } else { deserializedData.append(static_cast(byte)); } diff --git a/libnymea-remoteproxy/jsonrpc/tunnelproxyhandler.cpp b/libnymea-remoteproxy/jsonrpc/tunnelproxyhandler.cpp index c5456d8..73a82e6 100644 --- a/libnymea-remoteproxy/jsonrpc/tunnelproxyhandler.cpp +++ b/libnymea-remoteproxy/jsonrpc/tunnelproxyhandler.cpp @@ -84,11 +84,8 @@ TunnelProxyHandler::TunnelProxyHandler(QObject *parent) : JsonHandler(parent) params.clear(); returns.clear(); setDescription("ClientDisconnected", "Emitted whenever a new client has been connected to a registered server. " "Only tunnel proxy clients registered as server will receive this notification."); - params.insert("clientId", JsonTypes::basicTypeToString(JsonTypes::UInt)); - params.insert("name", JsonTypes::basicTypeToString(JsonTypes::String)); - params.insert("address", JsonTypes::basicTypeToString(JsonTypes::String)); + params.insert("socketAddress", JsonTypes::basicTypeToString(JsonTypes::UInt)); setParams("ClientDisconnected", params); - } QString TunnelProxyHandler::name() const @@ -148,10 +145,4 @@ JsonReply *TunnelProxyHandler::RegisterClient(const QVariantMap ¶ms, Transpo return createReply("RegisterClient", response); } - -//JsonReply *TunnelProxyHandler::RemoveClient(const QVariantMap ¶ms, TransportClient *transportClient) -//{ - -//} - } diff --git a/libnymea-remoteproxy/jsonrpc/tunnelproxyhandler.h b/libnymea-remoteproxy/jsonrpc/tunnelproxyhandler.h index 4fd1e62..c6524ef 100644 --- a/libnymea-remoteproxy/jsonrpc/tunnelproxyhandler.h +++ b/libnymea-remoteproxy/jsonrpc/tunnelproxyhandler.h @@ -45,10 +45,12 @@ public: QString name() const override; + // Server Q_INVOKABLE JsonReply *RegisterServer(const QVariantMap ¶ms, TransportClient *transportClient); Q_INVOKABLE JsonReply *DisconnectClient(const QVariantMap ¶ms, TransportClient *transportClient); - Q_INVOKABLE JsonReply *RegisterClient(const QVariantMap ¶ms, TransportClient *transportClient); + // Client + Q_INVOKABLE JsonReply *RegisterClient(const QVariantMap ¶ms, TransportClient *transportClient); signals: void ClientConnected(const QVariantMap ¶ms, TransportClient *transportClient); diff --git a/libnymea-remoteproxy/proxyconfiguration.cpp b/libnymea-remoteproxy/proxyconfiguration.cpp index d876c21..a7d4a1c 100644 --- a/libnymea-remoteproxy/proxyconfiguration.cpp +++ b/libnymea-remoteproxy/proxyconfiguration.cpp @@ -87,6 +87,16 @@ bool ProxyConfiguration::loadConfiguration(const QString &fileName) setTcpServerPort(static_cast(settings.value("port", 1213).toInt())); settings.endGroup(); + settings.beginGroup("WebSocketServerTunnelProxy"); + setWebSocketServerTunnelProxyHost(QHostAddress(settings.value("host", "127.0.0.1").toString())); + setWebSocketServerTunnelProxyPort(static_cast(settings.value("port", 2212).toInt())); + settings.endGroup(); + + settings.beginGroup("TcpServerTunnelProxy"); + setTcpServerTunnelProxyHost(QHostAddress(settings.value("host", "127.0.0.1").toString())); + setTcpServerTunnelProxyPort(static_cast(settings.value("port", 2213).toInt())); + settings.endGroup(); + // Load SSL configuration QSslConfiguration sslConfiguration; sslConfiguration.setPeerVerifyMode(QSslSocket::VerifyNone); diff --git a/libnymea-remoteproxy/server/jsonrpcserver.cpp b/libnymea-remoteproxy/server/jsonrpcserver.cpp index 8f92ee3..9fcb61a 100644 --- a/libnymea-remoteproxy/server/jsonrpcserver.cpp +++ b/libnymea-remoteproxy/server/jsonrpcserver.cpp @@ -140,10 +140,10 @@ void JsonRpcServer::sendResponse(TransportClient *client, int commandId, const Q if (client->slipEnabled()) { SlipDataProcessor::Frame frame; frame.socketAddress = 0x0000; - frame.data = data; + frame.data = data + '\n'; client->sendData(SlipDataProcessor::serializeData(SlipDataProcessor::buildFrame(frame))); } else { - client->sendData(data); + client->sendData(data + '\n'); } } @@ -159,10 +159,10 @@ void JsonRpcServer::sendErrorResponse(TransportClient *client, int commandId, co if (client->slipEnabled()) { SlipDataProcessor::Frame frame; frame.socketAddress = 0x0000; - frame.data = data; + frame.data = data + '\n'; client->sendData(SlipDataProcessor::serializeData(SlipDataProcessor::buildFrame(frame))); } else { - client->sendData(data); + client->sendData(data + '\n'); } } @@ -372,12 +372,12 @@ void JsonRpcServer::sendNotification(const QString &nameSpace, const QString &me if (transportClient->slipEnabled()) { SlipDataProcessor::Frame frame; frame.socketAddress = 0x0000; - frame.data = data; + frame.data = data + '\n'; qCDebug(dcJsonRpcTraffic()) << "Sending notification frame:" <sendData(SlipDataProcessor::serializeData(SlipDataProcessor::buildFrame(frame))); } else { qCDebug(dcJsonRpcTraffic()) << "Sending notification:" << data; - transportClient->sendData(data); + transportClient->sendData(data + '\n'); } } diff --git a/libnymea-remoteproxy/server/tcpsocketserver.cpp b/libnymea-remoteproxy/server/tcpsocketserver.cpp index 762c069..196da91 100644 --- a/libnymea-remoteproxy/server/tcpsocketserver.cpp +++ b/libnymea-remoteproxy/server/tcpsocketserver.cpp @@ -53,7 +53,7 @@ void TcpSocketServer::sendData(const QUuid &clientId, const QByteArray &data) } qCDebug(dcTcpSocketServerTraffic()) << "Send data to" << clientId.toString() << data + '\n'; - if (client->write(data + '\n') < 0) { + if (client->write(data) < 0) { qCWarning(dcTcpSocketServer()) << "Could not write data to client socket" << clientId.toString(); } } @@ -64,8 +64,10 @@ void TcpSocketServer::killClientConnection(const QUuid &clientId, const QString if (!client) return; - qCWarning(dcTcpSocketServer()) << "Killing client connection" << clientId.toString() << "Reason:" << killReason; - client->close(); + if (client->state() == QAbstractSocket::ConnectedState) { + qCWarning(dcTcpSocketServer()) << "Killing client connection" << clientId.toString() << "Reason:" << killReason; + client->close(); + } } bool TcpSocketServer::running() const diff --git a/libnymea-remoteproxy/server/websocketserver.cpp b/libnymea-remoteproxy/server/websocketserver.cpp index 402acf2..8f55ed5 100644 --- a/libnymea-remoteproxy/server/websocketserver.cpp +++ b/libnymea-remoteproxy/server/websocketserver.cpp @@ -64,7 +64,7 @@ void WebSocketServer::sendData(const QUuid &clientId, const QByteArray &data) client = m_clientList.value(clientId); if (client) { qCDebug(dcWebSocketServerTraffic()) << "--> Sending data to client:" << data; - client->sendTextMessage(data + '\n'); + client->sendTextMessage(data); } else { qCWarning(dcWebSocketServer()) << "Client" << clientId << "unknown to this transport"; } diff --git a/libnymea-remoteproxy/tunnelproxy/tunnelproxyclient.cpp b/libnymea-remoteproxy/tunnelproxy/tunnelproxyclient.cpp index b6f7519..600177f 100644 --- a/libnymea-remoteproxy/tunnelproxy/tunnelproxyclient.cpp +++ b/libnymea-remoteproxy/tunnelproxy/tunnelproxyclient.cpp @@ -46,6 +46,7 @@ QList TunnelProxyClient::processData(const QByteArray &data) } else { qCDebug(dcTunnelProxyServerTraffic()) << "Frame received"; packages.append(m_dataBuffer); + m_dataBuffer.clear(); } } else { m_dataBuffer.append(data.at(i)); diff --git a/libnymea-remoteproxy/tunnelproxy/tunnelproxyclientconnection.cpp b/libnymea-remoteproxy/tunnelproxy/tunnelproxyclientconnection.cpp index 667f265..35739d3 100644 --- a/libnymea-remoteproxy/tunnelproxy/tunnelproxyclientconnection.cpp +++ b/libnymea-remoteproxy/tunnelproxy/tunnelproxyclientconnection.cpp @@ -81,6 +81,7 @@ QDebug operator<<(QDebug debug, TunnelProxyClientConnection *clientConnection) debug.nospace() << "TunnelProxyClientConnection("; debug.nospace() << clientConnection->clientName() << ", "; debug.nospace() << clientConnection->clientUuid().toString() << ", "; + debug.nospace() << "server: " << clientConnection->serverUuid().toString() << ", "; debug.nospace() << clientConnection->transportClient() << ")"; return debug.space(); } diff --git a/libnymea-remoteproxy/tunnelproxy/tunnelproxyserver.cpp b/libnymea-remoteproxy/tunnelproxy/tunnelproxyserver.cpp index e56f2af..d9f8697 100644 --- a/libnymea-remoteproxy/tunnelproxy/tunnelproxyserver.cpp +++ b/libnymea-remoteproxy/tunnelproxy/tunnelproxyserver.cpp @@ -265,8 +265,8 @@ void TunnelProxyServer::onClientDisconnected(const QUuid &clientId) if (clientConnection->serverConnection()) { QVariantMap params; params.insert("socketAddress", clientConnection->socketAddress()); - m_jsonRpcServer->sendNotification("TunnelProxy", "ClientDisconnected", params, clientConnection->serverConnection()->transportClient()); clientConnection->serverConnection()->unregisterClientConnection(clientConnection); + m_jsonRpcServer->sendNotification("TunnelProxy", "ClientDisconnected", params, clientConnection->serverConnection()->transportClient()); } clientConnection->deleteLater(); @@ -304,8 +304,9 @@ void TunnelProxyServer::onClientDataAvailable(const QUuid &clientId, const QByte SlipDataProcessor::Frame frame; frame.socketAddress = clientConnection->socketAddress(); frame.data = data; - qCDebug(dcTunnelProxyServerTraffic()) << "Write client data to server using socket address" << clientConnection->socketAddress(); + qCDebug(dcTunnelProxyServerTraffic()) << "--> Tunnel data to server socket address" << clientConnection->socketAddress() << "to" << clientConnection->serverConnection() << qUtf8Printable(data); clientConnection->serverConnection()->transportClient()->sendData(SlipDataProcessor::serializeData(SlipDataProcessor::buildFrame(frame))); + } else if (tunnelProxyClient->type() == TunnelProxyClient::TypeServer) { // Data coming from a connected server connection if (tunnelProxyClient->slipEnabled()) { @@ -334,7 +335,7 @@ void TunnelProxyServer::onClientDataAvailable(const QUuid &clientId, const QByte return; } - qCDebug(dcTunnelProxyServerTraffic()) << "Sending data to" << clientConnection << qUtf8Printable(data); + qCDebug(dcTunnelProxyServerTraffic()) << "--> Tunnel data from server socket" << frame.socketAddress << "to" << clientConnection << qUtf8Printable(data); clientConnection->transportClient()->sendData(frame.data); } } diff --git a/libnymea-remoteproxyclient/proxyjsonrpcclient.cpp b/libnymea-remoteproxyclient/proxyjsonrpcclient.cpp index be9f7da..f40bb5d 100644 --- a/libnymea-remoteproxyclient/proxyjsonrpcclient.cpp +++ b/libnymea-remoteproxyclient/proxyjsonrpcclient.cpp @@ -27,6 +27,7 @@ #include "proxyjsonrpcclient.h" #include "proxyconnection.h" +#include "../common/slipdataprocessor.h" #include @@ -93,10 +94,30 @@ JsonReply *JsonRpcClient::callRegisterClient(const QUuid &clientUuid, const QStr return reply; } -void JsonRpcClient::sendRequest(const QVariantMap &request) +JsonReply *JsonRpcClient::callDisconnectClient(quint16 socketAddress) { - QByteArray data = QJsonDocument::fromVariant(request).toJson(QJsonDocument::Compact); - qCDebug(dcRemoteProxyClientJsonRpcTraffic()) << "Sending" << data; + QVariantMap params; + params.insert("socketAddress", socketAddress); + + JsonReply *reply = new JsonReply(m_commandId, "TunnelProxy", "DisconnectClient", params, this); + qCDebug(dcRemoteProxyClientJsonRpc()) << "Calling" << QString("%1.%2").arg(reply->nameSpace()).arg(reply->method()); + sendRequest(reply->requestMap(), true); + m_replies.insert(m_commandId, reply); + return reply; +} + +void JsonRpcClient::sendRequest(const QVariantMap &request, bool slipEnabled) +{ + QByteArray data = QJsonDocument::fromVariant(request).toJson(QJsonDocument::Compact) + '\n'; + + if (slipEnabled) { + SlipDataProcessor::Frame frame; + frame.socketAddress = 0x0000; + frame.data = data; + data = SlipDataProcessor::serializeData(SlipDataProcessor::buildFrame(frame)); + } + + qCDebug(dcRemoteProxyClientJsonRpcTraffic()) << "Sending" << qUtf8Printable(data); m_connection->sendData(data); } diff --git a/libnymea-remoteproxyclient/proxyjsonrpcclient.h b/libnymea-remoteproxyclient/proxyjsonrpcclient.h index fb44b36..a751748 100644 --- a/libnymea-remoteproxyclient/proxyjsonrpcclient.h +++ b/libnymea-remoteproxyclient/proxyjsonrpcclient.h @@ -66,7 +66,7 @@ private: QHash m_replies; - void sendRequest(const QVariantMap &request); + void sendRequest(const QVariantMap &request, bool slipEnabled = false); void processDataPackage(const QByteArray &data); signals: diff --git a/libnymea-remoteproxyclient/tunnelproxy/tunnelproxyremoteconnection.cpp b/libnymea-remoteproxyclient/tunnelproxy/tunnelproxyremoteconnection.cpp index cb0b0dd..e3778b6 100644 --- a/libnymea-remoteproxyclient/tunnelproxy/tunnelproxyremoteconnection.cpp +++ b/libnymea-remoteproxyclient/tunnelproxy/tunnelproxyremoteconnection.cpp @@ -77,6 +77,11 @@ void TunnelProxyRemoteConnection::ignoreSslErrors(const QList &errors m_connection->ignoreSslErrors(errors); } +QUrl TunnelProxyRemoteConnection::serverUrl() const +{ + return m_serverUrl; +} + QString TunnelProxyRemoteConnection::remoteProxyServer() const { return m_remoteProxyServer; @@ -138,6 +143,17 @@ void TunnelProxyRemoteConnection::disconnectServer() } } +bool TunnelProxyRemoteConnection::sendData(const QByteArray &data) +{ + if (!remoteConnected()) { + qCWarning(dcTunnelProxyRemoteConnection()) << "Could not send data. Not connected."; + return false; + } + + m_connection->sendData(data); + return true; +} + void TunnelProxyRemoteConnection::onConnectionChanged(bool connected) { if (connected) { diff --git a/libnymea-remoteproxyclient/tunnelproxy/tunnelproxyremoteconnection.h b/libnymea-remoteproxyclient/tunnelproxy/tunnelproxyremoteconnection.h index b4cd1c4..36ce220 100644 --- a/libnymea-remoteproxyclient/tunnelproxy/tunnelproxyremoteconnection.h +++ b/libnymea-remoteproxyclient/tunnelproxy/tunnelproxyremoteconnection.h @@ -74,6 +74,8 @@ public: void ignoreSslErrors(); void ignoreSslErrors(const QList &errors); + QUrl serverUrl() const; + QString remoteProxyServer() const; QString remoteProxyServerName() const; QString remoteProxyServerVersion() const; @@ -82,6 +84,7 @@ public: public slots: bool connectServer(const QUrl &url, const QUuid &serverUuid); void disconnectServer(); + bool sendData(const QByteArray &data); signals: void stateChanged(TunnelProxyRemoteConnection::State state); diff --git a/libnymea-remoteproxyclient/tunnelproxy/tunnelproxysocket.cpp b/libnymea-remoteproxyclient/tunnelproxy/tunnelproxysocket.cpp index 169d059..0da45c0 100644 --- a/libnymea-remoteproxyclient/tunnelproxy/tunnelproxysocket.cpp +++ b/libnymea-remoteproxyclient/tunnelproxy/tunnelproxysocket.cpp @@ -27,13 +27,15 @@ #include "tunnelproxysocket.h" #include "proxyconnection.h" +#include "tunnelproxysocketserver.h" #include "../common/slipdataprocessor.h" namespace remoteproxyclient { -TunnelProxySocket::TunnelProxySocket(ProxyConnection *connection, const QString &clientName, const QUuid &clientUuid, const QHostAddress &clientPeerAddress, quint16 socketAddress, QObject *parent) : +TunnelProxySocket::TunnelProxySocket(ProxyConnection *connection, TunnelProxySocketServer *socketServer, const QString &clientName, const QUuid &clientUuid, const QHostAddress &clientPeerAddress, quint16 socketAddress, QObject *parent) : QObject(parent), m_connection(connection), + m_socketServer(socketServer), m_clientName(clientName), m_clientUuid(clientUuid), m_clientPeerAddress(clientPeerAddress), @@ -62,6 +64,11 @@ quint16 TunnelProxySocket::socketAddress() const return m_socketAddress; } +bool TunnelProxySocket::connected() const +{ + return m_connected; +} + void TunnelProxySocket::writeData(const QByteArray &data) { SlipDataProcessor::Frame frame; @@ -72,7 +79,14 @@ void TunnelProxySocket::writeData(const QByteArray &data) void TunnelProxySocket::disconnectSocket() { + m_socketServer->requestSocketDisconnect(m_socketAddress); +} +void TunnelProxySocket::setDisconnected() +{ + m_connected = false; + emit connectedChanged(false); + emit disconnected(); } QDebug operator<<(QDebug debug, TunnelProxySocket *tunnelProxySocket) diff --git a/libnymea-remoteproxyclient/tunnelproxy/tunnelproxysocket.h b/libnymea-remoteproxyclient/tunnelproxy/tunnelproxysocket.h index bb3b6a7..a518e65 100644 --- a/libnymea-remoteproxyclient/tunnelproxy/tunnelproxysocket.h +++ b/libnymea-remoteproxyclient/tunnelproxy/tunnelproxysocket.h @@ -35,6 +35,7 @@ namespace remoteproxyclient { class ProxyConnection; +class TunnelProxySocketServer; class TunnelProxySocket : public QObject { @@ -47,25 +48,33 @@ public: QHostAddress clientPeerAddress() const; quint16 socketAddress() const; + bool connected() const; + void writeData(const QByteArray &data); void disconnectSocket(); signals: void dataReceived(const QByteArray &data); + + void connectedChanged(bool connected); void disconnected(); private: - explicit TunnelProxySocket(ProxyConnection *connection, const QString &clientName, const QUuid &clientUuid, const QHostAddress &clientPeerAddress, quint16 socketAddress, QObject *parent = nullptr); + explicit TunnelProxySocket(ProxyConnection *connection, TunnelProxySocketServer *socketServer, const QString &clientName, const QUuid &clientUuid, const QHostAddress &clientPeerAddress, quint16 socketAddress, QObject *parent = nullptr); ~TunnelProxySocket() = default; ProxyConnection *m_connection = nullptr; + TunnelProxySocketServer *m_socketServer = nullptr; + bool m_connected = true; // Note: on creatrion, the socket is connected, otherwise it would not have been created QString m_clientName; QUuid m_clientUuid; QHostAddress m_clientPeerAddress; quint16 m_socketAddress = 0xFFFF; + void setDisconnected(); + }; QDebug operator<<(QDebug debug, TunnelProxySocket *tunnelProxySocket); diff --git a/libnymea-remoteproxyclient/tunnelproxy/tunnelproxysocketserver.cpp b/libnymea-remoteproxyclient/tunnelproxy/tunnelproxysocketserver.cpp index 616eea6..47d4fcb 100644 --- a/libnymea-remoteproxyclient/tunnelproxy/tunnelproxysocketserver.cpp +++ b/libnymea-remoteproxyclient/tunnelproxy/tunnelproxysocketserver.cpp @@ -299,7 +299,7 @@ void TunnelProxySocketServer::onServerRegistrationFinished() void TunnelProxySocketServer::onTunnelProxyClientConnected(const QString &clientName, const QUuid &clientUuid, const QString &clientPeerAddress, quint16 socketAddress) { - TunnelProxySocket *tunnelProxySocket = new TunnelProxySocket(m_connection, clientName, clientUuid, QHostAddress(clientPeerAddress), socketAddress, this); + TunnelProxySocket *tunnelProxySocket = new TunnelProxySocket(m_connection, this, clientName, clientUuid, QHostAddress(clientPeerAddress), socketAddress, this); qCDebug(dcTunnelProxySocketServer()) << "--> New client connected" << tunnelProxySocket; m_tunnelProxySockets.insert(socketAddress, tunnelProxySocket); emit clientConnected(tunnelProxySocket); @@ -314,10 +314,24 @@ void TunnelProxySocketServer::onTunnelProxyClientDisconnected(quint16 socketAddr } qCDebug(dcTunnelProxySocketServer()) << "--> Client disconnected" << tunnelProxySocket; - emit tunnelProxySocket->disconnected(); + tunnelProxySocket->setDisconnected(); + emit clientDisconnected(tunnelProxySocket); tunnelProxySocket->deleteLater(); } +void TunnelProxySocketServer::requestSocketDisconnect(quint16 socketAddress) +{ + TunnelProxySocket *socket = m_tunnelProxySockets.value(socketAddress); + qCDebug(dcTunnelProxySocketServer()) << "Request to disconnect socket" << socket; + + JsonReply *reply = m_jsonClient->callDisconnectClient(socketAddress); + connect(reply, &JsonReply::finished, this, [=](){ + reply->deleteLater(); + // TODO: handle errors + qCDebug(dcTunnelProxySocketServer()) << "Request to disconnect client finished" << reply->response(); + }); +} + void TunnelProxySocketServer::setState(State state) { if (m_state == state) diff --git a/libnymea-remoteproxyclient/tunnelproxy/tunnelproxysocketserver.h b/libnymea-remoteproxyclient/tunnelproxy/tunnelproxysocketserver.h index 7a20bf2..e193bd3 100644 --- a/libnymea-remoteproxyclient/tunnelproxy/tunnelproxysocketserver.h +++ b/libnymea-remoteproxyclient/tunnelproxy/tunnelproxysocketserver.h @@ -45,6 +45,9 @@ class JsonRpcClient; class TunnelProxySocketServer : public QObject { Q_OBJECT + + friend class TunnelProxySocket; + public: enum State { StateConnecting, @@ -147,6 +150,8 @@ private: QByteArray m_dataBuffer; + void requestSocketDisconnect(quint16 socketAddress); + void setState(State state); void setRunning(bool running); void setError(QAbstractSocket::SocketError error); diff --git a/libnymea-remoteproxyclient/websocketconnection.cpp b/libnymea-remoteproxyclient/websocketconnection.cpp index 2b4dace..703ebdf 100644 --- a/libnymea-remoteproxyclient/websocketconnection.cpp +++ b/libnymea-remoteproxyclient/websocketconnection.cpp @@ -51,7 +51,7 @@ WebSocketConnection::~WebSocketConnection() void WebSocketConnection::sendData(const QByteArray &data) { - m_webSocket->sendTextMessage(QString::fromUtf8(data + '\n')); + m_webSocket->sendTextMessage(QString::fromUtf8(data)); } void WebSocketConnection::ignoreSslErrors() diff --git a/nymea-remoteproxy.conf b/nymea-remoteproxy.conf index 639f33c..6f21594 100644 --- a/nymea-remoteproxy.conf +++ b/nymea-remoteproxy.conf @@ -27,3 +27,12 @@ port=443 [TcpServer] host=127.0.0.1 port=80 + +[WebSocketServerTunnelProxy] +host=127.0.0.1 +port=2212 + +[TcpServerTunnelProxy] +host=127.0.0.1 +port=2213 + diff --git a/tests/resources/test-configuration-chain.conf b/tests/resources/test-configuration-chain.conf index 74dd11e..d8ad836 100644 --- a/tests/resources/test-configuration-chain.conf +++ b/tests/resources/test-configuration-chain.conf @@ -16,3 +16,11 @@ port=1212 [TcpServer] host=127.0.0.1 port=1213 + +[WebSocketServerTunnelProxy] +host=127.0.0.1 +port=2212 + +[TcpServerTunnelProxy] +host=127.0.0.1 +port=2213 diff --git a/tests/resources/test-configuration-faulty-certificate.conf b/tests/resources/test-configuration-faulty-certificate.conf index 526fe03..8a9b12e 100644 --- a/tests/resources/test-configuration-faulty-certificate.conf +++ b/tests/resources/test-configuration-faulty-certificate.conf @@ -16,3 +16,11 @@ port=1212 [TcpServer] host=127.0.0.1 port=1213 + +[WebSocketServerTunnelProxy] +host=127.0.0.1 +port=2212 + +[TcpServerTunnelProxy] +host=127.0.0.1 +port=2213 diff --git a/tests/resources/test-configuration-faulty-chain.conf b/tests/resources/test-configuration-faulty-chain.conf index 5c949e7..631254f 100644 --- a/tests/resources/test-configuration-faulty-chain.conf +++ b/tests/resources/test-configuration-faulty-chain.conf @@ -16,3 +16,11 @@ port=1212 [TcpServer] host=127.0.0.1 port=1213 + +[WebSocketServerTunnelProxy] +host=127.0.0.1 +port=2212 + +[TcpServerTunnelProxy] +host=127.0.0.1 +port=2213 diff --git a/tests/resources/test-configuration-faulty-key.conf b/tests/resources/test-configuration-faulty-key.conf index ae4307f..6017251 100644 --- a/tests/resources/test-configuration-faulty-key.conf +++ b/tests/resources/test-configuration-faulty-key.conf @@ -16,3 +16,11 @@ port=1212 [TcpServer] host=127.0.0.1 port=1213 + +[WebSocketServerTunnelProxy] +host=127.0.0.1 +port=2212 + +[TcpServerTunnelProxy] +host=127.0.0.1 +port=2213 diff --git a/tests/resources/test-configuration.conf b/tests/resources/test-configuration.conf index 54bec2c..80c5cc1 100644 --- a/tests/resources/test-configuration.conf +++ b/tests/resources/test-configuration.conf @@ -20,3 +20,11 @@ port=1212 [TcpServer] host=127.0.0.1 port=1213 + +[WebSocketServerTunnelProxy] +host=127.0.0.1 +port=2212 + +[TcpServerTunnelProxy] +host=127.0.0.1 +port=2213 diff --git a/tests/test-tunnelproxy/remoteproxyteststunnelproxy.cpp b/tests/test-tunnelproxy/remoteproxyteststunnelproxy.cpp index 0ff10c6..c3ae06d 100644 --- a/tests/test-tunnelproxy/remoteproxyteststunnelproxy.cpp +++ b/tests/test-tunnelproxy/remoteproxyteststunnelproxy.cpp @@ -30,6 +30,7 @@ #include "engine.h" #include "loggingcategories.h" #include "remoteproxyconnection.h" +#include "../common/slipdataprocessor.h" // Client #include "tunnelproxy/tunnelproxysocketserver.h" @@ -336,6 +337,34 @@ void RemoteProxyTestsTunnelProxy::registerClient() stopServer(); } +void RemoteProxyTestsTunnelProxy::testSlip_data() +{ + QTest::addColumn("data"); + QTest::addColumn("success"); + + QTest::newRow("valid: a lot of special characters") << QByteArray::fromHex("C0AABBCCDDEEFF12A1B2C3D4E5FFC0DBDCDDAA") << true; + QTest::newRow("valid: start and end with END protocol") << QByteArray::fromHex("C0C0C0C0C0C0C0C0C0C0DDDDCDCDCDCDCDCD") << true; + QTest::newRow("valid: normal text with a special characters") << QByteArray("Foo Bar text describing 123456770ß2123#+@$%/(!\"W=$*'*") << true; + QTest::newRow("invalid: escape followed by nor escaped special character") << QByteArray::fromHex("AADB12FFC0") << false; + +} + +void RemoteProxyTestsTunnelProxy::testSlip() +{ + QFETCH(QByteArray, data); + QFETCH(bool, success); + + if (success) { + QByteArray serializedData = SlipDataProcessor::serializeData(data); + QVERIFY(serializedData.endsWith(0xC0)); + QByteArray deserializedData = SlipDataProcessor::deserializeData(serializedData); + QVERIFY(deserializedData == data); + } else { + QByteArray deserializedData = SlipDataProcessor::deserializeData(data); + QVERIFY(deserializedData.isEmpty()); + } +} + void RemoteProxyTestsTunnelProxy::registerServerDuplicated() { // Start the server @@ -387,29 +416,11 @@ void RemoteProxyTestsTunnelProxy::registerServerDuplicated() // Try to register from a websocket with the same uuid QPair resultWebSocket = invokeWebSocketTunnelProxyApiCallPersistant("TunnelProxy.RegisterServer", params); response = resultWebSocket.first.toMap(); - QWebSocket *webSocket = resultWebSocket.second; QVERIFY(!response.isEmpty()); QVERIFY(response.value("status").toString() == "success"); QVERIFY(response.value("params").toMap().contains("tunnelProxyError")); verifyTunnelProxyError(response); - // Try to register again with the same uuid on the same socket - resultWebSocket = invokeWebSocketTunnelProxyApiCallPersistant("TunnelProxy.RegisterServer", params, true, webSocket); - response = resultWebSocket.first.toMap(); - QVERIFY(response.value("status").toString() == "success"); - QVERIFY(response.value("params").toMap().contains("tunnelProxyError")); - verifyTunnelProxyError(response, TunnelProxyServer::TunnelProxyErrorAlreadyRegistered); - - - QSignalSpy disconnectedWebSocketSpy(webSocket, &QWebSocket::disconnected); - QVERIFY(disconnectedWebSocketSpy.wait()); - QVERIFY(disconnectedWebSocketSpy.count() == 1); - - webSocket->close(); - delete webSocket; - - QTest::qWait(100); - resetDebugCategories(); // Clean up @@ -559,6 +570,7 @@ void RemoteProxyTestsTunnelProxy::testTunnelProxyServer() addDebugCategory("JsonRpcTraffic.debug=true"); addDebugCategory("TunnelProxySocketServer.debug=true"); addDebugCategory("TunnelProxyRemoteConnection.debug=true"); + addDebugCategory("TunnelProxyRemoteConnectionTraffic.debug=true"); addDebugCategory("RemoteProxyClientJsonRpcTraffic.debug=true"); // Tunnel proxy socket server @@ -579,6 +591,13 @@ void RemoteProxyTestsTunnelProxy::testTunnelProxyServer() QVERIFY(arguments.at(0).toBool() == true); QVERIFY(tunnelProxyServer->running()); + QCOMPARE(tunnelProxyServer->serverUrl(), m_serverUrlTunnelProxyTcp); + QCOMPARE(tunnelProxyServer->remoteProxyServer(), QString(SERVER_NAME_STRING)); + QCOMPARE(tunnelProxyServer->remoteProxyServerName(), Engine::instance()->configuration()->serverName()); + QCOMPARE(tunnelProxyServer->remoteProxyServerVersion(), QString(SERVER_VERSION_STRING)); + QCOMPARE(tunnelProxyServer->remoteProxyApiVersion(), QString(API_VERSION_STRING)); + + // Tunnel proxy client connection QString clientName = "Awesome client name"; QUuid clientUuid = QUuid::createUuid(); @@ -597,22 +616,50 @@ void RemoteProxyTestsTunnelProxy::testTunnelProxyServer() TunnelProxySocket *tunnelProxySocket = arguments.at(0).value(); QVERIFY(tunnelProxySocket->clientName() == clientName); QVERIFY(tunnelProxySocket->clientUuid() == clientUuid); + QVERIFY(!tunnelProxySocket->clientPeerAddress().isNull()); + QVERIFY(tunnelProxySocket->socketAddress() != 0x0000 && tunnelProxySocket->socketAddress() != 0xFFFF); + QVERIFY(tunnelProxySocket->connected()); + + QCOMPARE(clientConnection->serverUrl(), m_serverUrlTunnelProxyTcp); + QCOMPARE(clientConnection->remoteProxyServer(), QString(SERVER_NAME_STRING)); + QCOMPARE(clientConnection->remoteProxyServerName(), Engine::instance()->configuration()->serverName()); + QCOMPARE(clientConnection->remoteProxyServerVersion(), QString(SERVER_VERSION_STRING)); + QCOMPARE(clientConnection->remoteProxyApiVersion(), QString(API_VERSION_STRING)); + + // We have a remote connection, now disconnect the client and verify the socket dissapears on th server side + QSignalSpy clientDisconnectedSpy(tunnelProxyServer, &TunnelProxySocketServer::clientDisconnected); + + clientConnection->disconnectServer(); + + QVERIFY(clientDisconnectedSpy.wait()); + QVERIFY(clientDisconnectedSpy.count() == 1); + arguments = clientDisconnectedSpy.takeFirst(); + tunnelProxySocket = arguments.at(0).value(); + QVERIFY(tunnelProxySocket->clientName() == clientName); + QVERIFY(tunnelProxySocket->clientUuid() == clientUuid); + QVERIFY(!tunnelProxySocket->clientPeerAddress().isNull()); + QVERIFY(tunnelProxySocket->socketAddress() != 0x0000 && tunnelProxySocket->socketAddress() != 0xFFFF); + QVERIFY(!tunnelProxySocket->connected()); + // Stop the server connection and verify the client gets disconnected + QSignalSpy serverNotRunningSpy(tunnelProxyServer, &TunnelProxySocketServer::runningChanged); tunnelProxyServer->stopServer(); - QSignalSpy disconnectedSpy(clientConnection, &TunnelProxyRemoteConnection::remoteConnectedChanged); - QVERIFY(disconnectedSpy.wait()); - QVERIFY(disconnectedSpy.count() == 1); - arguments = disconnectedSpy.takeFirst(); + // Verify the remote connection is disconnected + serverNotRunningSpy.wait(); + QVERIFY(serverNotRunningSpy.count() == 1); + arguments = serverNotRunningSpy.takeFirst(); QVERIFY(arguments.at(0).toBool() == false); - QVERIFY(!clientConnection->remoteConnected()); + QVERIFY(!tunnelProxyServer->running()); + // Clean up + tunnelProxyServer->deleteLater(); + clientConnection->deleteLater(); resetDebugCategories(); - // Clean up stopServer(); } @@ -647,6 +694,12 @@ void RemoteProxyTestsTunnelProxy::testTunnelProxyClient() QVERIFY(arguments.at(0).toBool() == true); QVERIFY(tunnelProxyServer->running()); + QCOMPARE(tunnelProxyServer->serverUrl(), m_serverUrlTunnelProxyTcp); + QCOMPARE(tunnelProxyServer->remoteProxyServer(), QString(SERVER_NAME_STRING)); + QCOMPARE(tunnelProxyServer->remoteProxyServerName(), Engine::instance()->configuration()->serverName()); + QCOMPARE(tunnelProxyServer->remoteProxyServerVersion(), QString(SERVER_VERSION_STRING)); + QCOMPARE(tunnelProxyServer->remoteProxyApiVersion(), QString(API_VERSION_STRING)); + // Tunnel proxy client connection QString clientName = "Awesome client name"; @@ -666,15 +719,276 @@ void RemoteProxyTestsTunnelProxy::testTunnelProxyClient() QVERIFY(arguments.at(0).toBool() == true); QVERIFY(clientConnection->remoteConnected()); - // Verify server socket connected + QCOMPARE(clientConnection->serverUrl(), m_serverUrlTunnelProxyTcp); + QCOMPARE(clientConnection->remoteProxyServer(), QString(SERVER_NAME_STRING)); + QCOMPARE(clientConnection->remoteProxyServerName(), Engine::instance()->configuration()->serverName()); + QCOMPARE(clientConnection->remoteProxyServerVersion(), QString(SERVER_VERSION_STRING)); + QCOMPARE(clientConnection->remoteProxyApiVersion(), QString(API_VERSION_STRING)); + + // Stop the server and make sure the client gets disconnected + tunnelProxyServer->stopServer(); + + QSignalSpy clientRemoteDisonnectedSpy(clientConnection, &TunnelProxyRemoteConnection::remoteConnectedChanged); + QVERIFY(clientRemoteDisonnectedSpy.wait()); + QVERIFY(clientRemoteDisonnectedSpy.count() == 1); + arguments = clientRemoteDisonnectedSpy.takeFirst(); + QVERIFY(arguments.at(0).toBool() == false); + QVERIFY(!clientConnection->remoteConnected()); + // Clean up + tunnelProxyServer->deleteLater(); + clientConnection->deleteLater(); resetDebugCategories(); - // Clean up stopServer(); } +void RemoteProxyTestsTunnelProxy::testTunnelProxyServerSocketDisconnect() +{ + // Start the server + startServer(); + + resetDebugCategories(); + addDebugCategory("TunnelProxyServer.debug=true"); + addDebugCategory("TunnelProxyServerTraffic.debug=true"); + addDebugCategory("JsonRpcTraffic.debug=true"); + addDebugCategory("TunnelProxySocketServer.debug=true"); + addDebugCategory("TunnelProxyRemoteConnection.debug=true"); + addDebugCategory("TunnelProxyRemoteConnectionTraffic.debug=true"); + addDebugCategory("RemoteProxyClientJsonRpcTraffic.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()); + + QCOMPARE(tunnelProxyServer->serverUrl(), m_serverUrlTunnelProxyTcp); + QCOMPARE(tunnelProxyServer->remoteProxyServer(), QString(SERVER_NAME_STRING)); + QCOMPARE(tunnelProxyServer->remoteProxyServerName(), Engine::instance()->configuration()->serverName()); + QCOMPARE(tunnelProxyServer->remoteProxyServerVersion(), QString(SERVER_VERSION_STRING)); + QCOMPARE(tunnelProxyServer->remoteProxyApiVersion(), QString(API_VERSION_STRING)); + + + // Tunnel proxy client connection + QString clientName = "Awesome client name"; + QUuid clientUuid = QUuid::createUuid(); + + TunnelProxyRemoteConnection *clientConnection = new TunnelProxyRemoteConnection(clientUuid, clientName, this); + connect(clientConnection, &TunnelProxyRemoteConnection::sslErrors, this, [=](const QList &errors){ + clientConnection->ignoreSslErrors(errors); + }); + + clientConnection->connectServer(m_serverUrlTunnelProxyTcp, serverUuid); + + QSignalSpy clientConnectedSpy(tunnelProxyServer, &TunnelProxySocketServer::clientConnected); + QVERIFY(clientConnectedSpy.wait()); + QVERIFY(clientConnectedSpy.count() == 1); + arguments = clientConnectedSpy.takeFirst(); + TunnelProxySocket *tunnelProxySocket = arguments.at(0).value(); + QVERIFY(tunnelProxySocket->clientName() == clientName); + QVERIFY(tunnelProxySocket->clientUuid() == clientUuid); + QVERIFY(!tunnelProxySocket->clientPeerAddress().isNull()); + QVERIFY(tunnelProxySocket->socketAddress() != 0x0000 && tunnelProxySocket->socketAddress() != 0xFFFF); + QVERIFY(tunnelProxySocket->connected()); + + QCOMPARE(clientConnection->serverUrl(), m_serverUrlTunnelProxyTcp); + QCOMPARE(clientConnection->remoteProxyServer(), QString(SERVER_NAME_STRING)); + QCOMPARE(clientConnection->remoteProxyServerName(), Engine::instance()->configuration()->serverName()); + QCOMPARE(clientConnection->remoteProxyServerVersion(), QString(SERVER_VERSION_STRING)); + QCOMPARE(clientConnection->remoteProxyApiVersion(), QString(API_VERSION_STRING)); + QVERIFY(clientConnection->remoteConnected() == true); + + // Now request the TunnelProxySocket to disconnect and verify the client Connection really gets disconnected + QSignalSpy clientRemoteDisonnectedSpy(clientConnection, &TunnelProxyRemoteConnection::remoteConnectedChanged); + + tunnelProxySocket->disconnectSocket(); + + QVERIFY(clientRemoteDisonnectedSpy.wait()); + QVERIFY(clientRemoteDisonnectedSpy.count() == 1); + arguments = clientRemoteDisonnectedSpy.takeFirst(); + QVERIFY(arguments.at(0).toBool() == false); + QVERIFY(!clientConnection->remoteConnected()); + + QTest::qWait(100); + + // Clean up + tunnelProxyServer->deleteLater(); + clientConnection->deleteLater(); + + resetDebugCategories(); + + stopServer(); +} + +void RemoteProxyTestsTunnelProxy::tunnelProxyEndToEndTest() +{ + // Start the server + startServer(); + + resetDebugCategories(); + addDebugCategory("TunnelProxyServer.debug=true"); + addDebugCategory("TunnelProxyServerTraffic.debug=true"); + addDebugCategory("JsonRpcTraffic.debug=true"); + addDebugCategory("TunnelProxySocketServer.debug=true"); + addDebugCategory("TunnelProxyRemoteConnection.debug=true"); + addDebugCategory("TunnelProxyRemoteConnectionTraffic.debug=true"); + addDebugCategory("RemoteProxyClientJsonRpcTraffic.debug=true"); + + // ** Create the server ** + QString serverName = "nymea server"; + 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()); + QCOMPARE(tunnelProxyServer->serverUrl(), m_serverUrlTunnelProxyTcp); + QCOMPARE(tunnelProxyServer->remoteProxyServer(), QString(SERVER_NAME_STRING)); + QCOMPARE(tunnelProxyServer->remoteProxyServerName(), Engine::instance()->configuration()->serverName()); + QCOMPARE(tunnelProxyServer->remoteProxyServerVersion(), QString(SERVER_VERSION_STRING)); + QCOMPARE(tunnelProxyServer->remoteProxyApiVersion(), QString(API_VERSION_STRING)); + + + // ** Remote connection 1 ** + + QString clientOneName = "Client one"; + QUuid clientOneUuid = QUuid::createUuid(); + TunnelProxyRemoteConnection *remoteConnectionOne = new TunnelProxyRemoteConnection(clientOneUuid, clientOneName, this); + connect(remoteConnectionOne, &TunnelProxyRemoteConnection::sslErrors, this, [=](const QList &errors){ + remoteConnectionOne->ignoreSslErrors(errors); + }); + + remoteConnectionOne->connectServer(m_serverUrlTunnelProxyTcp, serverUuid); + + // ** Tunnel proxy server socket 1 ** + QSignalSpy remoteConnectedOneSpy(tunnelProxyServer, &TunnelProxySocketServer::clientConnected); + QVERIFY(remoteConnectedOneSpy.wait()); + QVERIFY(remoteConnectedOneSpy.count() == 1); + arguments = remoteConnectedOneSpy.takeFirst(); + + TunnelProxySocket *tunnelProxySocketOne = arguments.at(0).value(); + QVERIFY(tunnelProxySocketOne->clientName() == clientOneName); + QVERIFY(tunnelProxySocketOne->clientUuid() == clientOneUuid); + QVERIFY(!tunnelProxySocketOne->clientPeerAddress().isNull()); + QVERIFY(tunnelProxySocketOne->socketAddress() != 0x0000 && tunnelProxySocketOne->socketAddress() != 0xFFFF); + QVERIFY(tunnelProxySocketOne->connected()); + + qDebug() << "Have socket one" << tunnelProxySocketOne; + + // ** Send data in both directions + QByteArray testData("#sdföiabi23u4b34b598gvndafjibnföQIUH34982HRIPURBFÖWLKDÜOQw9h934utbf ljBiH9FBLAJF RF AF,A§uu)(\"§)§(u$)($=$(((($((!"); + + // Socket -> Remote connection + QSignalSpy remoteConnectionOneDataSpy(remoteConnectionOne, &TunnelProxyRemoteConnection::dataReady); + tunnelProxySocketOne->writeData(testData); + QVERIFY(remoteConnectionOneDataSpy.wait()); + QVERIFY(remoteConnectionOneDataSpy.count() == 1); + arguments = remoteConnectionOneDataSpy.takeFirst(); + QByteArray receivedTestData = arguments.at(0).toByteArray(); + QVERIFY(receivedTestData == testData); + + + // Remote connection -> Socket + QByteArray testData2("The biggest decision in life is about changing your life through changing your mind. – Albert Schweitzer"); + QSignalSpy tunnelProxySocketOneDataSpy(tunnelProxySocketOne, &TunnelProxySocket::dataReceived); + remoteConnectionOne->sendData(testData2); + QVERIFY(tunnelProxySocketOneDataSpy.wait()); + QVERIFY(tunnelProxySocketOneDataSpy.count() == 1); + arguments = tunnelProxySocketOneDataSpy.takeFirst(); + QByteArray receivedTestData2 = arguments.at(0).toByteArray(); + QVERIFY(receivedTestData2 == testData2); + + + + // ** Remote connection 2 ** + + QString clientTwoName = "Client two"; + QUuid clientTwoUuid = QUuid::createUuid(); + TunnelProxyRemoteConnection *remoteConnectionTwo = new TunnelProxyRemoteConnection(clientTwoUuid, clientTwoName, this); + connect(remoteConnectionTwo, &TunnelProxyRemoteConnection::sslErrors, this, [=](const QList &errors){ + remoteConnectionTwo->ignoreSslErrors(errors); + }); + + remoteConnectionTwo->connectServer(m_serverUrlTunnelProxyTcp, serverUuid); + + // ** Tunnel proxy server socket 2 ** + QSignalSpy remoteConnectedTwoSpy(tunnelProxyServer, &TunnelProxySocketServer::clientConnected); + QVERIFY(remoteConnectedTwoSpy.wait()); + QVERIFY(remoteConnectedTwoSpy.count() == 1); + arguments = remoteConnectedTwoSpy.takeFirst(); + + TunnelProxySocket *tunnelProxySocketTwo = arguments.at(0).value(); + QVERIFY(tunnelProxySocketTwo->clientName() == clientTwoName); + QVERIFY(tunnelProxySocketTwo->clientUuid() == clientTwoUuid); + QVERIFY(!tunnelProxySocketTwo->clientPeerAddress().isNull()); + QVERIFY(tunnelProxySocketTwo->socketAddress() != 0x0000 && tunnelProxySocketTwo->socketAddress() != 0xFFFF); + QVERIFY(tunnelProxySocketTwo->connected()); + + qDebug() << "Have socket two" << tunnelProxySocketTwo; + + // ** Send data in both directions + + // Socket -> Remote connection + QSignalSpy remoteConnectionTwoDataSpy(remoteConnectionTwo, &TunnelProxyRemoteConnection::dataReady); + tunnelProxySocketTwo->writeData(testData); + QVERIFY(remoteConnectionTwoDataSpy.wait()); + QVERIFY(remoteConnectionTwoDataSpy.count() == 1); + arguments = remoteConnectionTwoDataSpy.takeFirst(); + receivedTestData = arguments.at(0).toByteArray(); + QVERIFY(receivedTestData == testData); + + // Remote connection -> Socket + QSignalSpy tunnelProxySocketTwoDataSpy(tunnelProxySocketTwo, &TunnelProxySocket::dataReceived); + remoteConnectionTwo->sendData(testData2); + QVERIFY(tunnelProxySocketTwoDataSpy.wait()); + QVERIFY(tunnelProxySocketTwoDataSpy.count() == 1); + arguments = tunnelProxySocketTwoDataSpy.takeFirst(); + receivedTestData2 = arguments.at(0).toByteArray(); + QVERIFY(receivedTestData2 == testData2); + + Engine::instance()->tunnelProxyServer()->stopServer(); + + QTest::qWait(100); + + QVERIFY(!tunnelProxyServer->running()); + QVERIFY(!remoteConnectionOne->remoteConnected()); + QVERIFY(!remoteConnectionTwo->remoteConnected()); + + + // Clean up + tunnelProxyServer->deleteLater(); + remoteConnectionOne->deleteLater(); + remoteConnectionTwo->deleteLater(); + + resetDebugCategories(); + + stopServer(); + +} + QTEST_MAIN(RemoteProxyTestsTunnelProxy) diff --git a/tests/test-tunnelproxy/remoteproxyteststunnelproxy.h b/tests/test-tunnelproxy/remoteproxyteststunnelproxy.h index 8c0ca6b..cba9b28 100644 --- a/tests/test-tunnelproxy/remoteproxyteststunnelproxy.h +++ b/tests/test-tunnelproxy/remoteproxyteststunnelproxy.h @@ -60,6 +60,9 @@ private slots: void registerClient_data(); void registerClient(); + void testSlip_data(); + void testSlip(); + void registerServerDuplicated(); void registerClientDuplicated(); void crossRegisterServerClient(); @@ -67,6 +70,10 @@ private slots: // Client classes void testTunnelProxyServer(); void testTunnelProxyClient(); + void testTunnelProxyServerSocketDisconnect(); + + void tunnelProxyEndToEndTest(); + }; diff --git a/tests/testbase/basetest.cpp b/tests/testbase/basetest.cpp index e625ef7..154aee3 100644 --- a/tests/testbase/basetest.cpp +++ b/tests/testbase/basetest.cpp @@ -715,7 +715,6 @@ QPair BaseTest::invokeTcpSocketTunnelProxyApiCallPersist continue; break; - messageData.clear(); } else { messageData.append(rawData.at(i)); } @@ -780,13 +779,19 @@ QPair BaseTest::invokeWebSocketTunnelProxyApiCallPersist QJsonDocument jsonDoc = QJsonDocument::fromVariant(request); QByteArray payload = jsonDoc.toJson(QJsonDocument::Compact) + '\n'; + + if (socket->state() != QAbstractSocket::ConnectedState) { + qWarning() << "Socket not connected"; + return QPair(QVariant(), socket); + } + QSignalSpy dataSpy(socket, SIGNAL(textMessageReceived(QString))); if (slipEnabled) { SlipDataProcessor::Frame frame; frame.socketAddress = 0x0000; frame.data = payload; - socket->sendTextMessage(QString(SlipDataProcessor::serializeData(SlipDataProcessor::buildFrame(frame)))); + socket->sendTextMessage(QString::fromUtf8(SlipDataProcessor::serializeData(SlipDataProcessor::buildFrame(frame)))); } else { socket->sendTextMessage(QString(payload)); }