diff --git a/client/3rd-prebuilt b/client/3rd-prebuilt index f339911d..75e352b4 160000 --- a/client/3rd-prebuilt +++ b/client/3rd-prebuilt @@ -1 +1 @@ -Subproject commit f339911dcb75d8a199e508cc2c2f32851cf211b8 +Subproject commit 75e352b40ede4324248b7594b70dbdaa1a7a7f41 diff --git a/client/configurators/openvpn_configurator.cpp b/client/configurators/openvpn_configurator.cpp index 4fad4612..3bc6676a 100644 --- a/client/configurators/openvpn_configurator.cpp +++ b/client/configurators/openvpn_configurator.cpp @@ -110,18 +110,24 @@ QString OpenVpnConfigurator::processConfigWithLocalSettings(QString jsonConfig) QJsonObject json = QJsonDocument::fromJson(jsonConfig.toUtf8()).object(); QString config = json[config_key::config].toString(); - if (m_settings->routeMode() != Settings::VpnAllSites) { - config.replace("redirect-gateway def1 bypass-dhcp", ""); + QRegularExpression regex("redirect-gateway.*"); + config.replace(regex, ""); + + if (m_settings->routeMode() == Settings::VpnAllSites) { + config.append("\nredirect-gateway def1 ipv6 bypass-dhcp\n"); + // Prevent ipv6 leak + config.append("ifconfig-ipv6 fd15:53b6:dead::2/64 fd15:53b6:dead::1\n"); + config.append("block-ipv6\n"); } - else { - if(!config.contains("redirect-gateway def1 bypass-dhcp")) { - config.append("redirect-gateway def1 bypass-dhcp\n"); - } + if (m_settings->routeMode() == Settings::VpnOnlyForwardSites) { + // no redirect-gateway + } + if (m_settings->routeMode() == Settings::VpnAllExceptSites) { + config.append("\nredirect-gateway ipv6 !ipv4 bypass-dhcp\n"); + // Prevent ipv6 leak + config.append("ifconfig-ipv6 fd15:53b6:dead::2/64 fd15:53b6:dead::1\n"); + config.append("block-ipv6\n"); } - - // Prevent ipv6 leak - config.append("ifconfig-ipv6 fd15:53b6:dead::2/64 fd15:53b6:dead::1\n"); - config.append("redirect-gateway ipv6\n"); #ifndef MZ_WINDOWS config.replace("block-outside-dns", ""); @@ -146,9 +152,14 @@ QString OpenVpnConfigurator::processConfigWithExportSettings(QString jsonConfig) QJsonObject json = QJsonDocument::fromJson(jsonConfig.toUtf8()).object(); QString config = json[config_key::config].toString(); - if(!config.contains("redirect-gateway def1 bypass-dhcp")) { - config.append("redirect-gateway def1 bypass-dhcp\n"); - } + QRegularExpression regex("redirect-gateway.*"); + config.replace(regex, ""); + + config.append("\nredirect-gateway def1 ipv6 bypass-dhcp\n"); + + // Prevent ipv6 leak + config.append("ifconfig-ipv6 fd15:53b6:dead::2/64 fd15:53b6:dead::1\n"); + config.append("block-ipv6\n"); // remove block-outside-dns for all exported configs config.replace("block-outside-dns", ""); diff --git a/client/protocols/ios_vpnprotocol.h b/client/protocols/ios_vpnprotocol.h index ed5b45b0..9b4057e5 100644 --- a/client/protocols/ios_vpnprotocol.h +++ b/client/protocols/ios_vpnprotocol.h @@ -15,7 +15,7 @@ public: explicit IOSVpnProtocol(amnezia::Proto proto, const QJsonObject& configuration, QObject* parent = nullptr); static IOSVpnProtocol* instance(); - virtual ~IOSVpnProtocol() override = default; + virtual ~IOSVpnProtocol() override; bool initialize(); diff --git a/client/protocols/ios_vpnprotocol.mm b/client/protocols/ios_vpnprotocol.mm index 2195dbdd..0decc005 100644 --- a/client/protocols/ios_vpnprotocol.mm +++ b/client/protocols/ios_vpnprotocol.mm @@ -30,6 +30,12 @@ IOSVpnProtocol::IOSVpnProtocol(Proto proto, const QJsonObject &configuration, QO connect(this, &IOSVpnProtocol::newTransmittedDataCount, this, &IOSVpnProtocol::setBytesChanged); } +IOSVpnProtocol::~IOSVpnProtocol() +{ + qDebug() << "IOSVpnProtocol::~IOSVpnProtocol()"; + IOSVpnProtocol::stop(); +} + IOSVpnProtocol* IOSVpnProtocol::instance() { return s_instance; } @@ -158,9 +164,12 @@ void IOSVpnProtocol::checkStatus() } m_checkingStatus = true; + + QPointer weakSelf = this; [m_controller checkStatusWithCallback:^(NSString* serverIpv4Gateway, NSString* deviceIpv4Address, NSString* configString) { + if (!weakSelf) return; QString config = QString::fromNSString(configString); m_checkingStatus = false; @@ -185,7 +194,7 @@ void IOSVpnProtocol::checkStatus() } } - emit newTransmittedDataCount(rxBytes, txBytes); + emit weakSelf->newTransmittedDataCount(rxBytes, txBytes); }]; } diff --git a/client/protocols/openvpnprotocol.cpp b/client/protocols/openvpnprotocol.cpp index 6a2c8246..7db64231 100644 --- a/client/protocols/openvpnprotocol.cpp +++ b/client/protocols/openvpnprotocol.cpp @@ -42,6 +42,7 @@ QString OpenVpnProtocol::defaultConfigPath() void OpenVpnProtocol::stop() { qDebug() << "OpenVpnProtocol::stop()"; + setConnectionState(VpnProtocol::Disconnecting); // TODO: need refactoring // sendTermSignal() will even return true while server connected ??? @@ -52,10 +53,10 @@ void OpenVpnProtocol::stop() if (!sendTermSignal()) { killOpenVpnProcess(); } + QThread::msleep(10); m_managementServer.stop(); - qApp->processEvents(); - setConnectionState(Vpn::ConnectionState::Disconnecting); } + setConnectionState(VpnProtocol::Disconnected); } ErrorCode OpenVpnProtocol::prepare() @@ -78,11 +79,9 @@ ErrorCode OpenVpnProtocol::prepare() void OpenVpnProtocol::killOpenVpnProcess() { -#ifndef Q_OS_IOS if (m_openVpnProcess){ m_openVpnProcess->close(); } -#endif } void OpenVpnProtocol::readOpenVpnConfiguration(const QJsonObject &configuration) @@ -150,7 +149,6 @@ void OpenVpnProtocol::updateRouteGateway(QString line) ErrorCode OpenVpnProtocol::start() { -#ifndef Q_OS_IOS //qDebug() << "Start OpenVPN connection"; OpenVpnProtocol::stop(); @@ -164,6 +162,27 @@ ErrorCode OpenVpnProtocol::start() return lastError(); } + // Detect default gateway +#ifdef Q_OS_MAC + QProcess p; + p.setProcessChannelMode(QProcess::MergedChannels); + + p.start("route", QStringList() << "-n" << "get" << "default"); + p.waitForFinished(); + QString s = p.readAll(); + + QRegularExpression rx(R"(gateway:\s*(\d+\.\d+\.\d+\.\d+))"); + QRegularExpressionMatch match = rx.match(s); + if (match.hasMatch()) { + m_routeGateway = match.captured(1); + qDebug() << "Set VPN route gateway" << m_routeGateway; + } + else { + qWarning() << "Unable to set VPN route gateway, output:\n" << s; + } +#endif + + // QString vpnLogFileNamePath = Utils::systemLogPath() + "/openvpn.log"; // Utils::createEmptyFile(vpnLogFileNamePath); @@ -216,9 +235,6 @@ ErrorCode OpenVpnProtocol::start() //startTimeoutTimer(); return ErrorCode::NoError; -#else - return ErrorCode::NotImplementedError; -#endif } bool OpenVpnProtocol::sendTermSignal() diff --git a/client/ui/pages_logic/SitesLogic.cpp b/client/ui/pages_logic/SitesLogic.cpp index 7f653bfa..b5760dfb 100644 --- a/client/ui/pages_logic/SitesLogic.cpp +++ b/client/ui/pages_logic/SitesLogic.cpp @@ -66,12 +66,18 @@ void SitesLogic::onPushButtonAddCustomSitesClicked() m_settings->addVpnSite(mode, newSite, ip); if (!ip.isEmpty()) { - uiLogic()->m_vpnConnection->addRoutes(QStringList() << ip); - uiLogic()->m_vpnConnection->flushDns(); - } else if (Utils::ipAddressWithSubnetRegExp().exactMatch(newSite)) { - uiLogic()->m_vpnConnection->addRoutes(QStringList() << newSite); - uiLogic()->m_vpnConnection->flushDns(); + QMetaObject::invokeMethod(uiLogic()->m_vpnConnection, "addRoutes", + Qt::QueuedConnection, + Q_ARG(QStringList, QStringList() << ip)); } + else if (Utils::ipAddressWithSubnetRegExp().exactMatch(newSite)) { + QMetaObject::invokeMethod(uiLogic()->m_vpnConnection, "addRoutes", + Qt::QueuedConnection, + Q_ARG(QStringList, QStringList() << newSite)); + } + + QMetaObject::invokeMethod(uiLogic()->m_vpnConnection, "flushDns", + Qt::QueuedConnection); onUpdatePage(); }; @@ -118,17 +124,19 @@ void SitesLogic::onPushButtonSitesDeleteClicked(QStringList items) return; // sites.append(siteModel->data(row, 0).toString()); - if (uiLogic()->m_vpnConnection->connectionState() == Vpn::ConnectionState::Connected) { - // ips.append(siteModel->data(row, 1).toString()); + if (uiLogic()->m_vpnConnection && uiLogic()->m_vpnConnection->connectionState() == VpnProtocol::Connected) { + ips.append(siteModel->data(row, 1).toString()); } } m_settings->removeVpnSites(mode, sites); - if (uiLogic()->m_vpnConnection->connectionState() == Vpn::ConnectionState::Connected) { - uiLogic()->m_vpnConnection->deleteRoutes(ips); - uiLogic()->m_vpnConnection->flushDns(); - } + QMetaObject::invokeMethod(uiLogic()->m_vpnConnection, "deleteRoutes", + Qt::QueuedConnection, + Q_ARG(QStringList, ips)); + + QMetaObject::invokeMethod(uiLogic()->m_vpnConnection, "flushDns", + Qt::QueuedConnection); onUpdatePage(); } @@ -189,8 +197,12 @@ void SitesLogic::onPushButtonSitesImportClicked(const QString &fileName) m_settings->addVpnIps(mode, ips); m_settings->addVpnSites(mode, sites); - uiLogic()->m_vpnConnection->addRoutes(QStringList() << ips); - uiLogic()->m_vpnConnection->flushDns(); + QMetaObject::invokeMethod(uiLogic()->m_vpnConnection, "addRoutes", + Qt::QueuedConnection, + Q_ARG(QStringList, ips)); + + QMetaObject::invokeMethod(uiLogic()->m_vpnConnection, "flushDns", + Qt::QueuedConnection); onUpdatePage(); } diff --git a/client/utilities.cpp b/client/utilities.cpp index 990b4664..f984e9a8 100644 --- a/client/utilities.cpp +++ b/client/utilities.cpp @@ -221,7 +221,9 @@ QString Utils::openVpnExecPath() #ifdef Q_OS_WIN return Utils::executable("openvpn/openvpn", true); #elif defined Q_OS_LINUX - return Utils::usrExecutable("openvpn"); + // We have service that runs OpenVPN on Linux. We need to make same + // path for client and service. + return Utils::executable("../../client/bin/openvpn", true); #else return Utils::executable("/openvpn", true); #endif diff --git a/client/vpnconnection.cpp b/client/vpnconnection.cpp index 1f0902fb..5f3511d4 100644 --- a/client/vpnconnection.cpp +++ b/client/vpnconnection.cpp @@ -32,9 +32,9 @@ VpnConnection::VpnConnection(std::shared_ptr settings, std::shared_ptr configurator, QObject* parent) : QObject(parent), m_settings(settings), - m_configurator(configurator), - m_isIOSConnected(false) + m_configurator(configurator) { + m_checkTimer.setInterval(1000); } VpnConnection::~VpnConnection() @@ -96,31 +96,16 @@ void VpnConnection::onConnectionStateChanged(Vpn::ConnectionState state) #endif #ifdef Q_OS_IOS - if (state == Vpn::ConnectionState::Connected){ - m_isIOSConnected = true; - checkIOSStatus(); + if (state == VpnProtocol::Connected) { + m_checkTimer.start(); } else { - m_isIOSConnected = false; -// m_receivedBytes = 0; -// m_sentBytes = 0; + m_checkTimer.stop(); } #endif emit connectionStateChanged(state); } -#ifdef Q_OS_IOS -void VpnConnection::checkIOSStatus() -{ - QTimer::singleShot(1000, [this]() { - if(m_isIOSConnected){ - iosVpnProtocol->checkStatus(); - checkIOSStatus(); - } - } ); -} -#endif - const QString &VpnConnection::remoteAddress() const { return m_remoteAddress; @@ -236,7 +221,6 @@ QString VpnConnection::createVpnConfigurationForProto(int serverIndex, const ServerCredentials &credentials, DockerContainer container, const QJsonObject &containerConfig, Proto proto, ErrorCode *errorCode) { - ErrorCode e = ErrorCode::NoError; QMap lastVpnConfig = getLastVpnConfig(containerConfig); QString configData; @@ -246,19 +230,16 @@ QString VpnConnection::createVpnConfigurationForProto(int serverIndex, } else { configData = m_configurator->genVpnProtocolConfig(credentials, - container, containerConfig, proto, &e); + container, containerConfig, proto, errorCode); + + if (errorCode && *errorCode) { + return ""; + } QString configDataBeforeLocalProcessing = configData; configData = m_configurator->processConfigWithLocalSettings(serverIndex, container, proto, configData); - - if (errorCode && e) { - *errorCode = e; - return ""; - } - - if (serverIndex >= 0) { qDebug() << "VpnConnection::createVpnConfiguration: saving config for server #" << serverIndex << container << proto; QJsonObject protoObject = m_settings->protocolConfig(serverIndex, container, proto); @@ -267,7 +248,6 @@ QString VpnConnection::createVpnConfigurationForProto(int serverIndex, } } - if (errorCode) *errorCode = e; return configData; } @@ -275,18 +255,15 @@ QJsonObject VpnConnection::createVpnConfiguration(int serverIndex, const ServerCredentials &credentials, DockerContainer container, const QJsonObject &containerConfig, ErrorCode *errorCode) { - ErrorCode e = ErrorCode::NoError; QJsonObject vpnConfiguration; - for (ProtocolEnumNS::Proto proto : ContainerProps::protocolsForContainer(container)) { QJsonObject vpnConfigData = QJsonDocument::fromJson( createVpnConfigurationForProto( - serverIndex, credentials, container, containerConfig, proto, &e).toUtf8()). + serverIndex, credentials, container, containerConfig, proto, errorCode).toUtf8()). object(); - if (e) { - if (errorCode) *errorCode = e; + if (errorCode && *errorCode) { return {}; } @@ -356,16 +333,18 @@ void VpnConnection::connectToVpn(int serverIndex, m_vpnProtocol.reset(androidVpnProtocol); #elif defined Q_OS_IOS Proto proto = ContainerProps::defaultProtocol(container); - //if (iosVpnProtocol==NULL) { - iosVpnProtocol = new IOSVpnProtocol(proto, m_vpnConfiguration); - //} - // IOSVpnProtocol *iosVpnProtocol = new IOSVpnProtocol(proto, m_vpnConfiguration); + auto iosVpnProtocol = new IOSVpnProtocol(proto, m_vpnConfiguration); + if (!iosVpnProtocol->initialize()) { qDebug() << QString("Init failed") ; - emit Vpn::ConnectionState::Error; + emit VpnProtocol::Error; + iosVpnProtocol->deleteLater(); return; } + + connect(&m_checkTimer, &QTimer::timeout, iosVpnProtocol, &IOSVpnProtocol::checkStatus); m_vpnProtocol.reset(iosVpnProtocol); + #endif createProtocolConnections(); @@ -439,7 +418,11 @@ void VpnConnection::disconnectFromVpn() #endif return; } - m_vpnProtocol.data()->stop(); + + if (m_vpnProtocol) { + m_vpnProtocol->deleteLater(); + } + m_vpnProtocol = nullptr; } Vpn::ConnectionState VpnConnection::connectionState() @@ -450,10 +433,6 @@ Vpn::ConnectionState VpnConnection::connectionState() bool VpnConnection::isConnected() const { -#ifdef Q_OS_IOS - -#endif - if (!m_vpnProtocol.data()) { return false; } diff --git a/client/vpnconnection.h b/client/vpnconnection.h index 3a3a3047..41ad28c4 100644 --- a/client/vpnconnection.h +++ b/client/vpnconnection.h @@ -5,6 +5,7 @@ #include #include #include +#include #include "protocols/vpnprotocol.h" #include "core/defs.h" @@ -50,17 +51,12 @@ public: const QJsonObject &containerConfig, ErrorCode *errorCode = nullptr); - bool isConnected() const; bool isDisconnected() const; Vpn::ConnectionState connectionState(); QSharedPointer vpnProtocol() const; - void addRoutes(const QStringList &ips); - void deleteRoutes(const QStringList &ips); - void flushDns(); - const QString &remoteAddress() const; void addSitesRoutes(const QString &gw, Settings::RouteMode mode); @@ -74,6 +70,11 @@ public slots: void disconnectFromVpn(); + + void addRoutes(const QStringList &ips); + void deleteRoutes(const QStringList &ips); + void flushDns(); + signals: void bytesChanged(quint64 receivedBytes, quint64 sentBytes); void connectionStateChanged(Vpn::ConnectionState state); @@ -85,10 +86,6 @@ protected slots: void onBytesChanged(quint64 receivedBytes, quint64 sentBytes); void onConnectionStateChanged(Vpn::ConnectionState state); -#ifdef Q_OS_IOS - void checkIOSStatus(); -#endif - protected: QSharedPointer m_vpnProtocol; @@ -99,14 +96,14 @@ private: QJsonObject m_vpnConfiguration; QJsonObject m_routeMode; QString m_remoteAddress; - bool m_isIOSConnected; //remove later move to isConnected, + + // Only for iOS for now, check counters + QTimer m_checkTimer; #ifdef AMNEZIA_DESKTOP IpcClient *m_IpcClient {nullptr}; #endif -#ifdef Q_OS_IOS - IOSVpnProtocol * iosVpnProtocol{nullptr}; -#endif + #ifdef Q_OS_ANDROID AndroidVpnProtocol* androidVpnProtocol = nullptr; diff --git a/ipc/ipcserver.cpp b/ipc/ipcserver.cpp index cd959533..e9f57c60 100644 --- a/ipc/ipcserver.cpp +++ b/ipc/ipcserver.cpp @@ -18,6 +18,10 @@ IpcServer::IpcServer(QObject *parent): int IpcServer::createPrivilegedProcess() { +#ifdef MZ_DEBUG + qDebug() << "IpcServer::createPrivilegedProcess"; +#endif + m_localpid++; ProcessDescriptor pd(this); @@ -68,31 +72,55 @@ int IpcServer::createPrivilegedProcess() int IpcServer::routeAddList(const QString &gw, const QStringList &ips) { +#ifdef MZ_DEBUG + qDebug() << "IpcServer::routeAddList"; +#endif + return Router::routeAddList(gw, ips); } bool IpcServer::clearSavedRoutes() { +#ifdef MZ_DEBUG + qDebug() << "IpcServer::clearSavedRoutes"; +#endif + return Router::clearSavedRoutes(); } bool IpcServer::routeDeleteList(const QString &gw, const QStringList &ips) { +#ifdef MZ_DEBUG + qDebug() << "IpcServer::routeDeleteList"; +#endif + return Router::routeDeleteList(gw ,ips); } void IpcServer::flushDns() { +#ifdef MZ_DEBUG + qDebug() << "IpcServer::flushDns"; +#endif + return Router::flushDns(); } void IpcServer::resetIpStack() { +#ifdef MZ_DEBUG + qDebug() << "IpcServer::resetIpStack"; +#endif + Router::resetIpStack(); } bool IpcServer::checkAndInstallDriver() { +#ifdef MZ_DEBUG + qDebug() << "IpcServer::checkAndInstallDriver"; +#endif + #ifdef Q_OS_WIN return TapController::checkAndSetup(); #else @@ -102,6 +130,10 @@ bool IpcServer::checkAndInstallDriver() QStringList IpcServer::getTapList() { +#ifdef MZ_DEBUG + qDebug() << "IpcServer::getTapList"; +#endif + #ifdef Q_OS_WIN return TapController::getTapList(); #else @@ -111,13 +143,20 @@ QStringList IpcServer::getTapList() void IpcServer::cleanUp() { +#ifdef MZ_DEBUG qDebug() << "IpcServer::cleanUp"; +#endif + Logger::deinit(); Logger::cleanUp(); } void IpcServer::setLogsEnabled(bool enabled) { +#ifdef MZ_DEBUG + qDebug() << "IpcServer::setLogsEnabled"; +#endif + if (enabled) { Logger::init(); } @@ -128,6 +167,10 @@ void IpcServer::setLogsEnabled(bool enabled) bool IpcServer::copyWireguardConfig(const QString &sourcePath) { +#ifdef MZ_DEBUG + qDebug() << "IpcServer::copyWireguardConfig"; +#endif + #ifdef Q_OS_LINUX const QString wireguardConfigPath = "/etc/wireguard/wg99.conf"; if (QFile::exists(wireguardConfigPath)) @@ -147,6 +190,10 @@ bool IpcServer::copyWireguardConfig(const QString &sourcePath) bool IpcServer::isWireguardRunning() { +#ifdef MZ_DEBUG + qDebug() << "IpcServer::isWireguardRunning"; +#endif + #ifdef Q_OS_LINUX QProcess checkWireguardStatusProcess; @@ -170,5 +217,9 @@ bool IpcServer::isWireguardRunning() bool IpcServer::isWireguardConfigExists(const QString &configPath) { +#ifdef MZ_DEBUG + qDebug() << "IpcServer::isWireguardConfigExists"; +#endif + return QFileInfo::exists(configPath); } diff --git a/service/server/CMakeLists.txt b/service/server/CMakeLists.txt index 9a3aca4e..9046f687 100644 --- a/service/server/CMakeLists.txt +++ b/service/server/CMakeLists.txt @@ -233,7 +233,7 @@ if(WIN32) set(DEPLOY_PLATFORM_PATH "windows/x32") endif() elseif(LINUX) - set(DEPLOY_PLATFORM_PATH "linux/service") + set(DEPLOY_PLATFORM_PATH "linux/client") elseif(APPLE AND NOT IOS) set(DEPLOY_PLATFORM_PATH "macos") endif() diff --git a/service/server/router_linux.cpp b/service/server/router_linux.cpp index 169e9475..3517f8e6 100644 --- a/service/server/router_linux.cpp +++ b/service/server/router_linux.cpp @@ -50,7 +50,6 @@ bool RouterLinux::routeAdd(const QString &ipWithSubnet, const QString &gw, const route.rt_flags = RTF_UP | RTF_GATEWAY; route.rt_metric = 0; - //route.rt_dev = "ens33"; if (int err = ioctl(sock, SIOCADDRT, &route) < 0) { @@ -60,6 +59,8 @@ bool RouterLinux::routeAdd(const QString &ipWithSubnet, const QString &gw, const << " mask " << ((struct sockaddr_in *)&route.rt_genmask)->sin_addr.s_addr << " " << err; return false; } + + m_addedRoutes.append({ipWithSubnet, gw}); return true; } @@ -76,18 +77,23 @@ int RouterLinux::routeAddList(const QString &gw, const QStringList &ips) bool RouterLinux::clearSavedRoutes() { - // No need to delete routes after iface down - return true; - -// int cnt = 0; -// for (const QString &ip: m_addedRoutes) { -// if (routeDelete(ip)) cnt++; -// } - // return (cnt == m_addedRoutes.count()); + int temp_sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP); + int cnt = 0; + for (const Route &r: m_addedRoutes) { + if (routeDelete(r.dst, r.gw, temp_sock)) cnt++; + } + bool ret = (cnt == m_addedRoutes.count()); + m_addedRoutes.clear(); + close(temp_sock); + return ret; } bool RouterLinux::routeDelete(const QString &ipWithSubnet, const QString &gw, const int &sock) { +#ifdef MZ_DEBUG + qDebug().noquote() << "RouterMac::routeDelete: " << ipWithSubnet << gw; +#endif + QString ip = Utils::ipAddressFromIpWithSubnet(ipWithSubnet); QString mask = Utils::netMaskFromIpWithSubnet(ipWithSubnet); diff --git a/service/server/router_linux.h b/service/server/router_linux.h index ddd6e28f..6da20b7d 100644 --- a/service/server/router_linux.h +++ b/service/server/router_linux.h @@ -15,6 +15,11 @@ class RouterLinux : public QObject { Q_OBJECT public: + struct Route { + QString dst; + QString gw; + }; + static RouterLinux& Instance(); bool routeAdd(const QString &ip, const QString &gw, const int &sock); @@ -31,7 +36,7 @@ private: RouterLinux(RouterLinux const &) = delete; RouterLinux& operator= (RouterLinux const&) = delete; - QList m_addedRoutes; + QList m_addedRoutes; }; #endif // ROUTERLINUX_H diff --git a/service/server/router_mac.cpp b/service/server/router_mac.cpp index 6de6b99d..f2e88039 100644 --- a/service/server/router_mac.cpp +++ b/service/server/router_mac.cpp @@ -16,6 +16,10 @@ bool RouterMac::routeAdd(const QString &ipWithSubnet, const QString &gw) QString ip = Utils::ipAddressFromIpWithSubnet(ipWithSubnet); QString mask = Utils::netMaskFromIpWithSubnet(ipWithSubnet); +#ifdef MZ_DEBUG + qDebug().noquote() << "RouterMac::routeAdd: " << ipWithSubnet << gw; +#endif + if (!Utils::checkIPv4Format(ip) || !Utils::checkIPv4Format(gw)) { qCritical().noquote() << "Critical, trying to add invalid route: " << ip << gw; return false; @@ -39,7 +43,9 @@ bool RouterMac::routeAdd(const QString &ipWithSubnet, const QString &gw) strcpy(argv[i], parts.at(i).toStdString().c_str()); } + // TODO refactor mainRouteIface(argc, argv); + m_addedRoutes.append({ipWithSubnet, gw}); for (int i = 0; i < argc; i++) { delete [] argv[i]; @@ -59,14 +65,13 @@ int RouterMac::routeAddList(const QString &gw, const QStringList &ips) bool RouterMac::clearSavedRoutes() { - // No need to delete routes after iface down - return true; - -// int cnt = 0; -// for (const QString &ip: m_addedRoutes) { -// if (routeDelete(ip)) cnt++; -// } - // return (cnt == m_addedRoutes.count()); + int cnt = 0; + for (const Route &r: m_addedRoutes) { + if (routeDelete(r.dst, r.gw)) cnt++; + } + bool ret = (cnt == m_addedRoutes.count()); + m_addedRoutes.clear(); + return ret; } bool RouterMac::routeDelete(const QString &ipWithSubnet, const QString &gw) @@ -74,6 +79,10 @@ bool RouterMac::routeDelete(const QString &ipWithSubnet, const QString &gw) QString ip = Utils::ipAddressFromIpWithSubnet(ipWithSubnet); QString mask = Utils::netMaskFromIpWithSubnet(ipWithSubnet); +#ifdef MZ_DEBUG + qDebug().noquote() << "RouterMac::routeDelete: " << ipWithSubnet << gw; +#endif + if (!Utils::checkIPv4Format(ip) || !Utils::checkIPv4Format(gw)) { qCritical().noquote() << "Critical, trying to remove invalid route: " << ip << gw; return false; diff --git a/service/server/router_mac.h b/service/server/router_mac.h index d6e965c5..210918a4 100644 --- a/service/server/router_mac.h +++ b/service/server/router_mac.h @@ -18,6 +18,11 @@ class RouterMac : public QObject public: static RouterMac& Instance(); + struct Route { + QString dst; + QString gw; + }; + bool routeAdd(const QString &ip, const QString &gw); int routeAddList(const QString &gw, const QStringList &ips); bool clearSavedRoutes(); @@ -32,7 +37,7 @@ private: RouterMac(RouterMac const &) = delete; RouterMac& operator= (RouterMac const&) = delete; - QList m_addedRoutes; + QList m_addedRoutes; }; #endif // ROUTERMAC_H