From a1cb4ac5443ad6e4c9c8dc7d61a0743894cde95c Mon Sep 17 00:00:00 2001 From: pokamest Date: Thu, 18 Feb 2021 15:00:41 +0300 Subject: [PATCH] Custom routing done ShadowSocks enabled by default --- client/client.pro | 2 - client/core/defs.h | 12 +- client/core/errorstrings.h | 3 + client/core/ipcclient.cpp | 76 +++---- client/core/ipcclient.h | 22 +- client/core/openvpnconfigurator.cpp | 14 ++ client/core/openvpnconfigurator.h | 3 + client/core/servercontroller.cpp | 46 +++-- client/core/servercontroller.h | 4 +- client/managementserver.cpp | 3 +- client/message.cpp | 106 ---------- client/message.h | 34 ---- client/protocols/openvpnprotocol.cpp | 143 +++++-------- client/protocols/openvpnprotocol.h | 19 +- client/protocols/shadowsocksvpnprotocol.cpp | 44 ++-- client/protocols/shadowsocksvpnprotocol.h | 9 +- client/protocols/vpnprotocol.cpp | 33 +-- client/protocols/vpnprotocol.h | 18 +- client/server_scripts/template_openvpn.ovpn | 5 + .../server_scripts/template_shadowsocks.ovpn | 5 + client/settings.cpp | 41 ---- client/settings.h | 54 +++-- client/ui/mainwindow.cpp | 63 +++--- client/ui/mainwindow.h | 2 +- client/ui/mainwindow.ui | 61 ++---- client/vpnconnection.cpp | 112 +++++----- client/vpnconnection.h | 18 +- ipc/ipcinterface.rep | 11 + ipc/ipcserver.cpp | 53 ++++- ipc/ipcserver.h | 8 + ipc/ipcserverprocess.cpp | 14 +- service/server/localserver.cpp | 191 ------------------ service/server/localserver.h | 24 --- service/server/server.pro | 2 - service/server/tapcontroller_win.cpp | 4 + service/server/tapcontroller_win.h | 3 +- 36 files changed, 482 insertions(+), 780 deletions(-) delete mode 100644 client/message.cpp delete mode 100644 client/message.h diff --git a/client/client.pro b/client/client.pro index 39ce2fb80..1256427fc 100644 --- a/client/client.pro +++ b/client/client.pro @@ -19,7 +19,6 @@ HEADERS += \ debug.h \ defines.h \ managementserver.h \ - message.h \ protocols/shadowsocksvpnprotocol.h \ runguard.h \ settings.h \ @@ -37,7 +36,6 @@ SOURCES += \ debug.cpp \ main.cpp \ managementserver.cpp \ - message.cpp \ protocols/shadowsocksvpnprotocol.cpp \ runguard.cpp \ settings.cpp \ diff --git a/client/core/defs.h b/client/core/defs.h index 95bf8d165..e433f1422 100644 --- a/client/core/defs.h +++ b/client/core/defs.h @@ -34,8 +34,9 @@ enum ErrorCode InternalError, NotImplementedError, - // Server errorz + // Server errors ServerCheckFailed, + ServerPortAlreadyAllocatedError, // Ssh connection errors SshSocketError, SshTimeoutError, SshProtocolError, @@ -62,6 +63,15 @@ enum ErrorCode OpenVpnUnknownError }; +namespace config { +// config keys +static QString key_openvpn_config_data() { return "openvpn_config_data"; } +static QString key_openvpn_config_path() { return "openvpn_config_path"; } +static QString key_shadowsocks_config_data() { return "shadowsocks_config_data"; } + +} + + } // namespace amnezia #endif // DEFS_H diff --git a/client/core/errorstrings.h b/client/core/errorstrings.h index a19420a52..da9bf01de 100644 --- a/client/core/errorstrings.h +++ b/client/core/errorstrings.h @@ -11,7 +11,10 @@ static QString errorString(ErrorCode code){ case(NoError): return QObject::tr("No error"); case(UnknownError): return QObject::tr("Unknown Error"); case(NotImplementedError): return QObject::tr("Function not implemented"); + + // Server errors case(ServerCheckFailed): return QObject::tr("Server check failed"); + case(ServerPortAlreadyAllocatedError): return QObject::tr("Server port already used. Check for another software"); // Ssh connection errors case(SshSocketError): return QObject::tr("Ssh connection error"); diff --git a/client/core/ipcclient.cpp b/client/core/ipcclient.cpp index a9bc1c673..c8b5ede98 100644 --- a/client/core/ipcclient.cpp +++ b/client/core/ipcclient.cpp @@ -7,7 +7,18 @@ IpcClient &IpcClient::Instance() return s; } -QSharedPointer IpcClient::createPrivilegedProcess() +bool IpcClient::init() +{ + Instance().m_localSocket->waitForConnected(); + + if (!Instance().m_ipcClient) { + qDebug() << "IpcClient::init failed"; + return false; + } + return Instance().m_ipcClient->isReplicaValid(); +} + +QSharedPointer IpcClient::CreatePrivilegedProcess() { if (! Instance().m_ipcClient || ! Instance().m_ipcClient->isReplicaValid()) { qWarning() << "IpcClient::createPrivilegedProcess : IpcClient IpcClient replica is not valid"; @@ -18,47 +29,40 @@ QSharedPointer IpcClient::createPrivilegedProcess() futureResult.waitForFinished(1000); int pid = futureResult.returnValue(); - QSharedPointer replicaNode(new QRemoteObjectNode); - //Instance().m_processNodes.insert(pid, replica); + auto pd = QSharedPointer(new ProcessDescriptor()); + Instance().m_processNodes.insert(pid, pd); - QSharedPointer socket(new QLocalSocket(replicaNode.data())); - QSharedPointer ptr; + pd->localSocket.reset(new QLocalSocket(pd->replicaNode.data())); - connect(socket.data(), &QLocalSocket::connected, replicaNode.data(), [socket, replicaNode, &ptr]() { - replicaNode->addClientSideConnection(socket.data()); + connect(pd->localSocket.data(), &QLocalSocket::connected, pd->replicaNode.data(), [pd]() { + pd->replicaNode->addClientSideConnection(pd->localSocket.data()); - ptr.reset(replicaNode->acquire()); + pd->ipcProcess.reset(pd->replicaNode->acquire()); + if (!pd->ipcProcess) { + qWarning() << "Acquire IpcProcessInterfaceReplica failed"; + } + else { + pd->ipcProcess->waitForSource(1000); + if (!pd->ipcProcess->isReplicaValid()) { + qWarning() << "IpcProcessInterfaceReplica replica is not connected!"; + } - ptr->waitForSource(1000); - - if (!ptr->isReplicaValid()) { - qWarning() << "IpcProcessInterfaceReplica replica is not connected!"; + connect(pd->ipcProcess.data(), &IpcProcessInterfaceReplica::destroyed, pd->ipcProcess.data(), [pd](){ + pd->replicaNode->deleteLater(); + }); } }); - 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(); - }); + pd->localSocket->connectToServer(amnezia::getIpcProcessUrl(pid)); + pd->localSocket->waitForConnected(); + auto proccessReplica = QSharedPointer(pd->ipcProcess); return proccessReplica; } IpcClient::IpcClient(QObject *parent) : QObject(parent) { -// 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()); @@ -72,20 +76,4 @@ IpcClient::IpcClient(QObject *parent) : QObject(parent) }); m_localSocket->connectToServer(amnezia::getIpcServiceUrl()); - - - -// connect(m_ipcClient.data(), &IpcInterfaceReplica::stateChanged, [&](QRemoteObjectReplica::State state, QRemoteObjectReplica::State oldState){ - -//// qDebug() << "state" << state; -//// for (int i = 0; i < 10; ++i) { -//// QRemoteObjectPendingReply future = m_ipcClient->createPrivilegedProcess("", QStringList()); - -//// future.waitForFinished(); -//// qDebug() << "QRemoteObjectPendingReply" << QDateTime::currentMSecsSinceEpoch() - future.returnValue(); - -//// } -// }); - - } diff --git a/client/core/ipcclient.h b/client/core/ipcclient.h index e4b38fa3c..20482f47f 100644 --- a/client/core/ipcclient.h +++ b/client/core/ipcclient.h @@ -12,21 +12,31 @@ 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 bool init(); + static QSharedPointer Interface() { return Instance().m_ipcClient; } + static QSharedPointer CreatePrivilegedProcess(); signals: private: explicit IpcClient(QObject *parent = nullptr); - QRemoteObjectNode m_ClientNode; // create remote object node + QRemoteObjectNode m_ClientNode; QSharedPointer m_ipcClient; QSharedPointer m_localSocket; - //QMap> m_processNodes; + struct ProcessDescriptor { + ProcessDescriptor () { + replicaNode = QSharedPointer(new QRemoteObjectNode()); + ipcProcess = QSharedPointer(); + localSocket = QSharedPointer(); + } + QSharedPointer ipcProcess; + QSharedPointer replicaNode; + QSharedPointer localSocket; + }; + + QMap> m_processNodes; }; #endif // IPCCLIENT_H diff --git a/client/core/openvpnconfigurator.cpp b/client/core/openvpnconfigurator.cpp index fcbfbbacf..5b644e0ba 100644 --- a/client/core/openvpnconfigurator.cpp +++ b/client/core/openvpnconfigurator.cpp @@ -195,6 +195,12 @@ OpenVpnConfigurator::ConnectionData OpenVpnConfigurator::prepareOpenVpnConfig(co return connData; } +Settings &OpenVpnConfigurator::m_settings() +{ + static Settings s; + return s; +} + QString OpenVpnConfigurator::genOpenVpnConfig(const ServerCredentials &credentials, Protocol proto, ErrorCode *errorCode) { @@ -217,6 +223,13 @@ QString OpenVpnConfigurator::genOpenVpnConfig(const ServerCredentials &credentia config.replace("$LOCAL_PROXY_PORT", QString::number(ServerController::ssContainerPort())); } + config.replace("$PRIMARY_DNS", m_settings().primaryDns()); + config.replace("$SECONDARY_DNS", m_settings().secondaryDns()); + + if (m_settings().customRouting()) { + config.replace("redirect-gateway def1 bypass-dhcp", ""); + } + config.replace("$REMOTE_HOST", connData.host); config.replace("$REMOTE_PORT", "1194"); config.replace("$CA_CERT", connData.caCert); @@ -224,5 +237,6 @@ QString OpenVpnConfigurator::genOpenVpnConfig(const ServerCredentials &credentia config.replace("$PRIV_KEY", connData.privKey); config.replace("$TA_KEY", connData.taKey); + //qDebug().noquote() << config; return config; } diff --git a/client/core/openvpnconfigurator.h b/client/core/openvpnconfigurator.h index 182aa7d39..e2192fe33 100644 --- a/client/core/openvpnconfigurator.h +++ b/client/core/openvpnconfigurator.h @@ -5,6 +5,7 @@ #include #include "defs.h" +#include "settings.h" #include "servercontroller.h" @@ -37,6 +38,8 @@ private: static ConnectionData prepareOpenVpnConfig(const ServerCredentials &credentials, Protocol proto, ErrorCode *errorCode = nullptr); + + static Settings &m_settings(); }; #endif // OPENVPNCONFIGURATOR_H diff --git a/client/core/servercontroller.cpp b/client/core/servercontroller.cpp index 2042d2af1..ebf3b1ab5 100644 --- a/client/core/servercontroller.cpp +++ b/client/core/servercontroller.cpp @@ -7,6 +7,7 @@ #include #include #include +#include #include "sshconnectionmanager.h" @@ -23,7 +24,9 @@ QString ServerController::getContainerName(DockerContainer container) } ErrorCode ServerController::runScript(DockerContainer container, - const SshConnectionParameters &sshParams, QString script) + const SshConnectionParameters &sshParams, QString script, + const std::function &cbReadStdOut, + const std::function &cbReadStdErr) { QLoggingCategory::setFilterRules(QStringLiteral("qtc.ssh=false")); @@ -66,18 +69,20 @@ ErrorCode ServerController::runScript(DockerContainer container, wait.quit(); }); - QObject::connect(proc.data(), &SshRemoteProcess::readyReadStandardOutput, [proc](){ + QObject::connect(proc.data(), &SshRemoteProcess::readyReadStandardOutput, &wait, [proc, cbReadStdOut](){ QString s = proc->readAllStandardOutput(); if (s != "." && !s.isEmpty()) { - qDebug().noquote() << s; + qDebug().noquote() << "stdout" << s; } + if (cbReadStdOut) cbReadStdOut(s); }); - QObject::connect(proc.data(), &SshRemoteProcess::readyReadStandardError, [proc](){ + QObject::connect(proc.data(), &SshRemoteProcess::readyReadStandardError, &wait, [proc, cbReadStdErr](){ QString s = proc->readAllStandardError(); if (s != "." && !s.isEmpty()) { - qDebug().noquote() << s; + qDebug().noquote() << "stderr" << s; } + if (cbReadStdErr) cbReadStdErr(s); }); proc->start(); @@ -272,11 +277,12 @@ ErrorCode ServerController::removeServer(const ServerCredentials &credentials, P QString scriptFileName; DockerContainer container; - ErrorCode errorCode; if (proto == Protocol::Any) { - removeServer(credentials, Protocol::OpenVpn); - removeServer(credentials, Protocol::ShadowSocks); - return ErrorCode::NoError; + ErrorCode e = removeServer(credentials, Protocol::OpenVpn); + if (e) { + return e; + } + return removeServer(credentials, Protocol::ShadowSocks); } else if (proto == Protocol::OpenVpn) { scriptFileName = ":/server_scripts/remove_container.sh"; @@ -309,14 +315,14 @@ ErrorCode ServerController::setupServer(const ServerCredentials &credentials, Pr return setupShadowSocksServer(credentials); } else if (proto == Protocol::Any) { - return ErrorCode::NotImplementedError; + //return ErrorCode::NotImplementedError; // TODO: run concurently - // return setupOpenVpnServer(credentials); - //setupShadowSocksServer(credentials); + setupOpenVpnServer(credentials); + setupShadowSocksServer(credentials); } - return ErrorCode::NotImplementedError; + return ErrorCode::NoError; } ErrorCode ServerController::setupOpenVpnServer(const ServerCredentials &credentials) @@ -329,8 +335,20 @@ ErrorCode ServerController::setupOpenVpnServer(const ServerCredentials &credenti scriptData = file.readAll(); if (scriptData.isEmpty()) return ErrorCode::InternalError; - ErrorCode e = runScript(DockerContainer::OpenVpn, sshParams(credentials), scriptData); + QString stdOut; + auto cbReadStdOut = [&](const QString &data) { + stdOut += data + "\n"; + }; + auto cbReadStdErr = [&](const QString &data) { + stdOut += data + "\n"; + }; + + ErrorCode e = runScript(DockerContainer::OpenVpn, sshParams(credentials), scriptData, cbReadStdOut, cbReadStdErr); if (e) return e; + QApplication::processEvents(); + + if (stdOut.contains("port is already allocated")) return ErrorCode::ServerPortAlreadyAllocatedError; + if (stdOut.contains("Error response from daemon")) return ErrorCode::ServerCheckFailed; return checkOpenVpnServer(DockerContainer::OpenVpn, credentials); } diff --git a/client/core/servercontroller.h b/client/core/servercontroller.h index 56289b215..b02e2ed65 100644 --- a/client/core/servercontroller.h +++ b/client/core/servercontroller.h @@ -48,7 +48,9 @@ public: private: static QSsh::SshConnection *connectToHost(const QSsh::SshConnectionParameters &sshParams); static ErrorCode runScript(DockerContainer container, - const QSsh::SshConnectionParameters &sshParams, QString script); + const QSsh::SshConnectionParameters &sshParams, QString script, + const std::function &cbReadStdOut = nullptr, + const std::function &cbReadStdErr = nullptr); static ErrorCode setupOpenVpnServer(const ServerCredentials &credentials); static ErrorCode setupShadowSocksServer(const ServerCredentials &credentials); diff --git a/client/managementserver.cpp b/client/managementserver.cpp index 9b0b124a5..fbc6cbf44 100644 --- a/client/managementserver.cpp +++ b/client/managementserver.cpp @@ -54,8 +54,7 @@ void ManagementServer::onNewConnection() void ManagementServer::onSocketError(QAbstractSocket::SocketError socketError) { - Q_UNUSED(socketError); - + Q_UNUSED(socketError) qDebug().noquote() << QString("Mananement server error: %1").arg(m_socket->errorString()); } diff --git a/client/message.cpp b/client/message.cpp deleted file mode 100644 index 189c01607..000000000 --- a/client/message.cpp +++ /dev/null @@ -1,106 +0,0 @@ -#include "message.h" - -Message::Message(State state, const QStringList& args) : - m_valid(true), - m_state(state), - m_args(args) -{ - -} - -bool Message::isValid() const -{ - return m_valid; -} - -QString Message::textState() const -{ - switch (m_state) { - case State::Unknown: return "Unknown"; - case State::Initialize: return "Initialize"; - case State::StartRequest: return "StartRequest"; - case State::Started: return "Started"; - case State::FinishRequest: return "FinishRequest"; - case State::Finished: return "Finished"; - case State::RoutesAddRequest: return "RoutesAddRequest"; - case State::RouteDeleteRequest: return "RouteDeleteRequest"; - case State::ClearSavedRoutesRequest: return "ClearSavedRoutesRequest"; - case State::FlushDnsRequest: return "FlushDnsRequest"; - case State::InstallDriverRequest: return "InstallDriverRequest"; - default: - ; - } - return QString(); -} - -QString Message::rawData() const -{ - return m_rawData; -} - -Message::State Message::state() const -{ - return m_state; -} - -QString Message::toString() const -{ - if (!isValid()) { - return QString(); - } - - return QString("%1%2%3") - .arg(textState()) - .arg(m_dataSeparator) - .arg(argsToString()); -} - -QString Message::argAtIndex(int index) const -{ - if ((index + 1) > args().size()) { - return QString(); - } - - return args().at(index); -} - -QStringList Message::args() const -{ - return m_args; -} - -QString Message::argsToString() const -{ - return m_args.join(m_argSeparator); -} - -Message::Message(const QString& data) -{ - m_rawData = data; - m_valid = false; - if (data.isEmpty()) { - return; - } - - QStringList dataList = data.split(m_dataSeparator); - if ((dataList.size() != 2)) { - return; - } - - bool stateFound = false; - for (int i = static_cast(State::Unknown); i <= static_cast(State::InstallDriverRequest); i++ ) { - m_state = static_cast(i); - if (textState() == dataList.at(0)) { - stateFound = true; - break; - } - } - - if (!stateFound) { - return; - } - - m_args = dataList.at(1).split(m_argSeparator); - m_valid = true; -} - diff --git a/client/message.h b/client/message.h deleted file mode 100644 index ea02c6568..000000000 --- a/client/message.h +++ /dev/null @@ -1,34 +0,0 @@ -#ifndef MESSAGE_H -#define MESSAGE_H - -#include - -class Message { - -public: - enum class State {Unknown, Initialize, StartRequest, Started, FinishRequest, Finished, - RoutesAddRequest, RouteDeleteRequest, ClearSavedRoutesRequest, FlushDnsRequest, InstallDriverRequest}; - Message(State state, const QStringList& args); - Message(const QString& data); - - QString argAtIndex(int index) const; - QString argsToString() const; - QString toString() const; - QStringList args() const; - State state() const; - bool isValid() const; - QString rawData() const; - -protected: - QString textState() const; - - const QString m_argSeparator = ","; - const QString m_dataSeparator = "|"; - - bool m_valid; - State m_state; - QStringList m_args; - QString m_rawData; -}; - -#endif // MESSAGE_H diff --git a/client/protocols/openvpnprotocol.cpp b/client/protocols/openvpnprotocol.cpp index 57a95e5a0..a1591d558 100644 --- a/client/protocols/openvpnprotocol.cpp +++ b/client/protocols/openvpnprotocol.cpp @@ -9,13 +9,10 @@ #include "openvpnprotocol.h" #include "utils.h" - -OpenVpnProtocol::OpenVpnProtocol(const QString& args, QObject* parent) : - VpnProtocol(args, parent) - //m_requestFromUserToStop(false) +OpenVpnProtocol::OpenVpnProtocol(const QJsonObject &configuration, QObject* parent) : + VpnProtocol(configuration, parent) { - setConfigFile(args); - //connect(m_communicator, &Communicator::messageReceived, this, &OpenVpnProtocol::onMessageReceived); + readOpenVpnConfiguration(configuration); connect(&m_managementServer, &ManagementServer::readyRead, this, &OpenVpnProtocol::onReadyReadDataFromManagementServer); } @@ -25,35 +22,14 @@ OpenVpnProtocol::~OpenVpnProtocol() OpenVpnProtocol::stop(); } -void OpenVpnProtocol::onMessageReceived(const Message& message) -{ - if (!message.isValid()) { - qWarning().noquote() << QString("Message received: '%1', but it is not valid").arg(message.toString()); - return; - } - - switch (message.state()) { - case Message::State::Started: - qDebug() << "OpenVPN process started"; - break; - case Message::State::Finished: - qDebug().noquote() << QString("OpenVPN process finished with status %1").arg(message.argAtIndex(1)); - onOpenVpnProcessFinished(message.argAtIndex(1).toInt()); - break; - default: - qDebug().noquote() << QString("Message received: '%1'").arg(message.toString()); - ; - } -} - void OpenVpnProtocol::stop() { // TODO: need refactoring - // sendTermSignal() will evet return true while server connected + // sendTermSignal() will even return true while server connected ??? if ((m_connectionState == VpnProtocol::ConnectionState::Preparing) || (m_connectionState == VpnProtocol::ConnectionState::Connecting) || (m_connectionState == VpnProtocol::ConnectionState::Connected) || - (m_connectionState == VpnProtocol::ConnectionState::TunnelReconnecting)) { + (m_connectionState == VpnProtocol::ConnectionState::Reconnecting)) { if (!sendTermSignal()) { killOpenVpnProcess(); } @@ -61,27 +37,51 @@ void OpenVpnProtocol::stop() } } -void OpenVpnProtocol::killOpenVpnProcess() +ErrorCode OpenVpnProtocol::checkAndSetupTapDriver() { - // send command to kill openvpn process (if any). + if (!IpcClient::Interface()) { + 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::OpenVpnUnknownError; + } + return ErrorCode::NoError; } -bool OpenVpnProtocol::setConfigFile(const QString& configFileNamePath) +void OpenVpnProtocol::killOpenVpnProcess() { - m_configFileName = configFileNamePath; - QFileInfo file(m_configFileName); - - if (file.fileName().isEmpty()) { - m_configFileName = Utils::defaultVpnConfigFileName(); + if (m_openVpnProcess){ + m_openVpnProcess->close(); } +} - if (m_configFileName.isEmpty()) { - return false; +void OpenVpnProtocol::readOpenVpnConfiguration(const QJsonObject &configuration) +{ + if (configuration.contains(config::key_openvpn_config_data())) { + m_configFile.open(); + m_configFile.write(configuration.value(config::key_openvpn_config_data()).toString().toUtf8()); + m_configFile.close(); + m_configFileName = m_configFile.fileName(); + + qDebug().noquote() << QString("Set config data") << m_configFileName; } + else if (configuration.contains(config::key_openvpn_config_path())) { + m_configFileName = configuration.value(config::key_openvpn_config_path()).toString(); + QFileInfo file(m_configFileName); - qDebug().noquote() << QString("Set config file: '%1'").arg(configPath()); + if (file.fileName().isEmpty()) { + m_configFileName = Utils::defaultVpnConfigFileName(); + } - return false; + qDebug().noquote() << QString("Set config file: '%1'").arg(configPath()); + } } bool OpenVpnProtocol::openVpnProcessIsRunning() const @@ -99,7 +99,7 @@ QString OpenVpnProtocol::configPath() const return m_configFileName; } -void OpenVpnProtocol::writeCommand(const QString& command) +void OpenVpnProtocol::sendManagementCommand(const QString& command) { QIODevice *device = dynamic_cast(m_managementServer.socket().data()); if (device) { @@ -128,17 +128,9 @@ QString OpenVpnProtocol::openVpnExecPath() const ErrorCode OpenVpnProtocol::start() { - qDebug() << "Start OpenVPN connection"; - - //m_requestFromUserToStop = false; - m_openVpnStateSigTermHandlerTimer.stop(); + //qDebug() << "Start OpenVPN connection"; OpenVpnProtocol::stop(); -// if (communicator() && !communicator()->isConnected()) { -// setLastError(ErrorCode::AmneziaServiceConnectionFailed); -// return lastError(); -// } - if (!QFileInfo::exists(openVpnExecPath())) { setLastError(ErrorCode::OpenVpnExecutableMissing); return lastError(); @@ -152,13 +144,6 @@ ErrorCode OpenVpnProtocol::start() QString vpnLogFileNamePath = Utils::systemLogPath() + "/openvpn.log"; Utils::createEmptyFile(vpnLogFileNamePath); - QStringList args({openVpnExecPath(), - "--config" , configPath(), - "--management", m_managementHost, QString::number(m_managementPort), - "--management-client", - "--log-append", vpnLogFileNamePath - }); - if (!m_managementServer.start(m_managementHost, m_managementPort)) { setLastError(ErrorCode::OpenVpnManagementServerError); return lastError(); @@ -166,16 +151,18 @@ ErrorCode OpenVpnProtocol::start() setConnectionState(ConnectionState::Connecting); - m_openVpnProcess = IpcClient::createPrivilegedProcess(); + m_openVpnProcess = IpcClient::CreatePrivilegedProcess(); if (!m_openVpnProcess) { - qWarning() << "IpcProcess replica is not created!"; + //qWarning() << "IpcProcess replica is not created!"; + setLastError(ErrorCode::AmneziaServiceConnectionFailed); return ErrorCode::AmneziaServiceConnectionFailed; } m_openVpnProcess->waitForSource(1000); if (!m_openVpnProcess->isInitialized()) { qWarning() << "IpcProcess replica is not connected!"; + setLastError(ErrorCode::AmneziaServiceConnectionFailed); return ErrorCode::AmneziaServiceConnectionFailed; } m_openVpnProcess->setProgram(openVpnExecPath()); @@ -195,6 +182,10 @@ ErrorCode OpenVpnProtocol::start() qDebug() << "IpcProcessInterfaceReplica stateChanged" << newState; }); + connect(m_openVpnProcess.data(), &IpcProcessInterfaceReplica::finished, this, [&]() { + setConnectionState(ConnectionState::Disconnected); + }); + m_openVpnProcess->start(); //m_communicator->sendMessage(Message(Message::State::StartRequest, args)); @@ -203,20 +194,6 @@ ErrorCode OpenVpnProtocol::start() return ErrorCode::NoError; } -void OpenVpnProtocol::openVpnStateSigTermHandlerTimerEvent() -{ - bool processStatus = openVpnProcessIsRunning(); - if (processStatus) { - killOpenVpnProcess(); - } - onOpenVpnProcessFinished(0); -} - -void OpenVpnProtocol::openVpnStateSigTermHandler() -{ - m_openVpnStateSigTermHandlerTimer.start(5000); -} - bool OpenVpnProtocol::sendTermSignal() { return m_managementServer.writeCommand("signal SIGTERM"); @@ -256,10 +233,11 @@ void OpenVpnProtocol::onReadyReadDataFromManagementServer() setConnectionState(VpnProtocol::ConnectionState::Connected); continue; } else if (line.contains("EXITING,SIGTER")) { - openVpnStateSigTermHandler(); + //openVpnStateSigTermHandler(); + setConnectionState(VpnProtocol::ConnectionState::Disconnecting); continue; } else if (line.contains("RECONNECTING")) { - setConnectionState(VpnProtocol::ConnectionState::TunnelReconnecting); + setConnectionState(VpnProtocol::ConnectionState::Reconnecting); continue; } } @@ -294,19 +272,6 @@ void OpenVpnProtocol::onReadyReadDataFromManagementServer() } } -void OpenVpnProtocol::onOpenVpnProcessFinished(int exitCode) -{ - m_openVpnStateSigTermHandlerTimer.stop(); - if (m_connectionState == VpnProtocol::ConnectionState::Disconnected) { - qDebug() << "Already in disconnected state"; - return; - } - - qDebug().noquote() << QString("Process finished with code: %1").arg(exitCode); - - setConnectionState(VpnProtocol::ConnectionState::Disconnected); -} - void OpenVpnProtocol::updateVpnGateway() { QProcess ipconfig; diff --git a/client/protocols/openvpnprotocol.h b/client/protocols/openvpnprotocol.h index 701e1a6b8..af3ed47a0 100644 --- a/client/protocols/openvpnprotocol.h +++ b/client/protocols/openvpnprotocol.h @@ -6,7 +6,6 @@ #include #include "managementserver.h" -#include "message.h" #include "vpnprotocol.h" #include "core/ipcclient.h" @@ -16,39 +15,35 @@ class OpenVpnProtocol : public VpnProtocol Q_OBJECT public: - explicit OpenVpnProtocol(const QString& args = QString(), QObject* parent = nullptr); + explicit OpenVpnProtocol(const QJsonObject& configuration, QObject* parent = nullptr); virtual ~OpenVpnProtocol() override; ErrorCode start() override; void stop() override; + ErrorCode checkAndSetupTapDriver(); + protected slots: - void onMessageReceived(const Message& message); - void onOpenVpnProcessFinished(int exitCode); void onReadyReadDataFromManagementServer(); -protected: +private: QString configPath() const; QString openVpnExecPath() const; bool openVpnProcessIsRunning() const; bool sendTermSignal(); - bool setConfigFile(const QString& configFileNamePath); + void readOpenVpnConfiguration(const QJsonObject &configuration); void disconnectFromManagementServer(); void killOpenVpnProcess(); - void openVpnStateSigTermHandler(); - void openVpnStateSigTermHandlerTimerEvent(); void sendByteCount(); void sendInitialData(); - void writeCommand(const QString& command); + void sendManagementCommand(const QString& command); const QString m_managementHost = "127.0.0.1"; const unsigned int m_managementPort = 57775; ManagementServer m_managementServer; QString m_configFileName; - QTimer m_openVpnStateSigTermHandlerTimer; - //bool m_requestFromUserToStop; - + QTemporaryFile m_configFile; private: void updateRouteGateway(QString line); diff --git a/client/protocols/shadowsocksvpnprotocol.cpp b/client/protocols/shadowsocksvpnprotocol.cpp index ab19f8758..ce4dbcd79 100644 --- a/client/protocols/shadowsocksvpnprotocol.cpp +++ b/client/protocols/shadowsocksvpnprotocol.cpp @@ -8,31 +8,34 @@ #include #include -ShadowSocksVpnProtocol::ShadowSocksVpnProtocol(const QString &args, QObject *parent): - OpenVpnProtocol(args, parent) +ShadowSocksVpnProtocol::ShadowSocksVpnProtocol(const QJsonObject &configuration, QObject *parent): + OpenVpnProtocol(configuration, parent) { - m_shadowSocksConfig = args; + readShadowSocksConfiguration(configuration); } ErrorCode ShadowSocksVpnProtocol::start() { qDebug() << "ShadowSocksVpnProtocol::start()"; - QJsonObject config = QJsonDocument::fromJson(m_shadowSocksConfig.toUtf8()).object(); - ssProcess.setProcessChannelMode(QProcess::MergedChannels); + m_ssProcess.setProcessChannelMode(QProcess::MergedChannels); - ssProcess.setProgram(shadowSocksExecPath()); - ssProcess.setArguments(QStringList() << "-s" << config.value("server").toString() - << "-p" << QString::number(config.value("server_port").toInt()) - << "-l" << QString::number(config.value("local_port").toInt()) - << "-m" << config.value("method").toString() - << "-k" << config.value("password").toString() + m_ssProcess.setProgram(shadowSocksExecPath()); + m_ssProcess.setArguments(QStringList() << "-s" << m_shadowSocksConfig.value("server").toString() + << "-p" << QString::number(m_shadowSocksConfig.value("server_port").toInt()) + << "-l" << QString::number(m_shadowSocksConfig.value("local_port").toInt()) + << "-m" << m_shadowSocksConfig.value("method").toString() + << "-k" << m_shadowSocksConfig.value("password").toString() ); - ssProcess.start(); - ssProcess.waitForStarted(); + connect(&m_ssProcess, &QProcess::readyRead, this, [this](){ + qDebug().noquote() << m_ssProcess.readAll(); + }); - if (ssProcess.state() == QProcess::ProcessState::Running) { + m_ssProcess.start(); + m_ssProcess.waitForStarted(); + + if (m_ssProcess.state() == QProcess::ProcessState::Running) { setConnectionState(ConnectionState::Connecting); return OpenVpnProtocol::start(); @@ -42,8 +45,10 @@ ErrorCode ShadowSocksVpnProtocol::start() void ShadowSocksVpnProtocol::stop() { + OpenVpnProtocol::stop(); + qDebug() << "ShadowSocksVpnProtocol::stop()"; - ssProcess.kill(); + m_ssProcess.close(); } QString ShadowSocksVpnProtocol::shadowSocksExecPath() const @@ -55,7 +60,7 @@ QString ShadowSocksVpnProtocol::shadowSocksExecPath() const #endif } -QString ShadowSocksVpnProtocol::genShadowSocksConfig(const ServerCredentials &credentials, Protocol proto) +QJsonObject ShadowSocksVpnProtocol::genShadowSocksConfig(const ServerCredentials &credentials, Protocol proto) { QJsonObject ssConfig; ssConfig.insert("server", credentials.hostName); @@ -64,5 +69,10 @@ QString ShadowSocksVpnProtocol::genShadowSocksConfig(const ServerCredentials &cr ssConfig.insert("password", credentials.password); ssConfig.insert("timeout", 60); ssConfig.insert("method", ServerController::ssEncryption()); - return QJsonDocument(ssConfig).toJson(); + return ssConfig; +} + +void ShadowSocksVpnProtocol::readShadowSocksConfiguration(const QJsonObject &configuration) +{ + m_shadowSocksConfig = configuration.value(config::key_shadowsocks_config_data()).toObject(); } diff --git a/client/protocols/shadowsocksvpnprotocol.h b/client/protocols/shadowsocksvpnprotocol.h index b6645ea1f..8c2b58ef5 100644 --- a/client/protocols/shadowsocksvpnprotocol.h +++ b/client/protocols/shadowsocksvpnprotocol.h @@ -7,21 +7,22 @@ class ShadowSocksVpnProtocol : public OpenVpnProtocol { public: - ShadowSocksVpnProtocol(const QString& args = QString(), QObject* parent = nullptr); + ShadowSocksVpnProtocol(const QJsonObject& configuration, QObject* parent = nullptr); ErrorCode start() override; void stop() override; - static QString genShadowSocksConfig(const ServerCredentials &credentials, Protocol proto = Protocol::ShadowSocks); + static QJsonObject genShadowSocksConfig(const ServerCredentials &credentials, Protocol proto = Protocol::ShadowSocks); protected: + void readShadowSocksConfiguration(const QJsonObject &configuration); QString shadowSocksExecPath() const; protected: - QString m_shadowSocksConfig; + QJsonObject m_shadowSocksConfig; private: - QProcess ssProcess; + QProcess m_ssProcess; }; #endif // SHADOWSOCKSVPNPROTOCOL_H diff --git a/client/protocols/vpnprotocol.cpp b/client/protocols/vpnprotocol.cpp index b0765c6d3..2a6cac4b2 100644 --- a/client/protocols/vpnprotocol.cpp +++ b/client/protocols/vpnprotocol.cpp @@ -1,42 +1,26 @@ #include #include -//#include "communicator.h" #include "vpnprotocol.h" #include "core/errorstrings.h" -//Communicator* VpnProtocol::m_communicator = nullptr; - -VpnProtocol::VpnProtocol(const QString& args, QObject* parent) +VpnProtocol::VpnProtocol(const QJsonObject &configuration, QObject* parent) : QObject(parent), m_connectionState(ConnectionState::Unknown), + m_rawConfig(configuration), m_timeoutTimer(new QTimer(this)), m_receivedBytes(0), m_sentBytes(0) { m_timeoutTimer->setSingleShot(true); connect(m_timeoutTimer, &QTimer::timeout, this, &VpnProtocol::onTimeout); - - Q_UNUSED(args) } -//void VpnProtocol::initializeCommunicator(QObject* parent) -//{ -// if (!m_communicator) { -// m_communicator = new Communicator(parent); -// } -//} - -//Communicator* VpnProtocol::communicator() -//{ -// return m_communicator; -//} - void VpnProtocol::setLastError(ErrorCode lastError) { m_lastError = lastError; if (lastError){ - setConnectionState(ConnectionState::Disconnected); + setConnectionState(ConnectionState::Error); } qCritical().noquote() << "VpnProtocol error, code" << m_lastError << errorString(m_lastError); } @@ -79,9 +63,14 @@ void VpnProtocol::setBytesChanged(quint64 receivedBytes, quint64 sentBytes) void VpnProtocol::setConnectionState(VpnProtocol::ConnectionState state) { + qDebug() << "VpnProtocol::setConnectionState" << textConnectionState(state); + if (m_connectionState == state) { return; } + if (m_connectionState == ConnectionState::Disconnected && state == ConnectionState::Disconnecting) { + return; + } m_connectionState = state; if (m_connectionState == ConnectionState::Disconnected) { @@ -113,7 +102,7 @@ QString VpnProtocol::textConnectionState(ConnectionState connectionState) case ConnectionState::Connecting: return tr("Connecting..."); case ConnectionState::Connected: return tr("Connected"); case ConnectionState::Disconnecting: return tr("Disconnecting..."); - case ConnectionState::TunnelReconnecting: return tr("Reconnecting..."); + case ConnectionState::Reconnecting: return tr("Reconnecting..."); case ConnectionState::Error: return tr("Error"); default: ; @@ -127,12 +116,12 @@ QString VpnProtocol::textConnectionState() const return textConnectionState(m_connectionState); } -bool VpnProtocol::onConnected() const +bool VpnProtocol::isConnected() const { return m_connectionState == ConnectionState::Connected; } -bool VpnProtocol::onDisconnected() const +bool VpnProtocol::isDisconnected() const { return m_connectionState == ConnectionState::Disconnected; } diff --git a/client/protocols/vpnprotocol.h b/client/protocols/vpnprotocol.h index f3d9d4ea7..71d24a35f 100644 --- a/client/protocols/vpnprotocol.h +++ b/client/protocols/vpnprotocol.h @@ -3,30 +3,29 @@ #include #include +#include #include "core/defs.h" using namespace amnezia; class QTimer; -class Communicator; class VpnProtocol : public QObject { Q_OBJECT public: - explicit VpnProtocol(const QString& args = QString(), QObject* parent = nullptr); + explicit VpnProtocol(const QJsonObject& configuration, QObject* parent = nullptr); virtual ~VpnProtocol() override = default; - enum class ConnectionState {Unknown, Disconnected, Preparing, Connecting, Connected, Disconnecting, TunnelReconnecting, Error}; + enum ConnectionState {Unknown, Disconnected, Preparing, Connecting, Connected, Disconnecting, Reconnecting, Error}; + Q_ENUM(ConnectionState) - static Communicator* communicator(); static QString textConnectionState(ConnectionState connectionState); - //static void initializeCommunicator(QObject* parent = nullptr); - virtual bool onConnected() const; - virtual bool onDisconnected() const; + virtual bool isConnected() const; + virtual bool isDisconnected() const; virtual ErrorCode start() = 0; virtual void stop() = 0; @@ -54,18 +53,17 @@ protected: virtual void setBytesChanged(quint64 receivedBytes, quint64 sentBytes); virtual void setConnectionState(VpnProtocol::ConnectionState state); - //static Communicator* m_communicator; - ConnectionState m_connectionState; QString m_routeGateway; QString m_vpnGateway; + QJsonObject m_rawConfig; + private: QTimer* m_timeoutTimer; ErrorCode m_lastError; quint64 m_receivedBytes; quint64 m_sentBytes; - }; #endif // VPNPROTOCOL_H diff --git a/client/server_scripts/template_openvpn.ovpn b/client/server_scripts/template_openvpn.ovpn index ee0143586..6b4c4430b 100644 --- a/client/server_scripts/template_openvpn.ovpn +++ b/client/server_scripts/template_openvpn.ovpn @@ -12,6 +12,11 @@ tls-client tls-version-min 1.2 key-direction 1 remote-cert-tls server +redirect-gateway def1 bypass-dhcp + +dhcp-option DNS $PRIMARY_DNS +dhcp-option DNS $SECONDARY_DNS +block-outside-dns remote $REMOTE_HOST $REMOTE_PORT diff --git a/client/server_scripts/template_shadowsocks.ovpn b/client/server_scripts/template_shadowsocks.ovpn index c68cac7dc..730d544f5 100644 --- a/client/server_scripts/template_shadowsocks.ovpn +++ b/client/server_scripts/template_shadowsocks.ovpn @@ -12,6 +12,11 @@ tls-client tls-version-min 1.2 key-direction 1 remote-cert-tls server +redirect-gateway def1 bypass-dhcp + +dhcp-option DNS $PRIMARY_DNS +dhcp-option DNS $SECONDARY_DNS +block-outside-dns socks-proxy 127.0.0.1 $LOCAL_PROXY_PORT route $REMOTE_HOST 255.255.255.255 net_gateway diff --git a/client/settings.cpp b/client/settings.cpp index 5fdc23a09..a7e12278b 100644 --- a/client/settings.cpp +++ b/client/settings.cpp @@ -6,27 +6,6 @@ Settings::Settings(QObject* parent) : QObject(parent), m_settings (ORGANIZATION_NAME, APPLICATION_NAME, this) { - read(); -} - -void Settings::read() -{ - m_settings.beginGroup("Server"); - m_userName = m_settings.value("userName", QString()).toString(); - m_password = m_settings.value("password", QString()).toString(); - m_serverName = m_settings.value("serverName", QString()).toString(); - m_serverPort = m_settings.value("serverPort", 22).toInt(); - m_settings.endGroup(); -} - -void Settings::save() -{ - m_settings.beginGroup("Server"); - m_settings.setValue("userName", m_userName); - m_settings.setValue("password", m_password); - m_settings.setValue("serverName", m_serverName); - m_settings.setValue("serverPort", m_serverPort); - m_settings.endGroup(); } bool Settings::haveAuthData() const @@ -34,26 +13,6 @@ bool Settings::haveAuthData() const return (!serverName().isEmpty() && !userName().isEmpty() && !password().isEmpty()); } -void Settings::setUserName(const QString& login) -{ - m_userName = login; -} - -void Settings::setPassword(const QString& password) -{ - m_password = password; -} - -void Settings::setServerName(const QString& serverName) -{ - m_serverName = serverName; -} - -void Settings::setServerPort(int serverPort) -{ - m_serverPort = serverPort; -} - void Settings::setServerCredentials(const ServerCredentials &credentials) { setServerName(credentials.hostName); diff --git a/client/settings.h b/client/settings.h index 1feb8d005..602184c99 100644 --- a/client/settings.h +++ b/client/settings.h @@ -18,40 +18,50 @@ class Settings : public QObject public: explicit Settings(QObject* parent = nullptr); - void read(); - void save(); + QString userName() const { return m_settings.value("Server/userName", QString()).toString(); } + void setUserName(const QString& login) { m_settings.setValue("Server/userName", login); } - void setUserName(const QString& login); - void setPassword(const QString& password); - void setServerName(const QString& serverName); - void setServerPort(int serverPort = 22); - void setServerCredentials(const ServerCredentials &credentials); + QString password() const { return m_settings.value("Server/password", QString()).toString(); } + void setPassword(const QString& password) { m_settings.setValue("Server/password", password); } + + QString serverName() const { return m_settings.value("Server/serverName", QString()).toString(); } + void setServerName(const QString& serverName) { m_settings.setValue("Server/serverName", serverName); } + + int serverPort() const { return m_settings.value("Server/serverPort", 22).toInt(); } + void setServerPort(int serverPort = 22) { m_settings.setValue("Server/serverPort", serverPort); } - QString userName() const { return m_userName; } - QString password() const { return m_password; } - QString serverName() const { return m_serverName; } - int serverPort() const { return m_serverPort; } ServerCredentials serverCredentials(); - - + void setServerCredentials(const ServerCredentials &credentials); bool haveAuthData() const; + bool customRouting() const { return m_settings.value("Conf/customRouting", false).toBool(); } + void setCustomRouting(bool customRouting) { m_settings.setValue("Conf/customRouting", customRouting); } // list of sites to pass blocking added by user - QStringList customSites() { return m_settings.value("customSites").toStringList(); } - void setCustomSites(const QStringList &customSites) { m_settings.setValue("customSites", customSites); } + QStringList customSites() { return m_settings.value("Conf/customSites").toStringList(); } + void setCustomSites(const QStringList &customSites) { m_settings.setValue("Conf/customSites", customSites); } // list of ips to pass blocking generated from customSites - QStringList customIps() { return m_settings.value("customIps").toStringList(); } - void setCustomIps(const QStringList &customIps) { m_settings.setValue("customIps", customIps); } + QStringList customIps() { return m_settings.value("Conf/customIps").toStringList(); } + void setCustomIps(const QStringList &customIps) { m_settings.setValue("Conf/customIps", customIps); } + QString primaryDns() const { return m_settings.value("Conf/primaryDns", cloudFlareNs1()).toString(); } + QString secondaryDns() const { return m_settings.value("Conf/secondaryDns", cloudFlareNs2()).toString(); } -protected: + //QString primaryDns() const { return m_primaryDns; } + void setPrimaryDns(const QString &primaryDns) { m_settings.setValue("Conf/primaryDns", primaryDns); } + + //QString secondaryDns() const { return m_secondaryDns; } + void setSecondaryDns(const QString &secondaryDns) { m_settings.setValue("Conf/secondaryDns", secondaryDns); } + + QString cloudFlareNs1() const { return "1.1.1.1"; } + QString cloudFlareNs2() const { return "1.0.0.1"; } + + QString openNicNs5() const { return "94.103.153.176"; } + QString openNicNs13() const { return "144.76.103.143"; } + +private: QSettings m_settings; - QString m_userName; - QString m_password; - QString m_serverName; - int m_serverPort; }; #endif // SETTINGS_H diff --git a/client/ui/mainwindow.cpp b/client/ui/mainwindow.cpp index 92e35b6df..8541a675a 100644 --- a/client/ui/mainwindow.cpp +++ b/client/ui/mainwindow.cpp @@ -71,9 +71,9 @@ MainWindow::MainWindow(QWidget *parent) : ui->pushButton_sites_add_custom->click(); }); - initCustomSites(); + updateSettings(); - ui->pushButton_general_settings_exit->hide(); + //ui->pushButton_general_settings_exit->hide(); //ui->pushButton_share_connection->hide(); setFixedSize(width(),height()); @@ -101,7 +101,7 @@ MainWindow::~MainWindow() for (int i = 0; i < 50; i++) { qApp->processEvents(QEventLoop::ExcludeUserInputEvents); QThread::msleep(100); - if (m_vpnConnection->onDisconnected()) { + if (m_vpnConnection->isDisconnected()) { break; } } @@ -249,7 +249,6 @@ void MainWindow::onPushButtonNewServerConnectWithNewData(bool) if (ok) { m_settings.setServerCredentials(serverCredentials); - m_settings.save(); goToPage(Page::Vpn); qApp->processEvents(); @@ -272,7 +271,6 @@ void MainWindow::onPushButtonNewServerConnectWithExistingCode(bool) credentials.password = o.value("w").toString(); m_settings.setServerCredentials(credentials); - m_settings.save(); goToPage(Page::Vpn); qDebug() << QString("Added server %3@%1:%2"). @@ -299,7 +297,7 @@ bool MainWindow::installServer(ServerCredentials credentials, timer.start(1000); - ErrorCode e = ServerController::setupServer(credentials, Protocol::OpenVpn); + ErrorCode e = ServerController::setupServer(credentials, Protocol::Any); if (e) { page->setEnabled(true); button->setVisible(true); @@ -377,14 +375,11 @@ void MainWindow::onPushButtonForgetServer(bool) m_settings.setServerName(""); m_settings.setServerPort(); - m_settings.save(); - goToPage(Page::Start); } void MainWindow::onBytesChanged(quint64 receivedData, quint64 sentData) { - qDebug() << "MainWindow::onBytesChanged" << receivedData << sentData; ui->label_speed_received->setText(VpnConnection::bytesPerSecToText(receivedData)); ui->label_speed_sent->setText(VpnConnection::bytesPerSecToText(sentData)); } @@ -394,6 +389,7 @@ void MainWindow::onConnectionStateChanged(VpnProtocol::ConnectionState state) qDebug() << "MainWindow::onConnectionStateChanged" << VpnProtocol::textConnectionState(state); bool pushButtonConnectEnabled = false; + bool radioButtonsModeEnabled = false; ui->label_state->setText(VpnProtocol::textConnectionState(state)); setTrayState(state); @@ -403,32 +399,41 @@ void MainWindow::onConnectionStateChanged(VpnProtocol::ConnectionState state) onBytesChanged(0,0); ui->pushButton_connect->setChecked(false); pushButtonConnectEnabled = true; + radioButtonsModeEnabled = true; break; case VpnProtocol::ConnectionState::Preparing: pushButtonConnectEnabled = false; + radioButtonsModeEnabled = false; break; case VpnProtocol::ConnectionState::Connecting: pushButtonConnectEnabled = false; + radioButtonsModeEnabled = false; break; case VpnProtocol::ConnectionState::Connected: pushButtonConnectEnabled = true; + radioButtonsModeEnabled = false; break; case VpnProtocol::ConnectionState::Disconnecting: pushButtonConnectEnabled = false; + radioButtonsModeEnabled = false; break; - case VpnProtocol::ConnectionState::TunnelReconnecting: + case VpnProtocol::ConnectionState::Reconnecting: pushButtonConnectEnabled = true; + radioButtonsModeEnabled = false; break; case VpnProtocol::ConnectionState::Error: + ui->pushButton_connect->setChecked(false); pushButtonConnectEnabled = true; + radioButtonsModeEnabled = true; break; case VpnProtocol::ConnectionState::Unknown: - default: pushButtonConnectEnabled = true; - ; + radioButtonsModeEnabled = true; } ui->pushButton_connect->setEnabled(pushButtonConnectEnabled); + ui->radioButton_mode_all_sites->setEnabled(radioButtonsModeEnabled); + ui->radioButton_mode_selected_sites->setEnabled(radioButtonsModeEnabled); } void MainWindow::onVpnProtocolError(ErrorCode errorCode) @@ -519,7 +524,7 @@ void MainWindow::setupUiConnections() connect(ui->pushButton_server_settings_clear, SIGNAL(clicked(bool)), this, SLOT(onPushButtonClearServer(bool))); connect(ui->pushButton_server_settings_forget, SIGNAL(clicked(bool)), this, SLOT(onPushButtonForgetServer(bool))); - connect(ui->pushButton_blocked_list, &QPushButton::clicked, this, [this](){ goToPage(Page::Sites); }); + connect(ui->pushButton_vpn_add_site, &QPushButton::clicked, this, [this](){ goToPage(Page::Sites); }); connect(ui->pushButton_settings, &QPushButton::clicked, this, [this](){ goToPage(Page::GeneralSettings); }); connect(ui->pushButton_server_settings, &QPushButton::clicked, this, [this](){ goToPage(Page::ServerSettings); }); connect(ui->pushButton_share_connection, &QPushButton::clicked, this, [this](){ @@ -545,6 +550,12 @@ void MainWindow::setupUiConnections() connect(ui->pushButton_sites_add_custom, &QPushButton::clicked, this, [this](){ onPushButtonAddCustomSitesClicked(); }); connect(ui->pushButton_sites_delete_custom, &QPushButton::clicked, this, [this](){ onPushButtonDeleteCustomSiteClicked(); }); + + connect(ui->radioButton_mode_selected_sites, &QRadioButton::toggled, ui->pushButton_vpn_add_site, &QPushButton::setEnabled); + + connect(ui->radioButton_mode_selected_sites, &QRadioButton::toggled, this, [this](bool toggled) { + m_settings.setCustomRouting(toggled); + }); } void MainWindow::setTrayState(VpnProtocol::ConnectionState state) @@ -570,7 +581,7 @@ void MainWindow::setTrayState(VpnProtocol::ConnectionState state) case VpnProtocol::ConnectionState::Disconnecting: setTrayIcon(QString(resourcesPath).arg(DisconnectedTrayIconName)); break; - case VpnProtocol::ConnectionState::TunnelReconnecting: + case VpnProtocol::ConnectionState::Reconnecting: setTrayIcon(QString(resourcesPath).arg(DisconnectedTrayIconName)); break; case VpnProtocol::ConnectionState::Error: @@ -663,13 +674,13 @@ void MainWindow::onPushButtonAddCustomSitesClicked() customIps.append(newIp); m_settings.setCustomIps(customIps); - // add to routes immediatelly -// if (vpnStatus() == VPNStatusConnected) { -// //Router::Instance().routeAdd(newIp, vpnGate()); -// } + if (m_vpnConnection->connectionState() == VpnProtocol::ConnectionState::Connected) { + IpcClient::Interface()->routeAddList(m_vpnConnection->vpnProtocol()->vpnGateway(), + QStringList() << newIp); + } } - initCustomSites(); + updateSettings(); ui->lineEdit_sites_add_custom->clear(); } @@ -700,15 +711,19 @@ void MainWindow::onPushButtonDeleteCustomSiteClicked() m_settings.setCustomIps(customIps); - initCustomSites(); + updateSettings(); - //Router::Instance().routeDelete(Utils::getIPAddress(ipToDelete)); - //Router::Instance().flushDns(); + if (m_vpnConnection->connectionState() == VpnProtocol::ConnectionState::Connected) { + IpcClient::Interface()->routeDelete(ipToDelete); + IpcClient::Interface()->flushDns(); + } } -void MainWindow::initCustomSites() +void MainWindow::updateSettings() { customSitesModel->setStringList(m_settings.customSites()); + ui->radioButton_mode_selected_sites->setChecked(m_settings.customRouting()); + ui->pushButton_vpn_add_site->setEnabled(m_settings.customRouting()); } void MainWindow::updateShareCode() @@ -721,4 +736,6 @@ void MainWindow::updateShareCode() QByteArray ba = QJsonDocument(o).toJson().toBase64(QByteArray::Base64UrlEncoding | QByteArray::OmitTrailingEquals); ui->textEdit_sharing_code->setText(QString("vpn://%1").arg(QString(ba))); + + //qDebug() << "Share code" << QJsonDocument(o).toJson(); } diff --git a/client/ui/mainwindow.h b/client/ui/mainwindow.h index 90a4e5e0a..58cbcbd3c 100644 --- a/client/ui/mainwindow.h +++ b/client/ui/mainwindow.h @@ -74,7 +74,7 @@ private: void setTrayIcon(const QString &iconPath); void setupUiConnections(); - void initCustomSites(); + void updateSettings(); void updateShareCode(); diff --git a/client/ui/mainwindow.ui b/client/ui/mainwindow.ui index 10ff3837f..e5843d3a5 100644 --- a/client/ui/mainwindow.ui +++ b/client/ui/mainwindow.ui @@ -259,7 +259,7 @@ QPushButton:hover { - 0 + 2 @@ -315,32 +315,6 @@ color: #333333; Connection code - - - - 40 - 220 - 301 - 41 - - - - background: #181922; -border-radius: 4px; - - - 24 - - - Qt::AlignCenter - - - true - - - Connecting... - - @@ -944,7 +918,10 @@ font: 16px "Lato"; - + + + true + 20 @@ -972,7 +949,10 @@ font-size: 16px; line-height: 21px; } - + +QPushButton:!enabled { +background: #484952; +} + Add site @@ -1099,7 +1079,7 @@ color: #181922; - false + true @@ -1116,9 +1096,9 @@ color: #181922; true - + - false + true @@ -1157,23 +1137,6 @@ color: #181922; true - - - - 10 - 460 - 361 - 141 - - - - image: url(:/images/AmneziaVPN.png); -background-color: rgb(255, 255, 255); - - - - - diff --git a/client/vpnconnection.cpp b/client/vpnconnection.cpp index 081d35ed2..55fa5fb0a 100644 --- a/client/vpnconnection.cpp +++ b/client/vpnconnection.cpp @@ -1,26 +1,31 @@ #include #include #include +#include #include #include #include "ipc.h" +#include "core/ipcclient.h" #include "protocols/openvpnprotocol.h" #include "protocols/shadowsocksvpnprotocol.h" #include "utils.h" #include "vpnconnection.h" -//#include "communicator.h" VpnConnection::VpnConnection(QObject* parent) : QObject(parent) { - QTimer::singleShot(0, [](){ + QTimer::singleShot(0, this, [this](){ if (!IpcClient::init()) { qWarning() << "Error occured when init IPC client"; + emit serviceIsNotReady(); } }); +} - //VpnProtocol::initializeCommunicator(parent); +VpnConnection::~VpnConnection() +{ + m_vpnProtocol.clear(); } void VpnConnection::onBytesChanged(quint64 receivedBytes, quint64 sentBytes) @@ -30,28 +35,37 @@ void VpnConnection::onBytesChanged(quint64 receivedBytes, quint64 sentBytes) void VpnConnection::onConnectionStateChanged(VpnProtocol::ConnectionState state) { -// if (state == VpnProtocol::ConnectionState::Connected){ -// m_vpnProtocol->communicator()->sendMessage(Message(Message::State::FlushDnsRequest, QStringList())); + if (IpcClient::Interface()) { + if (state == VpnProtocol::ConnectionState::Connected && IpcClient::Interface()){ + IpcClient::Interface()->flushDns(); -// // add routes -// const QStringList &black_custom = m_settings.customIps(); -// qDebug() << "onConnect :: adding custom black routes, count:" << black_custom.size(); + if (m_settings.customRouting()) { + IpcClient::Interface()->routeAddList(m_vpnProtocol->vpnGateway(), + QStringList() << m_settings.primaryDns() << m_settings.secondaryDns()); + const QStringList &black_custom = m_settings.customIps(); + qDebug() << "onConnect :: adding custom black routes, count:" << black_custom.size(); -// QStringList args; -// args << m_vpnProtocol->vpnGateway(); -// args << black_custom; + IpcClient::Interface()->routeAddList(m_vpnProtocol->vpnGateway(), black_custom); + } + } + else if (state == VpnProtocol::ConnectionState::Error || state == VpnProtocol::ConnectionState::Disconnected) { + IpcClient::Interface()->flushDns(); + + if (m_settings.customRouting()) { + IpcClient::Interface()->clearSavedRoutes(); + } + } + } -// Message m(Message::State::RoutesAddRequest, args); -// m_vpnProtocol->communicator()->sendMessage(m); -// } -// else if (state == VpnProtocol::ConnectionState::Error) { -// m_vpnProtocol->communicator()->sendMessage(Message(Message::State::ClearSavedRoutesRequest, QStringList())); -// m_vpnProtocol->communicator()->sendMessage(Message(Message::State::FlushDnsRequest, QStringList())); -// } emit connectionStateChanged(state); } +QSharedPointer VpnConnection::vpnProtocol() const +{ + return m_vpnProtocol; +} + ErrorCode VpnConnection::lastError() const { if (!m_vpnProtocol.data()) { @@ -61,11 +75,12 @@ ErrorCode VpnConnection::lastError() const return m_vpnProtocol.data()->lastError(); } -ErrorCode VpnConnection::requestVpnConfig(const ServerCredentials &credentials, Protocol protocol) +ErrorCode VpnConnection::createVpnConfiguration(const ServerCredentials &credentials, Protocol protocol) { ErrorCode errorCode = ErrorCode::NoError; if (protocol == Protocol::OpenVpn || protocol == Protocol::ShadowSocks) { - QString configData = OpenVpnConfigurator::genOpenVpnConfig(credentials, protocol, &errorCode); + QString openVpnConfigData = OpenVpnConfigurator::genOpenVpnConfig(credentials, protocol, &errorCode); + m_vpnConfiguration.insert(config::key_openvpn_config_data(), openVpnConfigData); if (errorCode) { return errorCode; } @@ -73,57 +88,64 @@ ErrorCode VpnConnection::requestVpnConfig(const ServerCredentials &credentials, QFile file(Utils::defaultVpnConfigFileName()); if (file.open(QIODevice::WriteOnly | QIODevice::Truncate)){ QTextStream stream(&file); - stream << configData << endl; - return ErrorCode::NoError; + stream << openVpnConfigData << endl; + } + else { + return ErrorCode::FailedToSaveConfigData; } - - return ErrorCode::FailedToSaveConfigData; } - else { - return ErrorCode::NotImplementedError; - } - return ErrorCode::NotImplementedError; + if (protocol == Protocol::ShadowSocks) { + QJsonObject ssConfigData = ShadowSocksVpnProtocol::genShadowSocksConfig(credentials); + m_vpnConfiguration.insert(config::key_shadowsocks_config_data(), ssConfigData); + } + return ErrorCode::NoError; } ErrorCode VpnConnection::connectToVpn(const ServerCredentials &credentials, Protocol protocol) { - // protocol = Protocol::ShadowSocks; + qDebug() << "connectToVpn, CustomRouting is" << m_settings.customRouting(); + //protocol = Protocol::ShadowSocks; // TODO: Try protocols one by one in case of Protocol::Any // TODO: Implement some behavior in case if connection not stable qDebug() << "Connect to VPN"; emit connectionStateChanged(VpnProtocol::ConnectionState::Connecting); + + if (m_vpnProtocol) { + disconnect(m_vpnProtocol.data(), &VpnProtocol::protocolError, this, &VpnConnection::vpnProtocolError); + m_vpnProtocol->stop(); + m_vpnProtocol->deleteLater(); + } + qApp->processEvents(); if (protocol == Protocol::Any || protocol == Protocol::OpenVpn) { - ErrorCode e = requestVpnConfig(credentials, Protocol::OpenVpn); + ErrorCode e = createVpnConfiguration(credentials, Protocol::OpenVpn); if (e) { emit connectionStateChanged(VpnProtocol::ConnectionState::Error); return e; } - if (m_vpnProtocol) { - disconnect(m_vpnProtocol.data(), &VpnProtocol::protocolError, this, &VpnConnection::vpnProtocolError); + + m_vpnProtocol.reset(new OpenVpnProtocol(m_vpnConfiguration)); + e = static_cast(m_vpnProtocol.data())->checkAndSetupTapDriver(); + if (e) { + emit connectionStateChanged(VpnProtocol::ConnectionState::Error); + return e; } - m_vpnProtocol.reset(new OpenVpnProtocol()); - connect(m_vpnProtocol.data(), &VpnProtocol::protocolError, this, &VpnConnection::vpnProtocolError); } else if (protocol == Protocol::ShadowSocks) { - ErrorCode e = requestVpnConfig(credentials, Protocol::ShadowSocks); + ErrorCode e = createVpnConfiguration(credentials, Protocol::ShadowSocks); if (e) { emit connectionStateChanged(VpnProtocol::ConnectionState::Error); return e; } - if (m_vpnProtocol) { - disconnect(m_vpnProtocol.data(), &VpnProtocol::protocolError, this, &VpnConnection::vpnProtocolError); - } - - m_vpnProtocol.reset(new ShadowSocksVpnProtocol(ShadowSocksVpnProtocol::genShadowSocksConfig(credentials))); - connect(m_vpnProtocol.data(), &VpnProtocol::protocolError, this, &VpnConnection::vpnProtocolError); + m_vpnProtocol.reset(new ShadowSocksVpnProtocol(m_vpnConfiguration)); } + connect(m_vpnProtocol.data(), &VpnProtocol::protocolError, this, &VpnConnection::vpnProtocolError); connect(m_vpnProtocol.data(), SIGNAL(connectionStateChanged(VpnProtocol::ConnectionState)), this, SLOT(onConnectionStateChanged(VpnProtocol::ConnectionState))); connect(m_vpnProtocol.data(), SIGNAL(bytesChanged(quint64, quint64)), this, SLOT(onBytesChanged(quint64, quint64))); @@ -155,20 +177,20 @@ VpnProtocol::ConnectionState VpnConnection::connectionState() return m_vpnProtocol->connectionState(); } -bool VpnConnection::onConnected() const +bool VpnConnection::isConnected() const { if (!m_vpnProtocol.data()) { return false; } - return m_vpnProtocol.data()->onConnected(); + return m_vpnProtocol.data()->isConnected(); } -bool VpnConnection::onDisconnected() const +bool VpnConnection::isDisconnected() const { if (!m_vpnProtocol.data()) { return true; } - return m_vpnProtocol.data()->onDisconnected(); + return m_vpnProtocol.data()->isDisconnected(); } diff --git a/client/vpnconnection.h b/client/vpnconnection.h index 7ffddc57e..2b03cdb5b 100644 --- a/client/vpnconnection.h +++ b/client/vpnconnection.h @@ -19,34 +19,40 @@ class VpnConnection : public QObject public: explicit VpnConnection(QObject* parent = nullptr); - ~VpnConnection() override = default; + ~VpnConnection() override; static QString bytesPerSecToText(quint64 bytes); ErrorCode lastError() const; - ErrorCode requestVpnConfig(const ServerCredentials &credentials, Protocol protocol); + ErrorCode createVpnConfiguration(const ServerCredentials &credentials, Protocol protocol); + ErrorCode connectToVpn(const ServerCredentials &credentials, Protocol protocol = Protocol::Any); - bool onConnected() const; - bool onDisconnected() const; void disconnectFromVpn(); + bool isConnected() const; + bool isDisconnected() const; + VpnProtocol::ConnectionState connectionState(); + QSharedPointer vpnProtocol() const; + signals: void bytesChanged(quint64 receivedBytes, quint64 sentBytes); void connectionStateChanged(VpnProtocol::ConnectionState state); void vpnProtocolError(amnezia::ErrorCode error); + void serviceIsNotReady(); + protected slots: void onBytesChanged(quint64 receivedBytes, quint64 sentBytes); void onConnectionStateChanged(VpnProtocol::ConnectionState state); protected: - - QScopedPointer m_vpnProtocol; + QSharedPointer m_vpnProtocol; private: Settings m_settings; + QJsonObject m_vpnConfiguration; }; diff --git a/ipc/ipcinterface.rep b/ipc/ipcinterface.rep index e9bb9e32b..6c73bf97a 100644 --- a/ipc/ipcinterface.rep +++ b/ipc/ipcinterface.rep @@ -1,9 +1,20 @@ #include +#include class IpcInterface { SLOT( int createPrivilegedProcess() ); // return local pid //SIGNAL(sendMessage(const QByteArray &message)); + + // Route functions + SLOT( bool routeAdd(const QString &ip, const QString &gw, const QString &mask) ); + SLOT( int routeAddList(const QString &gw, const QStringList &ips) ); + SLOT( bool clearSavedRoutes() ); + SLOT( bool routeDelete(const QString &ip) ); + SLOT( void flushDns() ); + + SLOT( bool checkAndInstallDriver() ); + SLOT( QStringList getTapList() ); }; class IpcProcessInterface diff --git a/ipc/ipcserver.cpp b/ipc/ipcserver.cpp index 4cb958b17..fbe83fdef 100644 --- a/ipc/ipcserver.cpp +++ b/ipc/ipcserver.cpp @@ -1,8 +1,14 @@ #include "ipcserver.h" +#include #include #include +#include "router.h" +#ifdef Q_OS_WIN +#include "tapcontroller_win.h" +#endif + IpcServer::IpcServer(QObject *parent): IpcInterfaceSource(parent) {} @@ -11,13 +17,13 @@ int IpcServer::createPrivilegedProcess() { m_localpid++; - ProcessDescriptor pd; + ProcessDescriptor pd(this); // pd.serverNode->setHostUrl(QUrl(amnezia::getIpcProcessUrl(m_localpid))); // pd.serverNode->enableRemoting(pd.ipcProcess.data()); - pd.localServer = QSharedPointer(new QLocalServer(this)); + //pd.localServer = QSharedPointer(new QLocalServer(this)); pd.localServer->setSocketOptions(QLocalServer::WorldAccessOption); if (!pd.localServer->listen(amnezia::getIpcProcessUrl(m_localpid))) { @@ -46,3 +52,46 @@ int IpcServer::createPrivilegedProcess() return m_localpid; } + +bool IpcServer::routeAdd(const QString &ip, const QString &gw, const QString &mask) +{ + return Router::Instance().routeAdd(ip, gw, mask); +} + +int IpcServer::routeAddList(const QString &gw, const QStringList &ips) +{ + return Router::Instance().routeAddList(gw, ips); +} + +bool IpcServer::clearSavedRoutes() +{ + return Router::Instance().clearSavedRoutes(); +} + +bool IpcServer::routeDelete(const QString &ip) +{ + return Router::Instance().routeDelete(ip); +} + +void IpcServer::flushDns() +{ + return Router::Instance().flushDns(); +} + +bool IpcServer::checkAndInstallDriver() +{ +#ifdef Q_OS_WIN + return TapController::checkAndSetup(); +#else + return true; +#endif +} + +QStringList IpcServer::getTapList() +{ +#ifdef Q_OS_WIN + return TapController::getTapList(); +#else + return QStringList(); +#endif +} diff --git a/ipc/ipcserver.h b/ipc/ipcserver.h index 30c3fbe99..ae3142cd3 100644 --- a/ipc/ipcserver.h +++ b/ipc/ipcserver.h @@ -15,6 +15,14 @@ public: explicit IpcServer(QObject *parent = nullptr); virtual int createPrivilegedProcess() override; + virtual bool routeAdd(const QString &ip, const QString &gw, const QString &mask = QString()) override; + virtual int routeAddList(const QString &gw, const QStringList &ips) override; + virtual bool clearSavedRoutes() override; + virtual bool routeDelete(const QString &ip) override; + virtual void flushDns() override; + virtual bool checkAndInstallDriver() override; + virtual QStringList getTapList() override; + private: int m_localpid = 0; diff --git a/ipc/ipcserverprocess.cpp b/ipc/ipcserverprocess.cpp index 4418e0a76..a629f344b 100644 --- a/ipc/ipcserverprocess.cpp +++ b/ipc/ipcserverprocess.cpp @@ -5,12 +5,12 @@ IpcServerProcess::IpcServerProcess(QObject *parent) : IpcProcessInterfaceSource(parent), m_process(QSharedPointer(new QProcess())) { -// connect(m_process.data(), &QProcess::errorOccurred, this, &IpcServerProcess::errorOccurred); -// connect(m_process.data(), QOverload::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); + connect(m_process.data(), &QProcess::errorOccurred, this, &IpcServerProcess::errorOccurred); + connect(m_process.data(), QOverload::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); connect(m_process.data(), &QProcess::errorOccurred, [&](QProcess::ProcessError error){ qDebug() << "IpcServerProcess errorOccurred " << error; @@ -22,12 +22,10 @@ IpcServerProcess::IpcServerProcess(QObject *parent) : }); connect(m_process.data(), &QProcess::readyReadStandardOutput, [&](){ qDebug() << "IpcServerProcess StandardOutput " << m_process->readAllStandardOutput(); - }); connect(m_process.data(), &QProcess::readyRead, [&](){ qDebug() << "IpcServerProcess StandardOutput " << m_process->readAll(); - }); } diff --git a/service/server/localserver.cpp b/service/server/localserver.cpp index 30e17c6d2..f94d2dca8 100644 --- a/service/server/localserver.cpp +++ b/service/server/localserver.cpp @@ -14,8 +14,6 @@ #endif LocalServer::LocalServer(QObject *parent) : QObject(parent), -// m_clientConnection(nullptr), -// m_clientConnected(false), m_ipcServer(this) { // Create the server and listen outside of QtRO @@ -27,15 +25,6 @@ LocalServer::LocalServer(QObject *parent) : QObject(parent), 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 - - - - // 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()); @@ -49,186 +38,6 @@ LocalServer::LocalServer(QObject *parent) : QObject(parent), LocalServer::~LocalServer() { -// m_clientConnected = false; -// m_server->disconnect(); - -// QFile::remove(Utils::serverName()); - qDebug() << "Local server stopped"; } -//bool LocalServer::isRunning() const -//{ -// return true; -// //return m_server->isListening(); -//} - -//void LocalServer::onNewConnection() -//{ -// if (m_clientConnection) { -// m_clientConnection->deleteLater(); -// } - -// m_clientConnection = m_server->nextPendingConnection(); -// connect(m_clientConnection, &QLocalSocket::disconnected, this, &LocalServer::onDisconnected); -// m_clientConnected = true; - -// qDebug() << "New connection"; - -// for(;;) { -// qApp->processEvents(QEventLoop::ExcludeUserInputEvents); -// if (!m_clientConnected || !m_clientConnection) { -// break; -// } - -// if (m_clientConnection->waitForReadyRead(1000) && m_clientConnection->canReadLine()) { -// char buf[1024]; -// qint64 lineLength = m_clientConnection->readLine(buf, sizeof(buf)); -// if (lineLength != -1) { -// QString line = buf; -// line = line.simplified(); -// qDebug().noquote() << QString("Read line: '%1'").arg(line); -// Message incomingMessage(line); -// if (!incomingMessage.isValid()) { -// qWarning().noquote() << "Message is not valid!"; -// continue; -// } -// else { -// qDebug().noquote() << QString("Got message id: '%1'").arg(static_cast(incomingMessage.state())); -// //qDebug().noquote() << incomingMessage.rawData(); -// } - -// switch (incomingMessage.state()) { -// case Message::State::Initialize: -// #ifdef Q_OS_WIN -// TapController::Instance().checkAndSetup(); -// #endif -// sendMessage(Message(Message::State::Initialize, QStringList({"Server"}))); -// break; -// case Message::State::StartRequest: -// startProcess(incomingMessage.args()); -// break; -// case Message::State::FinishRequest: -// finishProcess(incomingMessage.args()); -// break; - -// case Message::State::RoutesAddRequest: -// routesAddRequest(incomingMessage.args()); -// break; -// case Message::State::RouteDeleteRequest: -// routeDeleteRequest(incomingMessage.args()); -// break; -// case Message::State::ClearSavedRoutesRequest: -// Router::Instance().clearSavedRoutes(); -// break; -// case Message::State::FlushDnsRequest: -// Router::Instance().flushDns(); -// break; -// case Message::State::InstallDriverRequest: -// checkAndInstallDriver(incomingMessage.args()); -// break; - -// default: -// ; -// } -// } -// } -// } - -// qDebug() << "Released"; -//} - -//void LocalServer::finishProcess(const QStringList& args) -//{ -// Q_UNUSED(args) -//} - -//void LocalServer::startProcess(const QStringList& messageArgs) -//{ -// if (messageArgs.size() < 1) { -// return; -// } - -// QProcess* process = new QProcess(); -// connect(process, SIGNAL(started()), this, SLOT(onStarted())); -// connect(process, SIGNAL(finished(int, QProcess::ExitStatus)), this, SLOT(onFinished(int, QProcess::ExitStatus))); - -// const QString program = messageArgs.at(0); -// QStringList args; -// for (int i = 1; i < messageArgs.size(); i++) { -// args.append(messageArgs.at(i)); -// } - -// QFileInfo fi(program); -// const QString baseName = fi.baseName(); -// if (!fi.exists()) { -// qWarning() << "This program does not exist"; -// sendMessage(Message(Message::State::Started, QStringList({baseName}))); -// sendMessage(Message(Message::State::Finished, QStringList({baseName, QString::number(-1)}))); -// return; -// } - -// process->setObjectName(baseName); - -// qDebug().noquote() << QString("Start process '%1' - '%2' with args '%3'") -// .arg(baseName).arg(program).arg(args.join(",")); - -// process->start(program, args); -// m_processList.append(process); -//} - -//void LocalServer::routesAddRequest(const QStringList &messageArgs) -//{ -// Router::Instance().routeAddList(messageArgs.first(), messageArgs.mid(1)); -//} - -//void LocalServer::routeDeleteRequest(const QStringList &messageArgs) -//{ -// Router::Instance().routeDelete(messageArgs.first()); -//} - -//void LocalServer::checkAndInstallDriver(const QStringList &messageArgs) -//{ - -//} - -//void LocalServer::onFinished(int exitCode, QProcess::ExitStatus exitStatus) -//{ -// Q_UNUSED(exitStatus) - -// QProcess* process = (QProcess*)sender(); -// sendMessage(Message(Message::State::Finished, QStringList({process->objectName(), QString::number(exitCode)}))); -//} - -//void LocalServer::onStarted() -//{ -// QProcess* process = (QProcess*)sender(); -// sendMessage(Message(Message::State::Started, QStringList({process->objectName()}))); -//} - -//void LocalServer::onDisconnected() -//{ -// if (!m_clientConnected) { -// return; -// } - -// m_clientConnected = false; -// QLocalSocket* clientConnection = (QLocalSocket*)sender(); -// clientConnection->deleteLater(); - -// qDebug() << "Diconnected"; -//} - -//void LocalServer::sendMessage(const Message& message) -//{ -// if (!m_clientConnection || !m_clientConnected) { -// qDebug()<< "Cannot send data, remote peer is not connected"; -// return; -// } - -// const QString data = message.toString(); -// bool status = m_clientConnection->write(QString(data + "\n").toUtf8()); - -// qDebug().noquote() << QString("Send message '%1', status '%2'").arg(data).arg(Utils::toString(status)); -//} - diff --git a/service/server/localserver.h b/service/server/localserver.h index 187a2a933..bbd9b630c 100644 --- a/service/server/localserver.h +++ b/service/server/localserver.h @@ -8,7 +8,6 @@ #include #include -#include "message.h" #include "ipcserver.h" class QLocalServer; @@ -23,30 +22,7 @@ public: explicit LocalServer(QObject* parent = nullptr); ~LocalServer(); -// bool isRunning() const; - -protected slots: -// void onDisconnected(); -// void onNewConnection(); - -// void onFinished(int exitCode, QProcess::ExitStatus exitStatus); -// void onStarted(); - -private: -// void finishProcess(const QStringList& messageArgs); -// void sendMessage(const Message& message); -// void startProcess(const QStringList& messageArgs); - -// void routesAddRequest(const QStringList& messageArgs); -// void routeDeleteRequest(const QStringList& messageArgs); - -// void checkAndInstallDriver(const QStringList& messageArgs); - QSharedPointer m_server; -// QPointer m_clientConnection; - -// QVector m_processList; -// bool m_clientConnected; IpcServer m_ipcServer; QRemoteObjectHost m_serverNode; diff --git a/service/server/server.pro b/service/server/server.pro index c5b0ce253..64c2e8951 100644 --- a/service/server/server.pro +++ b/service/server/server.pro @@ -4,7 +4,6 @@ CONFIG += console qt no_batch QT += core network remoteobjects HEADERS = \ - ../../client/message.h \ ../../client/utils.h \ ../../ipc/ipc.h \ ../../ipc/ipcserver.h \ @@ -15,7 +14,6 @@ HEADERS = \ systemservice.h SOURCES = \ - ../../client/message.cpp \ ../../client/utils.cpp \ ../../ipc/ipcserver.cpp \ ../../ipc/ipcserverprocess.cpp \ diff --git a/service/server/tapcontroller_win.cpp b/service/server/tapcontroller_win.cpp index 2c553fcf0..e30c20287 100644 --- a/service/server/tapcontroller_win.cpp +++ b/service/server/tapcontroller_win.cpp @@ -95,6 +95,10 @@ QStringList TapController::getTapList() else tapList.append(s); } + if (! tapList.isEmpty()) { + enableTapAdapter(tapList.first()); + } + return tapList; } diff --git a/service/server/tapcontroller_win.h b/service/server/tapcontroller_win.h index 6e1fb1ba4..37043c03b 100644 --- a/service/server/tapcontroller_win.h +++ b/service/server/tapcontroller_win.h @@ -1,4 +1,4 @@ -#ifndef TAPCONTROLLER_H +#ifndef TAPCONTROLLER_H #define TAPCONTROLLER_H #include @@ -35,7 +35,6 @@ private: static bool setupDriverCertificate(); static bool removeDriver(const QString& tapInstanceId); - }; #endif // TAPCONTROLLER_H