Fix client activation and improve dead socket handling
This commit is contained in:
parent
4d391f10ad
commit
0b031d7614
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -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();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -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;
|
||||||
|
|||||||
@ -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();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -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();
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user