diff --git a/client/core/ipcclient.cpp b/client/core/ipcclient.cpp index 1450539d..a9bc1c67 100644 --- a/client/core/ipcclient.cpp +++ b/client/core/ipcclient.cpp @@ -9,29 +9,69 @@ IpcClient &IpcClient::Instance() QSharedPointer IpcClient::createPrivilegedProcess() { - if (! Instance().m_ipcClient->isReplicaValid()) return nullptr; + if (! Instance().m_ipcClient || ! Instance().m_ipcClient->isReplicaValid()) { + qWarning() << "IpcClient::createPrivilegedProcess : IpcClient IpcClient replica is not valid"; + return nullptr; + } QRemoteObjectPendingReply futureResult = Instance().m_ipcClient->createPrivilegedProcess(); futureResult.waitForFinished(1000); int pid = futureResult.returnValue(); - QSharedPointer replica(new QRemoteObjectNode); + QSharedPointer replicaNode(new QRemoteObjectNode); //Instance().m_processNodes.insert(pid, replica); - replica->connectToNode(QUrl(amnezia::getIpcProcessUrl(pid))); - auto ptr = QSharedPointer(replica->acquire()); - connect(ptr.data(), &IpcProcessInterfaceReplica::destroyed, replica.data(), [replica](){ - replica->deleteLater(); + + QSharedPointer socket(new QLocalSocket(replicaNode.data())); + QSharedPointer ptr; + + connect(socket.data(), &QLocalSocket::connected, replicaNode.data(), [socket, replicaNode, &ptr]() { + replicaNode->addClientSideConnection(socket.data()); + + ptr.reset(replicaNode->acquire()); + + ptr->waitForSource(1000); + + if (!ptr->isReplicaValid()) { + qWarning() << "IpcProcessInterfaceReplica replica is not connected!"; + } + + }); + socket->connectToServer(amnezia::getIpcProcessUrl(pid)); + socket->waitForConnected(); + + auto proccessReplica = QSharedPointer(ptr); + + + +// replica->connectToNode(QUrl(amnezia::getIpcProcessUrl(pid))); +// auto ptr = QSharedPointer(replica->acquire()); + connect(proccessReplica.data(), &IpcProcessInterfaceReplica::destroyed, proccessReplica.data(), [replicaNode](){ + replicaNode->deleteLater(); }); - return ptr; + return proccessReplica; } IpcClient::IpcClient(QObject *parent) : QObject(parent) { - m_ClientNode.connectToNode(QUrl(QStringLiteral(IPC_SERVICE_URL))); - m_ipcClient.reset(m_ClientNode.acquire()); - m_ipcClient->waitForSource(1000); +// m_ClientNode.connectToNode(QUrl(amnezia::getIpcServiceUrl())); +// qDebug() << QUrl(amnezia::getIpcServiceUrl()); + + + m_localSocket.reset(new QLocalSocket(this)); + connect(m_localSocket.data(), &QLocalSocket::connected, &m_ClientNode, [this]() { + m_ClientNode.addClientSideConnection(m_localSocket.data()); + + m_ipcClient.reset(m_ClientNode.acquire()); + m_ipcClient->waitForSource(1000); + + if (!m_ipcClient->isReplicaValid()) { + qWarning() << "IpcClient replica is not connected!"; + } + + }); + m_localSocket->connectToServer(amnezia::getIpcServiceUrl()); diff --git a/client/core/ipcclient.h b/client/core/ipcclient.h index 67ad45ec..e4b38fa3 100644 --- a/client/core/ipcclient.h +++ b/client/core/ipcclient.h @@ -1,6 +1,7 @@ #ifndef IPCCLIENT_H #define IPCCLIENT_H +#include #include #include "ipc.h" @@ -11,11 +12,11 @@ class IpcClient : public QObject Q_OBJECT public: static IpcClient &Instance(); + static bool init() { return Instance().m_ipcClient->isReplicaValid(); } + static QSharedPointer ipcClient() { return Instance().m_ipcClient; } static QSharedPointer createPrivilegedProcess(); - static QSharedPointer ipcClient() { return Instance().m_ipcClient; } - signals: private: @@ -23,6 +24,7 @@ private: QRemoteObjectNode m_ClientNode; // create remote object node QSharedPointer m_ipcClient; + QSharedPointer m_localSocket; //QMap> m_processNodes; }; diff --git a/client/protocols/openvpnprotocol.cpp b/client/protocols/openvpnprotocol.cpp index af55d6d2..57a95e5a 100644 --- a/client/protocols/openvpnprotocol.cpp +++ b/client/protocols/openvpnprotocol.cpp @@ -4,7 +4,7 @@ #include #include -#include "communicator.h" +//#include "communicator.h" #include "debug.h" #include "openvpnprotocol.h" #include "utils.h" @@ -166,29 +166,36 @@ ErrorCode OpenVpnProtocol::start() setConnectionState(ConnectionState::Connecting); - QSharedPointer process = IpcClient::createPrivilegedProcess(); - process->waitForSource(1000); - if (!process->isInitialized()) { + m_openVpnProcess = IpcClient::createPrivilegedProcess(); + + if (!m_openVpnProcess) { + qWarning() << "IpcProcess replica is not created!"; return ErrorCode::AmneziaServiceConnectionFailed; } - process->setProgram(openVpnExecPath()); + + m_openVpnProcess->waitForSource(1000); + if (!m_openVpnProcess->isInitialized()) { + qWarning() << "IpcProcess replica is not connected!"; + return ErrorCode::AmneziaServiceConnectionFailed; + } + m_openVpnProcess->setProgram(openVpnExecPath()); QStringList arguments({"--config" , configPath(), "--management", m_managementHost, QString::number(m_managementPort), "--management-client", "--log-append", vpnLogFileNamePath }); - process->setArguments(arguments); + m_openVpnProcess->setArguments(arguments); qDebug() << arguments.join(" "); - connect(process.data(), &IpcProcessInterfaceReplica::errorOccurred, [&](QProcess::ProcessError error) { + connect(m_openVpnProcess.data(), &IpcProcessInterfaceReplica::errorOccurred, [&](QProcess::ProcessError error) { qDebug() << "IpcProcessInterfaceReplica errorOccurred" << error; }); - connect(process.data(), &IpcProcessInterfaceReplica::stateChanged, [&](QProcess::ProcessState newState) { + connect(m_openVpnProcess.data(), &IpcProcessInterfaceReplica::stateChanged, [&](QProcess::ProcessState newState) { qDebug() << "IpcProcessInterfaceReplica stateChanged" << newState; }); - process->start(); + m_openVpnProcess->start(); //m_communicator->sendMessage(Message(Message::State::StartRequest, args)); //startTimeoutTimer(); diff --git a/client/protocols/openvpnprotocol.h b/client/protocols/openvpnprotocol.h index 19b9735a..701e1a6b 100644 --- a/client/protocols/openvpnprotocol.h +++ b/client/protocols/openvpnprotocol.h @@ -53,6 +53,8 @@ protected: private: void updateRouteGateway(QString line); void updateVpnGateway(); + + QSharedPointer m_openVpnProcess; }; #endif // OPENVPNPROTOCOL_H diff --git a/client/protocols/shadowsocksvpnprotocol.cpp b/client/protocols/shadowsocksvpnprotocol.cpp index 80b164a1..ab19f875 100644 --- a/client/protocols/shadowsocksvpnprotocol.cpp +++ b/client/protocols/shadowsocksvpnprotocol.cpp @@ -1,7 +1,7 @@ #include "shadowsocksvpnprotocol.h" #include "core/servercontroller.h" -#include "communicator.h" +//#include "communicator.h" #include "debug.h" #include "utils.h" diff --git a/client/protocols/vpnprotocol.cpp b/client/protocols/vpnprotocol.cpp index 545e4291..b0765c6d 100644 --- a/client/protocols/vpnprotocol.cpp +++ b/client/protocols/vpnprotocol.cpp @@ -1,7 +1,7 @@ #include #include -#include "communicator.h" +//#include "communicator.h" #include "vpnprotocol.h" #include "core/errorstrings.h" diff --git a/client/ui/mainwindow.cpp b/client/ui/mainwindow.cpp index ad6a6be7..92e35b6d 100644 --- a/client/ui/mainwindow.cpp +++ b/client/ui/mainwindow.cpp @@ -11,7 +11,7 @@ #include #include -#include "communicator.h" +//#include "communicator.h" #include "core/errorstrings.h" #include "core/openvpnconfigurator.h" diff --git a/client/vpnconnection.cpp b/client/vpnconnection.cpp index 937720f3..081d35ed 100644 --- a/client/vpnconnection.cpp +++ b/client/vpnconnection.cpp @@ -10,10 +10,16 @@ #include "protocols/shadowsocksvpnprotocol.h" #include "utils.h" #include "vpnconnection.h" -#include "communicator.h" +//#include "communicator.h" VpnConnection::VpnConnection(QObject* parent) : QObject(parent) { + QTimer::singleShot(0, [](){ + if (!IpcClient::init()) { + qWarning() << "Error occured when init IPC client"; + } + }); + //VpnProtocol::initializeCommunicator(parent); } diff --git a/client/vpnconnection.h b/client/vpnconnection.h index a257103f..7ffddc57 100644 --- a/client/vpnconnection.h +++ b/client/vpnconnection.h @@ -8,6 +8,7 @@ #include "protocols/vpnprotocol.h" #include "core/defs.h" +#include "core/ipcclient.h" #include "settings.h" using namespace amnezia; diff --git a/ipc/ipc.h b/ipc/ipc.h index d17bee13..d78a450b 100644 --- a/ipc/ipc.h +++ b/ipc/ipc.h @@ -1,12 +1,30 @@ #ifndef IPC_H #define IPC_H +#include #include #define IPC_SERVICE_URL "local:AmneziaVpnIpcInterface" namespace amnezia { -inline QString getIpcProcessUrl(int pid) { return QString("%1_%2").arg(IPC_SERVICE_URL).arg(pid); } + +inline QString getIpcServiceUrl() { +#ifdef Q_OS_WIN + return IPC_SERVICE_URL; +#else + return QString("/tmp/%1").arg(IPC_SERVICE_URL); +#endif } +inline QString getIpcProcessUrl(int pid) { +#ifdef Q_OS_WIN + return QString("%1_%2").arg(IPC_SERVICE_URL).arg(pid); +#else + return QString("/tmp/%1_%2").arg(IPC_SERVICE_URL).arg(pid); +#endif +} + + +} // namespace amnezia + #endif // IPC_H diff --git a/ipc/ipcserver.cpp b/ipc/ipcserver.cpp index 5095171b..4cb958b1 100644 --- a/ipc/ipcserver.cpp +++ b/ipc/ipcserver.cpp @@ -1,6 +1,7 @@ #include "ipcserver.h" #include +#include IpcServer::IpcServer(QObject *parent): IpcInterfaceSource(parent) @@ -11,8 +12,35 @@ int IpcServer::createPrivilegedProcess() m_localpid++; ProcessDescriptor pd; - pd.serverNode->setHostUrl(QUrl(amnezia::getIpcProcessUrl(m_localpid))); - pd.serverNode->enableRemoting(pd.ipcProcess.data()); +// pd.serverNode->setHostUrl(QUrl(amnezia::getIpcProcessUrl(m_localpid))); +// pd.serverNode->enableRemoting(pd.ipcProcess.data()); + + + + pd.localServer = QSharedPointer(new QLocalServer(this)); + pd.localServer->setSocketOptions(QLocalServer::WorldAccessOption); + + if (!pd.localServer->listen(amnezia::getIpcProcessUrl(m_localpid))) { + qDebug() << QString("Unable to start the server: %1.").arg(pd.localServer->errorString()); + return -1; + } + +// connect(m_server.data(), &QLocalServer::newConnection, this, &LocalServer::onNewConnection); + +// qDebug().noquote() << QString("Local server started on '%1'").arg(m_server->serverName()); + +// m_serverNode.setHostUrl(QUrl(QStringLiteral(IPC_SERVICE_URL))); // create host node without Registry + + + + // Make sure any connections are handed to QtRO + QObject::connect(pd.localServer.data(), &QLocalServer::newConnection, this, [pd]() { + qDebug() << "LocalServer new connection"; + if (pd.serverNode) { + pd.serverNode->addHostSideConnection(pd.localServer->nextPendingConnection()); + pd.serverNode->enableRemoting(pd.ipcProcess.data()); + } + }); m_processes.insert(m_localpid, pd); diff --git a/ipc/ipcserver.h b/ipc/ipcserver.h index d77ac8d0..30c3fbe9 100644 --- a/ipc/ipcserver.h +++ b/ipc/ipcserver.h @@ -1,6 +1,7 @@ #ifndef IPCSERVER_H #define IPCSERVER_H +#include #include #include "ipc.h" @@ -21,9 +22,11 @@ private: ProcessDescriptor (QObject *parent = nullptr) { serverNode = QSharedPointer(new QRemoteObjectHost(parent)); ipcProcess = QSharedPointer(new IpcServerProcess(parent)); + localServer = QSharedPointer(new QLocalServer(parent)); } QSharedPointer ipcProcess; QSharedPointer serverNode; + QSharedPointer localServer; }; QMap m_processes; diff --git a/service/server/localserver.cpp b/service/server/localserver.cpp index 644afeec..30e17c6d 100644 --- a/service/server/localserver.cpp +++ b/service/server/localserver.cpp @@ -18,20 +18,33 @@ LocalServer::LocalServer(QObject *parent) : QObject(parent), // m_clientConnected(false), m_ipcServer(this) { -// m_server = QSharedPointer(new QLocalServer(this)); -// m_server->setSocketOptions(QLocalServer::WorldAccessOption); + // Create the server and listen outside of QtRO + m_server = QSharedPointer(new QLocalServer(this)); + m_server->setSocketOptions(QLocalServer::WorldAccessOption); -// if (!m_server->listen(Utils::serverName())) { -// qDebug() << QString("Unable to start the server: %1.").arg(m_server->errorString()); -// return; -// } + if (!m_server->listen(amnezia::getIpcServiceUrl())) { + qDebug() << QString("Unable to start the server: %1.").arg(m_server->errorString()); + return; + } // connect(m_server.data(), &QLocalServer::newConnection, this, &LocalServer::onNewConnection); // qDebug().noquote() << QString("Local server started on '%1'").arg(m_server->serverName()); - m_serverNode.setHostUrl(QUrl(QStringLiteral(IPC_SERVICE_URL))); // create host node without Registry - m_serverNode.enableRemoting(&m_ipcServer); // enable remoting/sharing +// m_serverNode.setHostUrl(QUrl(QStringLiteral(IPC_SERVICE_URL))); // create host node without Registry + + + + // Make sure any connections are handed to QtRO + QObject::connect(m_server.data(), &QLocalServer::newConnection, this, [this]() { + qDebug() << "LocalServer new connection"; + m_serverNode.addHostSideConnection(m_server->nextPendingConnection()); + + if (!m_isRemotingEnabled) { + m_isRemotingEnabled = true; + m_serverNode.enableRemoting(&m_ipcServer); + } + }); } LocalServer::~LocalServer() diff --git a/service/server/localserver.h b/service/server/localserver.h index aabf3e8e..187a2a93 100644 --- a/service/server/localserver.h +++ b/service/server/localserver.h @@ -50,6 +50,7 @@ private: IpcServer m_ipcServer; QRemoteObjectHost m_serverNode; + bool m_isRemotingEnabled = false; }; #endif // LOCALSERVER_H