Custom sites reimplemented
This commit is contained in:
parent
97e918ae72
commit
6c74f30d79
23 changed files with 833 additions and 312 deletions
|
@ -34,6 +34,7 @@ HEADERS += \
|
|||
ui/mainwindow.h \
|
||||
ui/qautostart.h \
|
||||
ui/server_widget.h \
|
||||
ui/sites_model.h \
|
||||
utils.h \
|
||||
vpnconnection.h \
|
||||
protocols/vpnprotocol.h \
|
||||
|
@ -60,6 +61,7 @@ SOURCES += \
|
|||
ui/mainwindow.cpp \
|
||||
ui/qautostart.cpp \
|
||||
ui/server_widget.cpp \
|
||||
ui/sites_model.cpp \
|
||||
utils.cpp \
|
||||
vpnconnection.cpp \
|
||||
protocols/vpnprotocol.cpp \
|
||||
|
|
|
@ -226,7 +226,7 @@ QString OpenVpnConfigurator::processConfigWithLocalSettings(QString config)
|
|||
config.replace("$PRIMARY_DNS", m_settings().primaryDns());
|
||||
config.replace("$SECONDARY_DNS", m_settings().secondaryDns());
|
||||
|
||||
if (m_settings().customRouting()) {
|
||||
if (m_settings().routeMode() == Settings::VpnOnlyForwardSites) {
|
||||
config.replace("redirect-gateway def1 bypass-dhcp", "");
|
||||
}
|
||||
else {
|
||||
|
|
BIN
client/images/folder.png
Normal file
BIN
client/images/folder.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 150 B |
|
@ -61,5 +61,6 @@
|
|||
<file>server_scripts/openvpn_shadowsocks/run_container.sh</file>
|
||||
<file>server_scripts/openvpn_shadowsocks/start.sh</file>
|
||||
<file>server_scripts/openvpn_shadowsocks/template.ovpn</file>
|
||||
<file>images/folder.png</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
#include "defines.h"
|
||||
#include "settings.h"
|
||||
#include "utils.h"
|
||||
|
||||
#include <QDebug>
|
||||
#include "protocols/protocols_defs.h"
|
||||
|
@ -205,6 +206,127 @@ QString Settings::nextAvailableServerName() const
|
|||
return tr("Server") + " " + QString::number(i);
|
||||
}
|
||||
|
||||
QString Settings::routeModeString(RouteMode mode) const
|
||||
{
|
||||
switch (mode) {
|
||||
case VpnAllSites:
|
||||
return "AllSites";
|
||||
case VpnOnlyForwardSites:
|
||||
return "ForwardSites";
|
||||
case VpnAllExceptSites:
|
||||
return "ExceptSites";
|
||||
}
|
||||
}
|
||||
|
||||
void Settings::addVpnSite(RouteMode mode, const QString &site, const QString &ip)
|
||||
{
|
||||
QVariantMap sites = vpnSites(mode);
|
||||
if (sites.contains(site) && ip.isEmpty()) return;
|
||||
|
||||
sites.insert(site, ip);
|
||||
setVpnSites(mode, sites);
|
||||
|
||||
// QStringList l = sites.value(site).toStringList();
|
||||
// if (!l.contains(ip)) {
|
||||
// if (!ip.isEmpty()) l.append(ip);
|
||||
// //l.append(ip);
|
||||
// sites.insert(site, l);
|
||||
// setVpnSites(mode, sites);
|
||||
// qDebug() << "sites after" << vpnSites(mode);
|
||||
// }
|
||||
}
|
||||
|
||||
QStringList Settings::getVpnIps(RouteMode mode) const
|
||||
{
|
||||
QStringList ips;
|
||||
const QVariantMap &m = vpnSites(mode);
|
||||
for (auto i = m.constBegin(); i != m.constEnd(); ++i) {
|
||||
if (Utils::checkIPFormat(i.key())) {
|
||||
ips.append(i.key());
|
||||
}
|
||||
else if (Utils::checkIPFormat(i.value().toString())) {
|
||||
ips.append(i.value().toString());
|
||||
}
|
||||
}
|
||||
ips.removeDuplicates();
|
||||
return ips;
|
||||
}
|
||||
|
||||
void Settings::removeVpnSite(RouteMode mode, const QString &site)
|
||||
{
|
||||
QVariantMap sites = vpnSites(mode);
|
||||
if (!sites.contains(site)) return;
|
||||
|
||||
sites.remove(site);
|
||||
setVpnSites(mode, sites);
|
||||
}
|
||||
|
||||
void Settings::addVpnIps(RouteMode mode, const QStringList &ips)
|
||||
{
|
||||
QVariantMap sites = vpnSites(mode);
|
||||
for (const QString &ip : ips) {
|
||||
if (ip.isEmpty()) continue;
|
||||
|
||||
sites.insert(ip, "");
|
||||
}
|
||||
|
||||
setVpnSites(mode, sites);
|
||||
}
|
||||
|
||||
void Settings::removeVpnSites(RouteMode mode, const QStringList &sites)
|
||||
{
|
||||
QVariantMap sitesMap = vpnSites(mode);
|
||||
for (const QString &site : sites) {
|
||||
if (site.isEmpty()) continue;
|
||||
|
||||
sitesMap.remove(site);
|
||||
}
|
||||
|
||||
setVpnSites(mode, sitesMap);
|
||||
}
|
||||
|
||||
//void Settings::addVpnForwardSite(const QString &site, const QString &ip)
|
||||
//{
|
||||
// auto sites = vpnForwardSites();
|
||||
// QStringList l = sites.value(site).toStringList();
|
||||
// if (!l.contains(ip)) {
|
||||
// l.append(ip);
|
||||
// setVpnForwardSites(sites);
|
||||
// }
|
||||
//}
|
||||
|
||||
//QStringList Settings::getVpnForwardIps() const
|
||||
//{
|
||||
// QStringList ips;
|
||||
// const QVariantMap &m = vpnForwardSites();
|
||||
// for (const QVariant &v : m) {
|
||||
// ips.append(v.toStringList());
|
||||
// }
|
||||
// ips.removeDuplicates();
|
||||
// return ips;
|
||||
//}
|
||||
|
||||
//void Settings::addVpnExceptSite(const QString &site, const QString &ip)
|
||||
//{
|
||||
// auto sites = vpnExceptSites();
|
||||
// QStringList l = sites.value(site).toStringList();
|
||||
// if (!l.contains(ip)) {
|
||||
// l.append(ip);
|
||||
// setVpnExceptSites(sites);
|
||||
// }
|
||||
//}
|
||||
|
||||
//QStringList Settings::getVpnExceptIps() const
|
||||
//{
|
||||
// QStringList ips;
|
||||
// const QVariantMap &m = vpnExceptSites();
|
||||
// for (const QVariant &v : m) {
|
||||
// ips.append(v.toStringList());
|
||||
// }
|
||||
// ips.removeDuplicates();
|
||||
// return ips;
|
||||
//}
|
||||
|
||||
QString Settings::primaryDns() const { return m_settings.value("Conf/primaryDns", cloudFlareNs1).toString(); }
|
||||
|
||||
QString Settings::secondaryDns() const { return m_settings.value("Conf/secondaryDns", cloudFlareNs2).toString(); }
|
||||
|
|
|
@ -67,16 +67,48 @@ public:
|
|||
bool isStartMinimized() const { return m_settings.value("Conf/startMinimized", false).toBool(); }
|
||||
void setStartMinimized(bool enabled) { m_settings.setValue("Conf/startMinimized", enabled); }
|
||||
|
||||
bool customRouting() const { return m_settings.value("Conf/customRouting", false).toBool(); }
|
||||
void setCustomRouting(bool customRouting) { m_settings.setValue("Conf/customRouting", customRouting); }
|
||||
enum RouteMode {
|
||||
VpnAllSites,
|
||||
VpnOnlyForwardSites,
|
||||
VpnAllExceptSites
|
||||
};
|
||||
Q_ENUM (RouteMode)
|
||||
|
||||
// list of sites to pass blocking added by user
|
||||
QStringList customSites() { return m_settings.value("Conf/customSites").toStringList(); }
|
||||
void setCustomSites(const QStringList &customSites) { m_settings.setValue("Conf/customSites", customSites); }
|
||||
QString routeModeString(RouteMode mode) const;
|
||||
|
||||
// list of ips to pass blocking generated from customSites
|
||||
QStringList customIps() { return m_settings.value("Conf/customIps").toStringList(); }
|
||||
void setCustomIps(const QStringList &customIps) { m_settings.setValue("Conf/customIps", customIps); }
|
||||
RouteMode routeMode() const { return static_cast<RouteMode>(m_settings.value("Conf/routeMode", 0).toInt()); }
|
||||
void setRouteMode(RouteMode mode) { m_settings.setValue("Conf/routeMode", mode); }
|
||||
// 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("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("Conf/customIps").toStringList(); }
|
||||
// void setCustomIps(const QStringList &customIps) { m_settings.setValue("Conf/customIps", customIps); }
|
||||
|
||||
|
||||
QVariantMap vpnSites(RouteMode mode) const { return m_settings.value("Conf/" + routeModeString(mode)).toMap(); }
|
||||
void setVpnSites(RouteMode mode, const QVariantMap &sites) { m_settings.setValue("Conf/"+ routeModeString(mode), sites); m_settings.sync(); }
|
||||
void addVpnSite(RouteMode mode, const QString &site, const QString &ip= "");
|
||||
QStringList getVpnIps(RouteMode mode) const;
|
||||
void removeVpnSite(RouteMode mode, const QString &site);
|
||||
|
||||
void addVpnIps(RouteMode mode, const QStringList &ip);
|
||||
void removeVpnSites(RouteMode mode, const QStringList &sites);
|
||||
|
||||
|
||||
// QVariantMap vpnForwardSites() const { return m_settings.value("Conf/vpnForwardSites").toMap(); }
|
||||
// void setVpnForwardSites(const QVariantMap &sites) { m_settings.setValue("Conf/vpnForwardSites", sites); }
|
||||
// void addVpnForwardSite(const QString &site, const QString &ip);
|
||||
// QStringList getVpnForwardIps() const;
|
||||
|
||||
// QVariantMap vpnExceptSites() const { return m_settings.value("Conf/vpnExceptSites").toMap(); }
|
||||
// void setVpnExceptSites(const QVariantMap &sites) { m_settings.setValue("Conf/vpnExceptSites", sites); }
|
||||
// void addVpnExceptSite(const QString &site, const QString &ip);
|
||||
// QStringList getVpnExceptIps() const;
|
||||
|
||||
QString primaryDns() const;
|
||||
QString secondaryDns() const;
|
||||
|
|
|
@ -4,6 +4,8 @@
|
|||
#include <QDesktopServices>
|
||||
#include <QFileDialog>
|
||||
#include <QHBoxLayout>
|
||||
#include <QHostInfo>
|
||||
#include <QItemSelectionModel>
|
||||
#include <QJsonDocument>
|
||||
#include <QJsonObject>
|
||||
#include <QKeyEvent>
|
||||
|
@ -59,6 +61,8 @@ MainWindow::MainWindow(QWidget *parent) :
|
|||
setupUiConnections();
|
||||
setupNewServerConnections();
|
||||
setupWizardConnections();
|
||||
setupVpnPageConnections();
|
||||
setupSitesPageConnections();
|
||||
setupGeneralSettingsConnections();
|
||||
setupAppSettingsConnections();
|
||||
setupNetworkSettingsConnections();
|
||||
|
@ -74,6 +78,11 @@ MainWindow::MainWindow(QWidget *parent) :
|
|||
ui->stackedWidget_main->setSpeed(200);
|
||||
ui->stackedWidget_main->setAnimation(QEasingCurve::Linear);
|
||||
|
||||
|
||||
ui->tableView_sites->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);
|
||||
// ui->tableView_sites->setColumnWidth(0, 450);
|
||||
// ui->tableView_sites->setColumnWidth(1, 120);
|
||||
|
||||
if (QOperatingSystemVersion::current() <= QOperatingSystemVersion::Windows7) {
|
||||
needToHideCustomTitlebar = true;
|
||||
}
|
||||
|
@ -96,10 +105,6 @@ MainWindow::MainWindow(QWidget *parent) :
|
|||
goToPage(Page::Vpn, true, false);
|
||||
}
|
||||
|
||||
connect(ui->lineEdit_sites_add_custom, &QLineEdit::returnPressed, [&](){
|
||||
ui->pushButton_sites_add_custom->click();
|
||||
});
|
||||
|
||||
//ui->pushButton_general_settings_exit->hide();
|
||||
updateSharingPage(selectedServerIndex, m_settings.serverCredentials(selectedServerIndex), selectedDockerContainer);
|
||||
|
||||
|
@ -143,6 +148,10 @@ MainWindow::MainWindow(QWidget *parent) :
|
|||
|
||||
//ui->toolBox_share_connection->removeItem(ui->toolBox_share_connection->indexOf(ui->page_share_shadowsocks));
|
||||
//ui->page_share_shadowsocks->setVisible(false);
|
||||
|
||||
|
||||
sitesModels.insert(Settings::VpnOnlyForwardSites, new SitesModel(Settings::VpnOnlyForwardSites));
|
||||
sitesModels.insert(Settings::VpnAllExceptSites, new SitesModel(Settings::VpnAllExceptSites));
|
||||
}
|
||||
|
||||
MainWindow::~MainWindow()
|
||||
|
@ -351,7 +360,8 @@ void MainWindow::keyPressEvent(QKeyEvent *event)
|
|||
#endif
|
||||
case Qt::Key_C:
|
||||
qDebug().noquote() << "Def server" << m_settings.defaultServerIndex() << m_settings.defaultContainerName(m_settings.defaultServerIndex());
|
||||
qDebug().noquote() << QJsonDocument(m_settings.containerConfig(m_settings.defaultServerIndex(), m_settings.defaultContainer(m_settings.defaultServerIndex()))).toJson();
|
||||
//qDebug().noquote() << QJsonDocument(m_settings.containerConfig(m_settings.defaultServerIndex(), m_settings.defaultContainer(m_settings.defaultServerIndex()))).toJson();
|
||||
qDebug().noquote() << QJsonDocument(m_settings.defaultServer()).toJson();
|
||||
break;
|
||||
case Qt::Key_A:
|
||||
goToPage(Page::Start);
|
||||
|
@ -369,6 +379,12 @@ void MainWindow::keyPressEvent(QKeyEvent *event)
|
|||
if (currentPage() == Page::Vpn) break;
|
||||
if (currentPage() == Page::ServerConfiguring) break;
|
||||
if (currentPage() == Page::Start && pagesStack.size() < 2) break;
|
||||
if (currentPage() == Page::Sites &&
|
||||
ui->tableView_sites->selectionModel()->selection().indexes().size() > 0) {
|
||||
ui->tableView_sites->clearSelection();
|
||||
break;
|
||||
}
|
||||
|
||||
if (! ui->stackedWidget_main->isAnimationRunning() && ui->stackedWidget_main->currentWidget()->isEnabled()) {
|
||||
closePage();
|
||||
}
|
||||
|
@ -626,6 +642,17 @@ void MainWindow::onPushButtonNewServerImport(bool)
|
|||
credentials.password = o.value("w").toString();
|
||||
if (credentials.password.isEmpty()) credentials.password = o.value(config_key::password).toString();
|
||||
|
||||
if (credentials.isValid()) {
|
||||
o.insert(config_key::hostName, credentials.hostName);
|
||||
o.insert(config_key::port, credentials.port);
|
||||
o.insert(config_key::userName, credentials.userName);
|
||||
o.insert(config_key::password, credentials.password);
|
||||
|
||||
o.remove("h");
|
||||
o.remove("p");
|
||||
o.remove("u");
|
||||
o.remove("w");
|
||||
}
|
||||
qDebug() << QString("Added server %3@%1:%2").
|
||||
arg(credentials.hostName).
|
||||
arg(credentials.port).
|
||||
|
@ -901,8 +928,7 @@ void MainWindow::onConnectionStateChanged(VpnProtocol::ConnectionState state)
|
|||
}
|
||||
|
||||
ui->pushButton_connect->setEnabled(pushButtonConnectEnabled);
|
||||
ui->radioButton_mode_all_sites->setEnabled(radioButtonsModeEnabled);
|
||||
ui->radioButton_mode_selected_sites->setEnabled(radioButtonsModeEnabled);
|
||||
ui->widget_vpn_mode->setEnabled(radioButtonsModeEnabled);
|
||||
}
|
||||
|
||||
void MainWindow::onVpnProtocolError(ErrorCode errorCode)
|
||||
|
@ -1013,27 +1039,6 @@ void MainWindow::setupUiConnections()
|
|||
connect(b, &QPushButton::clicked, this, [this](){ closePage(); });
|
||||
}
|
||||
|
||||
connect(ui->pushButton_sites_add_custom, &QPushButton::clicked, this, [this](){ onPushButtonAddCustomSitesClicked(); });
|
||||
|
||||
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);
|
||||
});
|
||||
|
||||
connect(ui->pushButton_servers_add_new, &QPushButton::clicked, this, [this](){ goToPage(Page::Start); });
|
||||
|
||||
connect(ui->lineEdit_server_settings_description, &QLineEdit::editingFinished, this, [this](){
|
||||
const QString &newText = ui->lineEdit_server_settings_description->text();
|
||||
QJsonObject server = m_settings.server(selectedServerIndex);
|
||||
server.insert(config_key::description, newText);
|
||||
m_settings.editServer(selectedServerIndex, server);
|
||||
updateServersListPage();
|
||||
});
|
||||
|
||||
connect(ui->lineEdit_server_settings_description, &QLineEdit::returnPressed, this, [this](){
|
||||
ui->lineEdit_server_settings_description->clearFocus();
|
||||
});
|
||||
}
|
||||
|
||||
void MainWindow::setupNewServerConnections()
|
||||
|
@ -1080,7 +1085,8 @@ void MainWindow::setupWizardConnections()
|
|||
|
||||
connect(ui->pushButton_setup_wizard_vpn_mode_finish, &QPushButton::clicked, this, [this](){
|
||||
installServer(getInstallConfigsFromWizardPage());
|
||||
m_settings.setCustomRouting(ui->checkBox_setup_wizard_vpn_mode->isChecked());
|
||||
if (ui->checkBox_setup_wizard_vpn_mode->isChecked()) m_settings.setRouteMode(Settings::VpnOnlyForwardSites);
|
||||
else m_settings.setRouteMode(Settings::VpnAllSites);
|
||||
});
|
||||
|
||||
connect(ui->pushButton_setup_wizard_low_finish, &QPushButton::clicked, this, [this](){
|
||||
|
@ -1092,6 +1098,86 @@ void MainWindow::setupWizardConnections()
|
|||
});
|
||||
}
|
||||
|
||||
void MainWindow::setupVpnPageConnections()
|
||||
{
|
||||
connect(ui->radioButton_vpn_mode_all_sites, &QRadioButton::toggled, ui->pushButton_vpn_add_site, &QPushButton::setDisabled);
|
||||
|
||||
connect(ui->radioButton_vpn_mode_all_sites, &QRadioButton::toggled, this, [this](bool toggled) {
|
||||
m_settings.setRouteMode(Settings::VpnAllSites);
|
||||
});
|
||||
|
||||
connect(ui->radioButton_vpn_mode_forward_sites, &QRadioButton::toggled, this, [this](bool toggled) {
|
||||
m_settings.setRouteMode(Settings::VpnOnlyForwardSites);
|
||||
});
|
||||
|
||||
connect(ui->radioButton_vpn_mode_except_sites, &QRadioButton::toggled, this, [this](bool toggled) {
|
||||
m_settings.setRouteMode(Settings::VpnAllExceptSites);
|
||||
});
|
||||
}
|
||||
|
||||
void MainWindow::setupSitesPageConnections()
|
||||
{
|
||||
connect(ui->pushButton_sites_add_custom, &QPushButton::clicked, this, [this](){ onPushButtonAddCustomSitesClicked(); });
|
||||
|
||||
connect(ui->lineEdit_sites_add_custom, &QLineEdit::returnPressed, [&](){
|
||||
ui->pushButton_sites_add_custom->click();
|
||||
});
|
||||
|
||||
connect(ui->pushButton_sites_delete, &QPushButton::clicked, this, [this](){
|
||||
Settings::RouteMode mode = m_settings.routeMode();
|
||||
|
||||
QItemSelectionModel* selection = ui->tableView_sites->selectionModel();
|
||||
if (!selection) return;
|
||||
|
||||
QModelIndexList indexes = selection->selectedRows();
|
||||
|
||||
QStringList sites;
|
||||
for (const QModelIndex &index : indexes) {
|
||||
sites.append(index.data().toString());
|
||||
}
|
||||
|
||||
m_settings.removeVpnSites(mode, sites);
|
||||
updateSitesPage();
|
||||
|
||||
// if (m_vpnConnection->connectionState() == VpnProtocol::ConnectionState::Connected) {
|
||||
// if (IpcClient::Interface()) IpcClient::Interface()->routeDelete(ipToDelete, "");
|
||||
// if (IpcClient::Interface()) IpcClient::Interface()->flushDns();
|
||||
// }
|
||||
|
||||
|
||||
// if (m_vpnConnection->connectionState() == VpnProtocol::ConnectionState::Connected) {
|
||||
// if (IpcClient::Interface())
|
||||
// IpcClient::Interface()->routeDelete(m_vpnConnection->vpnProtocol()->vpnGateway(),
|
||||
// QStringList() << ip);
|
||||
// }
|
||||
});
|
||||
|
||||
connect(ui->pushButton_sites_import, &QPushButton::clicked, this, [this](){
|
||||
QString fileName = QFileDialog::getOpenFileName(this, tr("Import IP addresses"),
|
||||
QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation));
|
||||
|
||||
QFile file(fileName);
|
||||
if (!file.open(QIODevice::ReadOnly)) return;
|
||||
|
||||
Settings::RouteMode mode = m_settings.routeMode();
|
||||
|
||||
QStringList ips;
|
||||
while (!file.atEnd()) {
|
||||
QString line = file.readLine();
|
||||
|
||||
int pos = 0;
|
||||
QRegExp rx = Utils::ipAddressWithSubnetRegExp();
|
||||
while ((pos = rx.indexIn(line, pos)) != -1) {
|
||||
ips << rx.cap(0);
|
||||
pos += rx.matchedLength();
|
||||
}
|
||||
}
|
||||
|
||||
m_settings.addVpnIps(mode, ips);
|
||||
updateSitesPage();
|
||||
});
|
||||
}
|
||||
|
||||
void MainWindow::setupAppSettingsConnections()
|
||||
{
|
||||
connect(ui->checkBox_app_settings_autostart, &QCheckBox::stateChanged, this, [this](int state){
|
||||
|
@ -1413,7 +1499,13 @@ void MainWindow::setupNewServerPageConnections()
|
|||
|
||||
void MainWindow::setupServerSettingsPageConnections()
|
||||
{
|
||||
connect(ui->pushButton_servers_add_new, &QPushButton::clicked, this, [this](){ goToPage(Page::Start); });
|
||||
|
||||
connect(ui->pushButton_server_settings_protocols, &QPushButton::clicked, this, [this](){ goToPage(Page::ServerVpnProtocols); });
|
||||
connect(ui->pushButton_server_settings_share_full, &QPushButton::clicked, this, [this](){
|
||||
updateSharingPage(selectedServerIndex, m_settings.serverCredentials(selectedServerIndex), DockerContainer::None);
|
||||
goToPage(Page::ShareConnection);
|
||||
});
|
||||
|
||||
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)));
|
||||
|
@ -1431,6 +1523,17 @@ void MainWindow::setupServerSettingsPageConnections()
|
|||
});
|
||||
});
|
||||
|
||||
connect(ui->lineEdit_server_settings_description, &QLineEdit::editingFinished, this, [this](){
|
||||
const QString &newText = ui->lineEdit_server_settings_description->text();
|
||||
QJsonObject server = m_settings.server(selectedServerIndex);
|
||||
server.insert(config_key::description, newText);
|
||||
m_settings.editServer(selectedServerIndex, server);
|
||||
updateServersListPage();
|
||||
});
|
||||
|
||||
connect(ui->lineEdit_server_settings_description, &QLineEdit::returnPressed, this, [this](){
|
||||
ui->lineEdit_server_settings_description->clearFocus();
|
||||
});
|
||||
}
|
||||
|
||||
void MainWindow::setupSharePageConnections()
|
||||
|
@ -1683,67 +1786,57 @@ void MainWindow::onTrayActionConnect()
|
|||
|
||||
void MainWindow::onPushButtonAddCustomSitesClicked()
|
||||
{
|
||||
if (ui->radioButton_vpn_mode_all_sites->isChecked()) return;
|
||||
Settings::RouteMode mode = m_settings.routeMode();
|
||||
|
||||
QString newSite = ui->lineEdit_sites_add_custom->text();
|
||||
|
||||
if (newSite.isEmpty()) return;
|
||||
if (!newSite.contains(".")) return;
|
||||
|
||||
// get domain name if it present
|
||||
newSite.replace("https://", "");
|
||||
newSite.replace("http://", "");
|
||||
newSite.replace("ftp://", "");
|
||||
if (!Utils::ipAddressWithSubnetRegExp().exactMatch(newSite)) {
|
||||
// get domain name if it present
|
||||
newSite.replace("https://", "");
|
||||
newSite.replace("http://", "");
|
||||
newSite.replace("ftp://", "");
|
||||
|
||||
newSite = newSite.split("/", QString::SkipEmptyParts).first();
|
||||
newSite = newSite.split("/", QString::SkipEmptyParts).first();
|
||||
}
|
||||
|
||||
qDebug() << "Adding site" << newSite;
|
||||
|
||||
QStringList customSites = m_settings.customSites();
|
||||
if (!customSites.contains(newSite)) {
|
||||
customSites.append(newSite);
|
||||
m_settings.setCustomSites(customSites);
|
||||
//qDebug() << "sites:" << m_settings.vpnSites(mode);
|
||||
|
||||
QString newIp = Utils::getIPAddress(newSite);
|
||||
QStringList customIps = m_settings.customIps();
|
||||
if (!newIp.isEmpty() && !customIps.contains(newIp)) {
|
||||
customIps.append(newIp);
|
||||
m_settings.setCustomIps(customIps);
|
||||
const auto &cbProcess = [this, mode](const QString &newSite, const QString &ip) {
|
||||
m_settings.addVpnSite(mode, newSite, ip);
|
||||
|
||||
if (m_vpnConnection->connectionState() == VpnProtocol::ConnectionState::Connected) {
|
||||
if (IpcClient::Interface()) IpcClient::Interface()->routeAddList(m_vpnConnection->vpnProtocol()->vpnGateway(),
|
||||
QStringList() << newIp);
|
||||
}
|
||||
if (m_vpnConnection->connectionState() == VpnProtocol::ConnectionState::Connected) {
|
||||
if (IpcClient::Interface())
|
||||
IpcClient::Interface()->routeAddList(m_vpnConnection->vpnProtocol()->vpnGateway(),
|
||||
QStringList() << ip);
|
||||
}
|
||||
|
||||
updateSitesPage();
|
||||
ui->lineEdit_sites_add_custom->clear();
|
||||
}
|
||||
else {
|
||||
qDebug() << "customSites already contains" << newSite;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
void MainWindow::onPushButtonDeleteCustomSiteClicked(const QString &siteToDelete)
|
||||
{
|
||||
if (siteToDelete.isEmpty()) {
|
||||
const auto &cbResolv = [this, cbProcess](const QHostInfo &hostInfo){
|
||||
const QList<QHostAddress> &addresses = hostInfo.addresses();
|
||||
if (!addresses.isEmpty()) {
|
||||
//qDebug() << "Resolved address for" << hostInfo.hostName() << addresses.first().toString();
|
||||
cbProcess(hostInfo.hostName(), addresses.first().toString());
|
||||
}
|
||||
};
|
||||
|
||||
ui->lineEdit_sites_add_custom->clear();
|
||||
|
||||
if (Utils::ipAddressWithSubnetRegExp().exactMatch(newSite)) {
|
||||
cbProcess(newSite, newSite);
|
||||
return;
|
||||
}
|
||||
|
||||
QString ipToDelete = Utils::getIPAddress(siteToDelete);
|
||||
|
||||
QStringList customSites = m_settings.customSites();
|
||||
customSites.removeAll(siteToDelete);
|
||||
qDebug() << "Deleted custom site:" << siteToDelete;
|
||||
m_settings.setCustomSites(customSites);
|
||||
|
||||
QStringList customIps = m_settings.customIps();
|
||||
customIps.removeAll(ipToDelete);
|
||||
qDebug() << "Deleted custom ip:" << ipToDelete;
|
||||
m_settings.setCustomIps(customIps);
|
||||
|
||||
updateSitesPage();
|
||||
|
||||
if (m_vpnConnection->connectionState() == VpnProtocol::ConnectionState::Connected) {
|
||||
if (IpcClient::Interface()) IpcClient::Interface()->routeDelete(ipToDelete, "");
|
||||
if (IpcClient::Interface()) IpcClient::Interface()->flushDns();
|
||||
else {
|
||||
cbProcess(newSite, "");
|
||||
updateSitesPage();
|
||||
int reqId = QHostInfo::lookupHost(newSite, this, cbResolv);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1769,16 +1862,20 @@ void MainWindow::updateStartPage()
|
|||
|
||||
void MainWindow::updateSitesPage()
|
||||
{
|
||||
ui->listWidget_sites->clear();
|
||||
for (const QString &site : m_settings.customSites()) {
|
||||
makeSitesListItem(ui->listWidget_sites, site);
|
||||
}
|
||||
Settings::RouteMode m = m_settings.routeMode();
|
||||
if (m == Settings::VpnAllSites) return;
|
||||
|
||||
ui->tableView_sites->setModel(sitesModels.value(m));
|
||||
sitesModels.value(m)->resetCache();
|
||||
}
|
||||
|
||||
void MainWindow::updateVpnPage()
|
||||
{
|
||||
ui->radioButton_mode_selected_sites->setChecked(m_settings.customRouting());
|
||||
ui->pushButton_vpn_add_site->setEnabled(m_settings.customRouting());
|
||||
Settings::RouteMode mode = m_settings.routeMode();
|
||||
ui->radioButton_vpn_mode_all_sites->setChecked(mode == Settings::VpnAllSites);
|
||||
ui->radioButton_vpn_mode_forward_sites->setChecked(mode == Settings::VpnOnlyForwardSites);
|
||||
ui->radioButton_vpn_mode_except_sites->setChecked(mode == Settings::VpnAllExceptSites);
|
||||
ui->pushButton_vpn_add_site->setEnabled(mode != Settings::VpnAllSites);
|
||||
}
|
||||
|
||||
void MainWindow::updateAppSettingsPage()
|
||||
|
@ -1868,20 +1965,6 @@ void MainWindow::updateProtocolsPage()
|
|||
ui->frame_openvpn_settings->setVisible(containers.contains(DockerContainer::OpenVpn));
|
||||
}
|
||||
|
||||
void MainWindow::updateShareCodePage()
|
||||
{
|
||||
// QJsonObject o;
|
||||
// o.insert("h", m_settings.serverName());
|
||||
// o.insert("p", m_settings.serverPort());
|
||||
// o.insert("u", m_settings.userName());
|
||||
// o.insert("w", m_settings.password());
|
||||
|
||||
// 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();
|
||||
}
|
||||
|
||||
void MainWindow::updateOpenVpnPage(const QJsonObject &openvpnConfig, DockerContainer container, bool haveAuthData)
|
||||
{
|
||||
ui->widget_proto_openvpn->setEnabled(haveAuthData);
|
||||
|
@ -1968,34 +2051,43 @@ void MainWindow::updateSharingPage(int serverIndex, const ServerCredentials &cre
|
|||
|
||||
const QJsonObject &containerConfig = m_settings.containerConfig(serverIndex, container);
|
||||
|
||||
for (QWidget *page : { ui->page_share_openvpn,
|
||||
ui->page_share_shadowsocks,
|
||||
ui->page_share_cloak,
|
||||
ui->page_share_full_access }) {
|
||||
for (QWidget *page : {
|
||||
ui->page_share_amnezia,
|
||||
ui->page_share_openvpn,
|
||||
ui->page_share_shadowsocks,
|
||||
ui->page_share_cloak,
|
||||
ui->page_share_full_access }) {
|
||||
|
||||
ui->toolBox_share_connection->removeItem(ui->toolBox_share_connection->indexOf(page));
|
||||
page->hide();
|
||||
}
|
||||
|
||||
if (container == DockerContainer::OpenVpn) {
|
||||
ui->toolBox_share_connection->addItem(ui->page_share_amnezia, tr(" Share for Amnezia client"));
|
||||
ui->toolBox_share_connection->addItem(ui->page_share_openvpn, tr(" Share for OpenVPN client"));
|
||||
|
||||
QJsonObject protoConfig = m_settings.protocolConfig(serverIndex, container, Protocol::OpenVpn);
|
||||
QString cfg = protoConfig.value(config_key::last_config).toString();
|
||||
if (!cfg.isEmpty()) {
|
||||
// TODO add redirect-gateway def1 bypass-dhcp here and on click Generate config
|
||||
ui->textEdit_share_openvpn_code->setPlainText(cfg);
|
||||
}
|
||||
else {
|
||||
cfg = tr("Press Generate config");
|
||||
ui->textEdit_share_openvpn_code->setPlainText(cfg);
|
||||
ui->pushButton_share_openvpn_copy->setEnabled(false);
|
||||
ui->pushButton_share_openvpn_save->setEnabled(false);
|
||||
}
|
||||
QString cfg = tr("Press Generate config");
|
||||
ui->textEdit_share_openvpn_code->setPlainText(cfg);
|
||||
ui->pushButton_share_openvpn_copy->setEnabled(false);
|
||||
ui->pushButton_share_openvpn_save->setEnabled(false);
|
||||
|
||||
// QJsonObject protoConfig = m_settings.protocolConfig(serverIndex, container, Protocol::OpenVpn);
|
||||
// QString cfg = protoConfig.value(config_key::last_config).toString();
|
||||
// if (!cfg.isEmpty()) {
|
||||
// // TODO add redirect-gateway def1 bypass-dhcp here and on click Generate config
|
||||
// ui->textEdit_share_openvpn_code->setPlainText(cfg);
|
||||
// }
|
||||
// else {
|
||||
// cfg = tr("Press Generate config");
|
||||
// ui->textEdit_share_openvpn_code->setPlainText(cfg);
|
||||
// ui->pushButton_share_openvpn_copy->setEnabled(false);
|
||||
// ui->pushButton_share_openvpn_save->setEnabled(false);
|
||||
// }
|
||||
ui->toolBox_share_connection->setCurrentWidget(ui->page_share_openvpn);
|
||||
}
|
||||
|
||||
if (container == DockerContainer::OpenVpnOverShadowSocks) {
|
||||
ui->toolBox_share_connection->addItem(ui->page_share_amnezia, tr(" Share for Amnezia client"));
|
||||
ui->toolBox_share_connection->addItem(ui->page_share_shadowsocks, tr(" Share for ShadowSocks client"));
|
||||
|
||||
QJsonObject protoConfig = m_settings.protocolConfig(serverIndex, container, Protocol::ShadowSocks);
|
||||
|
@ -2034,6 +2126,24 @@ void MainWindow::updateSharingPage(int serverIndex, const ServerCredentials &cre
|
|||
ui->toolBox_share_connection->layout()->update();
|
||||
}
|
||||
|
||||
if (container == DockerContainer::OpenVpnOverCloak) {
|
||||
ui->toolBox_share_connection->addItem(ui->page_share_amnezia, tr(" Share for Amnezia client"));
|
||||
}
|
||||
|
||||
// Full access
|
||||
if (container == DockerContainer::None) {
|
||||
ui->toolBox_share_connection->addItem(ui->page_share_full_access, tr(" Share server full access"));
|
||||
|
||||
const QJsonObject &server = m_settings.server(selectedServerIndex);
|
||||
|
||||
QByteArray ba = QJsonDocument(server).toJson().toBase64(QByteArray::Base64UrlEncoding | QByteArray::OmitTrailingEquals);
|
||||
|
||||
ui->textEdit_share_full_code->setText(QString("vpn://%1").arg(QString(ba)));
|
||||
ui->toolBox_share_connection->setCurrentWidget(ui->page_share_full_access);
|
||||
}
|
||||
|
||||
//ui->toolBox_share_connection->addItem(ui->page_share_amnezia, tr(" Share for Amnezia client"));
|
||||
|
||||
// Amnezia sharing
|
||||
// QJsonObject exportContainer;
|
||||
// for (Protocol p: protocolsForContainer(container)) {
|
||||
|
@ -2046,38 +2156,6 @@ void MainWindow::updateSharingPage(int serverIndex, const ServerCredentials &cre
|
|||
// ui->textEdit_share_amnezia_code->setPlainText(QJsonDocument(exportContainer).toJson());
|
||||
|
||||
ui->textEdit_share_amnezia_code->setPlainText(tr(""));
|
||||
repaint();
|
||||
update();
|
||||
updateGeometry();
|
||||
}
|
||||
|
||||
void MainWindow::makeSitesListItem(QListWidget *listWidget, const QString &address)
|
||||
{
|
||||
QSize size(310, 25);
|
||||
QWidget* widget = new QWidget;
|
||||
widget->resize(size);
|
||||
|
||||
QLabel *label = new QLabel(address, widget);
|
||||
label->resize(size);
|
||||
|
||||
QPushButton* btn = new QPushButton(widget);
|
||||
btn->resize(size);
|
||||
|
||||
QPushButton* btn1 = new QPushButton(widget);
|
||||
btn1->resize(30, 25);
|
||||
btn1->move(280, 0);
|
||||
btn1->setCursor(QCursor(Qt::PointingHandCursor));
|
||||
|
||||
connect(btn1, &QPushButton::clicked, this, [this, label]() {
|
||||
onPushButtonDeleteCustomSiteClicked(label->text());
|
||||
return;
|
||||
});
|
||||
|
||||
QListWidgetItem* item = new QListWidgetItem(listWidget);
|
||||
item->setSizeHint(size);
|
||||
listWidget->setItemWidget(item, widget);
|
||||
|
||||
widget->setStyleSheet(styleSheet());
|
||||
}
|
||||
|
||||
void MainWindow::makeServersListItem(QListWidget *listWidget, const QJsonObject &server, bool isDefault, int index)
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
#include "protocols/vpnprotocol.h"
|
||||
|
||||
#include "settings.h"
|
||||
#include "sites_model.h"
|
||||
|
||||
class VpnConnection;
|
||||
|
||||
|
@ -63,7 +64,6 @@ private slots:
|
|||
void onPushButtonForgetServer(bool);
|
||||
|
||||
void onPushButtonAddCustomSitesClicked();
|
||||
void onPushButtonDeleteCustomSiteClicked(const QString &siteToDelete);
|
||||
|
||||
void onTrayActionConnect(); // connect from context menu
|
||||
void setTrayState(VpnProtocol::ConnectionState state);
|
||||
|
@ -94,6 +94,8 @@ private:
|
|||
void setupUiConnections();
|
||||
void setupNewServerConnections();
|
||||
void setupWizardConnections();
|
||||
void setupVpnPageConnections();
|
||||
void setupSitesPageConnections();
|
||||
void setupAppSettingsConnections();
|
||||
void setupGeneralSettingsConnections();
|
||||
void setupNetworkSettingsConnections();
|
||||
|
@ -110,7 +112,6 @@ private:
|
|||
void updateServerPage();
|
||||
void updateServersListPage();
|
||||
void updateProtocolsPage();
|
||||
void updateShareCodePage();
|
||||
void updateOpenVpnPage(const QJsonObject &openvpnConfig, DockerContainer container, bool haveAuthData);
|
||||
void updateShadowSocksPage(const QJsonObject &ssConfig, DockerContainer container, bool haveAuthData);
|
||||
void updateCloakPage(const QJsonObject &ckConfig, DockerContainer container, bool haveAuthData);
|
||||
|
@ -118,7 +119,6 @@ private:
|
|||
void updateSharingPage(int serverIndex, const ServerCredentials &credentials,
|
||||
DockerContainer container);
|
||||
|
||||
void makeSitesListItem(QListWidget* listWidget, const QString &address);
|
||||
void makeServersListItem(QListWidget* listWidget, const QJsonObject &server, bool isDefault, int index);
|
||||
|
||||
void updateQRCodeImage(const QString &text, QLabel *label);
|
||||
|
@ -135,6 +135,8 @@ private:
|
|||
VpnConnection* m_vpnConnection;
|
||||
Settings m_settings;
|
||||
|
||||
QMap<Settings::RouteMode, SitesModel *> sitesModels;
|
||||
|
||||
QAction* m_trayActionConnect;
|
||||
QAction* m_trayActionDisconnect;
|
||||
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string/>
|
||||
<string>AmneziaVPN</string>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true">QMainWindow {
|
||||
|
@ -120,18 +120,18 @@ border-image: url(:/images/controls/check_on.png);
|
|||
}
|
||||
|
||||
|
||||
|
||||
QScrollBar:vertical { /* The area behind the scrollbar covering entire height. */
|
||||
background-color: grey;
|
||||
background-color: rgba(0, 0, 0,0);
|
||||
opacity: 100;
|
||||
width: 7px; /* set width to zero to hide scrollbar entirely. Can look quite clean and scrolling still works with mousewheel. */
|
||||
margin: 0px 0px; /* Takes the height of the buttons + 3 extra pixels to leave some free space between handle and buttons */
|
||||
width: 10px; /* set width to zero to hide scrollbar entirely. Can look quite clean and scrolling still works with mousewheel. */
|
||||
margin: 10px px; /* Takes the height of the buttons + 3 extra pixels to leave some free space between handle and buttons */
|
||||
|
||||
}
|
||||
|
||||
QScrollBar::handle:vertical { /* The handle you scroll with */
|
||||
image-position: center; /* image is used as a small gripper in the center of the scrollbar.. You can also use background-image to use two images */
|
||||
background-color: rgb(200, 200, 200);
|
||||
border: 2px solid rgb(240,240,240);
|
||||
border-radius: 1px;
|
||||
min-height: 10px;
|
||||
}
|
||||
|
@ -143,7 +143,7 @@ QScrollBar::handle:vertical:pressed { /* state when you hover over the handle */
|
|||
}
|
||||
QScrollBar::sub-line:vertical { /* button to scroll up */
|
||||
background-color: rgb(240,240,240);
|
||||
height: 0px;
|
||||
height: 10px;
|
||||
subcontrol-position: top;
|
||||
subcontrol-origin: margin;
|
||||
}
|
||||
|
@ -158,7 +158,8 @@ QScrollBar::up-arrow:vertical { /* arrow to scroll up with */
|
|||
|
||||
QScrollBar::add-line:vertical { /* Button to scroll down */
|
||||
background-color: rgb(240,240,240);
|
||||
height: 0px;
|
||||
height: 10px;
|
||||
padding-top: 2px;
|
||||
subcontrol-position: bottom;
|
||||
subcontrol-origin: margin;
|
||||
}
|
||||
|
@ -171,27 +172,9 @@ QScrollBar::down-arrow:vertical { /* arrow to scroll down with */
|
|||
}
|
||||
|
||||
QScrollBar::add-page:vertical, QScrollBar::sub-page:vertical {
|
||||
background-color: black;
|
||||
}
|
||||
background-color: rgb(240,240,240);
|
||||
|
||||
/*
|
||||
QGroupBox {
|
||||
border: 1px solid lightgray;
|
||||
border-radius: 2px;
|
||||
margin-top: 1ex;
|
||||
}
|
||||
|
||||
QGroupBox::title {
|
||||
font-size: 16px;
|
||||
font-style: normal;
|
||||
font-weight: normal;
|
||||
color: #181922;
|
||||
|
||||
subcontrol-origin: margin;
|
||||
subcontrol-position: top left;
|
||||
padding: 0 3px;
|
||||
}
|
||||
*/</string>
|
||||
}</string>
|
||||
</property>
|
||||
<widget class="QWidget" name="centralWidget">
|
||||
<property name="styleSheet">
|
||||
|
@ -291,7 +274,7 @@ QPushButton:hover {
|
|||
<string notr="true"/>
|
||||
</property>
|
||||
<property name="currentIndex">
|
||||
<number>1</number>
|
||||
<number>10</number>
|
||||
</property>
|
||||
<widget class="QWidget" name="page_start">
|
||||
<widget class="QLabel" name="label_25">
|
||||
|
@ -2720,7 +2703,7 @@ background: #211966;
|
|||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>370</y>
|
||||
<y>360</y>
|
||||
<width>380</width>
|
||||
<height>51</height>
|
||||
</rect>
|
||||
|
@ -2826,7 +2809,7 @@ font: 16px "Lato"; </string>
|
|||
<property name="geometry">
|
||||
<rect>
|
||||
<x>20</x>
|
||||
<y>550</y>
|
||||
<y>560</y>
|
||||
<width>341</width>
|
||||
<height>40</height>
|
||||
</rect>
|
||||
|
@ -2960,9 +2943,9 @@ color: #181922;
|
|||
<property name="geometry">
|
||||
<rect>
|
||||
<x>20</x>
|
||||
<y>450</y>
|
||||
<y>440</y>
|
||||
<width>281</width>
|
||||
<height>31</height>
|
||||
<height>21</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
|
@ -2983,49 +2966,11 @@ color: #181922;
|
|||
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QRadioButton" name="radioButton_mode_all_sites">
|
||||
<property name="enabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>20</x>
|
||||
<y>490</y>
|
||||
<width>341</width>
|
||||
<height>19</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>For all connections</string>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QRadioButton" name="radioButton_mode_selected_sites">
|
||||
<property name="enabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>20</x>
|
||||
<y>520</y>
|
||||
<width>341</width>
|
||||
<height>19</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>For selected sites</string>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QLabel" name="label_error_text">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>290</y>
|
||||
<y>280</y>
|
||||
<width>381</width>
|
||||
<height>61</height>
|
||||
</rect>
|
||||
|
@ -3043,10 +2988,77 @@ color: #181922;
|
|||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QWidget" name="widget_vpn_mode" native="true">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>20</x>
|
||||
<y>470</y>
|
||||
<width>351</width>
|
||||
<height>91</height>
|
||||
</rect>
|
||||
</property>
|
||||
<widget class="QRadioButton" name="radioButton_vpn_mode_except_sites">
|
||||
<property name="enabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>60</y>
|
||||
<width>341</width>
|
||||
<height>19</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Except selected sites</string>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QRadioButton" name="radioButton_vpn_mode_forward_sites">
|
||||
<property name="enabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>30</y>
|
||||
<width>341</width>
|
||||
<height>19</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>For selected sites</string>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QRadioButton" name="radioButton_vpn_mode_all_sites">
|
||||
<property name="enabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>341</width>
|
||||
<height>19</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>For all connections</string>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</widget>
|
||||
</widget>
|
||||
<widget class="QWidget" name="page_sites">
|
||||
<property name="styleSheet">
|
||||
<string notr="true">QListView {
|
||||
<string notr="true">/*QListView {
|
||||
outline: 0;
|
||||
background: transparent;
|
||||
border: none;
|
||||
|
@ -3071,7 +3083,8 @@ QListView::item:selected {
|
|||
border: none;
|
||||
background: rgba(167, 167, 167, 0.1);
|
||||
color: #181922;
|
||||
}</string>
|
||||
}
|
||||
*/</string>
|
||||
</property>
|
||||
<widget class="QPushButton" name="pushButton_back_from_sites">
|
||||
<property name="geometry">
|
||||
|
@ -3160,7 +3173,7 @@ color: #100A44;
|
|||
<rect>
|
||||
<x>20</x>
|
||||
<y>140</y>
|
||||
<width>281</width>
|
||||
<width>231</width>
|
||||
<height>31</height>
|
||||
</rect>
|
||||
</property>
|
||||
|
@ -3191,7 +3204,7 @@ color: #100A44;
|
|||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
<property name="placeholderText">
|
||||
<string>For example, yousite.com or 17.21.111.8</string>
|
||||
<string>yousite.com or IP address</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QPushButton" name="pushButton_sites_add_custom">
|
||||
|
@ -3200,7 +3213,7 @@ color: #100A44;
|
|||
</property>
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>310</x>
|
||||
<x>260</x>
|
||||
<y>140</y>
|
||||
<width>51</width>
|
||||
<height>31</height>
|
||||
|
@ -3246,50 +3259,127 @@ line-height: 150%;
|
|||
color: #333333;</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Web site or hostname or IP address</string>
|
||||
<string>Web site/Hostname/IP address/Subnet</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QListWidget" name="listWidget_sites">
|
||||
<widget class="QTableView" name="tableView_sites">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>20</x>
|
||||
<y>200</y>
|
||||
<width>340</width>
|
||||
<height>400</height>
|
||||
<width>341</width>
|
||||
<height>371</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true">QWidget {
|
||||
margin: 0px;
|
||||
padding: 0px;
|
||||
}
|
||||
|
||||
QPushButton:hover {
|
||||
image: url(:/images/close.png);
|
||||
image-position: right center;
|
||||
}
|
||||
|
||||
QListView {
|
||||
show-decoration-selected: 1; /* make the selection span the entire width of the view */
|
||||
}
|
||||
|
||||
QListView::item:selected:!active {
|
||||
<string notr="true">QTableView {
|
||||
background: transparent;
|
||||
gridline-color: transparent;
|
||||
|
||||
border: none;
|
||||
outline: none;
|
||||
show-decoration-selected: 1;
|
||||
}
|
||||
|
||||
QListView::item:selected:active {
|
||||
background: transparent;
|
||||
border: none;
|
||||
QTableView::item
|
||||
{
|
||||
padding-left: 5px;
|
||||
border-top: 1px solid lightgray;
|
||||
color: #181922;
|
||||
}
|
||||
|
||||
QListView::item:hover {
|
||||
background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1,
|
||||
stop: 0 #FAFBFE, stop: 1 #ECEEFF);
|
||||
QTableView::item::selected
|
||||
{
|
||||
border: 0px;
|
||||
padding-left: 5px;
|
||||
background-color: rgb(99, 180, 251);
|
||||
border: : rgb(99, 180, 251);
|
||||
}</string>
|
||||
</property>
|
||||
<property name="selectionMode">
|
||||
<enum>QAbstractItemView::NoSelection</enum>
|
||||
<enum>QAbstractItemView::ExtendedSelection</enum>
|
||||
</property>
|
||||
<property name="selectionBehavior">
|
||||
<enum>QAbstractItemView::SelectRows</enum>
|
||||
</property>
|
||||
<property name="showGrid">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="gridStyle">
|
||||
<enum>Qt::NoPen</enum>
|
||||
</property>
|
||||
<property name="cornerButtonEnabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<attribute name="horizontalHeaderVisible">
|
||||
<bool>false</bool>
|
||||
</attribute>
|
||||
<attribute name="verticalHeaderVisible">
|
||||
<bool>false</bool>
|
||||
</attribute>
|
||||
</widget>
|
||||
<widget class="QPushButton" name="pushButton_sites_delete">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>80</x>
|
||||
<y>589</y>
|
||||
<width>231</width>
|
||||
<height>31</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="cursor">
|
||||
<cursorShape>PointingHandCursor</cursorShape>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true">QPushButton {
|
||||
color:rgb(212, 212, 212);
|
||||
border-radius: 4px;
|
||||
|
||||
font-family: Lato;
|
||||
font-style: normal;
|
||||
font-weight: normal;
|
||||
font-size: 16px;
|
||||
line-height: 21px;
|
||||
|
||||
background: #100A44;
|
||||
border-radius: 4px;
|
||||
}
|
||||
QPushButton:hover {
|
||||
background: #211966;
|
||||
}</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Delete selected</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QPushButton" name="pushButton_sites_import">
|
||||
<property name="enabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>320</x>
|
||||
<y>140</y>
|
||||
<width>51</width>
|
||||
<height>31</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="cursor">
|
||||
<cursorShape>PointingHandCursor</cursorShape>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true">QPushButton {
|
||||
background: #100A44;
|
||||
border-radius: 4px;
|
||||
padding: 5px;
|
||||
image: url(:/images/folder.png);
|
||||
}
|
||||
QPushButton:hover {
|
||||
background: #211966;
|
||||
}</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</widget>
|
||||
|
@ -4471,7 +4561,7 @@ font-weight: bold;
|
|||
<property name="geometry">
|
||||
<rect>
|
||||
<x>40</x>
|
||||
<y>220</y>
|
||||
<y>210</y>
|
||||
<width>300</width>
|
||||
<height>40</height>
|
||||
</rect>
|
||||
|
@ -4528,6 +4618,40 @@ font-size: 20px;
|
|||
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QPushButton" name="pushButton_server_settings_share_full">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>40</x>
|
||||
<y>260</y>
|
||||
<width>300</width>
|
||||
<height>40</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="cursor">
|
||||
<cursorShape>PointingHandCursor</cursorShape>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true">QPushButton {
|
||||
color:rgb(212, 212, 212);
|
||||
border-radius: 4px;
|
||||
|
||||
font-family: Lato;
|
||||
font-style: normal;
|
||||
font-weight: normal;
|
||||
font-size: 16px;
|
||||
line-height: 21px;
|
||||
|
||||
background: #100A44;
|
||||
border-radius: 4px;
|
||||
}
|
||||
QPushButton:hover {
|
||||
background: #211966;
|
||||
}</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Share Server (FULL ACCESS)</string>
|
||||
</property>
|
||||
</widget>
|
||||
<zorder>label_server_settings_wait_info</zorder>
|
||||
<zorder>label_16</zorder>
|
||||
<zorder>label_17</zorder>
|
||||
|
@ -4539,6 +4663,7 @@ font-size: 20px;
|
|||
<zorder>pushButton_server_settings_protocols</zorder>
|
||||
<zorder>pushButton_back_from_server_settings</zorder>
|
||||
<zorder>label_server_settings_current_vpn_protocol</zorder>
|
||||
<zorder>pushButton_server_settings_share_full</zorder>
|
||||
</widget>
|
||||
<widget class="QWidget" name="page_server_protocols">
|
||||
<property name="styleSheet">
|
||||
|
@ -5284,7 +5409,30 @@ border-radius: 4px 0px 0px 4px;
|
|||
</widget>
|
||||
<widget class="QWidget" name="page_share_connection">
|
||||
<property name="styleSheet">
|
||||
<string notr="true"/>
|
||||
<string notr="true">QScrollBar::sub-line:vertical { /* button to scroll up */
|
||||
border-top-right-radius: 3px;
|
||||
background-color: rgb(240,240,240);
|
||||
height: 10px;
|
||||
subcontrol-position: top;
|
||||
subcontrol-origin: margin;
|
||||
margin-top: 3px;
|
||||
}
|
||||
|
||||
|
||||
QScrollBar::add-line:vertical { /* Button to scroll down */
|
||||
border-bottom-right-radius: 3px;
|
||||
background-color: rgb(240,240,240);
|
||||
height: 10px;
|
||||
padding-top: 2px;
|
||||
subcontrol-position: bottom;
|
||||
subcontrol-origin: margin;
|
||||
margin-bottom: 3px;
|
||||
}
|
||||
|
||||
|
||||
QScrollBar::add-page:vertical, QScrollBar::sub-page:vertical {
|
||||
background-color: rgb(240,240,240);
|
||||
}</string>
|
||||
</property>
|
||||
<widget class="QPushButton" name="pushButton_back_from_share">
|
||||
<property name="geometry">
|
||||
|
@ -5391,7 +5539,7 @@ QToolBox::tab:hover {
|
|||
<number>0</number>
|
||||
</property>
|
||||
<property name="currentIndex">
|
||||
<number>1</number>
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="tabSpacing">
|
||||
<number>6</number>
|
||||
|
@ -5401,8 +5549,8 @@ QToolBox::tab:hover {
|
|||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>100</width>
|
||||
<height>30</height>
|
||||
<width>360</width>
|
||||
<height>360</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
|
@ -5725,8 +5873,8 @@ background: #282932;
|
|||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>100</width>
|
||||
<height>30</height>
|
||||
<width>360</width>
|
||||
<height>360</height>
|
||||
</rect>
|
||||
</property>
|
||||
<attribute name="label">
|
||||
|
@ -5891,8 +6039,8 @@ background: #282932;
|
|||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>100</width>
|
||||
<height>30</height>
|
||||
<width>360</width>
|
||||
<height>360</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
|
@ -6115,8 +6263,8 @@ color: #15CDCB;
|
|||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>100</width>
|
||||
<height>30</height>
|
||||
<width>360</width>
|
||||
<height>360</height>
|
||||
</rect>
|
||||
</property>
|
||||
<attribute name="label">
|
||||
|
|
72
client/ui/sites_model.cpp
Normal file
72
client/ui/sites_model.cpp
Normal file
|
@ -0,0 +1,72 @@
|
|||
#include "sites_model.h"
|
||||
|
||||
SitesModel::SitesModel(Settings::RouteMode mode, QObject *parent)
|
||||
: m_mode(mode),
|
||||
QAbstractTableModel(parent)
|
||||
{
|
||||
}
|
||||
|
||||
void SitesModel::resetCache()
|
||||
{
|
||||
beginResetModel();
|
||||
m_ipsCache.clear();
|
||||
m_cacheReady = false;
|
||||
endResetModel();
|
||||
}
|
||||
|
||||
QVariant SitesModel::headerData(int section, Qt::Orientation orientation, int role) const
|
||||
{
|
||||
// FIXME: Implement me!
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
int SitesModel::rowCount(const QModelIndex &parent) const
|
||||
{
|
||||
if (!m_cacheReady) genCache();
|
||||
return m_ipsCache.size();
|
||||
}
|
||||
|
||||
int SitesModel::columnCount(const QModelIndex &parent) const
|
||||
{
|
||||
return 2;
|
||||
}
|
||||
|
||||
QVariant SitesModel::data(const QModelIndex &index, int role) const
|
||||
{
|
||||
if (!index.isValid())
|
||||
return QVariant();
|
||||
|
||||
if (!m_cacheReady) genCache();
|
||||
|
||||
if (role == Qt::DisplayRole){
|
||||
if (m_ipsCache.isEmpty()) return QVariant();
|
||||
|
||||
if (index.column() == 0) {
|
||||
return m_ipsCache.at(index.row()).first;
|
||||
}
|
||||
if (index.column() == 1) {
|
||||
return m_ipsCache.at(index.row()).second;
|
||||
}
|
||||
}
|
||||
|
||||
// if (role == Qt::TextAlignmentRole && index.column() == 1) {
|
||||
// return Qt::AlignRight;
|
||||
// }
|
||||
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
void SitesModel::genCache() const
|
||||
{
|
||||
qDebug() << "SitesModel::genCache";
|
||||
m_ipsCache.clear();
|
||||
|
||||
const QVariantMap &sites = m_settings.vpnSites(m_mode);
|
||||
auto i = sites.constBegin();
|
||||
while (i != sites.constEnd()) {
|
||||
m_ipsCache.append(qMakePair(i.key(), i.value().toString()));
|
||||
++i;
|
||||
}
|
||||
|
||||
m_cacheReady= true;
|
||||
}
|
36
client/ui/sites_model.h
Normal file
36
client/ui/sites_model.h
Normal file
|
@ -0,0 +1,36 @@
|
|||
#ifndef SITESMODEL_H
|
||||
#define SITESMODEL_H
|
||||
|
||||
#include <QAbstractTableModel>
|
||||
|
||||
#include "settings.h"
|
||||
|
||||
class SitesModel : public QAbstractTableModel
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit SitesModel(Settings::RouteMode mode, QObject *parent = nullptr);
|
||||
void resetCache();
|
||||
|
||||
// Header:
|
||||
QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override;
|
||||
|
||||
// Basic functionality:
|
||||
int rowCount(const QModelIndex &parent = QModelIndex()) const override;
|
||||
int columnCount(const QModelIndex &parent = QModelIndex()) const override;
|
||||
|
||||
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
|
||||
|
||||
private:
|
||||
void genCache() const;
|
||||
|
||||
private:
|
||||
Settings::RouteMode m_mode;
|
||||
Settings m_settings;
|
||||
|
||||
mutable QVector<QPair<QString, QString>> m_ipsCache;
|
||||
mutable bool m_cacheReady = false;
|
||||
};
|
||||
|
||||
#endif // SITESMODEL_H
|
|
@ -146,7 +146,7 @@ bool Utils::checkIPFormat(const QString& ip)
|
|||
return false;
|
||||
|
||||
QStringList list = ip.trimmed().split(".");
|
||||
foreach(QString it, list) {
|
||||
for (const QString &it : list) {
|
||||
if(it.toInt() <= 255 && it.toInt() >= 0)
|
||||
continue;
|
||||
return false;
|
||||
|
@ -154,6 +154,18 @@ bool Utils::checkIPFormat(const QString& ip)
|
|||
return true;
|
||||
}
|
||||
|
||||
bool Utils::checkIpSubnetFormat(const QString &ip)
|
||||
{
|
||||
if (!ip.contains("/")) return checkIPFormat(ip);
|
||||
|
||||
QStringList parts = ip.split("/");
|
||||
if (parts.size() != 2) return false;
|
||||
|
||||
bool ok;
|
||||
if (parts.at(1).toInt(&ok) <= 32 && ok) return checkIPFormat(parts.at(0));
|
||||
else return false;
|
||||
}
|
||||
|
||||
void Utils::killProcessByName(const QString &name)
|
||||
{
|
||||
qDebug().noquote() << "Kill process" << name;
|
||||
|
@ -164,6 +176,28 @@ void Utils::killProcessByName(const QString &name)
|
|||
#endif
|
||||
}
|
||||
|
||||
QString Utils::netMaskFromIpWithSubnet(const QString ip)
|
||||
{
|
||||
if (!ip.contains("/")) return "255.255.255.255";
|
||||
|
||||
bool ok;
|
||||
int prefix = ip.split("/").at(1).toInt(&ok);
|
||||
if (!ok) return "255.255.255.255";
|
||||
|
||||
unsigned long mask = (0xFFFFFFFF << (32 - prefix)) & 0xFFFFFFFF;
|
||||
|
||||
return QString("%1.%2.%3.%4")
|
||||
.arg(mask >> 24)
|
||||
.arg((mask >> 16) & 0xFF)
|
||||
.arg((mask >> 8) & 0xFF)
|
||||
.arg( mask & 0xFF);
|
||||
}
|
||||
|
||||
QString Utils::ipAddressFromIpWithSubnet(const QString ip)
|
||||
{
|
||||
return ip.split("/").first();
|
||||
}
|
||||
|
||||
#ifdef Q_OS_WIN
|
||||
// Inspired from http://stackoverflow.com/a/15281070/1529139
|
||||
// and http://stackoverflow.com/q/40059902/1529139
|
||||
|
|
|
@ -23,10 +23,14 @@ public:
|
|||
static QString getIPAddress(const QString& host);
|
||||
static QString getStringBetween(const QString& s, const QString& a, const QString& b);
|
||||
static bool checkIPFormat(const QString& ip);
|
||||
static bool checkIpSubnetFormat(const QString& ip);
|
||||
static QRegExp ipAddressRegExp() { return QRegExp("^((25[0-5]|(2[0-4]|1[0-9]|[1-9]|)[0-9])(\\.(?!$)|$)){4}$"); }
|
||||
static QRegExp ipAddressPortRegExp() { return QRegExp("^(?:(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\\.){3}"
|
||||
"(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])(\\:[0-9]{1,5}){0,1}$"); }
|
||||
|
||||
static QRegExp ipAddressWithSubnetRegExp() { return QRegExp("(?:(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\\.){3}"
|
||||
"(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])(\\/[0-9]{1,2}){0,1}"); }
|
||||
|
||||
static QRegExp ipNetwork24RegExp() { return QRegExp("^(?:(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\\.){3}"
|
||||
"0$"); }
|
||||
|
||||
|
@ -35,6 +39,9 @@ public:
|
|||
static bool processIsRunning(const QString& fileName);
|
||||
static void killProcessByName(const QString &name);
|
||||
|
||||
static QString netMaskFromIpWithSubnet(const QString ip);
|
||||
static QString ipAddressFromIpWithSubnet(const QString ip);
|
||||
|
||||
#ifdef Q_OS_WIN
|
||||
static bool signalCtrl(DWORD dwProcessId, DWORD dwCtrlEvent);
|
||||
#endif
|
||||
|
|
|
@ -43,22 +43,22 @@ void VpnConnection::onConnectionStateChanged(VpnProtocol::ConnectionState state)
|
|||
if (state == VpnProtocol::ConnectionState::Connected && IpcClient::Interface()){
|
||||
IpcClient::Interface()->flushDns();
|
||||
|
||||
if (m_settings.customRouting()) {
|
||||
if (m_settings.routeMode() == Settings::VpnOnlyForwardSites) {
|
||||
IpcClient::Interface()->routeDelete("0.0.0.0", m_vpnProtocol->vpnGateway());
|
||||
|
||||
IpcClient::Interface()->routeAddList(m_vpnProtocol->vpnGateway(),
|
||||
QStringList() << m_settings.primaryDns() << m_settings.secondaryDns());
|
||||
|
||||
const QStringList &black_custom = m_settings.customIps();
|
||||
qDebug() << "VpnConnection::onConnectionStateChanged :: adding custom routes, count:" << black_custom.size();
|
||||
const QStringList &forwardIps = m_settings.getVpnIps(Settings::VpnOnlyForwardSites);
|
||||
qDebug() << "VpnConnection::onConnectionStateChanged :: adding custom routes, count:" << forwardIps.size();
|
||||
|
||||
IpcClient::Interface()->routeAddList(m_vpnProtocol->vpnGateway(), black_custom);
|
||||
IpcClient::Interface()->routeAddList(m_vpnProtocol->vpnGateway(), forwardIps);
|
||||
}
|
||||
}
|
||||
else if (state == VpnProtocol::ConnectionState::Error) {
|
||||
IpcClient::Interface()->flushDns();
|
||||
|
||||
if (m_settings.customRouting()) {
|
||||
if (m_settings.routeMode() == Settings::VpnOnlyForwardSites) {
|
||||
IpcClient::Interface()->clearSavedRoutes();
|
||||
}
|
||||
}
|
||||
|
@ -199,7 +199,7 @@ ErrorCode VpnConnection::createVpnConfiguration(int serverIndex,
|
|||
|
||||
ErrorCode VpnConnection::connectToVpn(int serverIndex, const ServerCredentials &credentials, DockerContainer container, const QJsonObject &containerConfig)
|
||||
{
|
||||
qDebug() << "СonnectToVpn, CustomRouting is" << m_settings.customRouting();
|
||||
qDebug() << "СonnectToVpn, Route mode is" << m_settings.routeMode();
|
||||
|
||||
emit connectionStateChanged(VpnProtocol::ConnectionState::Connecting);
|
||||
|
||||
|
@ -276,7 +276,7 @@ void VpnConnection::disconnectFromVpn()
|
|||
if (IpcClient::Interface()) {
|
||||
IpcClient::Interface()->flushDns();
|
||||
|
||||
if (m_settings.customRouting()) {
|
||||
if (m_settings.routeMode() == Settings::VpnOnlyForwardSites) {
|
||||
IpcClient::Interface()->clearSavedRoutes();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,7 +7,7 @@ class IpcInterface
|
|||
//SIGNAL(sendMessage(const QByteArray &message));
|
||||
|
||||
// Route functions
|
||||
SLOT( bool routeAdd(const QString &ip, const QString &gw, const QString &mask) );
|
||||
SLOT( bool routeAdd(const QString &ip, const QString &gw) );
|
||||
SLOT( int routeAddList(const QString &gw, const QStringList &ips) );
|
||||
SLOT( bool clearSavedRoutes() );
|
||||
SLOT( bool routeDelete(const QString &ip, const QString &gw) );
|
||||
|
|
|
@ -53,9 +53,9 @@ int IpcServer::createPrivilegedProcess()
|
|||
return m_localpid;
|
||||
}
|
||||
|
||||
bool IpcServer::routeAdd(const QString &ip, const QString &gw, const QString &mask)
|
||||
bool IpcServer::routeAdd(const QString &ip, const QString &gw)
|
||||
{
|
||||
return Router::routeAdd(ip, gw, mask);
|
||||
return Router::routeAdd(ip, gw);
|
||||
}
|
||||
|
||||
int IpcServer::routeAddList(const QString &gw, const QStringList &ips)
|
||||
|
|
|
@ -15,7 +15,7 @@ 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 bool routeAdd(const QString &ip, const QString &gw) override;
|
||||
virtual int routeAddList(const QString &gw, const QStringList &ips) override;
|
||||
virtual bool clearSavedRoutes() override;
|
||||
virtual bool routeDelete(const QString &ip, const QString &gw) override;
|
||||
|
|
|
@ -7,12 +7,12 @@
|
|||
#endif
|
||||
|
||||
|
||||
bool Router::routeAdd(const QString &ip, const QString &gw, QString mask)
|
||||
bool Router::routeAdd(const QString &ip, const QString &gw)
|
||||
{
|
||||
#ifdef Q_OS_WIN
|
||||
return RouterWin::Instance().routeAdd(ip, gw, mask);
|
||||
return RouterWin::Instance().routeAdd(ip, gw);
|
||||
#elif defined (Q_OS_MAC)
|
||||
return RouterMac::Instance().routeAdd(ip, gw, mask);
|
||||
return RouterMac::Instance().routeAdd(ip, gw);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
|
@ -15,7 +15,7 @@ class Router : public QObject
|
|||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
static bool routeAdd(const QString &ip, const QString &gw, QString mask = QString());
|
||||
static bool routeAdd(const QString &ip, const QString &gw);
|
||||
static int routeAddList(const QString &gw, const QStringList &ips);
|
||||
static bool clearSavedRoutes();
|
||||
static bool routeDelete(const QString &ip, const QString &gw);
|
||||
|
|
|
@ -9,7 +9,7 @@ RouterMac &RouterMac::Instance()
|
|||
return s;
|
||||
}
|
||||
|
||||
bool RouterMac::routeAdd(const QString &ip, const QString &gw, QString mask)
|
||||
bool RouterMac::routeAdd(const QString &ip, const QString &gw)
|
||||
{
|
||||
int argc = 5;
|
||||
char **argv = new char*[argc];
|
||||
|
|
|
@ -18,7 +18,7 @@ class RouterMac : public QObject
|
|||
public:
|
||||
static RouterMac& Instance();
|
||||
|
||||
bool routeAdd(const QString &ip, const QString &gw, QString mask = QString());
|
||||
bool routeAdd(const QString &ip, const QString &gw);
|
||||
int routeAddList(const QString &gw, const QStringList &ips);
|
||||
bool clearSavedRoutes();
|
||||
bool routeDelete(const QString &ip, const QString &gw);
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
#include "router_win.h"
|
||||
#include "../client/utils.h"
|
||||
|
||||
#include <QProcess>
|
||||
|
||||
|
@ -8,20 +9,11 @@ RouterWin &RouterWin::Instance()
|
|||
return s;
|
||||
}
|
||||
|
||||
bool RouterWin::routeAdd(const QString &ip, const QString &gw, QString mask)
|
||||
bool RouterWin::routeAdd(const QString &ip, const QString &gw)
|
||||
{
|
||||
qDebug().noquote() << QString("ROUTE ADD: IP:%1 %2 GW %3")
|
||||
.arg(ip)
|
||||
.arg(mask)
|
||||
.arg(gw);
|
||||
|
||||
if (mask == "") {
|
||||
mask = "255.255.255.255";
|
||||
if (ip.endsWith(".0")) mask = "255.255.255.0";
|
||||
if (ip.endsWith(".0.0")) mask = "255.255.0.0";
|
||||
if (ip.endsWith(".0.0.0")) mask = "255.0.0.0";
|
||||
}
|
||||
//qDebug().noquote() << QString("ROUTE ADD: IP:%1 GW %2").arg(ip).arg(gw);
|
||||
|
||||
QString mask = Utils::netMaskFromIpWithSubnet(ip);
|
||||
|
||||
PMIB_IPFORWARDTABLE pIpForwardTable = NULL;
|
||||
MIB_IPFORWARDROW ipfrow;
|
||||
|
@ -58,7 +50,7 @@ bool RouterWin::routeAdd(const QString &ip, const QString &gw, QString mask)
|
|||
}
|
||||
|
||||
// address
|
||||
ipfrow.dwForwardDest = inet_addr(ip.toStdString().c_str());
|
||||
ipfrow.dwForwardDest = inet_addr(Utils::ipAddressFromIpWithSubnet(ip).toStdString().c_str());
|
||||
|
||||
// mask
|
||||
in_addr maskAddr;
|
||||
|
@ -109,12 +101,12 @@ bool RouterWin::routeAdd(const QString &ip, const QString &gw, QString mask)
|
|||
|
||||
int RouterWin::routeAddList(const QString &gw, const QStringList &ips)
|
||||
{
|
||||
qDebug().noquote() << QString("ROUTE ADD List: IPs size:%1, GW: %2")
|
||||
.arg(ips.size())
|
||||
.arg(gw);
|
||||
// qDebug().noquote() << QString("ROUTE ADD List: IPs size:%1, GW: %2")
|
||||
// .arg(ips.size())
|
||||
// .arg(gw);
|
||||
|
||||
qDebug().noquote() << QString("ROUTE ADD List: IPs:\n%1")
|
||||
.arg(ips.join("\n"));
|
||||
// qDebug().noquote() << QString("ROUTE ADD List: IPs:\n%1")
|
||||
// .arg(ips.join("\n"));
|
||||
|
||||
|
||||
|
||||
|
@ -188,15 +180,10 @@ int RouterWin::routeAddList(const QString &gw, const QStringList &ips)
|
|||
for (int i = 0; i < ips.size(); ++i) {
|
||||
QString ip = ips.at(i);
|
||||
if (ip.isEmpty()) continue;
|
||||
|
||||
mask = "255.255.255.255";
|
||||
if (ip.endsWith(".0")) mask = "255.255.255.0";
|
||||
if (ip.endsWith(".0.0")) mask = "255.255.0.0";
|
||||
if (ip.endsWith(".0.0.0")) mask = "255.0.0.0";
|
||||
QString mask = Utils::netMaskFromIpWithSubnet(ip);
|
||||
|
||||
// address
|
||||
ipfrow.dwForwardDest = inet_addr(ip.toStdString().c_str());
|
||||
|
||||
ipfrow.dwForwardDest = inet_addr(Utils::ipAddressFromIpWithSubnet(ip).toStdString().c_str());
|
||||
|
||||
// mask
|
||||
in_addr maskAddr;
|
||||
|
@ -280,7 +267,7 @@ bool RouterWin::routeDelete(const QString &ip, const QString &gw)
|
|||
|
||||
QProcess p;
|
||||
p.setProcessChannelMode(QProcess::MergedChannels);
|
||||
QString command = QString("route delete %1 %2").arg(ip).arg(gw);
|
||||
QString command = QString("route delete %1 %2").arg(Utils::ipAddressFromIpWithSubnet(ip)).arg(gw);
|
||||
|
||||
p.start(command);
|
||||
p.waitForFinished();
|
||||
|
|
|
@ -38,7 +38,7 @@ class RouterWin : public QObject
|
|||
public:
|
||||
static RouterWin& Instance();
|
||||
|
||||
bool routeAdd(const QString &ip, const QString &gw, QString mask = QString());
|
||||
bool routeAdd(const QString &ip, const QString &gw);
|
||||
int routeAddList(const QString &gw, const QStringList &ips);
|
||||
bool clearSavedRoutes();
|
||||
bool routeDelete(const QString &ip, const QString &gw);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue