Fix client activation and improve dead socket handling

This commit is contained in:
Simon Stürz 2023-02-27 22:15:39 +01:00
parent 4d391f10ad
commit 0b031d7614
5 changed files with 37 additions and 42 deletions

View File

@ -40,7 +40,7 @@ TcpSocketServer::TcpSocketServer(bool sslEnabled, const QSslConfiguration &sslCo
TcpSocketServer::~TcpSocketServer() TcpSocketServer::~TcpSocketServer()
{ {
stopServer(); TcpSocketServer::stopServer();
} }
void TcpSocketServer::sendData(const QUuid &clientId, const QByteArray &data) void TcpSocketServer::sendData(const QUuid &clientId, const QByteArray &data)
@ -130,7 +130,6 @@ bool TcpSocketServer::stopServer()
void TcpSocketServer::onDataAvailable(QSslSocket *client, const QByteArray &data) void TcpSocketServer::onDataAvailable(QSslSocket *client, const QByteArray &data)
{ {
//qCDebug(dcTcpSocketServerTraffic()) << "Emitting data available internal.";
QUuid clientId = m_clientList.key(client); QUuid clientId = m_clientList.key(client);
if (clientId.isNull()) { if (clientId.isNull()) {
qCWarning(dcTcpSocketServer()) << "Socket sent data but the uuid is null." << client << client->peerAddress().toString() << "Ignoring data..."; qCWarning(dcTcpSocketServer()) << "Socket sent data but the uuid is null." << client << client->peerAddress().toString() << "Ignoring data...";
@ -154,6 +153,7 @@ void TcpSocketServer::onSocketDisconnected(QSslSocket *client)
qCWarning(dcTcpSocketServer()) << "Socket disconnected but the uuid is null." << client << client->peerAddress().toString() << clientId.toString(); qCWarning(dcTcpSocketServer()) << "Socket disconnected but the uuid is null." << client << client->peerAddress().toString() << clientId.toString();
return; return;
} }
qCDebug(dcTcpSocketServer()) << "Client disconnected:" << client << client->peerAddress().toString() << clientId.toString(); qCDebug(dcTcpSocketServer()) << "Client disconnected:" << client << client->peerAddress().toString() << clientId.toString();
m_clientList.take(clientId); m_clientList.take(clientId);
// Note: the SslServer is deleting the socket object // Note: the SslServer is deleting the socket object
@ -191,21 +191,29 @@ void SslServer::incomingConnection(qintptr socketDescriptor)
connect(sslSocket, &SslClient::disconnected, this, [this, sslSocket](){ connect(sslSocket, &SslClient::disconnected, this, [this, sslSocket](){
qCDebug(dcTcpSocketServer()) << "Client socket disconnected:" << sslSocket << sslSocket->peerAddress().toString();; qCDebug(dcTcpSocketServer()) << "Client socket disconnected:" << sslSocket << sslSocket->peerAddress().toString();;
if (sslSocket->isEncrypted()) {
if (m_sslEnabled) {
// Only tell the upper layer the client has disconnecred if it was encrypted
if (sslSocket->isEncrypted()) {
emit socketDisconnected(sslSocket);
}
} else {
emit socketDisconnected(sslSocket); emit socketDisconnected(sslSocket);
} }
m_clients.removeAll(sslSocket); m_clients.removeAll(sslSocket);
qCDebug(dcTcpSocketServer()) << "SSL server client count" << m_clients.count();
sslSocket->deleteLater(); sslSocket->deleteLater();
}); });
connect(sslSocket, &QSslSocket::readyRead, this, [this, sslSocket](){ connect(sslSocket, &QSslSocket::readyRead, this, [this, sslSocket](){
if (sslSocket->isEncrypted()) {
QByteArray data = sslSocket->readAll(); // Only forward data from an encrypted socket if ssl is enabled
qCDebug(dcTcpSocketServerTraffic()) << "Data from socket" << sslSocket->peerAddress().toString() << data; if (m_sslEnabled && !sslSocket->isEncrypted())
emit dataAvailable(sslSocket, data); return;
}
QByteArray data = sslSocket->readAll();
qCDebug(dcTcpSocketServerTraffic()) << "Data from socket" << sslSocket->peerAddress().toString() << data;
emit dataAvailable(sslSocket, data);
}); });
connect(sslSocket, &SslClient::encrypted, this, [this, sslSocket](){ connect(sslSocket, &SslClient::encrypted, this, [this, sslSocket](){
@ -235,7 +243,6 @@ void SslServer::incomingConnection(qintptr socketDescriptor)
} }
m_clients.append(sslSocket); m_clients.append(sslSocket);
qCDebug(dcTcpSocketServer()) << "SSL server client count" << m_clients.count();
addPendingConnection(sslSocket); addPendingConnection(sslSocket);
} }

View File

@ -131,7 +131,7 @@ void TransportClient::addRxDataCount(int dataCount)
{ {
m_rxDataCount += dataCount; m_rxDataCount += dataCount;
if (dataCount > 0) { if (dataCount > 0) {
emit trafficOccurred(); emit rxDataCountChanged();
} }
} }
@ -144,7 +144,7 @@ void TransportClient::addTxDataCount(int dataCount)
{ {
m_txDataCount += dataCount; m_txDataCount += dataCount;
if (dataCount > 0) { if (dataCount > 0) {
emit trafficOccurred(); emit txDataCountChanged();
} }
} }

View File

@ -87,7 +87,8 @@ public:
virtual QList<QByteArray> processData(const QByteArray &data) = 0; virtual QList<QByteArray> processData(const QByteArray &data) = 0;
signals: signals:
void trafficOccurred(); void rxDataCountChanged();
void txDataCountChanged();
protected: protected:
TransportInterface *m_interface = nullptr; TransportInterface *m_interface = nullptr;

View File

@ -92,15 +92,17 @@ void TunnelProxyClient::activateClient()
// keep the connection up. If there is no data for more than one minute, // keep the connection up. If there is no data for more than one minute,
// we consider the connection as dead and terminate the connection. // we consider the connection as dead and terminate the connection.
Q_ASSERT_X(m_type != TypeNone, "TunnelProxyClient", "Activate client called but the client type is not specified yet. Make sure you activate either a client or a server.");
if (m_type != TypeServer) if (m_type != TypeServer)
return; return;
connect(this, &TransportClient::trafficOccurred, this, [this](){ // We must receive data, transmitt does not mean the socket is not dead
connect(this, &TransportClient::rxDataCountChanged, this, [this](){
m_inactiveTimer->start(); m_inactiveTimer->start();
}); });
m_inactiveTimer->setInterval(60000); m_inactiveTimer->setInterval(60000);
m_inactiveTimer->setSingleShot(true); m_inactiveTimer->setSingleShot(false);
m_inactiveTimer->start(); m_inactiveTimer->start();
} }

View File

@ -113,27 +113,21 @@ TunnelProxyServer::TunnelProxyError TunnelProxyServer::registerServer(const QUui
return TunnelProxyServer::TunnelProxyErrorAlreadyRegistered; return TunnelProxyServer::TunnelProxyErrorAlreadyRegistered;
} }
// This client has been registered successfully.
// Make sure it does not get disconnected any more because of inactivity.
tunnelProxyClient->activateClient();
tunnelProxyClient->setType(TunnelProxyClient::TypeServer); tunnelProxyClient->setType(TunnelProxyClient::TypeServer);
tunnelProxyClient->setUuid(serverUuid); tunnelProxyClient->setUuid(serverUuid);
tunnelProxyClient->setName(serverName); tunnelProxyClient->setName(serverName);
// This client has been registered successfully.
// Make sure it does not get disconnected any more because of inactivity.
tunnelProxyClient->activateClient();
// Enable SLIP from now on // Enable SLIP from now on
tunnelProxyClient->enableSlipAfterResponse(); tunnelProxyClient->enableSlipAfterResponse();
TunnelProxyServerConnection *serverConnection = new TunnelProxyServerConnection(tunnelProxyClient, serverUuid, serverName, tunnelProxyClient); TunnelProxyServerConnection *serverConnection = new TunnelProxyServerConnection(tunnelProxyClient, serverUuid, serverName, tunnelProxyClient);
m_tunnelProxyServerConnections.insert(serverUuid, serverConnection); m_tunnelProxyServerConnections.insert(serverUuid, serverConnection);
qCDebug(dcTunnelProxyServer()) << "New server connection registered successfully" << serverConnection; qCDebug(dcTunnelProxyServer()) << "New server connection registered successfully" << serverConnection;
// For debugging
qCDebug(dcTunnelProxyServer()) << "#### Total clients:" << m_proxyClients.count() << "JSON RPC clients:" << m_jsonRpcServer->registeredClientCount()
<< "Interface connections:" << tunnelProxyClient->interface()->connectionsCount()
<< "Servers:" << m_tunnelProxyServerConnections.count() << "Clients:" << m_tunnelProxyClientConnections.count();
return TunnelProxyServer::TunnelProxyErrorNoError; return TunnelProxyServer::TunnelProxyErrorNoError;
} }
@ -174,15 +168,16 @@ TunnelProxyServer::TunnelProxyError TunnelProxyServer::registerClient(const QUui
return TunnelProxyServer::TunnelProxyErrorServerNotFound; return TunnelProxyServer::TunnelProxyErrorServerNotFound;
} }
// This client has been registered successfully.
// Make sure it does not get disconnected any more because due to inactivity.
tunnelProxyClient->activateClient();
// Not registered yet, we have a connected server for the requested server uuid // Not registered yet, we have a connected server for the requested server uuid
tunnelProxyClient->setType(TunnelProxyClient::TypeClient); tunnelProxyClient->setType(TunnelProxyClient::TypeClient);
tunnelProxyClient->setUuid(clientUuid); tunnelProxyClient->setUuid(clientUuid);
tunnelProxyClient->setName(clientName); tunnelProxyClient->setName(clientName);
// This client has been registered successfully.
// Make sure it does not get disconnected any more because due to inactivity.
tunnelProxyClient->activateClient();
TunnelProxyClientConnection *clientConnection = new TunnelProxyClientConnection(tunnelProxyClient, clientUuid, clientName, this); TunnelProxyClientConnection *clientConnection = new TunnelProxyClientConnection(tunnelProxyClient, clientUuid, clientName, this);
clientConnection->setServerConnection(serverConnection); clientConnection->setServerConnection(serverConnection);
m_tunnelProxyClientConnections.insert(clientUuid, clientConnection); m_tunnelProxyClientConnections.insert(clientUuid, clientConnection);
@ -190,11 +185,6 @@ TunnelProxyServer::TunnelProxyError TunnelProxyServer::registerClient(const QUui
serverConnection->registerClientConnection(clientConnection); serverConnection->registerClientConnection(clientConnection);
qCDebug(dcTunnelProxyServer()) << "New client connection registered successfully" << clientConnection << "-->" << serverConnection;; qCDebug(dcTunnelProxyServer()) << "New client connection registered successfully" << clientConnection << "-->" << serverConnection;;
// For debugging
qCDebug(dcTunnelProxyServer()) << "#### Total clients:" << m_proxyClients.count() << "JSON RPC clients:" << m_jsonRpcServer->registeredClientCount()
<< "Interface connections:" << tunnelProxyClient->interface()->connectionsCount()
<< "Servers:" << m_tunnelProxyServerConnections.count() << "Clients:" << m_tunnelProxyClientConnections.count();
// Tell the server a new client want's to connect // Tell the server a new client want's to connect
QVariantMap params; QVariantMap params;
params.insert("clientName", tunnelProxyClient->name()); params.insert("clientName", tunnelProxyClient->name());
@ -328,10 +318,10 @@ void TunnelProxyServer::onClientConnected(const QUuid &clientId, const QHostAddr
m_proxyClients.insert(clientId, tunnelProxyClient); m_proxyClients.insert(clientId, tunnelProxyClient);
m_jsonRpcServer->registerClient(tunnelProxyClient); m_jsonRpcServer->registerClient(tunnelProxyClient);
// For debugging // // For debugging
qCDebug(dcTunnelProxyServer()) << "#### Total clients:" << m_proxyClients.count() << "JSON RPC clients:" << m_jsonRpcServer->registeredClientCount() // qCDebug(dcTunnelProxyServer()) << "#### Total clients:" << m_proxyClients.count() << "JSON RPC clients:" << m_jsonRpcServer->registeredClientCount()
<< "Interface connections:" << tunnelProxyClient->interface()->connectionsCount() // << "Interface connections:" << tunnelProxyClient->interface()->connectionsCount()
<< "Servers:" << m_tunnelProxyServerConnections.count() << "Clients:" << m_tunnelProxyClientConnections.count(); // << "Servers:" << m_tunnelProxyServerConnections.count() << "Clients:" << m_tunnelProxyClientConnections.count();
} }
void TunnelProxyServer::onClientDisconnected(const QUuid &clientId) void TunnelProxyServer::onClientDisconnected(const QUuid &clientId)
@ -378,11 +368,6 @@ void TunnelProxyServer::onClientDisconnected(const QUuid &clientId)
// Unregister from json rpc server // Unregister from json rpc server
m_jsonRpcServer->unregisterClient(tunnelProxyClient); m_jsonRpcServer->unregisterClient(tunnelProxyClient);
// For debugging
qCDebug(dcTunnelProxyServer()) << "#### Total clients:" << m_proxyClients.count() << "JSON RPC clients:" << m_jsonRpcServer->registeredClientCount()
<< "Interface connections:" << tunnelProxyClient->interface()->connectionsCount()
<< "Servers:" << m_tunnelProxyServerConnections.count() << "Clients:" << m_tunnelProxyClientConnections.count();
// Delete the proxy client // Delete the proxy client
tunnelProxyClient->deleteLater(); tunnelProxyClient->deleteLater();
} }