Add random traffic generator for test clients

This commit is contained in:
Simon Stürz 2023-02-09 09:47:51 +01:00
parent 8081c7804e
commit aecf6da7e1
14 changed files with 96 additions and 41 deletions

View File

@ -99,10 +99,11 @@ int main(int argc, char *argv[])
"a server application as client perspective.\n\n"
"Version: %1\n"
"API version: %2\n\n"
"Copyright %3 2021 nymea GmbH <developer@nymea.io>\n")
"Copyright %3 %4 nymea GmbH <developer@nymea.io>\n")
.arg(SERVER_VERSION_STRING)
.arg(API_VERSION_STRING)
.arg(QChar(0xA9)));
.arg(QChar(0xA9))
.arg(COPYRIGHT_YEAR_STRING));
QCommandLineOption urlOption(QStringList() << "u" << "url", "The proxy server url. Default ssl://dev-remoteproxy.nymea.io:4433", "url");
urlOption.setDefaultValue("ssl://dev-remoteproxy.nymea.io:4433");

View File

@ -61,8 +61,10 @@ void TcpSocketServer::sendData(const QUuid &clientId, const QByteArray &data)
void TcpSocketServer::killClientConnection(const QUuid &clientId, const QString &killReason)
{
QTcpSocket *client = m_clientList.value(clientId);
if (!client)
if (!client) {
qCWarning(dcTcpSocketServer()) << "Could not kill connection with id" << clientId.toString() << "with reason" << killReason << "because there is no socket with this id.";
return;
}
qCDebug(dcTcpSocketServer()) << "Killing client connection" << clientId.toString() << "Reason:" << killReason;
client->close();
@ -83,7 +85,7 @@ void TcpSocketServer::onDataAvailable(QSslSocket *client, const QByteArray &data
emit dataAvailable(clientId, data);
}
void TcpSocketServer::onClientConnected(QSslSocket *client)
void TcpSocketServer::onSocketConnected(QSslSocket *client)
{
QUuid clientId = QUuid::createUuid();
qCDebug(dcTcpSocketServer()) << "New client connected:" << client << client->peerAddress().toString() << clientId.toString();
@ -91,7 +93,7 @@ void TcpSocketServer::onClientConnected(QSslSocket *client)
emit clientConnected(clientId, client->peerAddress());
}
void TcpSocketServer::onClientDisconnected(QSslSocket *client)
void TcpSocketServer::onSocketDisconnected(QSslSocket *client)
{
QUuid clientId = m_clientList.key(client);
qCDebug(dcTcpSocketServer()) << "Client disconnected:" << client << client->peerAddress().toString() << clientId.toString();
@ -112,8 +114,8 @@ bool TcpSocketServer::startServer()
return false;
}
connect(m_server, &SslServer::clientConnected, this, &TcpSocketServer::onClientConnected);
connect(m_server, &SslServer::clientDisconnected, this, &TcpSocketServer::onClientDisconnected);
connect(m_server, &SslServer::socketConnected, this, &TcpSocketServer::onSocketConnected);
connect(m_server, &SslServer::socketDisconnected, this, &TcpSocketServer::onSocketDisconnected);
connect(m_server, &SslServer::dataAvailable, this, &TcpSocketServer::onDataAvailable);
qCDebug(dcTcpSocketServer()) << "Server started successfully.";
return true;
@ -149,13 +151,13 @@ void SslServer::incomingConnection(qintptr socketDescriptor)
QSslSocket *sslSocket = new QSslSocket(this);
qCDebug(dcTcpSocketServer()) << "Incomming connection" << sslSocket;
connect(sslSocket, &QSslSocket::readyRead, this, &SslServer::onSocketReadyRead);
connect(sslSocket, &QSslSocket::disconnected, this, &SslServer::onClientDisconnected);
connect(sslSocket, &QSslSocket::disconnected, this, &SslServer::onSocketDisconnected);
typedef void (QAbstractSocket:: *errorSignal)(QAbstractSocket::SocketError);
connect(sslSocket, static_cast<errorSignal>(&QAbstractSocket::error), this, &SslServer::onSocketError);
connect(sslSocket, &QSslSocket::encrypted, this, [this, sslSocket](){
qCDebug(dcTcpSocketServer()) << "SSL encryption established for" << sslSocket;
emit clientConnected(sslSocket);
emit socketConnected(sslSocket);
});
typedef void (QSslSocket:: *sslErrorsSignal)(const QList<QSslError> &);
@ -178,15 +180,15 @@ void SslServer::incomingConnection(qintptr socketDescriptor)
//addPendingConnection(sslSocket);
sslSocket->startServerEncryption();
} else {
emit clientConnected(sslSocket);
emit socketConnected(sslSocket);
}
}
void SslServer::onClientDisconnected()
void SslServer::onSocketDisconnected()
{
QSslSocket *sslSocket = qobject_cast<QSslSocket *>(sender());
qCDebug(dcTcpSocketServer()) << "Client socket disconnected:" << sslSocket << sslSocket->peerAddress().toString();;
emit clientDisconnected(sslSocket);
emit socketDisconnected(sslSocket);
sslSocket->deleteLater();
}

View File

@ -50,15 +50,15 @@ private:
QSslConfiguration m_config;
signals:
void clientConnected(QSslSocket *socket);
void clientDisconnected(QSslSocket *socket);
void socketConnected(QSslSocket *socket);
void socketDisconnected(QSslSocket *socket);
void dataAvailable(QSslSocket *socket, const QByteArray &data);
protected:
void incomingConnection(qintptr socketDescriptor) override;
private slots:
void onClientDisconnected();
void onSocketDisconnected();
void onSocketReadyRead();
void onSocketError(QAbstractSocket::SocketError);
@ -87,8 +87,8 @@ private:
private slots:
void onDataAvailable(QSslSocket *client, const QByteArray &data);
void onClientConnected(QSslSocket *client);
void onClientDisconnected(QSslSocket *client);
void onSocketConnected(QSslSocket *client);
void onSocketDisconnected(QSslSocket *client);
public slots:
bool startServer() override;

View File

@ -50,10 +50,11 @@ int main(int argc, char *argv[])
parser.setApplicationDescription(QString("\nThe nymea remote proxy monitor allowes to monitor the live server activity on the a local instance.\n\n"
"Server version: %1\n"
"API version: %2\n\n"
"Copyright %3 2022 nymea GmbH <developer@nymea.io>\n")
"Copyright %3 %4 nymea GmbH <developer@nymea.io>\n")
.arg(SERVER_VERSION_STRING)
.arg(API_VERSION_STRING)
.arg(QChar(0xA9)));
.arg(QChar(0xA9))
.arg(COPYRIGHT_YEAR_STRING));
QCommandLineOption socketOption(QStringList() << "s" << "socket", "The socket descriptor for the nymea-remoteproxy monitor socket. Default is /tmp/nymea-remoteproxy-monitor.sock", "socket");

View File

@ -15,7 +15,7 @@ authorizerLambdaFunction=system-services-authorizer-dev-checkToken
awsCredentialsUrl=http://169.254.169.254/latest/meta-data/iam/security-credentials/EC2-Remote-Connection-Proxy-Role
[SSL]
enabled=true
enabled=false
certificate=/etc/ssl/certs/ssl-cert-snakeoil.pem
certificateKey=/etc/ssl/private/ssl-cert-snakeoil.key
certificateChain=

View File

@ -4,6 +4,7 @@ include(nymea-remoteproxy.pri)
SERVER_NAME=nymea-remoteproxy
API_VERSION_MAJOR=0
API_VERSION_MINOR=5
COPYRIGHT_YEAR=2023
# Parse and export SERVER_VERSION
SERVER_VERSION=$$system('dpkg-parsechangelog | sed -n -e "s/^Version: //p"')

View File

@ -118,10 +118,11 @@ int main(int argc, char *argv[])
"registered nymea deamons to establish a tunnel connection.\n\n"
"Version: %1\n"
"API version: %2\n\n"
"Copyright %3 2022 nymea GmbH <developer@nymea.io>\n")
"Copyright %3 %4 nymea GmbH <developer@nymea.io>\n")
.arg(SERVER_VERSION_STRING)
.arg(API_VERSION_STRING)
.arg(QChar(0xA9)));
.arg(QChar(0xA9))
.arg(COPYRIGHT_YEAR_STRING));
QCommandLineOption logfileOption(QStringList() << "l" << "logging", "Write log file to the given logfile.",
"logfile", "/var/log/nymea-remoteproxy.log");

View File

@ -3,16 +3,24 @@
CHILD_PROCESSES=()
SERVER_URL=tcp://127.0.0.1:2213
SERVER_COUNTER=0
CLIENT_COUNTER=0
TOTAL_COUNTER=0
# Start server: Arguments: serverName serverUuid
function createServer() {
echo "--> Create server"
nymea-remoteproxy-tunnelclient -s -n "$1" --uuid "$2" -u $SERVER_URL -i & CHILD_PROCESSES+=("$!")
SERVER_COUNTER=$(($SERVER_COUNTER + 1))
TOTAL_COUNTER=$(($TOTAL_COUNTER + 1))
nymea-remoteproxy-tunnelclient -s -r -n "$1" --uuid "$2" -u $SERVER_URL -i & CHILD_PROCESSES+=("$!")
}
# Create client: Arguments: clientName serverUuid
function createClient() {
echo "--> Create client"
nymea-remoteproxy-tunnelclient -c -n "$1" --server-uuid "$2" -u $SERVER_URL -i & CHILD_PROCESSES+=("$!")
CLIENT_COUNTER=$(($CLIENT_COUNTER + 1))
TOTAL_COUNTER=$(($TOTAL_COUNTER + 1))
nymea-remoteproxy-tunnelclient -c -r -n "$1" --server-uuid "$2" -u $SERVER_URL -i & CHILD_PROCESSES+=("$!")
}
@ -38,7 +46,6 @@ function cleanup {
trap cleanup EXIT
createTunnelConnections 5
createTunnelConnections 3
createTunnelConnections 9
@ -52,4 +59,11 @@ createTunnelConnections 2
createTunnelConnections 1
createTunnelConnections 8
sleep 10
echo "------------------------------"
echo "Total: $TOTAL_COUNTER"
echo "Servers: $SERVER_COUNTER"
echo "Clients: $CLIENT_COUNTER"
sleep 300

View File

@ -1,15 +1,22 @@
#include "clientconnection.h"
ClientConnection::ClientConnection(const QUrl &serverUrl, const QString &name, const QUuid &uuid, const QUuid &serverUuid, bool insecure, QObject *parent) :
ClientConnection::ClientConnection(const QUrl &serverUrl, const QString &name, const QUuid &uuid, const QUuid &serverUuid, bool insecure, bool sendRandomData, QObject *parent) :
QObject(parent),
m_serverUrl(serverUrl),
m_name(name),
m_uuid(uuid),
m_serverUuid(serverUuid),
m_insecure(insecure)
m_insecure(insecure),
m_sendRandomData(sendRandomData)
{
m_remoteConnection = new TunnelProxyRemoteConnection(m_uuid, m_name);
m_timer.setSingleShot(true);
connect(&m_timer, &QTimer::timeout, this, [=](){
if (m_remoteConnection->remoteConnected()) {
m_remoteConnection->sendData(generateRandomString(100).toUtf8());
m_timer.start(1000);
}
});
connect(m_remoteConnection, &TunnelProxyRemoteConnection::stateChanged, this, [this](TunnelProxyRemoteConnection::State state){
qDebug() << state;
@ -22,12 +29,16 @@ ClientConnection::ClientConnection(const QUrl &serverUrl, const QString &name, c
}
});
connect(m_remoteConnection, &TunnelProxyRemoteConnection::remoteConnectedChanged, this, [](bool remoteConnected){
connect(m_remoteConnection, &TunnelProxyRemoteConnection::remoteConnectedChanged, this, [this](bool remoteConnected){
qDebug() << "Remote connection" << (remoteConnected ? "established successfully" : "disconnected");
if (remoteConnected) {
m_timer.start(1000);
}
});
connect(m_remoteConnection, &TunnelProxyRemoteConnection::dataReady, this, [](const QByteArray &data){
qDebug() << "Data received" << data;
connect(m_remoteConnection, &TunnelProxyRemoteConnection::dataReady, this, [this](const QByteArray &data){
if (!m_sendRandomData)
qDebug() << "Data received" << data;
});
connect(m_remoteConnection, &TunnelProxyRemoteConnection::errorOccurred, this, [](QAbstractSocket::SocketError error){
@ -50,3 +61,13 @@ void ClientConnection::connectToServer()
{
m_remoteConnection->connectServer(m_serverUrl, m_serverUuid);
}
QString ClientConnection::generateRandomString(uint length) const
{
const QString possibleCharacters("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789");
QString randomString;
for(uint i = 0; i < length; i++) {
randomString.append(possibleCharacters.at(qrand() % possibleCharacters.length()));
}
return randomString;
}

View File

@ -3,6 +3,7 @@
#include <QUrl>
#include <QObject>
#include <QTimer>
#include "tunnelproxy/tunnelproxyremoteconnection.h"
@ -12,7 +13,7 @@ class ClientConnection : public QObject
{
Q_OBJECT
public:
explicit ClientConnection(const QUrl &serverUrl, const QString &name, const QUuid &uuid, const QUuid &serverUuid, bool insecure, QObject *parent = nullptr);
explicit ClientConnection(const QUrl &serverUrl, const QString &name, const QUuid &uuid, const QUuid &serverUuid, bool insecure, bool sendRandomData, QObject *parent = nullptr);
void connectToServer();
@ -22,10 +23,12 @@ private:
QUuid m_uuid;
QUuid m_serverUuid;
bool m_insecure = false;
bool m_sendRandomData = false;
TunnelProxyRemoteConnection *m_remoteConnection = nullptr;
QTimer m_timer;
QString generateRandomString(uint length) const;
};
#endif // CLIENTCONNECTION_H

View File

@ -113,10 +113,11 @@ int main(int argc, char *argv[])
"or server on the tunnel proxy interface.\n\n"
"Version: %1\n"
"API version: %2\n\n"
"Copyright %3 2021 nymea GmbH <developer@nymea.io>\n")
"Copyright %3 %4 nymea GmbH <developer@nymea.io>\n")
.arg(SERVER_VERSION_STRING)
.arg(API_VERSION_STRING)
.arg(QChar(0xA9)));
.arg(QChar(0xA9))
.arg(COPYRIGHT_YEAR_STRING));
QCommandLineOption urlOption(QStringList() << "u" << "url", "The proxy server url. Default ssl://dev-remoteproxy.nymea.io:2213", "url");
urlOption.setDefaultValue("ssl://dev-remoteproxy.nymea.io:2213");
@ -134,6 +135,9 @@ int main(int argc, char *argv[])
QCommandLineOption nameOption(QStringList() << "n" << "name", "The name of the connecting client. If not specified a default name will be selected.", "name");
parser.addOption(nameOption);
QCommandLineOption randomDataOption(QStringList() << "r" << "random", "Send random data trough the tunnel. If you start a server, it will echo any client data received.");
parser.addOption(randomDataOption);
QCommandLineOption uuidOption(QStringList() << "uuid", "The uuid of the connecting client. If not specified, a new one will be created.", "uuid");
parser.addOption(uuidOption);
@ -196,7 +200,7 @@ int main(int argc, char *argv[])
// Create the server connection
ServerConnection *server = new ServerConnection(serverUrl, name, uuid, parser.isSet(insecureOption));
ServerConnection *server = new ServerConnection(serverUrl, name, uuid, parser.isSet(insecureOption), parser.isSet(randomDataOption));
server->startServer();
} else {
@ -238,7 +242,7 @@ int main(int argc, char *argv[])
QLoggingCategory::installFilter(loggingCategoryFilter);
// Create the server connection
ClientConnection *client = new ClientConnection(serverUrl, name, uuid, serverUuid, parser.isSet(insecureOption));
ClientConnection *client = new ClientConnection(serverUrl, name, uuid, serverUuid, parser.isSet(insecureOption), parser.isSet(randomDataOption));
client->connectToServer();
}

View File

@ -1,17 +1,23 @@
#include "serverconnection.h"
ServerConnection::ServerConnection(const QUrl &serverUrl, const QString &name, const QUuid &uuid, bool insecure, QObject *parent) :
ServerConnection::ServerConnection(const QUrl &serverUrl, const QString &name, const QUuid &uuid, bool insecure, bool echo, QObject *parent) :
QObject(parent),
m_serverUrl(serverUrl),
m_name(name),
m_uuid(uuid),
m_insecure(insecure)
m_insecure(insecure),
m_echo(echo)
{
m_socketServer = new TunnelProxySocketServer(m_uuid, m_name, this);
connect(m_socketServer, &TunnelProxySocketServer::clientConnected, this, [=](TunnelProxySocket *tunnelProxySocket){
qDebug() << "[+] Client connected" << tunnelProxySocket;
if (m_echo) {
connect(tunnelProxySocket, &TunnelProxySocket::dataReceived, m_socketServer, [tunnelProxySocket](const QByteArray &data){
tunnelProxySocket->writeData(data);
});
}
});
connect(m_socketServer, &TunnelProxySocketServer::clientDisconnected, this, [=](TunnelProxySocket *tunnelProxySocket){
@ -35,7 +41,6 @@ ServerConnection::ServerConnection(const QUrl &serverUrl, const QString &name, c
}
}
});
}
void ServerConnection::startServer()

View File

@ -12,7 +12,7 @@ class ServerConnection : public QObject
{
Q_OBJECT
public:
explicit ServerConnection(const QUrl &serverUrl, const QString &name, const QUuid &uuid, bool insecure, QObject *parent = nullptr);
explicit ServerConnection(const QUrl &serverUrl, const QString &name, const QUuid &uuid, bool insecure, bool echo, QObject *parent = nullptr);
void startServer();
@ -21,6 +21,7 @@ private:
QString m_name;
QUuid m_uuid;
bool m_insecure = false;
bool m_echo = false;
TunnelProxySocketServer *m_socketServer = nullptr;
};

View File

@ -34,5 +34,6 @@
#define SERVER_NAME_STRING '"$$SERVER_NAME"'
#define SERVER_VERSION_STRING '"$$SERVER_VERSION"'
#define API_VERSION_STRING '"$$API_VERSION_MAJOR.$$API_VERSION_MINOR"'
#define COPYRIGHT_YEAR_STRING '"$$COPYRIGHT_YEAR"'
#endif