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()
{
stopServer();
TcpSocketServer::stopServer();
}
void TcpSocketServer::sendData(const QUuid &clientId, const QByteArray &data)
@ -130,7 +130,6 @@ bool TcpSocketServer::stopServer()
void TcpSocketServer::onDataAvailable(QSslSocket *client, const QByteArray &data)
{
//qCDebug(dcTcpSocketServerTraffic()) << "Emitting data available internal.";
QUuid clientId = m_clientList.key(client);
if (clientId.isNull()) {
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();
return;
}
qCDebug(dcTcpSocketServer()) << "Client disconnected:" << client << client->peerAddress().toString() << clientId.toString();
m_clientList.take(clientId);
// Note: the SslServer is deleting the socket object
@ -191,21 +191,29 @@ void SslServer::incomingConnection(qintptr socketDescriptor)
connect(sslSocket, &SslClient::disconnected, this, [this, sslSocket](){
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);
}
m_clients.removeAll(sslSocket);
qCDebug(dcTcpSocketServer()) << "SSL server client count" << m_clients.count();
sslSocket->deleteLater();
});
connect(sslSocket, &QSslSocket::readyRead, this, [this, sslSocket](){
if (sslSocket->isEncrypted()) {
QByteArray data = sslSocket->readAll();
qCDebug(dcTcpSocketServerTraffic()) << "Data from socket" << sslSocket->peerAddress().toString() << data;
emit dataAvailable(sslSocket, data);
}
// Only forward data from an encrypted socket if ssl is enabled
if (m_sslEnabled && !sslSocket->isEncrypted())
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](){
@ -235,7 +243,6 @@ void SslServer::incomingConnection(qintptr socketDescriptor)
}
m_clients.append(sslSocket);
qCDebug(dcTcpSocketServer()) << "SSL server client count" << m_clients.count();
addPendingConnection(sslSocket);
}

View File

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

View File

@ -87,7 +87,8 @@ public:
virtual QList<QByteArray> processData(const QByteArray &data) = 0;
signals:
void trafficOccurred();
void rxDataCountChanged();
void txDataCountChanged();
protected:
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,
// 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)
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->setInterval(60000);
m_inactiveTimer->setSingleShot(true);
m_inactiveTimer->setSingleShot(false);
m_inactiveTimer->start();
}

View File

@ -113,27 +113,21 @@ TunnelProxyServer::TunnelProxyError TunnelProxyServer::registerServer(const QUui
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->setUuid(serverUuid);
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
tunnelProxyClient->enableSlipAfterResponse();
TunnelProxyServerConnection *serverConnection = new TunnelProxyServerConnection(tunnelProxyClient, serverUuid, serverName, tunnelProxyClient);
m_tunnelProxyServerConnections.insert(serverUuid, 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;
}
@ -174,15 +168,16 @@ TunnelProxyServer::TunnelProxyError TunnelProxyServer::registerClient(const QUui
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
tunnelProxyClient->setType(TunnelProxyClient::TypeClient);
tunnelProxyClient->setUuid(clientUuid);
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);
clientConnection->setServerConnection(serverConnection);
m_tunnelProxyClientConnections.insert(clientUuid, clientConnection);
@ -190,11 +185,6 @@ TunnelProxyServer::TunnelProxyError TunnelProxyServer::registerClient(const QUui
serverConnection->registerClientConnection(clientConnection);
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
QVariantMap params;
params.insert("clientName", tunnelProxyClient->name());
@ -328,10 +318,10 @@ void TunnelProxyServer::onClientConnected(const QUuid &clientId, const QHostAddr
m_proxyClients.insert(clientId, tunnelProxyClient);
m_jsonRpcServer->registerClient(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();
// // 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();
}
void TunnelProxyServer::onClientDisconnected(const QUuid &clientId)
@ -378,11 +368,6 @@ void TunnelProxyServer::onClientDisconnected(const QUuid &clientId)
// Unregister from json rpc server
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
tunnelProxyClient->deleteLater();
}