Finish and test first working tunnel proxy connection

This commit is contained in:
Simon Stürz 2021-08-04 13:05:37 +02:00
parent 30d6a9dd43
commit b9ebc345a5
28 changed files with 529 additions and 61 deletions

View File

@ -54,6 +54,9 @@ QByteArray SlipDataProcessor::deserializeData(const QByteArray &data)
// If escape byte, the next byte has to be a modified byte // If escape byte, the next byte has to be a modified byte
if (byte == ProtocolByteEsc) { if (byte == ProtocolByteEsc) {
escaped = true; escaped = true;
} else if (byte == ProtocolByteEnd) {
// We are done...lets skip the rest of the data since we got the end byte
break;
} else { } else {
deserializedData.append(static_cast<char>(byte)); deserializedData.append(static_cast<char>(byte));
} }

View File

@ -84,11 +84,8 @@ TunnelProxyHandler::TunnelProxyHandler(QObject *parent) : JsonHandler(parent)
params.clear(); returns.clear(); params.clear(); returns.clear();
setDescription("ClientDisconnected", "Emitted whenever a new client has been connected to a registered server. " 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."); "Only tunnel proxy clients registered as server will receive this notification.");
params.insert("clientId", JsonTypes::basicTypeToString(JsonTypes::UInt)); params.insert("socketAddress", JsonTypes::basicTypeToString(JsonTypes::UInt));
params.insert("name", JsonTypes::basicTypeToString(JsonTypes::String));
params.insert("address", JsonTypes::basicTypeToString(JsonTypes::String));
setParams("ClientDisconnected", params); setParams("ClientDisconnected", params);
} }
QString TunnelProxyHandler::name() const QString TunnelProxyHandler::name() const
@ -148,10 +145,4 @@ JsonReply *TunnelProxyHandler::RegisterClient(const QVariantMap &params, Transpo
return createReply("RegisterClient", response); return createReply("RegisterClient", response);
} }
//JsonReply *TunnelProxyHandler::RemoveClient(const QVariantMap &params, TransportClient *transportClient)
//{
//}
} }

View File

@ -45,10 +45,12 @@ public:
QString name() const override; QString name() const override;
// Server
Q_INVOKABLE JsonReply *RegisterServer(const QVariantMap &params, TransportClient *transportClient); Q_INVOKABLE JsonReply *RegisterServer(const QVariantMap &params, TransportClient *transportClient);
Q_INVOKABLE JsonReply *DisconnectClient(const QVariantMap &params, TransportClient *transportClient); Q_INVOKABLE JsonReply *DisconnectClient(const QVariantMap &params, TransportClient *transportClient);
Q_INVOKABLE JsonReply *RegisterClient(const QVariantMap &params, TransportClient *transportClient);
// Client
Q_INVOKABLE JsonReply *RegisterClient(const QVariantMap &params, TransportClient *transportClient);
signals: signals:
void ClientConnected(const QVariantMap &params, TransportClient *transportClient); void ClientConnected(const QVariantMap &params, TransportClient *transportClient);

View File

@ -87,6 +87,16 @@ bool ProxyConfiguration::loadConfiguration(const QString &fileName)
setTcpServerPort(static_cast<quint16>(settings.value("port", 1213).toInt())); setTcpServerPort(static_cast<quint16>(settings.value("port", 1213).toInt()));
settings.endGroup(); settings.endGroup();
settings.beginGroup("WebSocketServerTunnelProxy");
setWebSocketServerTunnelProxyHost(QHostAddress(settings.value("host", "127.0.0.1").toString()));
setWebSocketServerTunnelProxyPort(static_cast<quint16>(settings.value("port", 2212).toInt()));
settings.endGroup();
settings.beginGroup("TcpServerTunnelProxy");
setTcpServerTunnelProxyHost(QHostAddress(settings.value("host", "127.0.0.1").toString()));
setTcpServerTunnelProxyPort(static_cast<quint16>(settings.value("port", 2213).toInt()));
settings.endGroup();
// Load SSL configuration // Load SSL configuration
QSslConfiguration sslConfiguration; QSslConfiguration sslConfiguration;
sslConfiguration.setPeerVerifyMode(QSslSocket::VerifyNone); sslConfiguration.setPeerVerifyMode(QSslSocket::VerifyNone);

View File

@ -140,10 +140,10 @@ void JsonRpcServer::sendResponse(TransportClient *client, int commandId, const Q
if (client->slipEnabled()) { if (client->slipEnabled()) {
SlipDataProcessor::Frame frame; SlipDataProcessor::Frame frame;
frame.socketAddress = 0x0000; frame.socketAddress = 0x0000;
frame.data = data; frame.data = data + '\n';
client->sendData(SlipDataProcessor::serializeData(SlipDataProcessor::buildFrame(frame))); client->sendData(SlipDataProcessor::serializeData(SlipDataProcessor::buildFrame(frame)));
} else { } else {
client->sendData(data); client->sendData(data + '\n');
} }
} }
@ -159,10 +159,10 @@ void JsonRpcServer::sendErrorResponse(TransportClient *client, int commandId, co
if (client->slipEnabled()) { if (client->slipEnabled()) {
SlipDataProcessor::Frame frame; SlipDataProcessor::Frame frame;
frame.socketAddress = 0x0000; frame.socketAddress = 0x0000;
frame.data = data; frame.data = data + '\n';
client->sendData(SlipDataProcessor::serializeData(SlipDataProcessor::buildFrame(frame))); client->sendData(SlipDataProcessor::serializeData(SlipDataProcessor::buildFrame(frame)));
} else { } else {
client->sendData(data); client->sendData(data + '\n');
} }
} }
@ -372,12 +372,12 @@ void JsonRpcServer::sendNotification(const QString &nameSpace, const QString &me
if (transportClient->slipEnabled()) { if (transportClient->slipEnabled()) {
SlipDataProcessor::Frame frame; SlipDataProcessor::Frame frame;
frame.socketAddress = 0x0000; frame.socketAddress = 0x0000;
frame.data = data; frame.data = data + '\n';
qCDebug(dcJsonRpcTraffic()) << "Sending notification frame:" <<frame.socketAddress << qUtf8Printable(frame.data); qCDebug(dcJsonRpcTraffic()) << "Sending notification frame:" <<frame.socketAddress << qUtf8Printable(frame.data);
transportClient->sendData(SlipDataProcessor::serializeData(SlipDataProcessor::buildFrame(frame))); transportClient->sendData(SlipDataProcessor::serializeData(SlipDataProcessor::buildFrame(frame)));
} else { } else {
qCDebug(dcJsonRpcTraffic()) << "Sending notification:" << data; qCDebug(dcJsonRpcTraffic()) << "Sending notification:" << data;
transportClient->sendData(data); transportClient->sendData(data + '\n');
} }
} }

View File

@ -53,7 +53,7 @@ void TcpSocketServer::sendData(const QUuid &clientId, const QByteArray &data)
} }
qCDebug(dcTcpSocketServerTraffic()) << "Send data to" << clientId.toString() << data + '\n'; 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(); 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) if (!client)
return; return;
qCWarning(dcTcpSocketServer()) << "Killing client connection" << clientId.toString() << "Reason:" << killReason; if (client->state() == QAbstractSocket::ConnectedState) {
client->close(); qCWarning(dcTcpSocketServer()) << "Killing client connection" << clientId.toString() << "Reason:" << killReason;
client->close();
}
} }
bool TcpSocketServer::running() const bool TcpSocketServer::running() const

View File

@ -64,7 +64,7 @@ void WebSocketServer::sendData(const QUuid &clientId, const QByteArray &data)
client = m_clientList.value(clientId); client = m_clientList.value(clientId);
if (client) { if (client) {
qCDebug(dcWebSocketServerTraffic()) << "--> Sending data to client:" << data; qCDebug(dcWebSocketServerTraffic()) << "--> Sending data to client:" << data;
client->sendTextMessage(data + '\n'); client->sendTextMessage(data);
} else { } else {
qCWarning(dcWebSocketServer()) << "Client" << clientId << "unknown to this transport"; qCWarning(dcWebSocketServer()) << "Client" << clientId << "unknown to this transport";
} }

View File

@ -46,6 +46,7 @@ QList<QByteArray> TunnelProxyClient::processData(const QByteArray &data)
} else { } else {
qCDebug(dcTunnelProxyServerTraffic()) << "Frame received"; qCDebug(dcTunnelProxyServerTraffic()) << "Frame received";
packages.append(m_dataBuffer); packages.append(m_dataBuffer);
m_dataBuffer.clear();
} }
} else { } else {
m_dataBuffer.append(data.at(i)); m_dataBuffer.append(data.at(i));

View File

@ -81,6 +81,7 @@ QDebug operator<<(QDebug debug, TunnelProxyClientConnection *clientConnection)
debug.nospace() << "TunnelProxyClientConnection("; debug.nospace() << "TunnelProxyClientConnection(";
debug.nospace() << clientConnection->clientName() << ", "; debug.nospace() << clientConnection->clientName() << ", ";
debug.nospace() << clientConnection->clientUuid().toString() << ", "; debug.nospace() << clientConnection->clientUuid().toString() << ", ";
debug.nospace() << "server: " << clientConnection->serverUuid().toString() << ", ";
debug.nospace() << clientConnection->transportClient() << ")"; debug.nospace() << clientConnection->transportClient() << ")";
return debug.space(); return debug.space();
} }

View File

@ -265,8 +265,8 @@ void TunnelProxyServer::onClientDisconnected(const QUuid &clientId)
if (clientConnection->serverConnection()) { if (clientConnection->serverConnection()) {
QVariantMap params; QVariantMap params;
params.insert("socketAddress", clientConnection->socketAddress()); params.insert("socketAddress", clientConnection->socketAddress());
m_jsonRpcServer->sendNotification("TunnelProxy", "ClientDisconnected", params, clientConnection->serverConnection()->transportClient());
clientConnection->serverConnection()->unregisterClientConnection(clientConnection); clientConnection->serverConnection()->unregisterClientConnection(clientConnection);
m_jsonRpcServer->sendNotification("TunnelProxy", "ClientDisconnected", params, clientConnection->serverConnection()->transportClient());
} }
clientConnection->deleteLater(); clientConnection->deleteLater();
@ -304,8 +304,9 @@ void TunnelProxyServer::onClientDataAvailable(const QUuid &clientId, const QByte
SlipDataProcessor::Frame frame; SlipDataProcessor::Frame frame;
frame.socketAddress = clientConnection->socketAddress(); frame.socketAddress = clientConnection->socketAddress();
frame.data = data; 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))); clientConnection->serverConnection()->transportClient()->sendData(SlipDataProcessor::serializeData(SlipDataProcessor::buildFrame(frame)));
} else if (tunnelProxyClient->type() == TunnelProxyClient::TypeServer) { } else if (tunnelProxyClient->type() == TunnelProxyClient::TypeServer) {
// Data coming from a connected server connection // Data coming from a connected server connection
if (tunnelProxyClient->slipEnabled()) { if (tunnelProxyClient->slipEnabled()) {
@ -334,7 +335,7 @@ void TunnelProxyServer::onClientDataAvailable(const QUuid &clientId, const QByte
return; 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); clientConnection->transportClient()->sendData(frame.data);
} }
} }

View File

@ -27,6 +27,7 @@
#include "proxyjsonrpcclient.h" #include "proxyjsonrpcclient.h"
#include "proxyconnection.h" #include "proxyconnection.h"
#include "../common/slipdataprocessor.h"
#include <QJsonDocument> #include <QJsonDocument>
@ -93,10 +94,30 @@ JsonReply *JsonRpcClient::callRegisterClient(const QUuid &clientUuid, const QStr
return reply; return reply;
} }
void JsonRpcClient::sendRequest(const QVariantMap &request) JsonReply *JsonRpcClient::callDisconnectClient(quint16 socketAddress)
{ {
QByteArray data = QJsonDocument::fromVariant(request).toJson(QJsonDocument::Compact); QVariantMap params;
qCDebug(dcRemoteProxyClientJsonRpcTraffic()) << "Sending" << data; 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); m_connection->sendData(data);
} }

View File

@ -66,7 +66,7 @@ private:
QHash<int, JsonReply *> m_replies; QHash<int, JsonReply *> m_replies;
void sendRequest(const QVariantMap &request); void sendRequest(const QVariantMap &request, bool slipEnabled = false);
void processDataPackage(const QByteArray &data); void processDataPackage(const QByteArray &data);
signals: signals:

View File

@ -77,6 +77,11 @@ void TunnelProxyRemoteConnection::ignoreSslErrors(const QList<QSslError> &errors
m_connection->ignoreSslErrors(errors); m_connection->ignoreSslErrors(errors);
} }
QUrl TunnelProxyRemoteConnection::serverUrl() const
{
return m_serverUrl;
}
QString TunnelProxyRemoteConnection::remoteProxyServer() const QString TunnelProxyRemoteConnection::remoteProxyServer() const
{ {
return m_remoteProxyServer; 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) void TunnelProxyRemoteConnection::onConnectionChanged(bool connected)
{ {
if (connected) { if (connected) {

View File

@ -74,6 +74,8 @@ public:
void ignoreSslErrors(); void ignoreSslErrors();
void ignoreSslErrors(const QList<QSslError> &errors); void ignoreSslErrors(const QList<QSslError> &errors);
QUrl serverUrl() const;
QString remoteProxyServer() const; QString remoteProxyServer() const;
QString remoteProxyServerName() const; QString remoteProxyServerName() const;
QString remoteProxyServerVersion() const; QString remoteProxyServerVersion() const;
@ -82,6 +84,7 @@ public:
public slots: public slots:
bool connectServer(const QUrl &url, const QUuid &serverUuid); bool connectServer(const QUrl &url, const QUuid &serverUuid);
void disconnectServer(); void disconnectServer();
bool sendData(const QByteArray &data);
signals: signals:
void stateChanged(TunnelProxyRemoteConnection::State state); void stateChanged(TunnelProxyRemoteConnection::State state);

View File

@ -27,13 +27,15 @@
#include "tunnelproxysocket.h" #include "tunnelproxysocket.h"
#include "proxyconnection.h" #include "proxyconnection.h"
#include "tunnelproxysocketserver.h"
#include "../common/slipdataprocessor.h" #include "../common/slipdataprocessor.h"
namespace remoteproxyclient { 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), QObject(parent),
m_connection(connection), m_connection(connection),
m_socketServer(socketServer),
m_clientName(clientName), m_clientName(clientName),
m_clientUuid(clientUuid), m_clientUuid(clientUuid),
m_clientPeerAddress(clientPeerAddress), m_clientPeerAddress(clientPeerAddress),
@ -62,6 +64,11 @@ quint16 TunnelProxySocket::socketAddress() const
return m_socketAddress; return m_socketAddress;
} }
bool TunnelProxySocket::connected() const
{
return m_connected;
}
void TunnelProxySocket::writeData(const QByteArray &data) void TunnelProxySocket::writeData(const QByteArray &data)
{ {
SlipDataProcessor::Frame frame; SlipDataProcessor::Frame frame;
@ -72,7 +79,14 @@ void TunnelProxySocket::writeData(const QByteArray &data)
void TunnelProxySocket::disconnectSocket() 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) QDebug operator<<(QDebug debug, TunnelProxySocket *tunnelProxySocket)

View File

@ -35,6 +35,7 @@
namespace remoteproxyclient { namespace remoteproxyclient {
class ProxyConnection; class ProxyConnection;
class TunnelProxySocketServer;
class TunnelProxySocket : public QObject class TunnelProxySocket : public QObject
{ {
@ -47,25 +48,33 @@ public:
QHostAddress clientPeerAddress() const; QHostAddress clientPeerAddress() const;
quint16 socketAddress() const; quint16 socketAddress() const;
bool connected() const;
void writeData(const QByteArray &data); void writeData(const QByteArray &data);
void disconnectSocket(); void disconnectSocket();
signals: signals:
void dataReceived(const QByteArray &data); void dataReceived(const QByteArray &data);
void connectedChanged(bool connected);
void disconnected(); void disconnected();
private: 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; ~TunnelProxySocket() = default;
ProxyConnection *m_connection = nullptr; 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; QString m_clientName;
QUuid m_clientUuid; QUuid m_clientUuid;
QHostAddress m_clientPeerAddress; QHostAddress m_clientPeerAddress;
quint16 m_socketAddress = 0xFFFF; quint16 m_socketAddress = 0xFFFF;
void setDisconnected();
}; };
QDebug operator<<(QDebug debug, TunnelProxySocket *tunnelProxySocket); QDebug operator<<(QDebug debug, TunnelProxySocket *tunnelProxySocket);

View File

@ -299,7 +299,7 @@ void TunnelProxySocketServer::onServerRegistrationFinished()
void TunnelProxySocketServer::onTunnelProxyClientConnected(const QString &clientName, const QUuid &clientUuid, const QString &clientPeerAddress, quint16 socketAddress) 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; qCDebug(dcTunnelProxySocketServer()) << "--> New client connected" << tunnelProxySocket;
m_tunnelProxySockets.insert(socketAddress, tunnelProxySocket); m_tunnelProxySockets.insert(socketAddress, tunnelProxySocket);
emit clientConnected(tunnelProxySocket); emit clientConnected(tunnelProxySocket);
@ -314,10 +314,24 @@ void TunnelProxySocketServer::onTunnelProxyClientDisconnected(quint16 socketAddr
} }
qCDebug(dcTunnelProxySocketServer()) << "--> Client disconnected" << tunnelProxySocket; qCDebug(dcTunnelProxySocketServer()) << "--> Client disconnected" << tunnelProxySocket;
emit tunnelProxySocket->disconnected(); tunnelProxySocket->setDisconnected();
emit clientDisconnected(tunnelProxySocket);
tunnelProxySocket->deleteLater(); 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) void TunnelProxySocketServer::setState(State state)
{ {
if (m_state == state) if (m_state == state)

View File

@ -45,6 +45,9 @@ class JsonRpcClient;
class TunnelProxySocketServer : public QObject class TunnelProxySocketServer : public QObject
{ {
Q_OBJECT Q_OBJECT
friend class TunnelProxySocket;
public: public:
enum State { enum State {
StateConnecting, StateConnecting,
@ -147,6 +150,8 @@ private:
QByteArray m_dataBuffer; QByteArray m_dataBuffer;
void requestSocketDisconnect(quint16 socketAddress);
void setState(State state); void setState(State state);
void setRunning(bool running); void setRunning(bool running);
void setError(QAbstractSocket::SocketError error); void setError(QAbstractSocket::SocketError error);

View File

@ -51,7 +51,7 @@ WebSocketConnection::~WebSocketConnection()
void WebSocketConnection::sendData(const QByteArray &data) void WebSocketConnection::sendData(const QByteArray &data)
{ {
m_webSocket->sendTextMessage(QString::fromUtf8(data + '\n')); m_webSocket->sendTextMessage(QString::fromUtf8(data));
} }
void WebSocketConnection::ignoreSslErrors() void WebSocketConnection::ignoreSslErrors()

View File

@ -27,3 +27,12 @@ port=443
[TcpServer] [TcpServer]
host=127.0.0.1 host=127.0.0.1
port=80 port=80
[WebSocketServerTunnelProxy]
host=127.0.0.1
port=2212
[TcpServerTunnelProxy]
host=127.0.0.1
port=2213

View File

@ -16,3 +16,11 @@ port=1212
[TcpServer] [TcpServer]
host=127.0.0.1 host=127.0.0.1
port=1213 port=1213
[WebSocketServerTunnelProxy]
host=127.0.0.1
port=2212
[TcpServerTunnelProxy]
host=127.0.0.1
port=2213

View File

@ -16,3 +16,11 @@ port=1212
[TcpServer] [TcpServer]
host=127.0.0.1 host=127.0.0.1
port=1213 port=1213
[WebSocketServerTunnelProxy]
host=127.0.0.1
port=2212
[TcpServerTunnelProxy]
host=127.0.0.1
port=2213

View File

@ -16,3 +16,11 @@ port=1212
[TcpServer] [TcpServer]
host=127.0.0.1 host=127.0.0.1
port=1213 port=1213
[WebSocketServerTunnelProxy]
host=127.0.0.1
port=2212
[TcpServerTunnelProxy]
host=127.0.0.1
port=2213

View File

@ -16,3 +16,11 @@ port=1212
[TcpServer] [TcpServer]
host=127.0.0.1 host=127.0.0.1
port=1213 port=1213
[WebSocketServerTunnelProxy]
host=127.0.0.1
port=2212
[TcpServerTunnelProxy]
host=127.0.0.1
port=2213

View File

@ -20,3 +20,11 @@ port=1212
[TcpServer] [TcpServer]
host=127.0.0.1 host=127.0.0.1
port=1213 port=1213
[WebSocketServerTunnelProxy]
host=127.0.0.1
port=2212
[TcpServerTunnelProxy]
host=127.0.0.1
port=2213

View File

@ -30,6 +30,7 @@
#include "engine.h" #include "engine.h"
#include "loggingcategories.h" #include "loggingcategories.h"
#include "remoteproxyconnection.h" #include "remoteproxyconnection.h"
#include "../common/slipdataprocessor.h"
// Client // Client
#include "tunnelproxy/tunnelproxysocketserver.h" #include "tunnelproxy/tunnelproxysocketserver.h"
@ -336,6 +337,34 @@ void RemoteProxyTestsTunnelProxy::registerClient()
stopServer(); stopServer();
} }
void RemoteProxyTestsTunnelProxy::testSlip_data()
{
QTest::addColumn<QByteArray>("data");
QTest::addColumn<bool>("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() void RemoteProxyTestsTunnelProxy::registerServerDuplicated()
{ {
// Start the server // Start the server
@ -387,29 +416,11 @@ void RemoteProxyTestsTunnelProxy::registerServerDuplicated()
// Try to register from a websocket with the same uuid // Try to register from a websocket with the same uuid
QPair<QVariant, QWebSocket *> resultWebSocket = invokeWebSocketTunnelProxyApiCallPersistant("TunnelProxy.RegisterServer", params); QPair<QVariant, QWebSocket *> resultWebSocket = invokeWebSocketTunnelProxyApiCallPersistant("TunnelProxy.RegisterServer", params);
response = resultWebSocket.first.toMap(); response = resultWebSocket.first.toMap();
QWebSocket *webSocket = resultWebSocket.second;
QVERIFY(!response.isEmpty()); QVERIFY(!response.isEmpty());
QVERIFY(response.value("status").toString() == "success"); QVERIFY(response.value("status").toString() == "success");
QVERIFY(response.value("params").toMap().contains("tunnelProxyError")); QVERIFY(response.value("params").toMap().contains("tunnelProxyError"));
verifyTunnelProxyError(response); 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(); resetDebugCategories();
// Clean up // Clean up
@ -559,6 +570,7 @@ void RemoteProxyTestsTunnelProxy::testTunnelProxyServer()
addDebugCategory("JsonRpcTraffic.debug=true"); addDebugCategory("JsonRpcTraffic.debug=true");
addDebugCategory("TunnelProxySocketServer.debug=true"); addDebugCategory("TunnelProxySocketServer.debug=true");
addDebugCategory("TunnelProxyRemoteConnection.debug=true"); addDebugCategory("TunnelProxyRemoteConnection.debug=true");
addDebugCategory("TunnelProxyRemoteConnectionTraffic.debug=true");
addDebugCategory("RemoteProxyClientJsonRpcTraffic.debug=true"); addDebugCategory("RemoteProxyClientJsonRpcTraffic.debug=true");
// Tunnel proxy socket server // Tunnel proxy socket server
@ -579,6 +591,13 @@ void RemoteProxyTestsTunnelProxy::testTunnelProxyServer()
QVERIFY(arguments.at(0).toBool() == true); QVERIFY(arguments.at(0).toBool() == true);
QVERIFY(tunnelProxyServer->running()); 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 // Tunnel proxy client connection
QString clientName = "Awesome client name"; QString clientName = "Awesome client name";
QUuid clientUuid = QUuid::createUuid(); QUuid clientUuid = QUuid::createUuid();
@ -597,22 +616,50 @@ void RemoteProxyTestsTunnelProxy::testTunnelProxyServer()
TunnelProxySocket *tunnelProxySocket = arguments.at(0).value<TunnelProxySocket *>(); TunnelProxySocket *tunnelProxySocket = arguments.at(0).value<TunnelProxySocket *>();
QVERIFY(tunnelProxySocket->clientName() == clientName); QVERIFY(tunnelProxySocket->clientName() == clientName);
QVERIFY(tunnelProxySocket->clientUuid() == clientUuid); 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<TunnelProxySocket *>();
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 // Stop the server connection and verify the client gets disconnected
QSignalSpy serverNotRunningSpy(tunnelProxyServer, &TunnelProxySocketServer::runningChanged);
tunnelProxyServer->stopServer(); tunnelProxyServer->stopServer();
QSignalSpy disconnectedSpy(clientConnection, &TunnelProxyRemoteConnection::remoteConnectedChanged); // Verify the remote connection is disconnected
QVERIFY(disconnectedSpy.wait()); serverNotRunningSpy.wait();
QVERIFY(disconnectedSpy.count() == 1); QVERIFY(serverNotRunningSpy.count() == 1);
arguments = disconnectedSpy.takeFirst(); arguments = serverNotRunningSpy.takeFirst();
QVERIFY(arguments.at(0).toBool() == false); QVERIFY(arguments.at(0).toBool() == false);
QVERIFY(!clientConnection->remoteConnected()); QVERIFY(!tunnelProxyServer->running());
// Clean up
tunnelProxyServer->deleteLater();
clientConnection->deleteLater();
resetDebugCategories(); resetDebugCategories();
// Clean up
stopServer(); stopServer();
} }
@ -647,6 +694,12 @@ void RemoteProxyTestsTunnelProxy::testTunnelProxyClient()
QVERIFY(arguments.at(0).toBool() == true); QVERIFY(arguments.at(0).toBool() == true);
QVERIFY(tunnelProxyServer->running()); 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 // Tunnel proxy client connection
QString clientName = "Awesome client name"; QString clientName = "Awesome client name";
@ -666,15 +719,276 @@ void RemoteProxyTestsTunnelProxy::testTunnelProxyClient()
QVERIFY(arguments.at(0).toBool() == true); QVERIFY(arguments.at(0).toBool() == true);
QVERIFY(clientConnection->remoteConnected()); 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(); resetDebugCategories();
// Clean up
stopServer(); 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<QSslError> &errors){
tunnelProxyServer->ignoreSslErrors(errors);
});
tunnelProxyServer->startServer(m_serverUrlTunnelProxyTcp);
QSignalSpy serverRunningSpy(tunnelProxyServer, &TunnelProxySocketServer::runningChanged);
serverRunningSpy.wait();
QVERIFY(serverRunningSpy.count() == 1);
QList<QVariant> 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<QSslError> &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<TunnelProxySocket *>();
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<QSslError> &errors){
tunnelProxyServer->ignoreSslErrors(errors);
});
tunnelProxyServer->startServer(m_serverUrlTunnelProxyTcp);
QSignalSpy serverRunningSpy(tunnelProxyServer, &TunnelProxySocketServer::runningChanged);
serverRunningSpy.wait();
QVERIFY(serverRunningSpy.count() == 1);
QList<QVariant> 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<QSslError> &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<TunnelProxySocket *>();
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<QSslError> &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<TunnelProxySocket *>();
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) QTEST_MAIN(RemoteProxyTestsTunnelProxy)

View File

@ -60,6 +60,9 @@ private slots:
void registerClient_data(); void registerClient_data();
void registerClient(); void registerClient();
void testSlip_data();
void testSlip();
void registerServerDuplicated(); void registerServerDuplicated();
void registerClientDuplicated(); void registerClientDuplicated();
void crossRegisterServerClient(); void crossRegisterServerClient();
@ -67,6 +70,10 @@ private slots:
// Client classes // Client classes
void testTunnelProxyServer(); void testTunnelProxyServer();
void testTunnelProxyClient(); void testTunnelProxyClient();
void testTunnelProxyServerSocketDisconnect();
void tunnelProxyEndToEndTest();
}; };

View File

@ -715,7 +715,6 @@ QPair<QVariant, QSslSocket *> BaseTest::invokeTcpSocketTunnelProxyApiCallPersist
continue; continue;
break; break;
messageData.clear();
} else { } else {
messageData.append(rawData.at(i)); messageData.append(rawData.at(i));
} }
@ -780,13 +779,19 @@ QPair<QVariant, QWebSocket *> BaseTest::invokeWebSocketTunnelProxyApiCallPersist
QJsonDocument jsonDoc = QJsonDocument::fromVariant(request); QJsonDocument jsonDoc = QJsonDocument::fromVariant(request);
QByteArray payload = jsonDoc.toJson(QJsonDocument::Compact) + '\n'; QByteArray payload = jsonDoc.toJson(QJsonDocument::Compact) + '\n';
if (socket->state() != QAbstractSocket::ConnectedState) {
qWarning() << "Socket not connected";
return QPair<QVariant, QWebSocket *>(QVariant(), socket);
}
QSignalSpy dataSpy(socket, SIGNAL(textMessageReceived(QString))); QSignalSpy dataSpy(socket, SIGNAL(textMessageReceived(QString)));
if (slipEnabled) { if (slipEnabled) {
SlipDataProcessor::Frame frame; SlipDataProcessor::Frame frame;
frame.socketAddress = 0x0000; frame.socketAddress = 0x0000;
frame.data = payload; frame.data = payload;
socket->sendTextMessage(QString(SlipDataProcessor::serializeData(SlipDataProcessor::buildFrame(frame)))); socket->sendTextMessage(QString::fromUtf8(SlipDataProcessor::serializeData(SlipDataProcessor::buildFrame(frame))));
} else { } else {
socket->sendTextMessage(QString(payload)); socket->sendTextMessage(QString(payload));
} }