Qt remote objects IPC
This commit is contained in:
parent
c4df9c004b
commit
048a673d31
18 changed files with 340 additions and 25 deletions
|
@ -1,2 +1,3 @@
|
|||
TEMPLATE = subdirs
|
||||
SUBDIRS = client service platform
|
||||
|
||||
|
|
|
@ -10,9 +10,11 @@ include("3rd/QtSsh/src/ssh/ssh.pri")
|
|||
include("3rd/QtSsh/src/botan/botan.pri")
|
||||
|
||||
HEADERS += \
|
||||
../ipc/ipc.h \
|
||||
communicator.h \
|
||||
core/defs.h \
|
||||
core/errorstrings.h \
|
||||
core/ipcclient.h \
|
||||
core/openvpnconfigurator.h \
|
||||
core/servercontroller.h \
|
||||
debug.h \
|
||||
|
@ -32,6 +34,7 @@ HEADERS += \
|
|||
|
||||
SOURCES += \
|
||||
communicator.cpp \
|
||||
core/ipcclient.cpp \
|
||||
core/openvpnconfigurator.cpp \
|
||||
core/servercontroller.cpp \
|
||||
debug.cpp \
|
||||
|
@ -101,5 +104,5 @@ macx {
|
|||
LIBS += -framework Cocoa -framework ApplicationServices -framework CoreServices -framework Foundation -framework AppKit
|
||||
}
|
||||
|
||||
REPC_REPLICA += ../communicator/communicator.rep
|
||||
REPC_REPLICA += ../ipc/ipcinterface.rep
|
||||
|
||||
|
|
51
client/core/ipcclient.cpp
Normal file
51
client/core/ipcclient.cpp
Normal file
|
@ -0,0 +1,51 @@
|
|||
#include "ipcclient.h"
|
||||
#include <QRemoteObjectNode>
|
||||
|
||||
IpcClient &IpcClient::Instance()
|
||||
{
|
||||
static IpcClient s;
|
||||
return s;
|
||||
}
|
||||
|
||||
QSharedPointer<IpcProcessInterfaceReplica> IpcClient::createPrivilegedProcess()
|
||||
{
|
||||
if (! Instance().m_ipcClient->isReplicaValid()) return nullptr;
|
||||
|
||||
QRemoteObjectPendingReply<int> futureResult = Instance().m_ipcClient->createPrivilegedProcess();
|
||||
futureResult.waitForFinished(1000);
|
||||
|
||||
int pid = futureResult.returnValue();
|
||||
QSharedPointer<QRemoteObjectNode> replica(new QRemoteObjectNode);
|
||||
//Instance().m_processNodes.insert(pid, replica);
|
||||
|
||||
replica->connectToNode(QUrl(amnezia::getIpcProcessUrl(pid)));
|
||||
auto ptr = QSharedPointer<IpcProcessInterfaceReplica>(replica->acquire<IpcProcessInterfaceReplica>());
|
||||
connect(ptr.data(), &IpcProcessInterfaceReplica::destroyed, replica.data(), [replica](){
|
||||
replica->deleteLater();
|
||||
});
|
||||
|
||||
return ptr;
|
||||
}
|
||||
|
||||
IpcClient::IpcClient(QObject *parent) : QObject(parent)
|
||||
{
|
||||
m_ClientNode.connectToNode(QUrl(QStringLiteral(IPC_SERVICE_URL)));
|
||||
m_ipcClient.reset(m_ClientNode.acquire<IpcInterfaceReplica>());
|
||||
m_ipcClient->waitForSource(1000);
|
||||
|
||||
|
||||
|
||||
// connect(m_ipcClient.data(), &IpcInterfaceReplica::stateChanged, [&](QRemoteObjectReplica::State state, QRemoteObjectReplica::State oldState){
|
||||
|
||||
//// qDebug() << "state" << state;
|
||||
//// for (int i = 0; i < 10; ++i) {
|
||||
//// QRemoteObjectPendingReply<qint64> future = m_ipcClient->createPrivilegedProcess("", QStringList());
|
||||
|
||||
//// future.waitForFinished();
|
||||
//// qDebug() << "QRemoteObjectPendingReply" << QDateTime::currentMSecsSinceEpoch() - future.returnValue();
|
||||
|
||||
//// }
|
||||
// });
|
||||
|
||||
|
||||
}
|
30
client/core/ipcclient.h
Normal file
30
client/core/ipcclient.h
Normal file
|
@ -0,0 +1,30 @@
|
|||
#ifndef IPCCLIENT_H
|
||||
#define IPCCLIENT_H
|
||||
|
||||
#include <QObject>
|
||||
|
||||
#include "ipc.h"
|
||||
#include "rep_ipcinterface_replica.h"
|
||||
|
||||
class IpcClient : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
static IpcClient &Instance();
|
||||
|
||||
static QSharedPointer<IpcProcessInterfaceReplica> createPrivilegedProcess();
|
||||
|
||||
static QSharedPointer<IpcInterfaceReplica> ipcClient() { return Instance().m_ipcClient; }
|
||||
|
||||
signals:
|
||||
|
||||
private:
|
||||
explicit IpcClient(QObject *parent = nullptr);
|
||||
|
||||
QRemoteObjectNode m_ClientNode; // create remote object node
|
||||
QSharedPointer<IpcInterfaceReplica> m_ipcClient;
|
||||
|
||||
//QMap<int, QSharedPointer<QRemoteObjectNode>> m_processNodes;
|
||||
};
|
||||
|
||||
#endif // IPCCLIENT_H
|
|
@ -11,8 +11,8 @@
|
|||
|
||||
|
||||
OpenVpnProtocol::OpenVpnProtocol(const QString& args, QObject* parent) :
|
||||
VpnProtocol(args, parent),
|
||||
m_requestFromUserToStop(false)
|
||||
VpnProtocol(args, parent)
|
||||
//m_requestFromUserToStop(false)
|
||||
{
|
||||
setConfigFile(args);
|
||||
connect(m_communicator, &Communicator::messageReceived, this, &OpenVpnProtocol::onMessageReceived);
|
||||
|
@ -130,14 +130,14 @@ ErrorCode OpenVpnProtocol::start()
|
|||
{
|
||||
qDebug() << "Start OpenVPN connection";
|
||||
|
||||
m_requestFromUserToStop = false;
|
||||
//m_requestFromUserToStop = false;
|
||||
m_openVpnStateSigTermHandlerTimer.stop();
|
||||
OpenVpnProtocol::stop();
|
||||
|
||||
if (communicator() && !communicator()->isConnected()) {
|
||||
setLastError(ErrorCode::AmneziaServiceConnectionFailed);
|
||||
return lastError();
|
||||
}
|
||||
// if (communicator() && !communicator()->isConnected()) {
|
||||
// setLastError(ErrorCode::AmneziaServiceConnectionFailed);
|
||||
// return lastError();
|
||||
// }
|
||||
|
||||
if (!QFileInfo::exists(openVpnExecPath())) {
|
||||
setLastError(ErrorCode::OpenVpnExecutableMissing);
|
||||
|
@ -165,7 +165,20 @@ ErrorCode OpenVpnProtocol::start()
|
|||
}
|
||||
|
||||
setConnectionState(ConnectionState::Connecting);
|
||||
m_communicator->sendMessage(Message(Message::State::StartRequest, args));
|
||||
|
||||
QSharedPointer<IpcProcessInterfaceReplica> process = IpcClient::createPrivilegedProcess();
|
||||
process->waitForSource(1000);
|
||||
if (!process->isInitialized()) {
|
||||
return ErrorCode::AmneziaServiceConnectionFailed;
|
||||
}
|
||||
process->setProgram(openVpnExecPath());
|
||||
process->setArguments(QStringList() << "--config" << configPath()<<
|
||||
"--management"<< m_managementHost<< QString::number(m_managementPort)<<
|
||||
"--management-client"<<
|
||||
"--log-append"<< vpnLogFileNamePath);
|
||||
process->start();
|
||||
|
||||
//m_communicator->sendMessage(Message(Message::State::StartRequest, args));
|
||||
startTimeoutTimer();
|
||||
|
||||
return ErrorCode::NoError;
|
||||
|
|
|
@ -9,6 +9,8 @@
|
|||
#include "message.h"
|
||||
#include "vpnprotocol.h"
|
||||
|
||||
#include "core/ipcclient.h"
|
||||
|
||||
class OpenVpnProtocol : public VpnProtocol
|
||||
{
|
||||
Q_OBJECT
|
||||
|
@ -45,7 +47,7 @@ protected:
|
|||
ManagementServer m_managementServer;
|
||||
QString m_configFileName;
|
||||
QTimer m_openVpnStateSigTermHandlerTimer;
|
||||
bool m_requestFromUserToStop;
|
||||
//bool m_requestFromUserToStop;
|
||||
|
||||
|
||||
private:
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
#include <core/openvpnconfigurator.h>
|
||||
#include <core/servercontroller.h>
|
||||
|
||||
#include "ipc.h"
|
||||
#include "protocols/openvpnprotocol.h"
|
||||
#include "protocols/shadowsocksvpnprotocol.h"
|
||||
#include "utils.h"
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
#include <QObject>
|
||||
#include <QString>
|
||||
#include <QScopedPointer>
|
||||
#include <QRemoteObjectNode>
|
||||
|
||||
#include "protocols/vpnprotocol.h"
|
||||
#include "core/defs.h"
|
||||
|
@ -45,6 +46,7 @@ protected:
|
|||
|
||||
private:
|
||||
Settings m_settings;
|
||||
|
||||
};
|
||||
|
||||
#endif // VPNCONNECTION_H
|
||||
|
|
|
@ -1,6 +0,0 @@
|
|||
#include <QtCore>
|
||||
class RpcServer
|
||||
{
|
||||
SLOT(executeProcess(const QString &program, const QStringList &args));
|
||||
SIGNAL(sendMessage(const QByteArray &message));
|
||||
};
|
12
ipc/ipc.h
Normal file
12
ipc/ipc.h
Normal file
|
@ -0,0 +1,12 @@
|
|||
#ifndef IPC_H
|
||||
#define IPC_H
|
||||
|
||||
#include <QString>
|
||||
|
||||
#define IPC_SERVICE_URL "local:AmneziaVpnIpcInterface"
|
||||
|
||||
namespace amnezia {
|
||||
inline QString getIpcProcessUrl(int pid) { return QString("%1_%2").arg(IPC_SERVICE_URL).arg(pid); }
|
||||
}
|
||||
|
||||
#endif // IPC_H
|
32
ipc/ipcinterface.rep
Normal file
32
ipc/ipcinterface.rep
Normal file
|
@ -0,0 +1,32 @@
|
|||
#include <QtCore>
|
||||
|
||||
class IpcInterface
|
||||
{
|
||||
SLOT( int createPrivilegedProcess() ); // return local pid
|
||||
//SIGNAL(sendMessage(const QByteArray &message));
|
||||
};
|
||||
|
||||
class IpcProcessInterface
|
||||
{
|
||||
SLOT( start(const QString &program, const QStringList &args) );
|
||||
SLOT( start() );
|
||||
SLOT( close() );
|
||||
|
||||
SLOT( setArguments(const QStringList &arguments) );
|
||||
SLOT( setInputChannelMode(QProcess::InputChannelMode mode) );
|
||||
SLOT( setNativeArguments(const QString &arguments) );
|
||||
SLOT( setProcessChannelMode(QProcess::ProcessChannelMode mode) );
|
||||
SLOT( setProgram(const QString &program) );
|
||||
SLOT( setWorkingDirectory(const QString &dir) );
|
||||
|
||||
SLOT( QByteArray readAllStandardError() );
|
||||
SLOT( QByteArray readAllStandardOutput() );
|
||||
|
||||
|
||||
SIGNAL( errorOccurred(QProcess::ProcessError error) );
|
||||
SIGNAL( finished(int exitCode, QProcess::ExitStatus exitStatus) );
|
||||
SIGNAL( readyReadStandardError() );
|
||||
SIGNAL( readyReadStandardOutput() );
|
||||
SIGNAL( started() );
|
||||
SIGNAL( stateChanged(QProcess::ProcessState newState) );
|
||||
};
|
20
ipc/ipcserver.cpp
Normal file
20
ipc/ipcserver.cpp
Normal file
|
@ -0,0 +1,20 @@
|
|||
#include "ipcserver.h"
|
||||
|
||||
#include <QDateTime>
|
||||
|
||||
IpcServer::IpcServer(QObject *parent):
|
||||
IpcInterfaceSource(parent)
|
||||
{}
|
||||
|
||||
int IpcServer::createPrivilegedProcess()
|
||||
{
|
||||
m_localpid++;
|
||||
|
||||
ProcessDescriptor pd;
|
||||
pd.serverNode->setHostUrl(QUrl(amnezia::getIpcProcessUrl(m_localpid)));
|
||||
pd.serverNode->enableRemoting(pd.ipcProcess.data());
|
||||
|
||||
m_processes.insert(m_localpid, pd);
|
||||
|
||||
return m_localpid;
|
||||
}
|
32
ipc/ipcserver.h
Normal file
32
ipc/ipcserver.h
Normal file
|
@ -0,0 +1,32 @@
|
|||
#ifndef IPCSERVER_H
|
||||
#define IPCSERVER_H
|
||||
|
||||
#include <QObject>
|
||||
|
||||
#include "ipc.h"
|
||||
#include "ipcserverprocess.h"
|
||||
|
||||
#include "rep_ipcinterface_source.h"
|
||||
|
||||
class IpcServer : public IpcInterfaceSource
|
||||
{
|
||||
public:
|
||||
explicit IpcServer(QObject *parent = nullptr);
|
||||
virtual int createPrivilegedProcess() override;
|
||||
|
||||
private:
|
||||
int m_localpid = 0;
|
||||
|
||||
struct ProcessDescriptor {
|
||||
ProcessDescriptor (QObject *parent = nullptr) {
|
||||
serverNode = QSharedPointer<QRemoteObjectHost>(new QRemoteObjectHost(parent));
|
||||
ipcProcess = QSharedPointer<IpcServerProcess>(new IpcServerProcess(parent));
|
||||
}
|
||||
QSharedPointer<IpcServerProcess> ipcProcess;
|
||||
QSharedPointer<QRemoteObjectHost> serverNode;
|
||||
};
|
||||
|
||||
QMap<int, ProcessDescriptor> m_processes;
|
||||
};
|
||||
|
||||
#endif // IPCSERVER_H
|
71
ipc/ipcserverprocess.cpp
Normal file
71
ipc/ipcserverprocess.cpp
Normal file
|
@ -0,0 +1,71 @@
|
|||
#include "ipcserverprocess.h"
|
||||
#include <QProcess>
|
||||
|
||||
IpcServerProcess::IpcServerProcess(QObject *parent) :
|
||||
IpcProcessInterfaceSource(parent),
|
||||
m_process(QSharedPointer<QProcess>(new QProcess(this)))
|
||||
{
|
||||
connect(m_process.data(), &QProcess::errorOccurred, this, &IpcServerProcess::errorOccurred);
|
||||
connect(m_process.data(), QOverload<int, QProcess::ExitStatus>::of(&QProcess::finished), this, &IpcServerProcess::finished);
|
||||
connect(m_process.data(), &QProcess::readyReadStandardError, this, &IpcServerProcess::readyReadStandardError);
|
||||
connect(m_process.data(), &QProcess::readyReadStandardOutput, this, &IpcServerProcess::readyReadStandardOutput);
|
||||
connect(m_process.data(), &QProcess::started, this, &IpcServerProcess::started);
|
||||
connect(m_process.data(), &QProcess::stateChanged, this, &IpcServerProcess::stateChanged);
|
||||
}
|
||||
|
||||
void IpcServerProcess::start(const QString &program, const QStringList &args)
|
||||
{
|
||||
m_process->start(program, args);
|
||||
}
|
||||
|
||||
void IpcServerProcess::start()
|
||||
{
|
||||
m_process->start();
|
||||
qDebug() << "IpcServerProcess started, " << m_process->arguments();
|
||||
}
|
||||
|
||||
void IpcServerProcess::close()
|
||||
{
|
||||
m_process->close();
|
||||
}
|
||||
|
||||
void IpcServerProcess::setArguments(const QStringList &arguments)
|
||||
{
|
||||
m_process->setArguments(arguments);
|
||||
qDebug() << "IpcServerProcess started, " << arguments;
|
||||
}
|
||||
|
||||
void IpcServerProcess::setInputChannelMode(QProcess::InputChannelMode mode)
|
||||
{
|
||||
m_process->setInputChannelMode(mode);
|
||||
}
|
||||
|
||||
void IpcServerProcess::setNativeArguments(const QString &arguments)
|
||||
{
|
||||
m_process->setNativeArguments(arguments);
|
||||
}
|
||||
|
||||
void IpcServerProcess::setProcessChannelMode(QProcess::ProcessChannelMode mode)
|
||||
{
|
||||
m_process->setProcessChannelMode(mode);
|
||||
}
|
||||
|
||||
void IpcServerProcess::setProgram(const QString &program)
|
||||
{
|
||||
m_process->setProgram(program);
|
||||
}
|
||||
|
||||
void IpcServerProcess::setWorkingDirectory(const QString &dir)
|
||||
{
|
||||
m_process->setWorkingDirectory(dir);
|
||||
}
|
||||
|
||||
QByteArray IpcServerProcess::readAllStandardError()
|
||||
{
|
||||
return m_process->readAllStandardError();
|
||||
}
|
||||
|
||||
QByteArray IpcServerProcess::readAllStandardOutput()
|
||||
{
|
||||
return m_process->readAllStandardOutput();
|
||||
}
|
34
ipc/ipcserverprocess.h
Normal file
34
ipc/ipcserverprocess.h
Normal file
|
@ -0,0 +1,34 @@
|
|||
#ifndef IPCSERVERPROCESS_H
|
||||
#define IPCSERVERPROCESS_H
|
||||
|
||||
#include <QObject>
|
||||
#include "rep_ipcinterface_source.h"
|
||||
|
||||
|
||||
class IpcServerProcess : public IpcProcessInterfaceSource
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit IpcServerProcess(QObject *parent = nullptr);
|
||||
|
||||
void start(const QString &program, const QStringList &args) override;
|
||||
void start() override;
|
||||
void close() override;
|
||||
|
||||
void setArguments(const QStringList &arguments) override;
|
||||
void setInputChannelMode(QProcess::InputChannelMode mode) override;
|
||||
void setNativeArguments(const QString &arguments) override;
|
||||
void setProcessChannelMode(QProcess::ProcessChannelMode mode) override;
|
||||
void setProgram(const QString &program) override;
|
||||
void setWorkingDirectory(const QString &dir) override;
|
||||
|
||||
QByteArray readAllStandardError() override;
|
||||
QByteArray readAllStandardOutput() override;
|
||||
|
||||
signals:
|
||||
|
||||
private:
|
||||
QSharedPointer<QProcess> m_process;
|
||||
};
|
||||
|
||||
#endif // IPCSERVERPROCESS_H
|
|
@ -3,6 +3,7 @@
|
|||
#include <QLocalServer>
|
||||
#include <QLocalSocket>
|
||||
|
||||
#include "ipc.h"
|
||||
#include "localserver.h"
|
||||
#include "utils.h"
|
||||
|
||||
|
@ -14,19 +15,23 @@
|
|||
|
||||
LocalServer::LocalServer(QObject *parent) : QObject(parent),
|
||||
m_clientConnection(nullptr),
|
||||
m_clientConnected(false)
|
||||
m_clientConnected(false),
|
||||
m_ipcServer(this)
|
||||
{
|
||||
m_server = QSharedPointer<QLocalServer>(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(Utils::serverName())) {
|
||||
// qDebug() << QString("Unable to start the server: %1.").arg(m_server->errorString());
|
||||
// return;
|
||||
// }
|
||||
|
||||
connect(m_server.data(), &QLocalServer::newConnection, this, &LocalServer::onNewConnection);
|
||||
// connect(m_server.data(), &QLocalServer::newConnection, this, &LocalServer::onNewConnection);
|
||||
|
||||
qDebug().noquote() << QString("Local server started on '%1'").arg(m_server->serverName());
|
||||
// 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
|
||||
}
|
||||
|
||||
LocalServer::~LocalServer()
|
||||
|
@ -41,7 +46,8 @@ LocalServer::~LocalServer()
|
|||
|
||||
bool LocalServer::isRunning() const
|
||||
{
|
||||
return m_server->isListening();
|
||||
return true;
|
||||
//return m_server->isListening();
|
||||
}
|
||||
|
||||
void LocalServer::onNewConnection()
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
#include <QVector>
|
||||
|
||||
#include "message.h"
|
||||
#include "ipcserver.h"
|
||||
|
||||
class QLocalServer;
|
||||
class QLocalSocket;
|
||||
|
@ -46,6 +47,9 @@ private:
|
|||
|
||||
QVector<QProcess*> m_processList;
|
||||
bool m_clientConnected;
|
||||
|
||||
IpcServer m_ipcServer;
|
||||
QRemoteObjectHost m_serverNode;
|
||||
};
|
||||
|
||||
#endif // LOCALSERVER_H
|
||||
|
|
|
@ -1,11 +1,14 @@
|
|||
TARGET = AmneziaVPN-service
|
||||
TEMPLATE = app
|
||||
CONFIG += console qt no_batch
|
||||
QT += core network
|
||||
QT += core network remoteobjects
|
||||
|
||||
HEADERS = \
|
||||
../../client/message.h \
|
||||
../../client/utils.h \
|
||||
../../ipc/ipc.h \
|
||||
../../ipc/ipcserver.h \
|
||||
../../ipc/ipcserverprocess.h \
|
||||
localserver.h \
|
||||
log.h \
|
||||
router.h \
|
||||
|
@ -14,6 +17,8 @@ HEADERS = \
|
|||
SOURCES = \
|
||||
../../client/message.cpp \
|
||||
../../client/utils.cpp \
|
||||
../../ipc/ipcserver.cpp \
|
||||
../../ipc/ipcserverprocess.cpp \
|
||||
localserver.cpp \
|
||||
log.cpp \
|
||||
main.cpp \
|
||||
|
@ -47,3 +52,5 @@ include(../src/qtservice.pri)
|
|||
#}
|
||||
|
||||
INCLUDEPATH += "$$PWD/../../client"
|
||||
|
||||
REPC_SOURCE += ../../ipc/ipcinterface.rep
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue