VPN connection routine fixed

This commit is contained in:
pokamest 2021-11-19 19:02:39 +03:00
parent a9165aba25
commit 2773d7598b
14 changed files with 131 additions and 52 deletions

View file

@ -30,6 +30,7 @@ HEADERS += \
core/errorstrings.h \
core/ipcclient.h \
configurators/openvpn_configurator.h \
core/privileged_process.h \
core/scripts_registry.h \
core/server_defs.h \
core/servercontroller.h \
@ -80,6 +81,7 @@ SOURCES += \
core/errorstrings.cpp \
core/ipcclient.cpp \
configurators/openvpn_configurator.cpp \
core/privileged_process.cpp \
core/scripts_registry.cpp \
core/server_defs.cpp \
core/servercontroller.cpp \

View file

@ -63,7 +63,7 @@ bool IpcClient::init(IpcClient *instance)
return Instance()->m_ipcClient->isReplicaValid();
}
QSharedPointer<IpcProcessInterfaceReplica> IpcClient::CreatePrivilegedProcess()
QSharedPointer<PrivilegedProcess> IpcClient::CreatePrivilegedProcess()
{
#ifndef Q_OS_IOS
if (! Instance()->m_ipcClient || ! Instance()->m_ipcClient->isReplicaValid()) {
@ -84,17 +84,19 @@ QSharedPointer<IpcProcessInterfaceReplica> IpcClient::CreatePrivilegedProcess()
connect(pd->localSocket.data(), &QLocalSocket::connected, pd->replicaNode.data(), [pd]() {
pd->replicaNode->addClientSideConnection(pd->localSocket.data());
pd->ipcProcess.reset(pd->replicaNode->acquire<IpcProcessInterfaceReplica>());
IpcProcessInterfaceReplica *repl = pd->replicaNode->acquire<IpcProcessInterfaceReplica>();
PrivilegedProcess *priv = static_cast<PrivilegedProcess *>(repl);
pd->ipcProcess.reset(priv);
if (!pd->ipcProcess) {
qWarning() << "Acquire IpcProcessInterfaceReplica failed";
qWarning() << "Acquire PrivilegedProcess failed";
}
else {
pd->ipcProcess->waitForSource(1000);
if (!pd->ipcProcess->isReplicaValid()) {
qWarning() << "IpcProcessInterfaceReplica replica is not connected!";
qWarning() << "PrivilegedProcess replica is not connected!";
}
QObject::connect(pd->ipcProcess.data(), &IpcProcessInterfaceReplica::destroyed, pd->ipcProcess.data(), [pd](){
QObject::connect(pd->ipcProcess.data(), &PrivilegedProcess::destroyed, pd->ipcProcess.data(), [pd](){
pd->replicaNode->deleteLater();
});
}
@ -103,10 +105,10 @@ QSharedPointer<IpcProcessInterfaceReplica> IpcClient::CreatePrivilegedProcess()
pd->localSocket->connectToServer(amnezia::getIpcProcessUrl(pid));
pd->localSocket->waitForConnected();
auto proccessReplica = QSharedPointer<IpcProcessInterfaceReplica>(pd->ipcProcess);
auto proccessReplica = QSharedPointer<PrivilegedProcess>(pd->ipcProcess);
return proccessReplica;
#else
return QSharedPointer<IpcProcessInterfaceReplica>();
return QSharedPointer<PrivilegedProcess>();
#endif
}

View file

@ -7,13 +7,7 @@
#include "ipc.h"
#include "rep_ipc_interface_replica.h"
#ifndef Q_OS_IOS
#include "rep_ipc_process_interface_replica.h"
#else
class IpcProcessInterfaceReplica {
};
#endif
#include "privileged_process.h"
class IpcClient : public QObject
{
@ -24,7 +18,7 @@ public:
static IpcClient *Instance();
static bool init(IpcClient *instance);
static QSharedPointer<IpcInterfaceReplica> Interface();
static QSharedPointer<IpcProcessInterfaceReplica> CreatePrivilegedProcess();
static QSharedPointer<PrivilegedProcess> CreatePrivilegedProcess();
bool isSocketConnected() const;
@ -40,10 +34,10 @@ private:
struct ProcessDescriptor {
ProcessDescriptor () {
replicaNode = QSharedPointer<QRemoteObjectNode>(new QRemoteObjectNode());
ipcProcess = QSharedPointer<IpcProcessInterfaceReplica>();
ipcProcess = QSharedPointer<PrivilegedProcess>();
localSocket = QSharedPointer<QLocalSocket>();
}
QSharedPointer<IpcProcessInterfaceReplica> ipcProcess;
QSharedPointer<PrivilegedProcess> ipcProcess;
QSharedPointer<QRemoteObjectNode> replicaNode;
QSharedPointer<QLocalSocket> localSocket;
};

View file

@ -0,0 +1,27 @@
#include "privileged_process.h"
PrivilegedProcess::PrivilegedProcess() :
IpcProcessInterfaceReplica()
{
}
PrivilegedProcess::~PrivilegedProcess()
{
qDebug() << "PrivilegedProcess::~PrivilegedProcess()";
}
void PrivilegedProcess::waitForFinished(int msecs)
{
QSharedPointer<QEventLoop> loop(new QEventLoop);
connect(this, &PrivilegedProcess::finished, this, [this, loop](int exitCode, QProcess::ExitStatus exitStatus) mutable{
loop->quit();
loop.clear();
});
QTimer::singleShot(msecs, this, [this, loop]() mutable {
loop->quit();
loop.clear();
});
loop->exec();
}

View file

@ -0,0 +1,30 @@
#ifndef PRIVILEGED_PROCESS_H
#define PRIVILEGED_PROCESS_H
#include <QObject>
#ifndef Q_OS_IOS
#include "rep_ipc_process_interface_replica.h"
// This class is dangerous - instance of this class casted from base class,
// so it support only functions
// Do not add any members into it
//
class PrivilegedProcess : public IpcProcessInterfaceReplica
{
Q_OBJECT
public:
PrivilegedProcess();
~PrivilegedProcess() override;
void waitForFinished(int msecs);
};
#endif // PRIVILEGED_PROCESS_H
#else // defined Q_OS_IOS
class IpcProcessInterfaceReplica {};
class PrivilegedProcess {};
#endif

View file

@ -278,18 +278,18 @@ ErrorCode Ikev2Protocol::start()
certInstallProcess->setArguments(arguments);
// qDebug() << arguments.join(" ");
// connect(certInstallProcess.data(), &IpcProcessInterfaceReplica::errorOccurred, [certInstallProcess](QProcess::ProcessError error) {
// qDebug() << "IpcProcessInterfaceReplica errorOccurred" << error;
// connect(certInstallProcess.data(), &PrivilegedProcess::errorOccurred, [certInstallProcess](QProcess::ProcessError error) {
// qDebug() << "PrivilegedProcess errorOccurred" << error;
// });
// connect(certInstallProcess.data(), &IpcProcessInterfaceReplica::stateChanged, [certInstallProcess](QProcess::ProcessState newState) {
// qDebug() << "IpcProcessInterfaceReplica stateChanged" << newState;
// connect(certInstallProcess.data(), &PrivilegedProcess::stateChanged, [certInstallProcess](QProcess::ProcessState newState) {
// qDebug() << "PrivilegedProcess stateChanged" << newState;
// });
// connect(certInstallProcess.data(), &IpcProcessInterfaceReplica::readyRead, [certInstallProcess]() {
// connect(certInstallProcess.data(), &PrivilegedProcess::readyRead, [certInstallProcess]() {
// auto req = certInstallProcess->readAll();
// req.waitForFinished();
// qDebug() << "IpcProcessInterfaceReplica readyRead" << req.returnValue();
// qDebug() << "PrivilegedProcess readyRead" << req.returnValue();
// });

View file

@ -192,15 +192,15 @@ ErrorCode OpenVpnProtocol::start()
m_openVpnProcess->setArguments(arguments);
qDebug() << arguments.join(" ");
connect(m_openVpnProcess.data(), &IpcProcessInterfaceReplica::errorOccurred, [&](QProcess::ProcessError error) {
qDebug() << "IpcProcessInterfaceReplica errorOccurred" << error;
connect(m_openVpnProcess.data(), &PrivilegedProcess::errorOccurred, [&](QProcess::ProcessError error) {
qDebug() << "PrivilegedProcess errorOccurred" << error;
});
connect(m_openVpnProcess.data(), &IpcProcessInterfaceReplica::stateChanged, [&](QProcess::ProcessState newState) {
qDebug() << "IpcProcessInterfaceReplica stateChanged" << newState;
connect(m_openVpnProcess.data(), &PrivilegedProcess::stateChanged, [&](QProcess::ProcessState newState) {
qDebug() << "PrivilegedProcess stateChanged" << newState;
});
connect(m_openVpnProcess.data(), &IpcProcessInterfaceReplica::finished, this, [&]() {
connect(m_openVpnProcess.data(), &PrivilegedProcess::finished, this, [&]() {
setConnectionState(ConnectionState::Disconnected);
});

View file

@ -51,7 +51,7 @@ private:
void updateRouteGateway(QString line);
void updateVpnGateway(const QString &line);
QSharedPointer<IpcProcessInterfaceReplica> m_openVpnProcess;
QSharedPointer<PrivilegedProcess> m_openVpnProcess;
};
#endif // OPENVPNPROTOCOL_H

View file

@ -19,13 +19,16 @@ WireguardProtocol::WireguardProtocol(const QJsonObject &configuration, QObject*
WireguardProtocol::~WireguardProtocol()
{
qDebug() << "WireguardProtocol::~WireguardProtocol()";
//qDebug() << "WireguardProtocol::~WireguardProtocol() 1";
WireguardProtocol::stop();
QThread::msleep(200);
//qDebug() << "WireguardProtocol::~WireguardProtocol() 2";
}
void WireguardProtocol::stop()
{
//qDebug() << "WireguardProtocol::stop() 1";
#ifndef Q_OS_IOS
if (!QFileInfo::exists(wireguardExecPath())) {
qCritical() << "Wireguard executable missing!";
@ -56,19 +59,22 @@ void WireguardProtocol::stop()
qDebug() << arguments.join(" ");
connect(m_wireguardStopProcess.data(), &IpcProcessInterfaceReplica::errorOccurred, this, [this](QProcess::ProcessError error) {
qDebug() << "WireguardProtocol::WireguardProtocol errorOccurred" << error;
connect(m_wireguardStopProcess.data(), &PrivilegedProcess::errorOccurred, this, [this](QProcess::ProcessError error) {
qDebug() << "WireguardProtocol::WireguardProtocol Stop errorOccurred" << error;
setConnectionState(ConnectionState::Disconnected);
});
connect(m_wireguardStopProcess.data(), &IpcProcessInterfaceReplica::stateChanged, this, [this](QProcess::ProcessState newState) {
connect(m_wireguardStopProcess.data(), &PrivilegedProcess::stateChanged, this, [this](QProcess::ProcessState newState) {
qDebug() << "WireguardProtocol::WireguardProtocol Stop stateChanged" << newState;
});
m_wireguardStopProcess->start();
m_wireguardStopProcess->waitForFinished(10000);
setConnectionState(VpnProtocol::Disconnected);
#endif
//qDebug() << "WireguardProtocol::stop() 2";
}
void WireguardProtocol::readWireguardConfiguration(const QJsonObject &configuration)
@ -124,13 +130,15 @@ QString WireguardProtocol::wireguardExecPath() const
ErrorCode WireguardProtocol::start()
{
//qDebug() << "WireguardProtocol::start() 1";
#ifndef Q_OS_IOS
if (!m_isConfigLoaded) {
setLastError(ErrorCode::ConfigMissing);
return lastError();
}
//qDebug() << "Start OpenVPN connection";
//qDebug() << "Start Wireguard connection";
WireguardProtocol::stop();
if (!QFileInfo::exists(wireguardExecPath())) {
@ -168,38 +176,41 @@ ErrorCode WireguardProtocol::start()
qDebug() << arguments.join(" ");
connect(m_wireguardStartProcess.data(), &IpcProcessInterfaceReplica::errorOccurred, this, [this](QProcess::ProcessError error) {
connect(m_wireguardStartProcess.data(), &PrivilegedProcess::errorOccurred, this, [this](QProcess::ProcessError error) {
qDebug() << "WireguardProtocol::WireguardProtocol errorOccurred" << error;
setConnectionState(ConnectionState::Disconnected);
});
connect(m_wireguardStartProcess.data(), &IpcProcessInterfaceReplica::stateChanged, this, [this](QProcess::ProcessState newState) {
connect(m_wireguardStartProcess.data(), &PrivilegedProcess::stateChanged, this, [this](QProcess::ProcessState newState) {
qDebug() << "WireguardProtocol::WireguardProtocol stateChanged" << newState;
});
connect(m_wireguardStartProcess.data(), &IpcProcessInterfaceReplica::finished, this, [this]() {
connect(m_wireguardStartProcess.data(), &PrivilegedProcess::finished, this, [this]() {
setConnectionState(ConnectionState::Connected);
});
connect(m_wireguardStartProcess.data(), &IpcProcessInterfaceReplica::readyRead, this, [this]() {
connect(m_wireguardStartProcess.data(), &PrivilegedProcess::readyRead, this, [this]() {
QRemoteObjectPendingReply<QByteArray> reply = m_wireguardStartProcess->readAll();
reply.waitForFinished(1000);
qDebug() << "WireguardProtocol::WireguardProtocol readyRead" << reply.returnValue();
});
connect(m_wireguardStartProcess.data(), &IpcProcessInterfaceReplica::readyReadStandardOutput, this, [this]() {
connect(m_wireguardStartProcess.data(), &PrivilegedProcess::readyReadStandardOutput, this, [this]() {
QRemoteObjectPendingReply<QByteArray> reply = m_wireguardStartProcess->readAllStandardOutput();
reply.waitForFinished(1000);
qDebug() << "WireguardProtocol::WireguardProtocol readAllStandardOutput" << reply.returnValue();
});
connect(m_wireguardStartProcess.data(), &IpcProcessInterfaceReplica::readyReadStandardError, this, [this]() {
connect(m_wireguardStartProcess.data(), &PrivilegedProcess::readyReadStandardError, this, [this]() {
QRemoteObjectPendingReply<QByteArray> reply = m_wireguardStartProcess->readAllStandardError();
reply.waitForFinished(1000);
qDebug() << "WireguardProtocol::WireguardProtocol readAllStandardError" << reply.returnValue();
});
m_wireguardStartProcess->start();
m_wireguardStartProcess->waitForFinished(10000);
//qDebug() << "WireguardProtocol::start() 2";
return ErrorCode::NoError;
#else

View file

@ -36,8 +36,8 @@ private:
QString m_configFileName;
QFile m_configFile;
QSharedPointer<IpcProcessInterfaceReplica> m_wireguardStartProcess;
QSharedPointer<IpcProcessInterfaceReplica> m_wireguardStopProcess;
QSharedPointer<PrivilegedProcess> m_wireguardStartProcess;
QSharedPointer<PrivilegedProcess> m_wireguardStopProcess;
bool m_isConfigLoaded = false;

View file

@ -81,6 +81,8 @@ void VpnLogic::onConnectionStateChanged(VpnProtocol::ConnectionState state)
qDebug() << "VpnLogic::onConnectionStateChanged" << VpnProtocol::textConnectionState(state);
bool pbConnectEnabled = false;
bool pbConnectChecked = false;
bool rbModeEnabled = false;
bool pbConnectVisible = false;
set_labelStateText(VpnProtocol::textConnectionState(state));
@ -90,49 +92,57 @@ void VpnLogic::onConnectionStateChanged(VpnProtocol::ConnectionState state)
switch (state) {
case VpnProtocol::Disconnected:
onBytesChanged(0,0);
set_pushButtonConnectChecked(false);
pbConnectChecked = false;
pbConnectEnabled = true;
pbConnectVisible = true;
rbModeEnabled = true;
break;
case VpnProtocol::Preparing:
pbConnectChecked = true;
pbConnectEnabled = false;
pbConnectVisible = false;
rbModeEnabled = false;
break;
case VpnProtocol::Connecting:
pbConnectChecked = true;
pbConnectEnabled = false;
pbConnectVisible = false;
rbModeEnabled = false;
break;
case VpnProtocol::Connected:
pbConnectChecked = true;
pbConnectEnabled = true;
pbConnectVisible = true;
rbModeEnabled = false;
break;
case VpnProtocol::Disconnecting:
pbConnectChecked = false;
pbConnectEnabled = false;
pbConnectVisible = false;
rbModeEnabled = false;
break;
case VpnProtocol::Reconnecting:
pbConnectChecked = true;
pbConnectEnabled = true;
pbConnectVisible = false;
rbModeEnabled = false;
break;
case VpnProtocol::Error:
set_pushButtonConnectEnabled(false);
pbConnectChecked = false;
pbConnectEnabled = true;
pbConnectVisible = true;
rbModeEnabled = true;
break;
case VpnProtocol::Unknown:
pbConnectChecked = false;
pbConnectEnabled = true;
pbConnectVisible = true;
rbModeEnabled = true;
}
set_pushButtonConnectEnabled(pbConnectEnabled);
set_pushButtonConnectChecked(pbConnectChecked);
set_pushButtonConnectVisible(pbConnectVisible);
set_widgetVpnModeEnabled(rbModeEnabled);
}
@ -142,9 +152,9 @@ void VpnLogic::onVpnProtocolError(ErrorCode errorCode)
set_labelErrorText(errorString(errorCode));
}
void VpnLogic::onPushButtonConnectClicked(bool checked)
void VpnLogic::onPushButtonConnectClicked()
{
if (checked) {
if (! pushButtonConnectChecked()) {
onConnect();
} else {
onDisconnect();

View file

@ -33,7 +33,7 @@ public:
Q_INVOKABLE void onRadioButtonVpnModeForwardSitesClicked();
Q_INVOKABLE void onRadioButtonVpnModeExceptSitesClicked();
Q_INVOKABLE void onPushButtonConnectClicked(bool checked);
Q_INVOKABLE void onPushButtonConnectClicked();
public:
explicit VpnLogic(UiLogic *uiLogic, QObject *parent = nullptr);

View file

@ -53,10 +53,7 @@ PageBase {
height: width
checkable: true
checked: VpnLogic.pushButtonConnectChecked
onCheckedChanged: {
VpnLogic.pushButtonConnectChecked = checked
VpnLogic.onPushButtonConnectClicked(checked)
}
onClicked: VpnLogic.onPushButtonConnectClicked()
background: Image {
anchors.fill: parent
source: button_connect.checked ? "qrc:/images/connected.png"

View file

@ -28,7 +28,9 @@ VpnConnection::VpnConnection(QObject* parent) : QObject(parent)
VpnConnection::~VpnConnection()
{
//qDebug() << "VpnConnection::~VpnConnection() 1";
m_vpnProtocol.clear();
//qDebug() << "VpnConnection::~VpnConnection() 2";
}
void VpnConnection::onBytesChanged(quint64 receivedBytes, quint64 sentBytes)
@ -231,8 +233,11 @@ void VpnConnection::connectToVpn(int serverIndex,
if (m_vpnProtocol) {
disconnect(m_vpnProtocol.data(), &VpnProtocol::protocolError, this, &VpnConnection::vpnProtocolError);
//qDebug() << "VpnConnection::connectToVpn 1";
m_vpnProtocol->stop();
//qDebug() << "VpnConnection::connectToVpn 2";
m_vpnProtocol.reset();
//qDebug() << "VpnConnection::connectToVpn 3";
}
ErrorCode e = ErrorCode::NoError;
@ -281,7 +286,7 @@ QString VpnConnection::bytesPerSecToText(quint64 bytes)
void VpnConnection::disconnectFromVpn()
{
qDebug() << "Disconnect from VPN";
// qDebug() << "Disconnect from VPN 1";
if (IpcClient::Interface()) {
IpcClient::Interface()->flushDns();
@ -295,6 +300,7 @@ void VpnConnection::disconnectFromVpn()
return;
}
m_vpnProtocol.data()->stop();
// qDebug() << "Disconnect from VPN 2";
}
VpnProtocol::ConnectionState VpnConnection::connectionState()