Files
amnezia-client/client/core/ipcclient.cpp
T

126 lines
4.1 KiB
C++
Raw Normal View History

2021-02-02 01:47:40 +03:00
#include "ipcclient.h"
#include "ipc.h"
2021-02-02 01:47:40 +03:00
#include <QRemoteObjectNode>
#include <QtNetwork/qlocalsocket.h>
2021-10-26 12:59:20 +03:00
2025-12-18 13:18:11 +01:00
namespace
{
thread_local IpcClient ipcClient;
}
2021-10-26 12:59:20 +03:00
IpcClient::IpcClient(QObject *parent) : QObject(parent)
{
m_localSocket.setServerName(amnezia::getIpcServiceUrl());
2021-10-26 12:59:20 +03:00
connect(&m_localSocket, &QLocalSocket::connected, this, [this]() {
m_ClientNode.addClientSideConnection(&m_localSocket);
m_ipcClient.reset(m_ClientNode.acquire<IpcInterfaceReplica>());
m_Tun2SocksClient.reset(m_ClientNode.acquire<IpcProcessTun2SocksReplica>());
m_isSocketConnected = true;
});
2021-10-26 12:59:20 +03:00
2025-12-18 13:18:11 +01:00
connect(&m_localSocket, &QLocalSocket::disconnected, this, [this]() {
m_ipcClient.clear();
m_Tun2SocksClient.clear();
m_isSocketConnected = false;
});
2021-02-02 01:47:40 +03:00
}
IpcClient *IpcClient::Instance()
{
2025-12-18 13:18:11 +01:00
if (!ipcClient.m_isSocketConnected) {
ipcClient.establishConnection();
}
2025-12-18 13:18:11 +01:00
return &ipcClient;
2021-10-26 12:59:20 +03:00
}
2021-02-18 15:00:41 +03:00
2021-10-26 12:59:20 +03:00
QSharedPointer<IpcInterfaceReplica> IpcClient::Interface()
{
2025-12-18 13:18:11 +01:00
QSharedPointer<IpcInterfaceReplica> rep = Instance()->m_ipcClient;
if (rep.isNull()) {
qCritical() << "IpcClient::Interface(): Failed to acquire replica";
2025-02-08 20:30:54 +01:00
return nullptr;
}
if (!rep->waitForSource(1000)) {
qCritical() << "IpcClient::Interface(): Failed to initialize replica";
return nullptr;
}
if (!rep->isReplicaValid()) {
qWarning() << "IpcClient::Interface(): Replica is invalid";
}
return rep;
2021-10-26 12:59:20 +03:00
}
2024-09-20 04:12:22 -07:00
QSharedPointer<IpcProcessTun2SocksReplica> IpcClient::InterfaceTun2Socks()
{
2025-12-18 13:18:11 +01:00
QSharedPointer<IpcProcessTun2SocksReplica> rep = Instance()->m_Tun2SocksClient;
if (rep.isNull()) {
qCritical() << "IpcClient::InterfaceTun2Socks: Replica is undefined";
2025-02-08 20:30:54 +01:00
return nullptr;
}
if (!rep->waitForSource(1000)) {
qCritical() << "IpcClient::InterfaceTun2Socks: Failed to initialize replica";
return nullptr;
2021-02-18 15:00:41 +03:00
}
if (!rep->isReplicaValid()) {
qWarning() << "IpcClient::InterfaceTun2Socks(): Replica is invalid";
}
return rep;
}
2024-09-20 04:12:22 -07:00
bool IpcClient::establishConnection()
{
m_localSocket.connectToServer();
return m_localSocket.waitForConnected();
2021-02-18 15:00:41 +03:00
}
2021-11-19 19:02:39 +03:00
QSharedPointer<PrivilegedProcess> IpcClient::CreatePrivilegedProcess()
2021-02-02 01:47:40 +03:00
{
2025-12-18 13:18:11 +01:00
QSharedPointer<IpcInterfaceReplica> rep = Interface();
if (!rep) {
2025-12-18 13:18:11 +01:00
qCritical() << "IpcClient::createPrivilegedProcess: Replica is invalid";
2021-02-03 15:42:36 +03:00
return nullptr;
}
2021-02-02 01:47:40 +03:00
2025-12-18 13:18:11 +01:00
QRemoteObjectPendingReply<int> pidReply = rep->createPrivilegedProcess();
if (!pidReply.waitForFinished(5000)){
qCritical() << "IpcClient::createPrivilegedProcess: Failed to execute RO createPrivilegedProcess call";
return nullptr;
}
2021-02-03 15:42:36 +03:00
2025-12-18 13:18:11 +01:00
int pid = pidReply.returnValue();
QSharedPointer<ProcessDescriptor> pd(new ProcessDescriptor());
2021-02-03 15:42:36 +03:00
2021-02-18 15:00:41 +03:00
pd->localSocket.reset(new QLocalSocket(pd->replicaNode.data()));
2021-02-03 15:42:36 +03:00
2021-02-18 15:00:41 +03:00
connect(pd->localSocket.data(), &QLocalSocket::connected, pd->replicaNode.data(), [pd]() {
pd->replicaNode->addClientSideConnection(pd->localSocket.data());
2021-02-03 15:42:36 +03:00
2021-11-19 19:02:39 +03:00
IpcProcessInterfaceReplica *repl = pd->replicaNode->acquire<IpcProcessInterfaceReplica>();
2025-12-18 13:18:11 +01:00
// TODO: rework the unsafe cast below
2021-11-19 19:02:39 +03:00
PrivilegedProcess *priv = static_cast<PrivilegedProcess *>(repl);
pd->ipcProcess.reset(priv);
2021-02-18 15:00:41 +03:00
if (!pd->ipcProcess) {
2021-11-19 19:02:39 +03:00
qWarning() << "Acquire PrivilegedProcess failed";
2025-02-08 20:30:54 +01:00
} else {
2021-02-18 15:00:41 +03:00
pd->ipcProcess->waitForSource(1000);
if (!pd->ipcProcess->isReplicaValid()) {
2021-11-19 19:02:39 +03:00
qWarning() << "PrivilegedProcess replica is not connected!";
2021-02-18 15:00:41 +03:00
}
2025-02-08 20:30:54 +01:00
QObject::connect(pd->ipcProcess.data(), &PrivilegedProcess::destroyed, pd->ipcProcess.data(),
[pd]() { pd->replicaNode->deleteLater(); });
2021-02-03 15:42:36 +03:00
}
2021-02-02 01:47:40 +03:00
});
2025-12-18 13:18:11 +01:00
2021-02-18 15:00:41 +03:00
pd->localSocket->connectToServer(amnezia::getIpcProcessUrl(pid));
2025-12-18 13:18:11 +01:00
if (!pd->localSocket->waitForConnected()) {
qCritical() << "IpcClient::createPrivilegedProcess: Failed to connect to process' socket";
return nullptr;
}
2021-02-03 15:42:36 +03:00
2023-04-11 09:50:44 -04:00
auto processReplica = QSharedPointer<PrivilegedProcess>(pd->ipcProcess);
return processReplica;
2021-02-02 01:47:40 +03:00
}