fix: cannot connect to IPC on Windows (#2083)

* fix: replace localsocket by QtRO-embedded one

* fix: make IpcClient initialization lazy
This commit is contained in:
Yaroslav Gurov
2025-12-19 15:44:42 +01:00
committed by GitHub
parent bec06b3a5e
commit 92aba49705
2 changed files with 16 additions and 49 deletions
+8 -33
View File
@@ -3,41 +3,22 @@
#include <QRemoteObjectNode> #include <QRemoteObjectNode>
#include <QtNetwork/qlocalsocket.h> #include <QtNetwork/qlocalsocket.h>
namespace
{
thread_local IpcClient ipcClient;
}
IpcClient::IpcClient(QObject *parent) : QObject(parent) IpcClient::IpcClient(QObject *parent) : QObject(parent)
{ {
connect(&m_localSocket, &QLocalSocket::connected, this, [this]() { m_node.connectToNode(QUrl("local:" + amnezia::getIpcServiceUrl()));
m_ClientNode.reset(new QRemoteObjectNode); m_interface.reset(m_node.acquire<IpcInterfaceReplica>());
m_ClientNode->addClientSideConnection(&m_localSocket); m_tun2socks.reset(m_node.acquire<IpcProcessTun2SocksReplica>());
m_ipcClient.reset(m_ClientNode->acquire<IpcInterfaceReplica>());
m_Tun2SocksClient.reset(m_ClientNode->acquire<IpcProcessTun2SocksReplica>());
m_isSocketConnected = true;
});
connect(&m_localSocket, &QLocalSocket::disconnected, this, [this]() {
m_ClientNode.clear();
m_ipcClient.clear();
m_Tun2SocksClient.clear();
m_isSocketConnected = false;
});
} }
IpcClient *IpcClient::Instance() IpcClient& IpcClient::Instance()
{ {
if (!ipcClient.m_isSocketConnected) { thread_local IpcClient ipcClient;
ipcClient.establishConnection(); return ipcClient;
}
return &ipcClient;
} }
QSharedPointer<IpcInterfaceReplica> IpcClient::Interface() QSharedPointer<IpcInterfaceReplica> IpcClient::Interface()
{ {
QSharedPointer<IpcInterfaceReplica> rep = Instance()->m_ipcClient; QSharedPointer<IpcInterfaceReplica> rep = Instance().m_interface;
if (rep.isNull()) { if (rep.isNull()) {
qCritical() << "IpcClient::Interface(): Failed to acquire replica"; qCritical() << "IpcClient::Interface(): Failed to acquire replica";
return nullptr; return nullptr;
@@ -54,7 +35,7 @@ QSharedPointer<IpcInterfaceReplica> IpcClient::Interface()
QSharedPointer<IpcProcessTun2SocksReplica> IpcClient::InterfaceTun2Socks() QSharedPointer<IpcProcessTun2SocksReplica> IpcClient::InterfaceTun2Socks()
{ {
QSharedPointer<IpcProcessTun2SocksReplica> rep = Instance()->m_Tun2SocksClient; QSharedPointer<IpcProcessTun2SocksReplica> rep = Instance().m_tun2socks;
if (rep.isNull()) { if (rep.isNull()) {
qCritical() << "IpcClient::InterfaceTun2Socks: Replica is undefined"; qCritical() << "IpcClient::InterfaceTun2Socks: Replica is undefined";
return nullptr; return nullptr;
@@ -69,12 +50,6 @@ QSharedPointer<IpcProcessTun2SocksReplica> IpcClient::InterfaceTun2Socks()
return rep; return rep;
} }
bool IpcClient::establishConnection()
{
m_localSocket.connectToServer(amnezia::getIpcServiceUrl());
return m_localSocket.waitForConnected();
}
QSharedPointer<PrivilegedProcess> IpcClient::CreatePrivilegedProcess() QSharedPointer<PrivilegedProcess> IpcClient::CreatePrivilegedProcess()
{ {
QSharedPointer<IpcInterfaceReplica> rep = Interface(); QSharedPointer<IpcInterfaceReplica> rep = Interface();
+8 -16
View File
@@ -15,7 +15,7 @@ class IpcClient : public QObject
public: public:
explicit IpcClient(QObject *parent = nullptr); explicit IpcClient(QObject *parent = nullptr);
static IpcClient *Instance(); static IpcClient& Instance();
static QSharedPointer<IpcInterfaceReplica> Interface(); static QSharedPointer<IpcInterfaceReplica> Interface();
static QSharedPointer<IpcProcessTun2SocksReplica> InterfaceTun2Socks(); static QSharedPointer<IpcProcessTun2SocksReplica> InterfaceTun2Socks();
@@ -24,10 +24,10 @@ public:
template <typename Func> template <typename Func>
static auto withInterface(Func func) static auto withInterface(Func func)
{ {
QSharedPointer<IpcInterfaceReplica> iface = Instance()->m_ipcClient; QSharedPointer<IpcInterfaceReplica> iface = Instance().m_interface;
using ReturnType = decltype(func(std::declval<QSharedPointer<IpcInterfaceReplica>>())); using ReturnType = decltype(func(std::declval<QSharedPointer<IpcInterfaceReplica>>()));
if (iface.isNull() || !iface->isReplicaValid()) { if (iface.isNull() || !iface->waitForSource(1000) || !iface->isReplicaValid()) {
qWarning() << "IpcClient::withInterface(): Service is not running"; qWarning() << "IpcClient::withInterface(): Service is not running";
if constexpr (std::is_void_v<ReturnType>) if constexpr (std::is_void_v<ReturnType>)
@@ -42,25 +42,19 @@ public:
template <typename OnSuccess, typename OnFailure> template <typename OnSuccess, typename OnFailure>
static auto withInterface(OnSuccess onSuccess, OnFailure onFailure) static auto withInterface(OnSuccess onSuccess, OnFailure onFailure)
{ {
QSharedPointer<IpcInterfaceReplica> iface = Instance()->m_ipcClient; QSharedPointer<IpcInterfaceReplica> iface = Instance().m_interface;
if (iface.isNull() || !iface->waitForSource(1000) || !iface->isReplicaValid()) {
if (iface.isNull() || !iface->isReplicaValid()) {
return onFailure(); return onFailure();
} }
return onSuccess(iface); return onSuccess(iface);
} }
bool isSocketConnected() const;
signals: signals:
private: private:
bool establishConnection(); QRemoteObjectNode m_node;
QSharedPointer<IpcInterfaceReplica> m_interface;
QLocalSocket m_localSocket; QSharedPointer<IpcProcessTun2SocksReplica> m_tun2socks;
QSharedPointer<QRemoteObjectNode> m_ClientNode;
QSharedPointer<IpcInterfaceReplica> m_ipcClient;
QSharedPointer<IpcProcessTun2SocksReplica> m_Tun2SocksClient;
struct ProcessDescriptor { struct ProcessDescriptor {
ProcessDescriptor () { ProcessDescriptor () {
@@ -72,8 +66,6 @@ private:
QSharedPointer<QRemoteObjectNode> replicaNode; QSharedPointer<QRemoteObjectNode> replicaNode;
QSharedPointer<QLocalSocket> localSocket; QSharedPointer<QLocalSocket> localSocket;
}; };
bool m_isSocketConnected {false};
}; };
#endif // IPCCLIENT_H #endif // IPCCLIENT_H