diff --git a/client/core/ipcclient.cpp b/client/core/ipcclient.cpp index 5c3ec85f5..c9dc0c732 100644 --- a/client/core/ipcclient.cpp +++ b/client/core/ipcclient.cpp @@ -1,123 +1,88 @@ #include "ipcclient.h" +#include "ipc.h" #include - -IpcClient *IpcClient::m_instance = nullptr; +#include IpcClient::IpcClient(QObject *parent) : QObject(parent) { -} + m_localSocket.setServerName(amnezia::getIpcServiceUrl()); -IpcClient::~IpcClient() -{ - if (m_localSocket) - m_localSocket->close(); -} + connect(&m_localSocket, &QLocalSocket::connected, this, [this]() { + m_ClientNode.addClientSideConnection(&m_localSocket); + m_ipcClient.reset(m_ClientNode.acquire()); + m_Tun2SocksClient.reset(m_ClientNode.acquire()); + m_isSocketConnected = true; + }); -bool IpcClient::isSocketConnected() const -{ - return m_isSocketConnected; -} - -void IpcClient::closeAndResetInstance(bool deleteSelf) -{ - if (m_localSocket) - { - m_localSocket->disconnectFromServer(); - m_localSocket->deleteLater(); - m_localSocket.clear(); - } - m_ipcClient.reset(); - m_Tun2SocksClient.reset(); - m_isSocketConnected = false; - if (deleteSelf) { - m_instance = nullptr; - } + connect(&m_localSocket, &QLocalSocket::disconnected, [this]() { + m_ipcClient.clear(); + m_Tun2SocksClient.clear(); + m_isSocketConnected = false; + }); } IpcClient *IpcClient::Instance() { - return m_instance; + static IpcClient instance; + + QMutexLocker locker(&instance.m_mutex); + + if (!instance.m_isSocketConnected) { + instance.establishConnection(); + } + + return &instance; } QSharedPointer IpcClient::Interface() { - if (!Instance()) + auto rep = Instance()->m_ipcClient; + if (!rep) { + qCritical() << "IpcClient::Interface(): Replica is undefined"; return nullptr; - return Instance()->m_ipcClient; + } + if (!rep->waitForSource(1000)) { + qCritical() << "IpcClient::Interface(): Failed to initialize replica"; + return nullptr; + } + if (!rep->isReplicaValid()) { + qWarning() << "IpcClient::Interface(): Replica is invalid"; + } + return rep; } QSharedPointer IpcClient::InterfaceTun2Socks() { - if (!Instance()) + auto rep = Instance()->m_Tun2SocksClient; + if (!rep) { + qCritical() << "IpcClient::InterfaceTun2Socks: Replica is undefined"; return nullptr; - return Instance()->m_Tun2SocksClient; + } + if (!rep->waitForSource(1000)) { + qCritical() << "IpcClient::InterfaceTun2Socks: Failed to initialize replica"; + return nullptr; + } + if (!rep->isReplicaValid()) { + qWarning() << "IpcClient::InterfaceTun2Socks(): Replica is invalid"; + } + return rep; } -bool IpcClient::init(IpcClient *instance) +bool IpcClient::establishConnection() { - if (m_instance && m_instance != instance) { - m_instance->closeAndResetInstance(false); - m_instance->deleteLater(); - } - m_instance = instance; - - Instance()->m_localSocket = new QLocalSocket(Instance()); - connect(Instance()->m_localSocket.data(), &QLocalSocket::connected, &Instance()->m_ClientNode, []() { - Instance()->m_ClientNode.addClientSideConnection(Instance()->m_localSocket.data()); - auto cliNode = Instance()->m_ClientNode.acquire(); - cliNode->waitForSource(5000); - Instance()->m_ipcClient.reset(cliNode); - - if (!Instance()->m_ipcClient) { - qWarning() << "IpcClient is not ready!"; - } - - Instance()->m_ipcClient->waitForSource(1000); - - if (!Instance()->m_ipcClient->isReplicaValid()) { - qWarning() << "IpcClient replica is not connected!"; - } - - auto t2sNode = Instance()->m_ClientNode.acquire(); - t2sNode->waitForSource(5000); - Instance()->m_Tun2SocksClient.reset(t2sNode); - - if (!Instance()->m_Tun2SocksClient) { - qWarning() << "IpcClient::m_Tun2SocksClient is not ready!"; - } - - Instance()->m_Tun2SocksClient->waitForSource(1000); - - if (!Instance()->m_Tun2SocksClient->isReplicaValid()) { - qWarning() << "IpcClient::m_Tun2SocksClient replica is not connected!"; - } - }); - - connect(Instance()->m_localSocket, &QLocalSocket::disconnected, - [instance]() { instance->m_isSocketConnected = false; }); - - Instance()->m_localSocket->connectToServer(amnezia::getIpcServiceUrl()); - Instance()->m_localSocket->waitForConnected(); - - if (!Instance()->m_ipcClient) { - qDebug() << "IpcClient::init failed"; - return false; - } - - qDebug() << "IpcClient::init succeed"; - instance->m_isSocketConnected = (Instance()->m_ipcClient->isReplicaValid() && Instance()->m_Tun2SocksClient->isReplicaValid()); - - return Instance()->isSocketConnected(); + m_localSocket.connectToServer(); + return m_localSocket.waitForConnected(); } QSharedPointer IpcClient::CreatePrivilegedProcess() { - if (!Instance()->m_ipcClient || !Instance()->m_ipcClient->isReplicaValid()) { - qWarning() << "IpcClient::createPrivilegedProcess : IpcClient IpcClient replica is not valid"; + auto rep = Interface(); + if (!rep) { + qCritical() << "IpcClient::createPrivilegedProcess : IpcClient IpcClient replica is not valid"; return nullptr; } - QRemoteObjectPendingReply futureResult = Instance()->m_ipcClient->createPrivilegedProcess(); + QRemoteObjectPendingReply futureResult = rep->createPrivilegedProcess(); futureResult.waitForFinished(5000); int pid = futureResult.returnValue(); diff --git a/client/core/ipcclient.h b/client/core/ipcclient.h index b692e1130..502c81917 100644 --- a/client/core/ipcclient.h +++ b/client/core/ipcclient.h @@ -17,24 +17,20 @@ public: explicit IpcClient(QObject *parent = nullptr); static IpcClient *Instance(); - static bool init(IpcClient *instance); static QSharedPointer Interface(); static QSharedPointer InterfaceTun2Socks(); static QSharedPointer CreatePrivilegedProcess(); bool isSocketConnected() const; - void closeAndResetInstance(bool deleteSelf = false); - signals: private: - ~IpcClient() override; + bool establishConnection(); + QMutex m_mutex; + QLocalSocket m_localSocket; QRemoteObjectNode m_ClientNode; - QRemoteObjectNode m_Tun2SocksNode; QSharedPointer m_ipcClient; - QPointer m_localSocket; - QPointer m_tun2socksSocket; QSharedPointer m_Tun2SocksClient; struct ProcessDescriptor { @@ -50,8 +46,6 @@ private: QMap> m_processNodes; bool m_isSocketConnected {false}; - - static IpcClient *m_instance; }; #endif // IPCCLIENT_H diff --git a/client/vpnconnection.cpp b/client/vpnconnection.cpp index 3f664d40a..7af2eff41 100644 --- a/client/vpnconnection.cpp +++ b/client/vpnconnection.cpp @@ -218,27 +218,16 @@ void VpnConnection::deleteRoutes(const QStringList &ips) #endif } +// TODO: replace with something like +// VpnConnection::withInterface([](iface){ }) bool VpnConnection::InterfaceReady() { #ifdef AMNEZIA_DESKTOP - if (m_IpcClient) { - m_IpcClient->closeAndResetInstance(true); - m_IpcClient->deleteLater(); - m_IpcClient = nullptr; + if (auto iface = IpcClient::Interface(); iface == nullptr) { + qWarning() << "Error occurred when init IPC client"; + emit serviceIsNotReady(); + return false; } - if (!m_IpcClient) { - m_IpcClient = new IpcClient(this); - } - - if (!m_IpcClient->isSocketConnected()) { - if (!IpcClient::init(m_IpcClient)) { - qWarning() << "Error occurred when init IPC client"; - emit serviceIsNotReady(); - return false; - } - } - - return IpcClient::Interface() != nullptr; #endif return true; } diff --git a/client/vpnconnection.h b/client/vpnconnection.h index 348858aa1..9e275b701 100644 --- a/client/vpnconnection.h +++ b/client/vpnconnection.h @@ -93,10 +93,6 @@ private: // Only for iOS for now, check counters QTimer m_checkTimer; -#ifdef AMNEZIA_DESKTOP - IpcClient *m_IpcClient {nullptr}; -#endif - #ifdef Q_OS_ANDROID AndroidVpnProtocol* androidVpnProtocol = nullptr; diff --git a/common/logger/logger.cpp b/common/logger/logger.cpp index f1d40f47b..3ec17cd73 100644 --- a/common/logger/logger.cpp +++ b/common/logger/logger.cpp @@ -91,17 +91,8 @@ void Logger::deInit() bool Logger::setServiceLogsEnabled(bool enabled) { #ifdef AMNEZIA_DESKTOP - IpcClient *m_IpcClient = new IpcClient; - - if (!m_IpcClient->isSocketConnected()) { - if (!IpcClient::init(m_IpcClient)) { - qWarning() << "Error occurred when init IPC client"; - return false; - } - } - - if (m_IpcClient->Interface()) { - m_IpcClient->Interface()->setLogsEnabled(enabled); + if (auto iface = IpcClient::Interface(); iface) { + iface->setLogsEnabled(enabled); } else { qWarning() << "Error occurred setting up service logs"; return false; @@ -208,19 +199,8 @@ void Logger::clearLogs(bool isServiceLogger) void Logger::clearServiceLogs() { #ifdef AMNEZIA_DESKTOP - IpcClient *m_IpcClient = new IpcClient; - - if (!m_IpcClient->isSocketConnected()) { - if (!IpcClient::init(m_IpcClient)) { - qWarning() << "Error occurred when init IPC client"; - return; - } - } - - if (m_IpcClient->Interface()) { - m_IpcClient->Interface()->clearLogs(); - } else { - qWarning() << "Error occurred cleaning up service logs"; + if (auto iface = IpcClient::Interface(); iface) { + iface->clearLogs(); } #endif }