Fix possible crash on client disconnected and make sure also async requests will be killed if requested by the server

This commit is contained in:
Simon Stürz 2023-02-14 12:29:48 +01:00
parent ecf58505d1
commit 1a3a69c01f
5 changed files with 32 additions and 12 deletions

View File

@ -301,7 +301,13 @@ void JsonRpcServer::asyncReplyFinished()
if (!reply->success()) { if (!reply->success()) {
// Disconnect this client since the request was not successfully // Disconnect this client since the request was not successfully
transportClient->interface()->killClientConnection(transportClient->clientId(), "API call was not successfully."); transportClient->killConnectionAfterResponse("API call was not successfully.");
}
// If the server decided to kill the connection after the response, do it now
if (transportClient->killConnectionRequested()) {
transportClient->killConnection(transportClient->killConnectionReason());
} }
} else { } else {

View File

@ -27,16 +27,15 @@
#include "tunnelproxyclientconnection.h" #include "tunnelproxyclientconnection.h"
#include "server/transportclient.h" #include "server/transportclient.h"
#include "tunnelproxy/tunnelproxyserverconnection.h"
namespace remoteproxy { namespace remoteproxy {
TunnelProxyClientConnection::TunnelProxyClientConnection(TransportClient *transportClient, TunnelProxyServerConnection *serverConnection, const QUuid &clientUuid, const QString &clientName, const QUuid &serverUuid, QObject *parent) : TunnelProxyClientConnection::TunnelProxyClientConnection(TransportClient *transportClient, const QUuid &clientUuid, const QString &clientName, QObject *parent) :
QObject(parent), QObject(parent),
m_transportClient(transportClient), m_transportClient(transportClient),
m_serverConnection(serverConnection),
m_clientUuid(clientUuid), m_clientUuid(clientUuid),
m_clientName(clientName), m_clientName(clientName)
m_serverUuid(serverUuid)
{ {
} }
@ -51,6 +50,17 @@ TunnelProxyServerConnection *TunnelProxyClientConnection::serverConnection() con
return m_serverConnection; return m_serverConnection;
} }
void TunnelProxyClientConnection::setServerConnection(TunnelProxyServerConnection *serverConnection)
{
m_serverConnection = serverConnection;
if (m_serverConnection) {
m_serverUuid = m_serverConnection->serverUuid();
} else {
m_serverUuid = QUuid();
}
}
QUuid TunnelProxyClientConnection::clientUuid() const QUuid TunnelProxyClientConnection::clientUuid() const
{ {
return m_clientUuid; return m_clientUuid;

View File

@ -41,11 +41,12 @@ class TunnelProxyClientConnection : public QObject
{ {
Q_OBJECT Q_OBJECT
public: public:
explicit TunnelProxyClientConnection(TransportClient *transportClient, TunnelProxyServerConnection *serverConnection, const QUuid &clientUuid, const QString &clientName, const QUuid &serverUuid, QObject *parent = nullptr); explicit TunnelProxyClientConnection(TransportClient *transportClient, const QUuid &clientUuid, const QString &clientName, QObject *parent = nullptr);
TransportClient *transportClient() const; TransportClient *transportClient() const;
TunnelProxyServerConnection *serverConnection() const; TunnelProxyServerConnection *serverConnection() const;
void setServerConnection(TunnelProxyServerConnection *serverConnection);
QUuid clientUuid() const; QUuid clientUuid() const;
QString clientName() const; QString clientName() const;

View File

@ -153,7 +153,8 @@ TunnelProxyServer::TunnelProxyError TunnelProxyServer::registerClient(const QUui
tunnelProxyClient->setUuid(clientUuid); tunnelProxyClient->setUuid(clientUuid);
tunnelProxyClient->setName(clientName); tunnelProxyClient->setName(clientName);
TunnelProxyClientConnection *clientConnection = new TunnelProxyClientConnection(tunnelProxyClient, serverConnection, clientUuid, clientName, serverUuid); TunnelProxyClientConnection *clientConnection = new TunnelProxyClientConnection(tunnelProxyClient, clientUuid, clientName, this);
clientConnection->setServerConnection(serverConnection);
m_tunnelProxyClientConnections.insert(clientUuid, clientConnection); m_tunnelProxyClientConnections.insert(clientUuid, clientConnection);
qCDebug(dcTunnelProxyServer()) << "Register client" << clientConnection << "-->" << serverConnection; qCDebug(dcTunnelProxyServer()) << "Register client" << clientConnection << "-->" << serverConnection;
@ -303,7 +304,6 @@ void TunnelProxyServer::onClientDisconnected(const QUuid &clientId)
if (!serverConnection) { if (!serverConnection) {
qCWarning(dcTunnelProxyServer()) << "Could not find server connection for disconnected tunnel proxy client claiming to be a server."; qCWarning(dcTunnelProxyServer()) << "Could not find server connection for disconnected tunnel proxy client claiming to be a server.";
} else { } else {
foreach (TunnelProxyClientConnection *clientConnection, serverConnection->clientConnections()) { foreach (TunnelProxyClientConnection *clientConnection, serverConnection->clientConnections()) {
serverConnection->unregisterClientConnection(clientConnection); serverConnection->unregisterClientConnection(clientConnection);
clientConnection->setSocketAddress(0xFFFF); clientConnection->setSocketAddress(0xFFFF);
@ -319,11 +319,12 @@ void TunnelProxyServer::onClientDisconnected(const QUuid &clientId)
if (!clientConnection) { if (!clientConnection) {
qCWarning(dcTunnelProxyServer()) << "Could not find client connection for disconnected tunnel proxy client claiming to be a client."; qCWarning(dcTunnelProxyServer()) << "Could not find client connection for disconnected tunnel proxy client claiming to be a client.";
} else { } else {
if (clientConnection->serverConnection()) { TunnelProxyServerConnection *serverConnection = clientConnection->serverConnection();
if (serverConnection) {
QVariantMap params; QVariantMap params;
params.insert("socketAddress", clientConnection->socketAddress()); params.insert("socketAddress", clientConnection->socketAddress());
clientConnection->serverConnection()->unregisterClientConnection(clientConnection); serverConnection->unregisterClientConnection(clientConnection);
m_jsonRpcServer->sendNotification("TunnelProxy", "ClientDisconnected", params, clientConnection->serverConnection()->transportClient()); m_jsonRpcServer->sendNotification("TunnelProxy", "ClientDisconnected", params, serverConnection->transportClient());
} }
clientConnection->deleteLater(); clientConnection->deleteLater();

View File

@ -62,16 +62,18 @@ QList<TunnelProxyClientConnection *> TunnelProxyServerConnection::clientConnecti
void TunnelProxyServerConnection::registerClientConnection(TunnelProxyClientConnection *clientConnection) void TunnelProxyServerConnection::registerClientConnection(TunnelProxyClientConnection *clientConnection)
{ {
m_clientConnections.insert(clientConnection->clientUuid(), clientConnection);
quint16 socketAddress = getFreeAddress(); quint16 socketAddress = getFreeAddress();
clientConnection->setSocketAddress(socketAddress); clientConnection->setSocketAddress(socketAddress);
m_clientConnectionsAddresses.insert(socketAddress, clientConnection); m_clientConnectionsAddresses.insert(socketAddress, clientConnection);
m_clientConnections.insert(clientConnection->clientUuid(), clientConnection);
clientConnection->setServerConnection(this);
} }
void TunnelProxyServerConnection::unregisterClientConnection(TunnelProxyClientConnection *clientConnection) void TunnelProxyServerConnection::unregisterClientConnection(TunnelProxyClientConnection *clientConnection)
{ {
m_clientConnections.remove(clientConnection->clientUuid()); m_clientConnections.remove(clientConnection->clientUuid());
m_clientConnectionsAddresses.remove(clientConnection->socketAddress()); m_clientConnectionsAddresses.remove(clientConnection->socketAddress());
clientConnection->setServerConnection(nullptr);
} }
TunnelProxyClientConnection *TunnelProxyServerConnection::getClientConnection(quint16 socketAddress) TunnelProxyClientConnection *TunnelProxyServerConnection::getClientConnection(quint16 socketAddress)