diff --git a/libnymea-remoteproxy/proxyserver.cpp b/libnymea-remoteproxy/proxyserver.cpp index 5cea8cf..02a2157 100644 --- a/libnymea-remoteproxy/proxyserver.cpp +++ b/libnymea-remoteproxy/proxyserver.cpp @@ -168,6 +168,7 @@ void ProxyServer::establishTunnel(ProxyClient *firstClient, ProxyClient *secondC Q_ARG(ProxyClient *, tunnel.clientTwo())); } + void ProxyServer::onClientConnected(const QUuid &clientId, const QHostAddress &address) { TransportInterface *interface = static_cast(sender()); @@ -211,7 +212,6 @@ void ProxyServer::onClientDisconnected(const QUuid &clientId) // Delete the proxy client proxyClient->deleteLater(); } - } void ProxyServer::onClientDataAvailable(const QUuid &clientId, const QByteArray &data) @@ -260,12 +260,13 @@ void ProxyServer::onProxyClientAuthenticated() qCDebug(dcProxyServer()) << "Client authenticated" << proxyClient; if (m_tunnels.contains(proxyClient->token())) { - qCWarning(dcProxyServer()) << "There is already a tunnel connection for this token. A third client is not allowed."; - // Note: remove the authenticated token, so the current tunnel will not interrupted. - proxyClient->setToken(QString()); - proxyClient->setAuthenticated(false); - proxyClient->killConnection("There is already an established tunnel with this token."); - return; + // A new connection attempt with the same token, kill the old tunnel connection and allow the new connection to stablish the tunnel + qCWarning(dcProxyServer()) << "New authenticated client which already has a tunnel connection. Closing and clean up the old tunnel."; + + TunnelConnection tunnel = m_tunnels.take(proxyClient->token()); + qCDebug(dcProxyServer()) << "Killing " << tunnel; + tunnel.clientOne()->killConnection("Clean up for new connection."); + tunnel.clientTwo()->killConnection("Clean up for new connection."); } // Check if we have an other authenticated client with this token @@ -283,7 +284,6 @@ void ProxyServer::onProxyClientAuthenticated() // All ok so far. Create the tunnel establishTunnel(tunnelEnd, proxyClient); - } else { // Append and wait for the other client m_authenticatedClients.insert(proxyClient->token(), proxyClient); diff --git a/libnymea-remoteproxy/proxyserver.h b/libnymea-remoteproxy/proxyserver.h index d99408c..37f4d3f 100644 --- a/libnymea-remoteproxy/proxyserver.h +++ b/libnymea-remoteproxy/proxyserver.h @@ -65,6 +65,7 @@ private: ProxyClient *getRemoteClient(ProxyClient *proxyClient); void sendResponse(TransportInterface *interface, const QUuid &clientId, const QVariantMap &response = QVariantMap()); + void establishTunnel(ProxyClient *firstClient, ProxyClient *secondClient); signals: diff --git a/tests/test-offline/nymea-remoteproxy-tests-offline.cpp b/tests/test-offline/nymea-remoteproxy-tests-offline.cpp index f463f43..cbb0636 100644 --- a/tests/test-offline/nymea-remoteproxy-tests-offline.cpp +++ b/tests/test-offline/nymea-remoteproxy-tests-offline.cpp @@ -75,7 +75,6 @@ void RemoteProxyOfflineTests::dummyAuthenticator() } - void RemoteProxyOfflineTests::monitorServer() { // Start the server @@ -494,6 +493,7 @@ void RemoteProxyOfflineTests::trippleConnection() // Connect one QSignalSpy connectionOneReadySpy(connectionOne, &RemoteProxyConnection::ready); + QSignalSpy connectionOneDisconnectedSpy(connectionOne, &RemoteProxyConnection::disconnected); QVERIFY(connectionOne->connectServer(m_serverUrl)); connectionOneReadySpy.wait(); QVERIFY(connectionOneReadySpy.count() == 1); @@ -501,19 +501,12 @@ void RemoteProxyOfflineTests::trippleConnection() // Connect two QSignalSpy connectionTwoReadySpy(connectionTwo, &RemoteProxyConnection::ready); + QSignalSpy connectionTwoDisconnectedSpy(connectionTwo, &RemoteProxyConnection::disconnected); QVERIFY(connectionTwo->connectServer(m_serverUrl)); connectionTwoReadySpy.wait(); QVERIFY(connectionTwoReadySpy.count() == 1); QVERIFY(connectionTwo->isConnected()); - // Connect two - QSignalSpy connectionThreeReadySpy(connectionThree, &RemoteProxyConnection::ready); - QVERIFY(connectionThree->connectServer(m_serverUrl)); - connectionThreeReadySpy.wait(); - QVERIFY(connectionThreeReadySpy.count() == 1); - QVERIFY(connectionThree->isConnected()); - - // Authenticate one QSignalSpy connectionOneAuthenticatedSpy(connectionOne, &RemoteProxyConnection::authenticated); QVERIFY(connectionOne->authenticate(m_testToken)); @@ -537,17 +530,28 @@ void RemoteProxyOfflineTests::trippleConnection() // Wait for both to be connected remoteConnectionEstablishedOne.wait(500); - // Now connect a third connection and make sure it gets disconnected + // Now connect a third connection and make sure the tunnel gets closed + + // Connect three + QSignalSpy connectionThreeReadySpy(connectionThree, &RemoteProxyConnection::ready); + QVERIFY(connectionThree->connectServer(m_serverUrl)); + connectionThreeReadySpy.wait(); + QVERIFY(connectionThreeReadySpy.count() == 1); + QVERIFY(connectionThree->isConnected()); // Authenticate three - QSignalSpy connectionThreeDisconnectSpy(connectionThree, &RemoteProxyConnection::disconnected); + QSignalSpy connectionThreeAuthenticatedSpy(connectionThree, &RemoteProxyConnection::authenticated); QVERIFY(connectionThree->authenticate(m_testToken)); - connectionThreeDisconnectSpy.wait(); - + connectionThreeAuthenticatedSpy.wait(); QVERIFY(connectionOneAuthenticatedSpy.count() == 1); - QVERIFY(!connectionThree->isConnected()); - QVERIFY(!connectionThree->isAuthenticated()); - QVERIFY(connectionThree->state() == RemoteProxyConnection::StateDisconnected); + + connectionOneDisconnectedSpy.wait(200); + connectionTwoDisconnectedSpy.wait(200); + + QVERIFY(connectionOneDisconnectedSpy.count() >= 1); + QVERIFY(connectionTwoDisconnectedSpy.count() >= 1); + QVERIFY(connectionOne->state() == RemoteProxyConnection::StateDisconnected); + QVERIFY(connectionTwo->state() == RemoteProxyConnection::StateDisconnected); // Clean up stopServer(); @@ -559,7 +563,7 @@ void RemoteProxyOfflineTests::duplicateUuid() startServer(); // Configure moch authenticator - m_mockAuthenticator->setTimeoutDuration(100); + m_mockAuthenticator->setTimeoutDuration(10); m_mockAuthenticator->setExpectedAuthenticationError(); QUuid connectionUuid = QUuid::createUuid(); @@ -602,10 +606,10 @@ void RemoteProxyOfflineTests::duplicateUuid() QSignalSpy disconnectSpyTwo(connectionTwo, &RemoteProxyConnection::disconnected); QVERIFY(connectionTwo->authenticate(m_testToken)); - disconnectSpyOne.wait(); + disconnectSpyOne.wait(200); QVERIFY(disconnectSpyOne.count() >= 1); - disconnectSpyTwo.wait(); + disconnectSpyTwo.wait(200); QVERIFY(disconnectSpyTwo.count() >= 1); connectionOne->deleteLater(); diff --git a/tests/testbase/basetest.cpp b/tests/testbase/basetest.cpp index e018785..acdcbac 100644 --- a/tests/testbase/basetest.cpp +++ b/tests/testbase/basetest.cpp @@ -199,7 +199,7 @@ void BaseTest::initTestCase() m_mockAuthenticator = new MockAuthenticator(this); m_dummyAuthenticator = new DummyAuthenticator(this); - m_awsAuthenticator = new AwsAuthenticator(m_configuration->awsCredentialsUrl(), this); + //m_awsAuthenticator = new AwsAuthenticator(m_configuration->awsCredentialsUrl(), this); m_authenticator = qobject_cast(m_mockAuthenticator); @@ -226,7 +226,7 @@ void BaseTest::cleanupTestCase() delete m_configuration; delete m_mockAuthenticator; delete m_dummyAuthenticator; - delete m_awsAuthenticator; + //delete m_awsAuthenticator; m_authenticator = nullptr;