Finish and test first working tunnel proxy connection
This commit is contained in:
parent
30d6a9dd43
commit
b9ebc345a5
@ -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));
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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 ¶ms, Transpo
|
|||||||
return createReply("RegisterClient", response);
|
return createReply("RegisterClient", response);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//JsonReply *TunnelProxyHandler::RemoveClient(const QVariantMap ¶ms, TransportClient *transportClient)
|
|
||||||
//{
|
|
||||||
|
|
||||||
//}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -45,10 +45,12 @@ public:
|
|||||||
|
|
||||||
QString name() const override;
|
QString name() const override;
|
||||||
|
|
||||||
|
// Server
|
||||||
Q_INVOKABLE JsonReply *RegisterServer(const QVariantMap ¶ms, TransportClient *transportClient);
|
Q_INVOKABLE JsonReply *RegisterServer(const QVariantMap ¶ms, TransportClient *transportClient);
|
||||||
Q_INVOKABLE JsonReply *DisconnectClient(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:
|
signals:
|
||||||
void ClientConnected(const QVariantMap ¶ms, TransportClient *transportClient);
|
void ClientConnected(const QVariantMap ¶ms, TransportClient *transportClient);
|
||||||
|
|||||||
@ -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);
|
||||||
|
|||||||
@ -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');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
@ -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";
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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));
|
||||||
|
|||||||
@ -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();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -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:
|
||||||
|
|||||||
@ -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) {
|
||||||
|
|||||||
@ -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);
|
||||||
|
|||||||
@ -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)
|
||||||
|
|||||||
@ -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);
|
||||||
|
|||||||
@ -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)
|
||||||
|
|||||||
@ -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);
|
||||||
|
|||||||
@ -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()
|
||||||
|
|||||||
@ -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
|
||||||
|
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
@ -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)
|
||||||
|
|||||||
@ -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();
|
||||||
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -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));
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user