Abstract transport interface client and restructure client classes

This commit is contained in:
Simon Stürz 2021-07-29 11:38:55 +02:00
parent acd48bf7bf
commit 24e7c2983f
27 changed files with 479 additions and 262 deletions

18
debian/control vendored
View File

@ -2,10 +2,16 @@ Source: nymea-remoteproxy
Section: utils Section: utils
Priority: options Priority: options
Maintainer: Simon Stürz <simon.stuerz@nymea.io> Maintainer: Simon Stürz <simon.stuerz@nymea.io>
Build-depends: debhelper (>= 0.0.0),
libqt5websockets5-dev,
libncurses5-dev,
Standards-Version: 3.9.3 Standards-Version: 3.9.3
Homepage: https://nymea.io
Vcs-Git: https://github.com/nymea/nymea-remoteproxy.git
Build-depends: debhelper (>= 9.0.0),
dpkg-dev (>= 1.16.1~),
pkg-config,
qtbase5-dev,
qtbase5-dev-tools,
libqt5websockets5-dev,
libncurses5-dev
Package: nymea-remoteproxy Package: nymea-remoteproxy
@ -31,9 +37,11 @@ Description: The nymea remote proxy server lib
Package: libnymea-remoteproxy-dev Package: libnymea-remoteproxy-dev
Architecture: any Architecture: any
Section: libdevel Section: libdevel
Multi-Arch: same
Depends: ${shlibs:Depends}, Depends: ${shlibs:Depends},
${misc:Depends}, ${misc:Depends},
libnymea-remoteproxy (= ${binary:Version}), libnymea-remoteproxy (= ${binary:Version}),
pkg-config
Description: The nymea remote proxy server lib - development files Description: The nymea remote proxy server lib - development files
The nymea remote proxy server lib - development files The nymea remote proxy server lib - development files
@ -59,9 +67,11 @@ Description: The nymea remote proxy server client lib
Package: libnymea-remoteproxyclient-dev Package: libnymea-remoteproxyclient-dev
Architecture: any Architecture: any
Section: libdevel Section: libdevel
Multi-Arch: same
Depends: ${shlibs:Depends}, Depends: ${shlibs:Depends},
${misc:Depends}, ${misc:Depends},
libnymea-remoteproxyclient (= ${binary:Version}), libnymea-remoteproxyclient (= ${binary:Version}),
pkg-config
Description: The nymea remote proxy server client lib - development files Description: The nymea remote proxy server client lib - development files
The nymea remote proxy server client lib - development files The nymea remote proxy server client lib - development files
@ -81,4 +91,4 @@ Depends: ${shlibs:Depends},
${misc:Depends}, ${misc:Depends},
libncurses5, libncurses5,
Description: The nymea remote proxy monitor tool Description: The nymea remote proxy monitor tool
The nymea remote proxy server tests The nymea remote proxy server monitor

14
debian/rules vendored
View File

@ -1,7 +1,11 @@
#!/usr/bin/make -f #!/usr/bin/make -f
# -*- makefile -*-
export DH_VERBOSE=1
DEB_HOST_MULTIARCH ?= $(shell dpkg-architecture -qDEB_HOST_MULTIARCH) DEB_HOST_MULTIARCH ?= $(shell dpkg-architecture -qDEB_HOST_MULTIARCH)
include /usr/share/dpkg/buildflags.mk
PREPROCESS_FILES := $(wildcard debian/*.in) PREPROCESS_FILES := $(wildcard debian/*.in)
@ -11,17 +15,9 @@ $(PREPROCESS_FILES:.in=): %: %.in
override_dh_install: $(PREPROCESS_FILES:.in=) override_dh_install: $(PREPROCESS_FILES:.in=)
dh_install dh_install
override_dh_strip:
dh_strip --dbg-package=libnymea-remoteproxy-dbg
dh_strip --dbg-package=libnymea-remoteproxyclient-dbg
#override_dh_auto_test:
# make test
override_dh_auto_clean: override_dh_auto_clean:
dh_auto_clean dh_auto_clean
find . -name *.qm -exec rm {} \;
rm -rf $(PREPROCESS_FILES:.in=) rm -rf $(PREPROCESS_FILES:.in=)
%: %:
dh $@ --with systemd --parallel dh $@ --buildsystem=qmake --with systemd --parallel

View File

@ -25,7 +25,7 @@
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#include "proxyclient.h" #include "proxy/proxyclient.h"
#include "authenticator.h" #include "authenticator.h"
#include "authenticationreply.h" #include "authenticationreply.h"

View File

@ -26,7 +26,7 @@
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#include "engine.h" #include "engine.h"
#include "proxyclient.h" #include "proxy/proxyclient.h"
#include "awsauthenticator.h" #include "awsauthenticator.h"
#include "loggingcategories.h" #include "loggingcategories.h"

View File

@ -30,7 +30,7 @@
#include <QObject> #include <QObject>
#include "proxyclient.h" #include "proxy/proxyclient.h"
#include "authentication/authenticator.h" #include "authentication/authenticator.h"
namespace remoteproxy { namespace remoteproxy {

View File

@ -28,6 +28,7 @@
#include "jsontypes.h" #include "jsontypes.h"
#include "loggingcategories.h" #include "loggingcategories.h"
#include "authenticationhandler.h" #include "authenticationhandler.h"
#include "server/transportclient.h"
#include "engine.h" #include "engine.h"
@ -60,7 +61,7 @@ QString AuthenticationHandler::name() const
return "Authentication"; return "Authentication";
} }
JsonReply *AuthenticationHandler::Authenticate(const QVariantMap &params, ProxyClient *proxyClient) JsonReply *AuthenticationHandler::Authenticate(const QVariantMap &params, TransportClient *transportClient)
{ {
QString uuid = params.value("uuid").toString(); QString uuid = params.value("uuid").toString();
QString name = params.value("name").toString(); QString name = params.value("name").toString();
@ -71,6 +72,7 @@ JsonReply *AuthenticationHandler::Authenticate(const QVariantMap &params, ProxyC
JsonReply *jsonReply = createAsyncReply("Authenticate"); JsonReply *jsonReply = createAsyncReply("Authenticate");
// Set the token for this proxy client // Set the token for this proxy client
ProxyClient *proxyClient = qobject_cast<ProxyClient *>(transportClient);
proxyClient->setUuid(uuid); proxyClient->setUuid(uuid);
proxyClient->setName(name); proxyClient->setName(name);
proxyClient->setToken(token); proxyClient->setToken(token);

View File

@ -35,6 +35,8 @@
namespace remoteproxy { namespace remoteproxy {
class TransportClient;
class AuthenticationHandler : public JsonHandler class AuthenticationHandler : public JsonHandler
{ {
Q_OBJECT Q_OBJECT
@ -44,7 +46,7 @@ public:
QString name() const override; QString name() const override;
Q_INVOKABLE JsonReply *Authenticate(const QVariantMap &params, ProxyClient *proxyClient); Q_INVOKABLE JsonReply *Authenticate(const QVariantMap &params, TransportClient *transportClient);
private: private:
QHash<AuthenticationReply *, JsonReply *> m_runningAuthentications; QHash<AuthenticationReply *, JsonReply *> m_runningAuthentications;

View File

@ -75,7 +75,7 @@ QVariantMap JsonHandler::introspect(const QMetaMethod::MethodType &type)
} }
break; break;
default: default:
;;// Nothing to do for slots break; // Nothing to do for slots
} }
} }
} }

View File

@ -54,8 +54,6 @@ QVariantMap JsonTypes::allTypes()
allTypes.insert("AuthenticationError", authenticationError()); allTypes.insert("AuthenticationError", authenticationError());
allTypes.insert("TunnelProxyError", tunnelProxyError()); allTypes.insert("TunnelProxyError", tunnelProxyError());
// Types
return allTypes; return allTypes;
} }

View File

@ -55,17 +55,16 @@ QString TunnelProxyHandler::name() const
return "TunnelProxy"; return "TunnelProxy";
} }
JsonReply *TunnelProxyHandler::RegisterServer(const QVariantMap &params, ProxyClient *proxyClient) JsonReply *TunnelProxyHandler::RegisterServer(const QVariantMap &params, TransportClient *transportClient)
{ {
qCDebug(dcJsonRpc()) << name() << "register server" << params << proxyClient; qCDebug(dcJsonRpc()) << name() << "register server" << params << transportClient;
QUuid serverUuid = params.value("uuid").toUuid(); QUuid serverUuid = params.value("uuid").toUuid();
QString serverName = params.value("name").toString(); QString serverName = params.value("name").toString();
TunnelProxyManager::Error error = Engine::instance()->tunnelProxyManager()->registerServer(proxyClient->clientId(), serverUuid, serverName); TunnelProxyManager::Error error = Engine::instance()->tunnelProxyManager()->registerServer(transportClient->clientId(), serverUuid, serverName);
QVariantMap response; QVariantMap response;
response.insert("tunnelProxyError", JsonTypes::tunnelProxyErrorToString(error)); response.insert("tunnelProxyError", JsonTypes::tunnelProxyErrorToString(error));
return createReply("RegisterServer", response); return createReply("RegisterServer", response);
} }

View File

@ -34,6 +34,8 @@
namespace remoteproxy { namespace remoteproxy {
class TransportClient;
class TunnelProxyHandler : public JsonHandler class TunnelProxyHandler : public JsonHandler
{ {
Q_OBJECT Q_OBJECT
@ -43,7 +45,7 @@ public:
QString name() const override; QString name() const override;
Q_INVOKABLE JsonReply *RegisterServer(const QVariantMap &params, ProxyClient *proxyClient); Q_INVOKABLE JsonReply *RegisterServer(const QVariantMap &params, TransportClient *transportClient);
signals: signals:

View File

@ -5,61 +5,65 @@ TARGET = nymea-remoteproxy
HEADERS += \ HEADERS += \
engine.h \ engine.h \
logengine.h \
loggingcategories.h \ loggingcategories.h \
tunnelproxy/tunnelproxymanager.h \
tunnelproxy/tunnelproxyserver.h \
server/tcpsocketserver.h \
server/transportinterface.h \
server/websocketserver.h \
server/jsonrpcserver.h \
server/monitorserver.h \
proxyclient.h \
proxy/proxyserver.h \
proxy/tunnelconnection.h \
proxyconfiguration.h \ proxyconfiguration.h \
jsonrpc/jsonhandler.h \
jsonrpc/jsonreply.h \
jsonrpc/jsontypes.h \
jsonrpc/authenticationhandler.h \
jsonrpc/tunnelproxyhandler.h \
authentication/authenticator.h \ authentication/authenticator.h \
authentication/authenticationreply.h \ authentication/authenticationreply.h \
authentication/dummy/dummyauthenticator.h \
authentication/aws/awsauthenticator.h \ authentication/aws/awsauthenticator.h \
authentication/aws/userinformation.h \ authentication/aws/userinformation.h \
authentication/aws/authenticationprocess.h \ authentication/aws/authenticationprocess.h \
authentication/aws/sigv4utils.h \ authentication/aws/sigv4utils.h \
authentication/aws/awscredentialprovider.h \ authentication/aws/awscredentialprovider.h \
logengine.h authentication/dummy/dummyauthenticator.h \
jsonrpc/jsonhandler.h \
jsonrpc/jsonreply.h \
jsonrpc/jsontypes.h \
jsonrpc/authenticationhandler.h \
jsonrpc/tunnelproxyhandler.h \
proxy/proxyclient.h \
proxy/proxyserver.h \
proxy/tunnelconnection.h \
server/tcpsocketserver.h \
server/transportinterface.h \
server/websocketserver.h \
server/jsonrpcserver.h \
server/transportclient.h \
server/monitorserver.h \
tunnelproxy/tunnelproxyclientconnection.h \
tunnelproxy/tunnelproxymanager.h \
tunnelproxy/tunnelproxyserverconnection.h
SOURCES += \ SOURCES += \
engine.cpp \ engine.cpp \
logengine.cpp \
loggingcategories.cpp \ loggingcategories.cpp \
tunnelproxy/tunnelproxymanager.cpp \
tunnelproxy/tunnelproxyserver.cpp \
server/tcpsocketserver.cpp \
server/transportinterface.cpp \
server/websocketserver.cpp \
server/jsonrpcserver.cpp \
server/monitorserver.cpp \
proxyclient.cpp \
proxy/proxyserver.cpp \
proxy/tunnelconnection.cpp \
proxyconfiguration.cpp \ proxyconfiguration.cpp \
jsonrpc/jsonhandler.cpp \
jsonrpc/jsonreply.cpp \
jsonrpc/jsontypes.cpp \
jsonrpc/authenticationhandler.cpp \
jsonrpc/tunnelproxyhandler.cpp \
authentication/authenticator.cpp \ authentication/authenticator.cpp \
authentication/authenticationreply.cpp \ authentication/authenticationreply.cpp \
authentication/dummy/dummyauthenticator.cpp \
authentication/aws/awsauthenticator.cpp \ authentication/aws/awsauthenticator.cpp \
authentication/aws/userinformation.cpp \ authentication/aws/userinformation.cpp \
authentication/aws/authenticationprocess.cpp \ authentication/aws/authenticationprocess.cpp \
authentication/aws/sigv4utils.cpp \ authentication/aws/sigv4utils.cpp \
authentication/aws/awscredentialprovider.cpp \ authentication/aws/awscredentialprovider.cpp \
logengine.cpp authentication/dummy/dummyauthenticator.cpp \
jsonrpc/jsonhandler.cpp \
jsonrpc/jsonreply.cpp \
jsonrpc/jsontypes.cpp \
jsonrpc/authenticationhandler.cpp \
jsonrpc/tunnelproxyhandler.cpp \
proxy/proxyclient.cpp \
proxy/proxyserver.cpp \
proxy/tunnelconnection.cpp \
server/tcpsocketserver.cpp \
server/transportinterface.cpp \
server/transportclient.cpp \
server/websocketserver.cpp \
server/jsonrpcserver.cpp \
server/monitorserver.cpp \
tunnelproxy/tunnelproxyclientconnection.cpp \
tunnelproxy/tunnelproxymanager.cpp \
tunnelproxy/tunnelproxyserverconnection.cpp
# install header file with relative subdirectory # install header file with relative subdirectory

View File

@ -34,39 +34,14 @@
namespace remoteproxy { namespace remoteproxy {
ProxyClient::ProxyClient(TransportInterface *interface, const QUuid &clientId, const QHostAddress &address, QObject *parent) : ProxyClient::ProxyClient(TransportInterface *interface, const QUuid &clientId, const QHostAddress &address, QObject *parent) :
QObject(parent), TransportClient(interface, clientId, address, parent)
m_interface(interface),
m_clientId(clientId),
m_peerAddress(address)
{ {
m_creationTimeStamp = QDateTime::currentDateTimeUtc().toTime_t();
m_timer = new QTimer(this); m_timer = new QTimer(this);
connect(m_timer, &QTimer::timeout, this, &ProxyClient::timeoutOccured); connect(m_timer, &QTimer::timeout, this, &ProxyClient::timeoutOccured);
m_timer->setSingleShot(true); m_timer->setSingleShot(true);
resetTimer(); resetTimer();
} }
QUuid ProxyClient::clientId() const
{
return m_clientId;
}
QHostAddress ProxyClient::peerAddress() const
{
return m_peerAddress;
}
uint ProxyClient::creationTime() const
{
return m_creationTimeStamp;
}
QString ProxyClient::creationTimeString() const
{
return QDateTime::fromTime_t(creationTime()).toString("dd.MM.yyyy hh:mm:ss");
}
bool ProxyClient::isAuthenticated() const bool ProxyClient::isAuthenticated() const
{ {
return m_authenticated; return m_authenticated;
@ -106,11 +81,6 @@ void ProxyClient::setUserName(const QString &userName)
m_userName = userName; m_userName = userName;
} }
TransportInterface *ProxyClient::interface() const
{
return m_interface;
}
QString ProxyClient::uuid() const QString ProxyClient::uuid() const
{ {
return m_uuid; return m_uuid;
@ -156,26 +126,6 @@ void ProxyClient::setNonce(const QString &nonce)
m_nonce = nonce; m_nonce = nonce;
} }
quint64 ProxyClient::rxDataCount() const
{
return m_rxDataCount;
}
void ProxyClient::addRxDataCount(int dataCount)
{
m_rxDataCount += static_cast<quint64>(dataCount);
}
quint64 ProxyClient::txDataCount() const
{
return m_txDataCount;
}
void ProxyClient::addTxDataCount(int dataCount)
{
m_txDataCount += static_cast<quint64>(dataCount);
}
ProxyClient::TimerWaitState ProxyClient::timerWaitState() const ProxyClient::TimerWaitState ProxyClient::timerWaitState() const
{ {
return m_timerWaitState; return m_timerWaitState;
@ -195,28 +145,6 @@ void ProxyClient::resetTimer()
} }
} }
void ProxyClient::sendData(const QByteArray &data)
{
if (!m_interface)
return;
m_interface->sendData(m_clientId, data);
}
void ProxyClient::killConnection(const QString &reason)
{
if (!m_interface)
return;
m_interface->killClientConnection(m_clientId, reason);
}
int ProxyClient::generateMessageId()
{
m_messageId++;
return m_messageId;
}
QList<QByteArray> ProxyClient::processData(const QByteArray &data) QList<QByteArray> ProxyClient::processData(const QByteArray &data)
{ {
QList<QByteArray> packages; QList<QByteArray> packages;
@ -237,11 +165,6 @@ QList<QByteArray> ProxyClient::processData(const QByteArray &data)
return packages; return packages;
} }
int ProxyClient::bufferSize() const
{
return m_dataBuffers.size();
}
QDebug operator<<(QDebug debug, ProxyClient *proxyClient) QDebug operator<<(QDebug debug, ProxyClient *proxyClient)
{ {
debug.nospace() << "ProxyClient("; debug.nospace() << "ProxyClient(";

View File

@ -34,11 +34,11 @@
#include <QTimer> #include <QTimer>
#include <QHostAddress> #include <QHostAddress>
#include "server/transportinterface.h" #include "server/transportclient.h"
namespace remoteproxy { namespace remoteproxy {
class ProxyClient : public QObject class ProxyClient : public TransportClient
{ {
Q_OBJECT Q_OBJECT
@ -51,12 +51,6 @@ public:
explicit ProxyClient(TransportInterface *interface, const QUuid &clientId, const QHostAddress &address, QObject *parent = nullptr); explicit ProxyClient(TransportInterface *interface, const QUuid &clientId, const QHostAddress &address, QObject *parent = nullptr);
QUuid clientId() const;
QHostAddress peerAddress() const;
uint creationTime() const;
QString creationTimeString() const;
bool isAuthenticated() const; bool isAuthenticated() const;
void setAuthenticated(bool isAuthenticated); void setAuthenticated(bool isAuthenticated);
@ -66,8 +60,6 @@ public:
QString userName() const; QString userName() const;
void setUserName(const QString &userName); void setUserName(const QString &userName);
TransportInterface *interface() const;
// Properties from auth request // Properties from auth request
QString uuid() const; QString uuid() const;
void setUuid(const QString &uuid); void setUuid(const QString &uuid);
@ -83,32 +75,17 @@ public:
QString nonce() const; QString nonce() const;
void setNonce(const QString &nonce); void setNonce(const QString &nonce);
quint64 rxDataCount() const;
void addRxDataCount(int dataCount);
quint64 txDataCount() const;
void addTxDataCount(int dataCount);
// Actions for this client // Actions for this client
TimerWaitState timerWaitState() const; TimerWaitState timerWaitState() const;
void resetTimer(); void resetTimer();
void sendData(const QByteArray &data);
void killConnection(const QString &reason);
// Json server methods // Json server methods
int generateMessageId(); QList<QByteArray> processData(const QByteArray &data) override;
QList<QByteArray> processData(const QByteArray &data);
int bufferSize() const;
private: private:
TransportInterface *m_interface = nullptr;
QTimer *m_timer = nullptr; QTimer *m_timer = nullptr;
TimerWaitState m_timerWaitState = TimerWaitStateInactive; TimerWaitState m_timerWaitState = TimerWaitStateInactive;
QUuid m_clientId;
QHostAddress m_peerAddress;
uint m_creationTimeStamp = 0;
bool m_authenticated = false; bool m_authenticated = false;
bool m_tunnelConnected = false; bool m_tunnelConnected = false;
@ -119,14 +96,6 @@ private:
QString m_userName; QString m_userName;
// Json data information
int m_messageId = 0;
QByteArray m_dataBuffers;
bool m_bufferSizeViolation = false;
quint64 m_rxDataCount = 0;
quint64 m_txDataCount = 0;
signals: signals:
void authenticated(); void authenticated();
void tunnelConnected(); void tunnelConnected();

View File

@ -199,13 +199,13 @@ void ProxyServer::establishTunnel(ProxyClient *firstClient, ProxyClient *secondC
Q_ARG(QString, m_jsonRpcServer->name()), Q_ARG(QString, m_jsonRpcServer->name()),
Q_ARG(QString, "TunnelEstablished"), Q_ARG(QString, "TunnelEstablished"),
Q_ARG(QVariantMap, notificationParamsFirst), Q_ARG(QVariantMap, notificationParamsFirst),
Q_ARG(ProxyClient*, tunnel.clientOne())); Q_ARG(TransportClient*, tunnel.clientOne()));
QMetaObject::invokeMethod(m_jsonRpcServer, QString("sendNotification").toLatin1().data(), Qt::QueuedConnection, QMetaObject::invokeMethod(m_jsonRpcServer, QString("sendNotification").toLatin1().data(), Qt::QueuedConnection,
Q_ARG(QString, m_jsonRpcServer->name()), Q_ARG(QString, m_jsonRpcServer->name()),
Q_ARG(QString, "TunnelEstablished"), Q_ARG(QString, "TunnelEstablished"),
Q_ARG(QVariantMap, notificationParamsSecond), Q_ARG(QVariantMap, notificationParamsSecond),
Q_ARG(ProxyClient*, tunnel.clientTwo())); Q_ARG(TransportClient*, tunnel.clientTwo()));
} }
void ProxyServer::onClientConnected(const QUuid &clientId, const QHostAddress &address) void ProxyServer::onClientConnected(const QUuid &clientId, const QHostAddress &address)
@ -391,7 +391,7 @@ void ProxyServer::onProxyClientTimeoutOccured()
void ProxyServer::startServer() void ProxyServer::startServer()
{ {
qCDebug(dcProxyServer()) << "Start proxy server."; qCDebug(dcProxyServer()) << "Starting proxy server...";
foreach (TransportInterface *interface, m_transportInterfaces) { foreach (TransportInterface *interface, m_transportInterfaces) {
interface->startServer(); interface->startServer();
} }
@ -400,7 +400,7 @@ void ProxyServer::startServer()
void ProxyServer::stopServer() void ProxyServer::stopServer()
{ {
qCDebug(dcProxyServer()) << "Stop proxy server."; qCDebug(dcProxyServer()) << "Stopping proxy...";
foreach (TransportInterface *interface, m_transportInterfaces) { foreach (TransportInterface *interface, m_transportInterfaces) {
interface->stopServer(); interface->stopServer();
} }

View File

@ -85,10 +85,10 @@ QString JsonRpcServer::name() const
return "RemoteProxy"; return "RemoteProxy";
} }
JsonReply *JsonRpcServer::Hello(const QVariantMap &params, ProxyClient *proxyClient) const JsonReply *JsonRpcServer::Hello(const QVariantMap &params, TransportClient *transportClient) const
{ {
Q_UNUSED(params) Q_UNUSED(params)
Q_UNUSED(proxyClient) Q_UNUSED(transportClient)
QVariantMap data; QVariantMap data;
data.insert("server", SERVER_NAME_STRING); data.insert("server", SERVER_NAME_STRING);
@ -99,10 +99,10 @@ JsonReply *JsonRpcServer::Hello(const QVariantMap &params, ProxyClient *proxyCli
return createReply("Hello", data); return createReply("Hello", data);
} }
JsonReply *JsonRpcServer::Introspect(const QVariantMap &params, ProxyClient *proxyClient) const JsonReply *JsonRpcServer::Introspect(const QVariantMap &params, TransportClient *transportClient) const
{ {
Q_UNUSED(params) Q_UNUSED(params)
Q_UNUSED(proxyClient) Q_UNUSED(transportClient)
qCDebug(dcJsonRpc()) << "Introspect called."; qCDebug(dcJsonRpc()) << "Introspect called.";
@ -126,7 +126,7 @@ JsonReply *JsonRpcServer::Introspect(const QVariantMap &params, ProxyClient *pro
return createReply("Introspect", data); return createReply("Introspect", data);
} }
void JsonRpcServer::sendResponse(ProxyClient *client, int commandId, const QVariantMap &params) void JsonRpcServer::sendResponse(TransportClient *client, int commandId, const QVariantMap &params)
{ {
QVariantMap response; QVariantMap response;
response.insert("id", commandId); response.insert("id", commandId);
@ -138,7 +138,7 @@ void JsonRpcServer::sendResponse(ProxyClient *client, int commandId, const QVari
client->sendData(data); client->sendData(data);
} }
void JsonRpcServer::sendErrorResponse(ProxyClient *client, int commandId, const QString &error) void JsonRpcServer::sendErrorResponse(TransportClient *client, int commandId, const QString &error)
{ {
QVariantMap errorResponse; QVariantMap errorResponse;
errorResponse.insert("id", commandId); errorResponse.insert("id", commandId);
@ -172,14 +172,14 @@ void JsonRpcServer::unregisterHandler(JsonHandler *handler)
m_handlers.remove(handler->name()); m_handlers.remove(handler->name());
} }
void JsonRpcServer::processDataPackage(ProxyClient *proxyClient, const QByteArray &data) void JsonRpcServer::processDataPackage(TransportClient *transportClient, const QByteArray &data)
{ {
QJsonParseError error; QJsonParseError error;
QJsonDocument jsonDoc = QJsonDocument::fromJson(data, &error); QJsonDocument jsonDoc = QJsonDocument::fromJson(data, &error);
if(error.error != QJsonParseError::NoError) { if(error.error != QJsonParseError::NoError) {
qCWarning(dcJsonRpc) << "Failed to parse JSON data" << data << ":" << error.errorString(); qCWarning(dcJsonRpc) << "Failed to parse JSON data" << data << ":" << error.errorString();
sendErrorResponse(proxyClient, -1, QString("Failed to parse JSON data: %1").arg(error.errorString())); sendErrorResponse(transportClient, -1, QString("Failed to parse JSON data: %1").arg(error.errorString()));
proxyClient->killConnection("Invalid JSON data received."); transportClient->killConnection("Invalid JSON data received.");
return; return;
} }
@ -189,16 +189,16 @@ void JsonRpcServer::processDataPackage(ProxyClient *proxyClient, const QByteArra
int commandId = message.value("id").toInt(&success); int commandId = message.value("id").toInt(&success);
if (!success) { if (!success) {
qCWarning(dcJsonRpc()) << "Error parsing command. Missing \"id\":" << message; qCWarning(dcJsonRpc()) << "Error parsing command. Missing \"id\":" << message;
sendErrorResponse(proxyClient, -1, "Error parsing command. Missing 'id'"); sendErrorResponse(transportClient, -1, "Error parsing command. Missing 'id'");
proxyClient->killConnection("The id property is missing in the request."); transportClient->killConnection("The id property is missing in the request.");
return; return;
} }
QStringList commandList = message.value("method").toString().split('.'); QStringList commandList = message.value("method").toString().split('.');
if (commandList.count() != 2) { if (commandList.count() != 2) {
qCWarning(dcJsonRpc) << "Error parsing method.\nGot:" << message.value("method").toString() << "\nExpected: \"Namespace.method\""; qCWarning(dcJsonRpc) << "Error parsing method.\nGot:" << message.value("method").toString() << "\nExpected: \"Namespace.method\"";
sendErrorResponse(proxyClient, commandId, QString("Error parsing method. Got: '%1'', Expected: 'Namespace.method'").arg(message.value("method").toString())); sendErrorResponse(transportClient, commandId, QString("Error parsing method. Got: '%1'', Expected: 'Namespace.method'").arg(message.value("method").toString()));
proxyClient->killConnection("Invalid method passed."); transportClient->killConnection("Invalid method passed.");
return; return;
} }
@ -207,30 +207,30 @@ void JsonRpcServer::processDataPackage(ProxyClient *proxyClient, const QByteArra
JsonHandler *handler = m_handlers.value(targetNamespace); JsonHandler *handler = m_handlers.value(targetNamespace);
if (!handler) { if (!handler) {
sendErrorResponse(proxyClient, commandId, "No such namespace"); sendErrorResponse(transportClient, commandId, "No such namespace");
proxyClient->killConnection("No such namespace."); transportClient->killConnection("No such namespace.");
return; return;
} }
if (!handler->hasMethod(method)) { if (!handler->hasMethod(method)) {
sendErrorResponse(proxyClient, commandId, "No such method"); sendErrorResponse(transportClient, commandId, "No such method");
proxyClient->killConnection("No such method."); transportClient->killConnection("No such method.");
return; return;
} }
QVariantMap params = message.value("params").toMap(); QVariantMap params = message.value("params").toMap();
QPair<bool, QString> validationResult = handler->validateParams(method, params); QPair<bool, QString> validationResult = handler->validateParams(method, params);
if (!validationResult.first) { if (!validationResult.first) {
sendErrorResponse(proxyClient, commandId, "Invalid params: " + validationResult.second); sendErrorResponse(transportClient, commandId, "Invalid params: " + validationResult.second);
proxyClient->killConnection("Invalid params passed."); transportClient->killConnection("Invalid params passed.");
return; return;
} }
JsonReply *reply; JsonReply *reply;
QMetaObject::invokeMethod(handler, method.toLatin1().data(), Q_RETURN_ARG(JsonReply*, reply), Q_ARG(QVariantMap, params), Q_ARG(ProxyClient *, proxyClient)); QMetaObject::invokeMethod(handler, method.toLatin1().data(), Q_RETURN_ARG(JsonReply*, reply), Q_ARG(QVariantMap, params), Q_ARG(TransportClient *, transportClient));
if (reply->type() == JsonReply::TypeAsync) { if (reply->type() == JsonReply::TypeAsync) {
m_asyncReplies.insert(reply, proxyClient); m_asyncReplies.insert(reply, transportClient);
reply->setClientId(proxyClient->clientId()); reply->setClientId(transportClient->clientId());
reply->setCommandId(commandId); reply->setCommandId(commandId);
connect(reply, &JsonReply::finished, this, &JsonRpcServer::asyncReplyFinished); connect(reply, &JsonReply::finished, this, &JsonRpcServer::asyncReplyFinished);
@ -244,9 +244,9 @@ void JsonRpcServer::processDataPackage(ProxyClient *proxyClient, const QByteArra
// qCWarning(dcJsonRpc()) << "Return value validation failed of sync reply. This should never happen. Please check the source code."; // qCWarning(dcJsonRpc()) << "Return value validation failed of sync reply. This should never happen. Please check the source code.";
// } // }
reply->setClientId(proxyClient->clientId()); reply->setClientId(transportClient->clientId());
reply->setCommandId(commandId); reply->setCommandId(commandId);
sendResponse(proxyClient, commandId, reply->data()); sendResponse(transportClient, commandId, reply->data());
reply->deleteLater(); reply->deleteLater();
} }
} }
@ -256,10 +256,10 @@ void JsonRpcServer::asyncReplyFinished()
JsonReply *reply = static_cast<JsonReply *>(sender()); JsonReply *reply = static_cast<JsonReply *>(sender());
reply->deleteLater(); reply->deleteLater();
ProxyClient *proxyClient = m_asyncReplies.take(reply); TransportClient *transportClient = m_asyncReplies.take(reply);
qCDebug(dcJsonRpc()) << "Async reply finished" << reply->handler()->name() << reply->method() << reply->clientId().toString(); qCDebug(dcJsonRpc()) << "Async reply finished" << reply->handler()->name() << reply->method() << reply->clientId().toString();
if (!proxyClient) { if (!transportClient) {
qCWarning(dcJsonRpc()) << "Got an async reply but the client does not exist any more."; qCWarning(dcJsonRpc()) << "Got an async reply but the client does not exist any more.";
return; return;
} }
@ -274,71 +274,71 @@ void JsonRpcServer::asyncReplyFinished()
qCWarning(dcJsonRpc()) << "Return value validation failed. This should never happen. Please check the source code."; qCWarning(dcJsonRpc()) << "Return value validation failed. This should never happen. Please check the source code.";
} }
sendResponse(proxyClient, reply->commandId(), reply->data()); sendResponse(transportClient, reply->commandId(), reply->data());
if (!reply->success()) { if (!reply->success()) {
// Disconnect this client since the request was not successfully // Disconnect this client since the request was not successfully
proxyClient->interface()->killClientConnection(proxyClient->clientId(), "API call was not successfully."); transportClient->interface()->killClientConnection(transportClient->clientId(), "API call was not successfully.");
} }
} else { } else {
qCWarning(dcJsonRpc()) << "The reply timeouted."; qCWarning(dcJsonRpc()) << "The reply timeouted.";
sendErrorResponse(proxyClient, reply->commandId(), "Command timed out"); sendErrorResponse(transportClient, reply->commandId(), "Command timed out");
// Disconnect this client since he requested something that created a timeout // Disconnect this client since he requested something that created a timeout
proxyClient->killConnection("API call timeouted."); transportClient->killConnection("API call timeouted.");
} }
} }
void JsonRpcServer::registerClient(ProxyClient *proxyClient) void JsonRpcServer::registerClient(TransportClient *transportClient)
{ {
qCDebug(dcJsonRpc()) << "Register client" << proxyClient; qCDebug(dcJsonRpc()) << "Register client" << transportClient;
if (m_clients.contains(proxyClient)) { if (m_clients.contains(transportClient)) {
qCWarning(dcJsonRpc()) << "Client already registered" << proxyClient; qCWarning(dcJsonRpc()) << "Client already registered" << transportClient;
return; return;
} }
m_clients.append(proxyClient); m_clients.append(transportClient);
} }
void JsonRpcServer::unregisterClient(ProxyClient *proxyClient) void JsonRpcServer::unregisterClient(TransportClient *transportClient)
{ {
qCDebug(dcJsonRpc()) << "Unregister client" << proxyClient; qCDebug(dcJsonRpc()) << "Unregister client" << transportClient;
if (!m_clients.contains(proxyClient)) { if (!m_clients.contains(transportClient)) {
qCWarning(dcJsonRpc()) << "Client was not registered" << proxyClient; qCWarning(dcJsonRpc()) << "Client was not registered" << transportClient;
return; return;
} }
m_clients.removeAll(proxyClient); m_clients.removeAll(transportClient);
if (m_asyncReplies.values().contains(proxyClient)) { if (m_asyncReplies.values().contains(transportClient)) {
qCWarning(dcJsonRpc()) << "Client was still waiting for a reply. Clean up reply"; qCWarning(dcJsonRpc()) << "Client was still waiting for a reply. Clean up reply";
JsonReply *reply = m_asyncReplies.key(proxyClient); JsonReply *reply = m_asyncReplies.key(transportClient);
m_asyncReplies.remove(reply); m_asyncReplies.remove(reply);
// Note: the reply will be deleted in the finished slot // Note: the reply will be deleted in the finished slot
} }
} }
void JsonRpcServer::processData(ProxyClient *proxyClient, const QByteArray &data) void JsonRpcServer::processData(TransportClient *transportClient, const QByteArray &data)
{ {
if (!m_clients.contains(proxyClient)) if (!m_clients.contains(transportClient))
return; return;
qCDebug(dcJsonRpcTraffic()) << "Incoming data from" << proxyClient << ": " << data; qCDebug(dcJsonRpcTraffic()) << "Incoming data from" << transportClient << ": " << data;
// Handle package fragmentation // Handle package fragmentation
QList<QByteArray> packages = proxyClient->processData(data); QList<QByteArray> packages = transportClient->processData(data);
// Make sure the buffer size is in range // Make sure the buffer size is in range
if (proxyClient->bufferSize() > 1024 * 10) { if (transportClient->bufferSize() > 1024 * 10) {
qCWarning(dcJsonRpc()) << "Data buffer size violation from" << proxyClient; qCWarning(dcJsonRpc()) << "Data buffer size violation from" << transportClient;
proxyClient->killConnection("Data buffer size violation."); transportClient->killConnection("Data buffer size violation.");
return; return;
} }
foreach (const QByteArray &package, packages) { foreach (const QByteArray &package, packages) {
processDataPackage(proxyClient, package); processDataPackage(transportClient, package);
} }
} }
void JsonRpcServer::sendNotification(const QString &nameSpace, const QString &method, const QVariantMap &params, ProxyClient *proxyClient) void JsonRpcServer::sendNotification(const QString &nameSpace, const QString &method, const QVariantMap &params, TransportClient *transportClient)
{ {
QVariantMap notification; QVariantMap notification;
notification.insert("id", m_notificationId++); notification.insert("id", m_notificationId++);
@ -347,7 +347,7 @@ void JsonRpcServer::sendNotification(const QString &nameSpace, const QString &me
QByteArray data = QJsonDocument::fromVariant(notification).toJson(QJsonDocument::Compact); QByteArray data = QJsonDocument::fromVariant(notification).toJson(QJsonDocument::Compact);
qCDebug(dcJsonRpcTraffic()) << "Sending notification:" << data; qCDebug(dcJsonRpcTraffic()) << "Sending notification:" << data;
proxyClient->sendData(data); transportClient->sendData(data);
} }
} }

View File

@ -31,7 +31,7 @@
#include <QObject> #include <QObject>
#include <QVariant> #include <QVariant>
#include "proxyclient.h" #include "proxy/proxyclient.h"
#include "jsonrpc/jsonreply.h" #include "jsonrpc/jsonreply.h"
#include "transportinterface.h" #include "transportinterface.h"
#include "jsonrpc/jsonhandler.h" #include "jsonrpc/jsonhandler.h"
@ -48,8 +48,8 @@ public:
QString name() const override; QString name() const override;
Q_INVOKABLE JsonReply *Hello(const QVariantMap &params, ProxyClient *proxyClient = nullptr) const; Q_INVOKABLE JsonReply *Hello(const QVariantMap &params, TransportClient *transportClient = nullptr) const;
Q_INVOKABLE JsonReply *Introspect(const QVariantMap &params, ProxyClient *proxyClient = nullptr) const; Q_INVOKABLE JsonReply *Introspect(const QVariantMap &params, TransportClient *transportClient = nullptr) const;
void registerHandler(JsonHandler *handler); void registerHandler(JsonHandler *handler);
void unregisterHandler(JsonHandler *handler); void unregisterHandler(JsonHandler *handler);
@ -59,29 +59,29 @@ signals:
private: private:
QHash<QString, JsonHandler *> m_handlers; QHash<QString, JsonHandler *> m_handlers;
QHash<JsonReply *, ProxyClient *> m_asyncReplies; QHash<JsonReply *, TransportClient *> m_asyncReplies;
QList<ProxyClient *> m_clients; QList<TransportClient *> m_clients;
int m_notificationId = 0; int m_notificationId = 0;
void sendResponse(ProxyClient *client, int commandId, const QVariantMap &params = QVariantMap()); void sendResponse(TransportClient *client, int commandId, const QVariantMap &params = QVariantMap());
void sendErrorResponse(ProxyClient *client, int commandId, const QString &error); void sendErrorResponse(TransportClient *client, int commandId, const QString &error);
QString formatAssertion(const QString &targetNamespace, const QString &method, JsonHandler *handler, const QVariantMap &data) const; QString formatAssertion(const QString &targetNamespace, const QString &method, JsonHandler *handler, const QVariantMap &data) const;
void processDataPackage(ProxyClient *proxyClient, const QByteArray &data); void processDataPackage(TransportClient *transportClient, const QByteArray &data);
private slots: private slots:
void asyncReplyFinished(); void asyncReplyFinished();
public slots: public slots:
// Client registration for JSON RPC traffic // Client registration for JSON RPC traffic
void registerClient(ProxyClient *proxyClient); void registerClient(TransportClient *transportClient);
void unregisterClient(ProxyClient *proxyClient); void unregisterClient(TransportClient *transportClient);
// Process data from client // Process data from client
void processData(ProxyClient *proxyClient, const QByteArray &data); void processData(TransportClient *transportClient, const QByteArray &data);
void sendNotification(const QString &nameSpace, const QString &method, const QVariantMap &params, ProxyClient *proxyClient = nullptr); void sendNotification(const QString &nameSpace, const QString &method, const QVariantMap &params, TransportClient *transportClient = nullptr);
}; };

View File

@ -0,0 +1,116 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
* Copyright 2013 - 2021, nymea GmbH
* Contact: contact@nymea.io
*
* This file is part of nymea.
* This project including source code and documentation is protected by copyright law, and
* remains the property of nymea GmbH. All rights, including reproduction, publication,
* editing and translation, are reserved. The use of this project is subject to the terms of a
* license agreement to be concluded with nymea GmbH in accordance with the terms
* of use of nymea GmbH, available under https://nymea.io/license
*
* GNU General Public License Usage
* Alternatively, this project may be redistributed and/or modified under
* the terms of the GNU General Public License as published by the Free Software Foundation,
* GNU version 3. this project is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with this project.
* If not, see <https://www.gnu.org/licenses/>.
*
* For any further details and any questions please contact us under contact@nymea.io
* or see our FAQ/Licensing Information on https://nymea.io/license/faq
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#include "transportclient.h"
#include "server/transportinterface.h"
#include <QDateTime>
namespace remoteproxy {
TransportClient::TransportClient(TransportInterface *interface, const QUuid &clientId, const QHostAddress &address, QObject *parent) :
QObject(parent),
m_interface(interface),
m_clientId(clientId),
m_peerAddress(address)
{
m_creationTimeStamp = QDateTime::currentDateTimeUtc().toMSecsSinceEpoch() / 1000;
}
QUuid TransportClient::clientId() const
{
return m_clientId;
}
QHostAddress TransportClient::peerAddress() const
{
return m_peerAddress;
}
uint TransportClient::creationTime() const
{
return m_creationTimeStamp;
}
QString TransportClient::creationTimeString() const
{
return QDateTime::fromMSecsSinceEpoch(creationTime() * 1000).toString("dd.MM.yyyy hh:mm:ss");
}
TransportInterface *TransportClient::interface() const
{
return m_interface;
}
quint64 TransportClient::rxDataCount() const
{
return m_rxDataCount;
}
void TransportClient::addRxDataCount(int dataCount)
{
m_rxDataCount += static_cast<quint64>(dataCount);
}
quint64 TransportClient::txDataCount() const
{
return m_txDataCount;
}
void TransportClient::addTxDataCount(int dataCount)
{
m_txDataCount += static_cast<quint64>(dataCount);
}
int TransportClient::bufferSize() const
{
return m_dataBuffers.size();
}
int TransportClient::generateMessageId()
{
m_messageId++;
return m_messageId;
}
void TransportClient::sendData(const QByteArray &data)
{
if (!m_interface)
return;
m_interface->sendData(m_clientId, data);
}
void TransportClient::killConnection(const QString &reason)
{
if (!m_interface)
return;
m_interface->killClientConnection(m_clientId, reason);
}
}

View File

@ -0,0 +1,90 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
* Copyright 2013 - 2021, nymea GmbH
* Contact: contact@nymea.io
*
* This file is part of nymea.
* This project including source code and documentation is protected by copyright law, and
* remains the property of nymea GmbH. All rights, including reproduction, publication,
* editing and translation, are reserved. The use of this project is subject to the terms of a
* license agreement to be concluded with nymea GmbH in accordance with the terms
* of use of nymea GmbH, available under https://nymea.io/license
*
* GNU General Public License Usage
* Alternatively, this project may be redistributed and/or modified under
* the terms of the GNU General Public License as published by the Free Software Foundation,
* GNU version 3. this project is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with this project.
* If not, see <https://www.gnu.org/licenses/>.
*
* For any further details and any questions please contact us under contact@nymea.io
* or see our FAQ/Licensing Information on https://nymea.io/license/faq
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#ifndef TRANSPORTCLIENT_H
#define TRANSPORTCLIENT_H
#include <QObject>
#include <QUuid>
#include <QDebug>
#include <QHostAddress>
namespace remoteproxy {
class TransportInterface;
class TransportClient : public QObject
{
Q_OBJECT
public:
explicit TransportClient(TransportInterface *interface, const QUuid &clientId, const QHostAddress &address, QObject *parent = nullptr);
virtual ~TransportClient() = default;
QUuid clientId() const;
QHostAddress peerAddress() const;
uint creationTime() const;
QString creationTimeString() const;
TransportInterface *interface() const;
quint64 rxDataCount() const;
void addRxDataCount(int dataCount);
quint64 txDataCount() const;
void addTxDataCount(int dataCount);
int bufferSize() const;
int generateMessageId();
virtual void sendData(const QByteArray &data);
virtual void killConnection(const QString &reason);
virtual QList<QByteArray> processData(const QByteArray &data) = 0;
protected:
TransportInterface *m_interface = nullptr;
QUuid m_clientId;
QHostAddress m_peerAddress;
uint m_creationTimeStamp = 0;
QByteArray m_dataBuffers;
// Json data information
int m_messageId = 0;
// Statistics info
quint64 m_rxDataCount = 0;
quint64 m_txDataCount = 0;
};
}
#endif // TRANSPORTCLIENT_H

View File

@ -0,0 +1,37 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
* Copyright 2013 - 2021, nymea GmbH
* Contact: contact@nymea.io
*
* This file is part of nymea.
* This project including source code and documentation is protected by copyright law, and
* remains the property of nymea GmbH. All rights, including reproduction, publication,
* editing and translation, are reserved. The use of this project is subject to the terms of a
* license agreement to be concluded with nymea GmbH in accordance with the terms
* of use of nymea GmbH, available under https://nymea.io/license
*
* GNU General Public License Usage
* Alternatively, this project may be redistributed and/or modified under
* the terms of the GNU General Public License as published by the Free Software Foundation,
* GNU version 3. this project is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with this project.
* If not, see <https://www.gnu.org/licenses/>.
*
* For any further details and any questions please contact us under contact@nymea.io
* or see our FAQ/Licensing Information on https://nymea.io/license/faq
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#include "tunnelproxyclientconnection.h"
namespace remoteproxy {
TunnelProxyClientConnection::TunnelProxyClientConnection(QObject *parent) : QObject(parent)
{
}
}

View File

@ -0,0 +1,47 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
* Copyright 2013 - 2021, nymea GmbH
* Contact: contact@nymea.io
*
* This file is part of nymea.
* This project including source code and documentation is protected by copyright law, and
* remains the property of nymea GmbH. All rights, including reproduction, publication,
* editing and translation, are reserved. The use of this project is subject to the terms of a
* license agreement to be concluded with nymea GmbH in accordance with the terms
* of use of nymea GmbH, available under https://nymea.io/license
*
* GNU General Public License Usage
* Alternatively, this project may be redistributed and/or modified under
* the terms of the GNU General Public License as published by the Free Software Foundation,
* GNU version 3. this project is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with this project.
* If not, see <https://www.gnu.org/licenses/>.
*
* For any further details and any questions please contact us under contact@nymea.io
* or see our FAQ/Licensing Information on https://nymea.io/license/faq
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#ifndef TUNNELPROXYCLIENTCONNECTION_H
#define TUNNELPROXYCLIENTCONNECTION_H
#include <QObject>
namespace remoteproxy {
class TunnelProxyClientConnection : public QObject
{
Q_OBJECT
public:
explicit TunnelProxyClientConnection(QObject *parent = nullptr);
signals:
};
}
#endif // TUNNELPROXYCLIENTCONNECTION_H

View File

@ -38,7 +38,6 @@ TunnelProxyManager::TunnelProxyManager(QObject *parent) :
m_jsonRpcServer = new JsonRpcServer(this); m_jsonRpcServer = new JsonRpcServer(this);
m_jsonRpcServer->registerHandler(m_jsonRpcServer); m_jsonRpcServer->registerHandler(m_jsonRpcServer);
m_jsonRpcServer->registerHandler(new TunnelProxyHandler(this)); m_jsonRpcServer->registerHandler(new TunnelProxyHandler(this));
} }
TunnelProxyManager::~TunnelProxyManager() TunnelProxyManager::~TunnelProxyManager()
@ -86,7 +85,7 @@ TunnelProxyManager::Error TunnelProxyManager::registerServer(const QUuid &client
// Check if requested already as client // Check if requested already as client
TunnelProxyServer *proxyServer = new TunnelProxyServer(m_proxyClients.value(clientId), serverUuid, serverName); TunnelProxyServerConnection *proxyServer = new TunnelProxyServerConnection(m_proxyClients.value(clientId), serverUuid, serverName);
m_proxyClientsTunnelServer.insert(clientId, proxyServer); m_proxyClientsTunnelServer.insert(clientId, proxyServer);
m_tunnelServers.insert(proxyServer->serverUuid(), proxyServer); m_tunnelServers.insert(proxyServer->serverUuid(), proxyServer);
@ -95,7 +94,7 @@ TunnelProxyManager::Error TunnelProxyManager::registerServer(const QUuid &client
void TunnelProxyManager::startServer() void TunnelProxyManager::startServer()
{ {
qCDebug(dcTunnelProxyManager()) << "Starting tunnel proxy manager..."; qCDebug(dcTunnelProxyManager()) << "Starting tunnel proxy...";
foreach (TransportInterface *interface, m_transportInterfaces) { foreach (TransportInterface *interface, m_transportInterfaces) {
interface->startServer(); interface->startServer();
} }
@ -104,7 +103,7 @@ void TunnelProxyManager::startServer()
void TunnelProxyManager::stopServer() void TunnelProxyManager::stopServer()
{ {
qCDebug(dcTunnelProxyManager()) << "Stopping tunnel proxy server..."; qCDebug(dcTunnelProxyManager()) << "Stopping tunnel proxy...";
foreach (TransportInterface *interface, m_transportInterfaces) { foreach (TransportInterface *interface, m_transportInterfaces) {
interface->stopServer(); interface->stopServer();
} }
@ -123,19 +122,42 @@ void TunnelProxyManager::onClientConnected(const QUuid &clientId, const QHostAdd
qCDebug(dcTunnelProxyManager()) << "New client connected" << interface->serverName() << clientId.toString() << address.toString(); qCDebug(dcTunnelProxyManager()) << "New client connected" << interface->serverName() << clientId.toString() << address.toString();
ProxyClient *proxyClient = new ProxyClient(interface, clientId, address, this); ProxyClient *proxyClient = new ProxyClient(interface, clientId, address, this);
m_proxyClients.insert(clientId, proxyClient); m_proxyClients.insert(clientId, proxyClient);
m_jsonRpcServer->registerClient(proxyClient); m_jsonRpcServer->registerClient(proxyClient);
} }
void TunnelProxyManager::onClientDisconnected(const QUuid &clientId) void TunnelProxyManager::onClientDisconnected(const QUuid &clientId)
{ {
Q_UNUSED(clientId) TransportInterface *interface = static_cast<TransportInterface *>(sender());
qCDebug(dcProxyServer()) << "Client disconnected" << interface->serverName() << clientId.toString();
if (!m_proxyClients.contains(clientId)) {
qCWarning(dcProxyServer()) << "Unknown client disconnected from proxy server." << clientId.toString();
return;
}
ProxyClient *proxyClient = m_proxyClients.take(clientId);
// Unregister from json rpc server
m_jsonRpcServer->unregisterClient(proxyClient);
// Delete the proxy client
proxyClient->deleteLater();
} }
void TunnelProxyManager::onClientDataAvailable(const QUuid &clientId, const QByteArray &data) void TunnelProxyManager::onClientDataAvailable(const QUuid &clientId, const QByteArray &data)
{ {
Q_UNUSED(clientId) Q_UNUSED(clientId)
Q_UNUSED(data) Q_UNUSED(data)
ProxyClient *proxyClient = m_proxyClients.value(clientId);
if (!proxyClient) {
qCWarning(dcProxyServer()) << "Could not find client for uuid" << clientId;
return;
}
qCDebug(dcProxyServerTraffic()) << "Client data available" << proxyClient << qUtf8Printable(data);
m_jsonRpcServer->processData(proxyClient, data);
} }
} }

View File

@ -33,7 +33,7 @@
#include "server/jsonrpcserver.h" #include "server/jsonrpcserver.h"
#include "server/transportinterface.h" #include "server/transportinterface.h"
#include "tunnelproxyserver.h" #include "tunnelproxyserverconnection.h"
namespace remoteproxy { namespace remoteproxy {
@ -83,8 +83,8 @@ private:
QHash<QUuid, ProxyClient *> m_proxyClients; // clients QHash<QUuid, ProxyClient *> m_proxyClients; // clients
// Server connections // Server connections
QHash<QUuid, TunnelProxyServer *> m_proxyClientsTunnelServer; // clientUuid, object QHash<QUuid, TunnelProxyServerConnection *> m_proxyClientsTunnelServer; // clientUuid, object
QHash<QUuid, TunnelProxyServer *> m_tunnelServers; // server uuid, object QHash<QUuid, TunnelProxyServerConnection *> m_tunnelServers; // server uuid, object
}; };

View File

@ -25,11 +25,11 @@
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#include "tunnelproxyserver.h" #include "tunnelproxyserverconnection.h"
namespace remoteproxy { namespace remoteproxy {
TunnelProxyServer::TunnelProxyServer(ProxyClient *proxyClient, const QUuid &serverUuid, const QString &serverName, QObject *parent) : TunnelProxyServerConnection::TunnelProxyServerConnection(ProxyClient *proxyClient, const QUuid &serverUuid, const QString &serverName, QObject *parent) :
QObject(parent), QObject(parent),
m_proxyClient(proxyClient), m_proxyClient(proxyClient),
m_serverUuid(serverUuid), m_serverUuid(serverUuid),
@ -38,17 +38,17 @@ TunnelProxyServer::TunnelProxyServer(ProxyClient *proxyClient, const QUuid &serv
} }
ProxyClient *TunnelProxyServer::proxyClient() const ProxyClient *TunnelProxyServerConnection::proxyClient() const
{ {
return m_proxyClient; return m_proxyClient;
} }
QUuid TunnelProxyServer::serverUuid() const QUuid TunnelProxyServerConnection::serverUuid() const
{ {
return m_serverUuid; return m_serverUuid;
} }
QString TunnelProxyServer::serverName() const QString TunnelProxyServerConnection::serverName() const
{ {
return m_serverName; return m_serverName;
} }

View File

@ -25,20 +25,20 @@
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#ifndef TUNNELPROXYSERVER_H #ifndef TUNNELPROXYSERVERCONNECTION_H
#define TUNNELPROXYSERVER_H #define TUNNELPROXYSERVERCONNECTION_H
#include <QObject> #include <QObject>
#include "proxyclient.h" #include "proxy/proxyclient.h"
namespace remoteproxy { namespace remoteproxy {
class TunnelProxyServer : public QObject class TunnelProxyServerConnection : public QObject
{ {
Q_OBJECT Q_OBJECT
public: public:
explicit TunnelProxyServer(ProxyClient *proxyClient, const QUuid &serverUuid, const QString &serverName, QObject *parent = nullptr); explicit TunnelProxyServerConnection(ProxyClient *proxyClient, const QUuid &serverUuid, const QString &serverName, QObject *parent = nullptr);
ProxyClient *proxyClient() const; ProxyClient *proxyClient() const;
@ -56,4 +56,4 @@ private:
} }
#endif // TUNNELPROXYSERVER_H #endif // TUNNELPROXYSERVERCONNECTION_H

View File

@ -96,7 +96,7 @@ void RemoteProxyTestsTunnelProxy::getIntrospect()
// WebSocket // WebSocket
response = invokeWebSocketTunnelProxyApiCall("RemoteProxy.Introspect").toMap(); response = invokeWebSocketTunnelProxyApiCall("RemoteProxy.Introspect").toMap();
//qDebug() << qUtf8Printable(QJsonDocument::fromVariant(response).toJson(QJsonDocument::Indented)); qDebug() << qUtf8Printable(QJsonDocument::fromVariant(response).toJson(QJsonDocument::Indented));
QVERIFY(!response.isEmpty()); QVERIFY(!response.isEmpty());
QVERIFY(response.value("status").toString() == "success"); QVERIFY(response.value("status").toString() == "success");
QVERIFY(response.value("params").toMap().contains("methods")); QVERIFY(response.value("params").toMap().contains("methods"));

View File

@ -25,7 +25,7 @@
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#include "proxyclient.h" #include "proxy/proxyclient.h"
#include "mockauthenticator.h" #include "mockauthenticator.h"
#include "loggingcategories.h" #include "loggingcategories.h"
#include "authentication/authenticationreply.h" #include "authentication/authenticationreply.h"