diff --git a/client/core/controllers/gatewayController.cpp b/client/core/controllers/gatewayController.cpp index 175e002cb..9288a1753 100644 --- a/client/core/controllers/gatewayController.cpp +++ b/client/core/controllers/gatewayController.cpp @@ -74,7 +74,11 @@ GatewayController::EncryptedRequestData GatewayController::prepareRequest(const QString host = QUrl(encRequestData.request.url()).host(); QString ip = NetworkUtilities::getIPAddress(host); if (!ip.isEmpty()) { - IpcClient::Interface()->addKillSwitchAllowedRange(QStringList { ip }); + IpcClient::withInterface([&](QSharedPointer iface) { + QRemoteObjectPendingReply reply = iface->addKillSwitchAllowedRange(QStringList { ip }); + if (!reply.waitForFinished(1000) || !reply.returnValue()) + qWarning() << "GatewayController::prepareRequest(): Failed to execute remote addKillSwitchAllowedRange call"; + }); } } #endif diff --git a/client/core/ipcclient.cpp b/client/core/ipcclient.cpp index 7f4774a3d..d9ab13f9b 100644 --- a/client/core/ipcclient.cpp +++ b/client/core/ipcclient.cpp @@ -10,16 +10,16 @@ namespace IpcClient::IpcClient(QObject *parent) : QObject(parent) { - m_localSocket.setServerName(amnezia::getIpcServiceUrl()); - connect(&m_localSocket, &QLocalSocket::connected, this, [this]() { - m_ClientNode.addClientSideConnection(&m_localSocket); - m_ipcClient.reset(m_ClientNode.acquire()); - m_Tun2SocksClient.reset(m_ClientNode.acquire()); + m_ClientNode.reset(new QRemoteObjectNode); + m_ClientNode->addClientSideConnection(&m_localSocket); + m_ipcClient.reset(m_ClientNode->acquire()); + m_Tun2SocksClient.reset(m_ClientNode->acquire()); m_isSocketConnected = true; }); connect(&m_localSocket, &QLocalSocket::disconnected, this, [this]() { + m_ClientNode.clear(); m_ipcClient.clear(); m_Tun2SocksClient.clear(); m_isSocketConnected = false; @@ -71,7 +71,7 @@ QSharedPointer IpcClient::InterfaceTun2Socks() bool IpcClient::establishConnection() { - m_localSocket.connectToServer(); + m_localSocket.connectToServer(amnezia::getIpcServiceUrl()); return m_localSocket.waitForConnected(); } diff --git a/client/core/ipcclient.h b/client/core/ipcclient.h index 2d2541869..f797a3407 100644 --- a/client/core/ipcclient.h +++ b/client/core/ipcclient.h @@ -4,7 +4,6 @@ #include #include -#include "ipc.h" #include "rep_ipc_interface_replica.h" #include "rep_ipc_process_tun2socks_replica.h" @@ -14,21 +13,52 @@ class IpcClient : public QObject { Q_OBJECT public: - explicit IpcClient(QObject *parent = nullptr); + explicit IpcClient(QObject *parent = nullptr); - static IpcClient *Instance(); - static QSharedPointer Interface(); - static QSharedPointer InterfaceTun2Socks(); - static QSharedPointer CreatePrivilegedProcess(); + static IpcClient *Instance(); - bool isSocketConnected() const; + static QSharedPointer Interface(); + static QSharedPointer InterfaceTun2Socks(); + static QSharedPointer CreatePrivilegedProcess(); + + template + static auto withInterface(Func func) + { + QSharedPointer iface = Instance()->m_ipcClient; + using ReturnType = decltype(func(std::declval>())); + + if (iface.isNull() || !iface->isReplicaValid()) { + qWarning() << "IpcClient::withInterface(): Service is not running"; + + if constexpr (std::is_void_v) + return; + else + return ReturnType{}; + } + + return func(iface); + } + + template + static auto withInterface(OnSuccess onSuccess, OnFailure onFailure) + { + QSharedPointer iface = Instance()->m_ipcClient; + + if (iface.isNull() || !iface->isReplicaValid()) { + return onFailure(); + } + + return onSuccess(iface); + } + + bool isSocketConnected() const; signals: private: bool establishConnection(); QLocalSocket m_localSocket; - QRemoteObjectNode m_ClientNode; + QSharedPointer m_ClientNode; QSharedPointer m_ipcClient; QSharedPointer m_Tun2SocksClient; diff --git a/client/protocols/ikev2_vpn_protocol_windows.cpp b/client/protocols/ikev2_vpn_protocol_windows.cpp index 97071f100..030e29cdf 100644 --- a/client/protocols/ikev2_vpn_protocol_windows.cpp +++ b/client/protocols/ikev2_vpn_protocol_windows.cpp @@ -6,6 +6,7 @@ #include +#include "ipc.h" #include "logger.h" #include "ikev2_vpn_protocol_windows.h" #include "utilities.h" diff --git a/client/protocols/openvpnprotocol.cpp b/client/protocols/openvpnprotocol.cpp index 87799a727..b518aac42 100644 --- a/client/protocols/openvpnprotocol.cpp +++ b/client/protocols/openvpnprotocol.cpp @@ -7,7 +7,7 @@ #include #include "core/networkUtilities.h" -#include "logger.h" +#include "ipc.h" #include "openvpnprotocol.h" #include "utilities.h" #include "version.h" @@ -56,8 +56,12 @@ void OpenVpnProtocol::stop() } #if defined(Q_OS_WIN) || defined(Q_OS_LINUX) || defined(Q_OS_MACOS) - QRemoteObjectPendingReply disableKillSwitchResp = IpcClient::Interface()->disableKillSwitch(); - disableKillSwitchResp.waitForFinished(1000); + IpcClient::withInterface([](QSharedPointer iface) { + QRemoteObjectPendingReply reply = iface->disableKillSwitch(); + if (!reply.waitForFinished(1000) && !reply.returnValue()) { + qWarning() << "OpenVpnProtocol::stop(): Failed to disable killswitch"; + } + }); #endif setConnectionState(Vpn::ConnectionState::Disconnected); @@ -65,21 +69,24 @@ void OpenVpnProtocol::stop() ErrorCode OpenVpnProtocol::prepare() { - if (!IpcClient::Interface()) { + return IpcClient::withInterface([](QSharedPointer iface) { + QRemoteObjectPendingReply listReply = iface->getTapList(); + if (!listReply.waitForFinished(1000)) { + return ErrorCode::InternalError; + } + + QStringList list = listReply.returnValue(); + if (list.empty()) { + QRemoteObjectPendingReply installReply = iface->checkAndInstallDriver(); + if (!installReply.waitForFinished() || !installReply.returnValue()) { + return ErrorCode::OpenVpnTapAdapterError; + } + } + + return ErrorCode::NoError; + }, [] () { return ErrorCode::AmneziaServiceConnectionFailed; - } - - QRemoteObjectPendingReply resultCheck = IpcClient::Interface()->getTapList(); - resultCheck.waitForFinished(); - - if (resultCheck.returnValue().isEmpty()) { - QRemoteObjectPendingReply resultInstall = IpcClient::Interface()->checkAndInstallDriver(); - resultInstall.waitForFinished(); - - if (!resultInstall.returnValue()) - return ErrorCode::OpenVpnTapAdapterError; - } - return ErrorCode::NoError; + }); } void OpenVpnProtocol::killOpenVpnProcess() @@ -173,8 +180,17 @@ ErrorCode OpenVpnProtocol::start() } #ifdef AMNEZIA_DESKTOP - IpcClient::Interface()->addKillSwitchAllowedRange(QStringList(NetworkUtilities::getIPAddress( - m_configData.value(amnezia::config_key::hostName).toString()))); + const ErrorCode res = IpcClient::withInterface([&](QSharedPointer iface) { + QString ip = NetworkUtilities::getIPAddress(m_configData.value(amnezia::config_key::hostName).toString()); + QRemoteObjectPendingReply reply = iface->addKillSwitchAllowedRange(QStringList(ip)); + if (!reply.waitForFinished(1000) || !reply.returnValue()) { + return ErrorCode::AmneziaServiceConnectionFailed; + } + return ErrorCode::NoError; + }); + if (res != ErrorCode::NoError) { + return res; + } #endif // Detect default gateway @@ -337,30 +353,37 @@ void OpenVpnProtocol::updateVpnGateway(const QString &line) m_vpnGateway = l.split(" ").at(2); #ifdef Q_OS_WIN QThread::msleep(300); - QList netInterfaces = QNetworkInterface::allInterfaces(); - for (int i = 0; i < netInterfaces.size(); i++) { - for (int j=0; j < netInterfaces.at(i).addressEntries().size(); j++) - { - // killSwitch toggle - if (m_vpnLocalAddress == netInterfaces.at(i).addressEntries().at(j).ip().toString()) { - if (QVariant(m_configData.value(config_key::killSwitchOption).toString()).toBool()) { - IpcClient::Interface()->enableKillSwitch(m_configData, netInterfaces.at(i).index()); + IpcClient::withInterface([&](QSharedPointer iface) { + QList netInterfaces = QNetworkInterface::allInterfaces(); + for (int i = 0; i < netInterfaces.size(); i++) { + for (int j=0; j < netInterfaces.at(i).addressEntries().size(); j++) + { + // killSwitch toggle + if (m_vpnLocalAddress == netInterfaces.at(i).addressEntries().at(j).ip().toString()) { + if (QVariant(m_configData.value(config_key::killSwitchOption).toString()).toBool()) { + iface->enableKillSwitch(m_configData, netInterfaces.at(i).index()); + } + m_configData.insert("vpnAdapterIndex", netInterfaces.at(i).index()); + m_configData.insert("vpnGateway", m_vpnGateway); + m_configData.insert("vpnServer", + NetworkUtilities::getIPAddress(m_configData.value(amnezia::config_key::hostName).toString())); + iface->enablePeerTraffic(m_configData); } - m_configData.insert("vpnAdapterIndex", netInterfaces.at(i).index()); - m_configData.insert("vpnGateway", m_vpnGateway); - m_configData.insert("vpnServer", - NetworkUtilities::getIPAddress(m_configData.value(amnezia::config_key::hostName).toString())); - IpcClient::Interface()->enablePeerTraffic(m_configData); } } - } + }); #endif #if defined(Q_OS_LINUX) || defined(Q_OS_MACOS) // killSwitch toggle if (QVariant(m_configData.value(config_key::killSwitchOption).toString()).toBool()) { m_configData.insert("vpnServer", NetworkUtilities::getIPAddress(m_configData.value(amnezia::config_key::hostName).toString())); - IpcClient::Interface()->enableKillSwitch(m_configData, 0); + IpcClient::withInterface([&](QSharedPointer iface) { + QRemoteObjectPendingReply reply = iface->enableKillSwitch(m_configData, 0); + if (!reply.waitForFinished(1000) || !reply.returnValue()) { + qWarning() << "OpenVpnProtocol::updateVpnGateway(): Failed to enable killswitch"; + } + }); } #endif qDebug() << QString("Set vpn local address %1, gw %2").arg(m_vpnLocalAddress).arg(vpnGateway()); diff --git a/client/protocols/xrayprotocol.cpp b/client/protocols/xrayprotocol.cpp index d61d688ba..575960b2d 100755 --- a/client/protocols/xrayprotocol.cpp +++ b/client/protocols/xrayprotocol.cpp @@ -29,7 +29,14 @@ ErrorCode XrayProtocol::start() { qDebug() << "XrayProtocol::start()"; - IpcClient::Interface()->xrayStart(QJsonDocument(m_xrayConfig).toJson()); + const ErrorCode err = IpcClient::withInterface([&](QSharedPointer iface) { + iface->xrayStart(QJsonDocument(m_xrayConfig).toJson()); + return ErrorCode::NoError; + }, [] () { + return ErrorCode::AmneziaServiceConnectionFailed; + }); + if (err != ErrorCode::NoError) + return err; setConnectionState(Vpn::ConnectionState::Connecting); return startTun2Sock(); @@ -44,45 +51,47 @@ ErrorCode XrayProtocol::startTun2Sock() connect(m_t2sProcess.data(), &IpcProcessTun2SocksReplica::setConnectionState, this, [&](int vpnState) { qDebug() << "PrivilegedProcess setConnectionState " << vpnState; - if (vpnState == Vpn::ConnectionState::Connected) { - setConnectionState(Vpn::ConnectionState::Connecting); - QList dnsAddr; + IpcClient::withInterface([&](QSharedPointer iface) { + if (vpnState == Vpn::ConnectionState::Connected) { + setConnectionState(Vpn::ConnectionState::Connecting); + QList dnsAddr; - dnsAddr.push_back(QHostAddress(m_primaryDNS)); - // We don't use secondary DNS if primary DNS is AmneziaDNS - if (!m_primaryDNS.contains(amnezia::protocols::dns::amneziaDnsIp)) { - dnsAddr.push_back(QHostAddress(m_secondaryDNS)); + dnsAddr.push_back(QHostAddress(m_primaryDNS)); + // We don't use secondary DNS if primary DNS is AmneziaDNS + if (!m_primaryDNS.contains(amnezia::protocols::dns::amneziaDnsIp)) { + dnsAddr.push_back(QHostAddress(m_secondaryDNS)); + } + #ifdef Q_OS_WIN + QThread::msleep(8000); + #endif + #ifdef Q_OS_MACOS + QThread::msleep(5000); + iface->createTun("utun22", amnezia::protocols::xray::defaultLocalAddr); + iface->updateResolvers("utun22", dnsAddr); + #endif + #ifdef Q_OS_LINUX + QThread::msleep(1000); + iface->createTun("tun2", amnezia::protocols::xray::defaultLocalAddr); + iface->updateResolvers("tun2", dnsAddr); + #endif + if (m_routeMode == Settings::RouteMode::VpnAllSites) { + iface->routeAddList(m_vpnGateway, QStringList() << "1.0.0.0/8" << "2.0.0.0/7" << "4.0.0.0/6" << "8.0.0.0/5" << "16.0.0.0/4" << "32.0.0.0/3" << "64.0.0.0/2" << "128.0.0.0/1"); + } + iface->StopRoutingIpv6(); + #ifdef Q_OS_WIN + iface->updateResolvers("tun2", dnsAddr); + #endif + setConnectionState(Vpn::ConnectionState::Connected); } -#ifdef Q_OS_WIN - QThread::msleep(8000); -#endif -#ifdef Q_OS_MACOS - QThread::msleep(5000); - IpcClient::Interface()->createTun("utun22", amnezia::protocols::xray::defaultLocalAddr); - IpcClient::Interface()->updateResolvers("utun22", dnsAddr); -#endif -#ifdef Q_OS_LINUX - QThread::msleep(1000); - IpcClient::Interface()->createTun("tun2", amnezia::protocols::xray::defaultLocalAddr); - IpcClient::Interface()->updateResolvers("tun2", dnsAddr); -#endif - if (m_routeMode == Settings::RouteMode::VpnAllSites) { - IpcClient::Interface()->routeAddList(m_vpnGateway, QStringList() << "1.0.0.0/8" << "2.0.0.0/7" << "4.0.0.0/6" << "8.0.0.0/5" << "16.0.0.0/4" << "32.0.0.0/3" << "64.0.0.0/2" << "128.0.0.0/1"); + #if !defined(Q_OS_MACOS) + if (vpnState == Vpn::ConnectionState::Disconnected) { + setConnectionState(Vpn::ConnectionState::Disconnected); + iface->deleteTun("tun2"); + iface->StartRoutingIpv6(); + iface->clearSavedRoutes(); } - IpcClient::Interface()->StopRoutingIpv6(); -#ifdef Q_OS_WIN - IpcClient::Interface()->updateResolvers("tun2", dnsAddr); -#endif - setConnectionState(Vpn::ConnectionState::Connected); - } -#if !defined(Q_OS_MACOS) - if (vpnState == Vpn::ConnectionState::Disconnected) { - setConnectionState(Vpn::ConnectionState::Disconnected); - IpcClient::Interface()->deleteTun("tun2"); - IpcClient::Interface()->StartRoutingIpv6(); - IpcClient::Interface()->clearSavedRoutes(); - } #endif + }); }); return ErrorCode::NoError; @@ -90,19 +99,29 @@ ErrorCode XrayProtocol::startTun2Sock() void XrayProtocol::stop() { -#ifdef AMNEZIA_DESKTOP - QRemoteObjectPendingReply StartRoutingIpv6Resp = IpcClient::Interface()->StartRoutingIpv6(); - StartRoutingIpv6Resp.waitForFinished(1000); - QRemoteObjectPendingReply restoreResolvers = IpcClient::Interface()->restoreResolvers(); - restoreResolvers.waitForFinished(1000); -#if !defined(Q_OS_MACOS) - QRemoteObjectPendingReply deleteTunResp = IpcClient::Interface()->deleteTun("tun2"); - deleteTunResp.waitForFinished(1000); -#endif -#endif qDebug() << "XrayProtocol::stop()"; - IpcClient::Interface()->xrayStop(); + IpcClient::withInterface([](QSharedPointer iface) { +#ifdef AMNEZIA_DESKTOP + QRemoteObjectPendingReply StartRoutingIpv6Resp = iface->StartRoutingIpv6(); + if (!StartRoutingIpv6Resp.waitForFinished(1000)) { + qWarning() << "XrayProtocol::stop(): Failed to start routing ipv6"; + } + + QRemoteObjectPendingReply restoreResolvers = iface->restoreResolvers(); + if (!restoreResolvers.waitForFinished(1000)) { + qWarning() << "XrayProtocol::stop(): Failed to restore resolvers"; + } + + #if !defined(Q_OS_MACOS) + QRemoteObjectPendingReply deleteTunResp = iface->deleteTun("tun2"); + if (!deleteTunResp.waitForFinished(1000)) { + qWarning() << "XrayProtocol::stop(): Failed to delete tun"; + } + #endif +#endif + iface->xrayStop(); + }); if (m_t2sProcess) { m_t2sProcess->stop(); diff --git a/client/ui/controllers/connectionController.cpp b/client/ui/controllers/connectionController.cpp index c85367da5..23f43bc1f 100644 --- a/client/ui/controllers/connectionController.cpp +++ b/client/ui/controllers/connectionController.cpp @@ -6,6 +6,7 @@ #include #endif +#include "utilities.h" #include "core/controllers/vpnConfigurationController.h" #include "version.h" diff --git a/client/vpnconnection.cpp b/client/vpnconnection.cpp index 7af2eff41..d9683b32e 100644 --- a/client/vpnconnection.cpp +++ b/client/vpnconnection.cpp @@ -57,10 +57,13 @@ void VpnConnection::onBytesChanged(quint64 receivedBytes, quint64 sentBytes) void VpnConnection::onKillSwitchModeChanged(bool enabled) { #ifdef AMNEZIA_DESKTOP - if (InterfaceReady()) { - qDebug() << "Set KillSwitch Strict mode enabled " << enabled; - IpcClient::Interface()->refreshKillSwitch(enabled); - } + IpcClient::withInterface([enabled](QSharedPointer iface){ + QRemoteObjectPendingReply reply = iface->refreshKillSwitch(enabled); + if (reply.waitForFinished(1000) && reply.returnValue()) + qDebug() << "VpnConnection::onKillSwitchModeChanged: Killswitch refreshed"; + else + qWarning() << "VpnConnection::onKillSwitchModeChanged: Failed to execute remote refreshKillSwitch call"; + }); #endif } @@ -69,29 +72,29 @@ void VpnConnection::onConnectionStateChanged(Vpn::ConnectionState state) #ifdef AMNEZIA_DESKTOP auto container = m_settings->defaultContainer(m_settings->defaultServerIndex()); - if (InterfaceReady()) { + IpcClient::withInterface([&](QSharedPointer iface) { if (state == Vpn::ConnectionState::Connected) { - IpcClient::Interface()->resetIpStack(); - IpcClient::Interface()->flushDns(); + iface->resetIpStack(); + iface->flushDns(); if (!ContainerProps::isAwgContainer(container) && container != DockerContainer::WireGuard) { QString dns1 = m_vpnConfiguration.value(config_key::dns1).toString(); QString dns2 = m_vpnConfiguration.value(config_key::dns2).toString(); - IpcClient::Interface()->routeAddList(m_vpnProtocol->vpnGateway(), QStringList() << dns1 << dns2); + iface->routeAddList(m_vpnProtocol->vpnGateway(), QStringList() << dns1 << dns2); if (m_settings->isSitesSplitTunnelingEnabled()) { - IpcClient::Interface()->routeDeleteList(m_vpnProtocol->vpnGateway(), QStringList() << "0.0.0.0"); + iface->routeDeleteList(m_vpnProtocol->vpnGateway(), QStringList() << "0.0.0.0"); // qDebug() << "VpnConnection::onConnectionStateChanged :: adding custom routes, count:" << forwardIps.size(); if (m_settings->routeMode() == Settings::VpnOnlyForwardSites) { QTimer::singleShot(1000, m_vpnProtocol.data(), [this]() { addSitesRoutes(m_vpnProtocol->vpnGateway(), m_settings->routeMode()); }); } else if (m_settings->routeMode() == Settings::VpnAllExceptSites) { - IpcClient::Interface()->routeAddList(m_vpnProtocol->vpnGateway(), QStringList() << "0.0.0.0/1"); - IpcClient::Interface()->routeAddList(m_vpnProtocol->vpnGateway(), QStringList() << "128.0.0.0/1"); + iface->routeAddList(m_vpnProtocol->vpnGateway(), QStringList() << "0.0.0.0/1"); + iface->routeAddList(m_vpnProtocol->vpnGateway(), QStringList() << "128.0.0.0/1"); - IpcClient::Interface()->routeAddList(m_vpnProtocol->routeGateway(), QStringList() << remoteAddress()); + iface->routeAddList(m_vpnProtocol->routeGateway(), QStringList() << remoteAddress()); addSitesRoutes(m_vpnProtocol->routeGateway(), m_settings->routeMode()); } } @@ -111,21 +114,21 @@ void VpnConnection::onConnectionStateChanged(Vpn::ConnectionState state) } else if (state == Vpn::ConnectionState::Error) { m_pendingNetworkCheck = false; - IpcClient::Interface()->flushDns(); + iface->flushDns(); if (m_settings->isSitesSplitTunnelingEnabled()) { if (m_settings->routeMode() == Settings::VpnOnlyForwardSites) { - IpcClient::Interface()->clearSavedRoutes(); + iface->clearSavedRoutes(); } } } else if (state == Vpn::ConnectionState::Connecting) { } else if (state == Vpn::ConnectionState::Disconnected) { m_pendingNetworkCheck = false; - auto result = IpcClient::Interface()->stopNetworkCheck(); + auto result = iface->stopNetworkCheck(); result.waitForFinished(3000); } - } + }); #endif #if defined(Q_OS_IOS) || defined(MACOS_NE) @@ -161,8 +164,9 @@ void VpnConnection::addSitesRoutes(const QString &gw, Settings::RouteMode mode) } ips.removeDuplicates(); - // add all IPs immediately - IpcClient::Interface()->routeAddList(gw, ips); + IpcClient::withInterface([&](QSharedPointer iface) { + iface->routeAddList(gw, ips); + }); // re-resolve domains for (const QString &site : sites) { @@ -174,7 +178,9 @@ void VpnConnection::addSitesRoutes(const QString &gw, Settings::RouteMode mode) const QString &ip = addr.toString(); // qDebug() << "VpnConnection::addSitesRoutes updating site" << site << ip; if (!ips.contains(ip)) { - IpcClient::Interface()->routeAddList(gw, QStringList() << ip); + IpcClient::withInterface([&gw, &ip](QSharedPointer iface) { + iface->routeAddList(gw, QStringList() << ip); + }); m_settings->addVpnSite(mode, site, ip); } flushDns(); @@ -195,48 +201,42 @@ QSharedPointer VpnConnection::vpnProtocol() const void VpnConnection::addRoutes(const QStringList &ips) { #ifdef AMNEZIA_DESKTOP - if (connectionState() == Vpn::ConnectionState::Connected && IpcClient::Interface()) { - if (m_settings->routeMode() == Settings::VpnOnlyForwardSites) { - IpcClient::Interface()->routeAddList(m_vpnProtocol->vpnGateway(), ips); - } else if (m_settings->routeMode() == Settings::VpnAllExceptSites) { - IpcClient::Interface()->routeAddList(m_vpnProtocol->routeGateway(), ips); + IpcClient::withInterface([&](QSharedPointer iface) { + if (connectionState() == Vpn::ConnectionState::Connected) { + if (m_settings->routeMode() == Settings::VpnOnlyForwardSites) { + iface->routeAddList(m_vpnProtocol->vpnGateway(), ips); + } else if (m_settings->routeMode() == Settings::VpnAllExceptSites) { + iface->routeAddList(m_vpnProtocol->routeGateway(), ips); + } } - } + }); #endif } void VpnConnection::deleteRoutes(const QStringList &ips) { #ifdef AMNEZIA_DESKTOP - if (connectionState() == Vpn::ConnectionState::Connected && IpcClient::Interface()) { - if (m_settings->routeMode() == Settings::VpnOnlyForwardSites) { - IpcClient::Interface()->routeDeleteList(vpnProtocol()->vpnGateway(), ips); - } else if (m_settings->routeMode() == Settings::VpnAllExceptSites) { - IpcClient::Interface()->routeDeleteList(m_vpnProtocol->routeGateway(), ips); + IpcClient::withInterface([&](QSharedPointer iface) { + if (connectionState() == Vpn::ConnectionState::Connected) { + if (m_settings->routeMode() == Settings::VpnOnlyForwardSites) { + iface->routeDeleteList(vpnProtocol()->vpnGateway(), ips); + } else if (m_settings->routeMode() == Settings::VpnAllExceptSites) { + iface->routeDeleteList(m_vpnProtocol->routeGateway(), ips); + } } - } + }); #endif } -// TODO: replace with something like -// VpnConnection::withInterface([](iface){ }) -bool VpnConnection::InterfaceReady() -{ -#ifdef AMNEZIA_DESKTOP - if (auto iface = IpcClient::Interface(); iface == nullptr) { - qWarning() << "Error occurred when init IPC client"; - emit serviceIsNotReady(); - return false; - } -#endif - return true; -} - void VpnConnection::flushDns() { #ifdef AMNEZIA_DESKTOP - if (InterfaceReady()) - IpcClient::Interface()->flushDns(); + IpcClient::withInterface([](QSharedPointer iface) { + auto reply = iface->flushDns(); + if (reply.waitForFinished(1000) || !reply.returnValue()) { + qWarning() << "VpnConnection::flushDns(): Failed to flush DNS"; + } + }); #endif } @@ -253,7 +253,7 @@ ErrorCode VpnConnection::lastError() const return ErrorCode::AndroidError; #endif - if (!m_vpnProtocol.data()) { + if (m_vpnProtocol.isNull()) { return ErrorCode::InternalError; } @@ -268,11 +268,6 @@ void VpnConnection::connectToVpn(int serverIndex, const ServerCredentials &crede .arg(ContainerProps::containerToString(container)) << m_settings->routeMode(); - if (!InterfaceReady()) { - emit connectionStateChanged(Vpn::ConnectionState::Error); - return; - } - m_remoteAddress = NetworkUtilities::getIPAddress(credentials.hostName); emit connectionStateChanged(Vpn::ConnectionState::Connecting); @@ -314,7 +309,7 @@ void VpnConnection::connectToVpn(int serverIndex, const ServerCredentials &crede createProtocolConnections(); - ErrorCode errorCode = m_vpnProtocol.data()->start(); + ErrorCode errorCode = m_vpnProtocol->start(); if (errorCode != ErrorCode::NoError) emit connectionStateChanged(Vpn::ConnectionState::Error); } @@ -353,6 +348,7 @@ void VpnConnection::createProtocolConnections() m_connectionLoseHandle = QMetaObject::Connection(); m_networkChangeHandle = QMetaObject::Connection(); + // TODO: replace unsafe IpcClient::Interface() calls m_connectionLoseHandle = connect(IpcClient::Interface().data(), &IpcInterfaceReplica::connectionLose, this, [this]() { qDebug() << "Connection Lose"; @@ -499,13 +495,10 @@ bool VpnConnection::startNetworkCheckIfReady() return false; } - auto iface = IpcClient::Interface(); - if (!iface) { - return false; - } - - iface->startNetworkCheck(gateway, localAddress); - return true; + return IpcClient::withInterface([&](QSharedPointer iface) { + QRemoteObjectPendingReply reply = iface->startNetworkCheck(gateway, localAddress); + return reply.waitForFinished() && reply.returnValue(); + }); #else return false; #endif @@ -544,35 +537,40 @@ QString VpnConnection::bytesPerSecToText(quint64 bytes) void VpnConnection::disconnectFromVpn() { -#ifdef AMNEZIA_DESKTOP - if (InterfaceReady()) { - - m_vpnProtocol.data()->stop(); - qDebug() << "Interface is ready!"; - - QRemoteObjectPendingReply flushDnsResp = IpcClient::Interface()->flushDns(); - flushDnsResp.waitForFinished(1000); - - qDebug() << "Flushed DNS"; - // delete cached routes - QRemoteObjectPendingReply clearSavedRoutesResp = IpcClient::Interface()->clearSavedRoutes(); - clearSavedRoutesResp.waitForFinished(1000); + if (m_vpnProtocol.isNull()) { + emit connectionStateChanged(Vpn::ConnectionState::Disconnected); + return; } + + m_vpnProtocol->stop(); + +#ifdef AMNEZIA_DESKTOP + IpcClient::withInterface([](QSharedPointer iface) { + QRemoteObjectPendingReply flushReply = iface->flushDns(); + if (flushReply.waitForFinished(5000) && flushReply.returnValue()) + qDebug() << "VpnConnection::disconnectFromVpn(): Successfully flushed DNS"; + else + qWarning() << "VpnConnection::disconnectFromVpn(): Failed to flush DNS"; + + QRemoteObjectPendingReply clearSavedRoutesReply = iface->clearSavedRoutes(); + if (clearSavedRoutesReply.waitForFinished(5000) && clearSavedRoutesReply.returnValue()) + qDebug() << "VpnConnection::disconnectFromVpn(): Successfully cleared saved routes"; + else + qWarning() << "VpnConnection::disconnectFromVpn(): Failed to clear saved routes"; + }); #endif #ifdef Q_OS_ANDROID - if (m_vpnProtocol && m_vpnProtocol.data()) { - auto *const connection = new QMetaObject::Connection; - *connection = connect(AndroidController::instance(), &AndroidController::vpnStateChanged, this, - [this, connection](AndroidController::ConnectionState state) { - if (state == AndroidController::ConnectionState::DISCONNECTED) { - onConnectionStateChanged(Vpn::ConnectionState::Disconnected); - disconnect(*connection); - delete connection; - } - }); - m_vpnProtocol.data()->stop(); - } + auto *const connection = new QMetaObject::Connection; + *connection = connect(AndroidController::instance(), &AndroidController::vpnStateChanged, this, + [this, connection](AndroidController::ConnectionState state) { + if (state == AndroidController::ConnectionState::DISCONNECTED) { + onConnectionStateChanged(Vpn::ConnectionState::Disconnected); + disconnect(*connection); + delete connection; + } + }); + m_vpnProtocol->stop(); #endif #if defined(Q_OS_IOS) || defined(MACOS_NE) @@ -580,15 +578,8 @@ void VpnConnection::disconnectFromVpn() disconnect(&m_checkTimer, &QTimer::timeout, IosController::Instance(), &IosController::checkStatus); #endif - if (!m_vpnProtocol.data()) { - emit connectionStateChanged(Vpn::ConnectionState::Disconnected); - return; - } - #if !defined(Q_OS_ANDROID) && !defined(AMNEZIA_DESKTOP) - if (m_vpnProtocol) { - m_vpnProtocol->deleteLater(); - } + m_vpnProtocol->deleteLater(); #endif m_vpnProtocol = nullptr; @@ -603,18 +594,18 @@ Vpn::ConnectionState VpnConnection::connectionState() bool VpnConnection::isConnected() const { - if (!m_vpnProtocol.data()) { + if (m_vpnProtocol.isNull()) { return false; } - return m_vpnProtocol.data()->isConnected(); + return m_vpnProtocol->isConnected(); } bool VpnConnection::isDisconnected() const { - if (!m_vpnProtocol.data()) { + if (m_vpnProtocol.isNull()) { return true; } - return m_vpnProtocol.data()->isDisconnected(); + return m_vpnProtocol->isDisconnected(); } diff --git a/client/vpnconnection.h b/client/vpnconnection.h index 9e275b701..070ab36fa 100644 --- a/client/vpnconnection.h +++ b/client/vpnconnection.h @@ -105,7 +105,6 @@ private: void appendSplitTunnelingConfig(); void appendKillSwitchConfig(); bool startNetworkCheckIfReady(); - bool InterfaceReady(); }; #endif // VPNCONNECTION_H diff --git a/common/logger/logger.cpp b/common/logger/logger.cpp index 3ec17cd73..95592264d 100644 --- a/common/logger/logger.cpp +++ b/common/logger/logger.cpp @@ -91,12 +91,14 @@ void Logger::deInit() bool Logger::setServiceLogsEnabled(bool enabled) { #ifdef AMNEZIA_DESKTOP - if (auto iface = IpcClient::Interface(); iface) { + return IpcClient::withInterface([enabled](QSharedPointer iface) { iface->setLogsEnabled(enabled); - } else { - qWarning() << "Error occurred setting up service logs"; + qDebug() << "Logger::setServiceLogsEnabled(): Logs transitioned to be " << (enabled ? "enabled" : "disabled"); + return true; + },[](){ + qWarning() << "Logger::setServiceLogsEnabled(): Service is not running"; return false; - } + }); #endif return true; @@ -199,9 +201,12 @@ void Logger::clearLogs(bool isServiceLogger) void Logger::clearServiceLogs() { #ifdef AMNEZIA_DESKTOP - if (auto iface = IpcClient::Interface(); iface) { + IpcClient::withInterface([](QSharedPointer iface) { iface->clearLogs(); - } + qDebug() << "Logger::clearServiceLogs(): Logs cleared"; + }, []() { + qWarning() << "Logger::clearServiceLogs(): Service is not running"; + }); #endif }