Multiprotocol support

This commit is contained in:
pokamest 2021-05-07 23:28:37 +03:00
parent d424bb24cf
commit de67f244da
44 changed files with 2159 additions and 863 deletions

View file

@ -5,6 +5,7 @@
#include <configurators/openvpn_configurator.h>
#include <configurators/cloak_configurator.h>
#include <configurators/shadowsocks_configurator.h>
#include <core/servercontroller.h>
#include "ipc.h"
@ -80,11 +81,78 @@ ErrorCode VpnConnection::lastError() const
return m_vpnProtocol.data()->lastError();
}
ErrorCode VpnConnection::createVpnConfiguration(const ServerCredentials &credentials, DockerContainer container)
QMap<Protocol, QString> VpnConnection::getLastVpnConfig(const QJsonObject &containerConfig)
{
QMap<Protocol, QString> configs;
for (Protocol proto: { Protocol::OpenVpn,
Protocol::ShadowSocks,
Protocol::Cloak,
Protocol::WireGuard}) {
QString cfg = containerConfig.value(protoToString(proto)).toObject().value(config_key::last_config).toString();
if (!cfg.isEmpty()) configs.insert(proto, cfg);
}
return configs;
}
QString VpnConnection::createVpnConfigurationForProto(int serverIndex,
const ServerCredentials &credentials, DockerContainer container, const QJsonObject &containerConfig, Protocol proto,
ErrorCode *errorCode)
{
ErrorCode e = ErrorCode::NoError;
auto lastVpnConfig = getLastVpnConfig(containerConfig);
QString configData;
if (lastVpnConfig.contains(proto)) {
configData = lastVpnConfig.value(proto);
qDebug() << "VpnConnection::createVpnConfiguration using saved config for " << protoToString(proto);
}
else {
if (proto == Protocol::OpenVpn) {
configData = OpenVpnConfigurator::genOpenVpnConfig(credentials,
container, containerConfig, &e);
}
else if (proto == Protocol::Cloak) {
configData = CloakConfigurator::genCloakConfig(credentials,
container, containerConfig, &e);
}
else if (proto == Protocol::ShadowSocks) {
configData = ShadowSocksConfigurator::genShadowSocksConfig(credentials,
container, containerConfig, &e);
}
if (errorCode && e) {
*errorCode = e;
return "";
}
if (serverIndex >= 0) {
QJsonObject protoObject = m_settings.protocolConfig(serverIndex, container, proto);
protoObject.insert(config_key::last_config, configData);
m_settings.setProtocolConfig(serverIndex, container, proto, protoObject);
}
}
if (errorCode) *errorCode = e;
return configData;
}
ErrorCode VpnConnection::createVpnConfiguration(int serverIndex,
const ServerCredentials &credentials, DockerContainer container, const QJsonObject &containerConfig)
{
ErrorCode errorCode = ErrorCode::NoError;
if (container == DockerContainer::OpenVpn || container == DockerContainer::ShadowSocksOverOpenVpn || container == DockerContainer::OpenVpnOverCloak) {
QString openVpnConfigData = OpenVpnConfigurator::genOpenVpnConfig(credentials, container, &errorCode);
if (container == DockerContainer::OpenVpn ||
container == DockerContainer::OpenVpnOverShadowSocks ||
container == DockerContainer::OpenVpnOverCloak) {
QString openVpnConfigData =
createVpnConfigurationForProto(
serverIndex, credentials, container, containerConfig, Protocol::OpenVpn, &errorCode);
m_vpnConfiguration.insert(config::key_openvpn_config_data, openVpnConfigData);
if (errorCode) {
return errorCode;
@ -101,13 +169,21 @@ ErrorCode VpnConnection::createVpnConfiguration(const ServerCredentials &credent
}
}
if (container == DockerContainer::ShadowSocksOverOpenVpn) {
QJsonObject ssConfigData = ShadowSocksVpnProtocol::genShadowSocksConfig(credentials);
if (container == DockerContainer::OpenVpnOverShadowSocks) {
QJsonObject ssConfigData = QJsonDocument::fromJson(
createVpnConfigurationForProto(
serverIndex, credentials, container, containerConfig, Protocol::ShadowSocks, &errorCode).toUtf8()).
object();
m_vpnConfiguration.insert(config::key_shadowsocks_config_data, ssConfigData);
}
if (container == DockerContainer::OpenVpnOverCloak) {
QJsonObject cloakConfigData = CloakConfigurator::genCloakConfig(credentials, DockerContainer::OpenVpnOverCloak, &errorCode);
QJsonObject cloakConfigData = QJsonDocument::fromJson(
createVpnConfigurationForProto(
serverIndex, credentials, container, containerConfig, Protocol::Cloak, &errorCode).toUtf8()).
object();
m_vpnConfiguration.insert(config::key_cloak_config_data, cloakConfigData);
}
@ -115,17 +191,9 @@ ErrorCode VpnConnection::createVpnConfiguration(const ServerCredentials &credent
return ErrorCode::NoError;
}
ErrorCode VpnConnection::connectToVpn(const ServerCredentials &credentials, DockerContainer container)
ErrorCode VpnConnection::connectToVpn(int serverIndex, const ServerCredentials &credentials, DockerContainer container, const QJsonObject &containerConfig)
{
qDebug() << "connectToVpn, CustomRouting is" << m_settings.customRouting();
// qDebug() << "Cred" << m_settings.serverCredentials().hostName <<
// m_settings.serverCredentials().password;
//protocol = Protocol::ShadowSocks;
container = DockerContainer::OpenVpnOverCloak;
// 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";
qDebug() << "СonnectToVpn, CustomRouting is" << m_settings.customRouting();
emit connectionStateChanged(VpnProtocol::ConnectionState::Connecting);
@ -133,13 +201,10 @@ ErrorCode VpnConnection::connectToVpn(const ServerCredentials &credentials, Dock
disconnect(m_vpnProtocol.data(), &VpnProtocol::protocolError, this, &VpnConnection::vpnProtocolError);
m_vpnProtocol->stop();
m_vpnProtocol.reset();
//m_vpnProtocol->deleteLater();
}
//qApp->processEvents();
if (container == DockerContainer::None || container == DockerContainer::OpenVpn) {
ErrorCode e = createVpnConfiguration(credentials, DockerContainer::OpenVpn);
ErrorCode e = createVpnConfiguration(serverIndex, credentials, DockerContainer::OpenVpn, containerConfig);
if (e) {
emit connectionStateChanged(VpnProtocol::ConnectionState::Error);
return e;
@ -152,8 +217,8 @@ ErrorCode VpnConnection::connectToVpn(const ServerCredentials &credentials, Dock
return e;
}
}
else if (container == DockerContainer::ShadowSocksOverOpenVpn) {
ErrorCode e = createVpnConfiguration(credentials, DockerContainer::ShadowSocksOverOpenVpn);
else if (container == DockerContainer::OpenVpnOverShadowSocks) {
ErrorCode e = createVpnConfiguration(serverIndex, credentials, DockerContainer::OpenVpnOverShadowSocks, containerConfig);
if (e) {
emit connectionStateChanged(VpnProtocol::ConnectionState::Error);
return e;
@ -167,7 +232,7 @@ ErrorCode VpnConnection::connectToVpn(const ServerCredentials &credentials, Dock
}
}
else if (container == DockerContainer::OpenVpnOverCloak) {
ErrorCode e = createVpnConfiguration(credentials, DockerContainer::OpenVpnOverCloak);
ErrorCode e = createVpnConfiguration(serverIndex, credentials, DockerContainer::OpenVpnOverCloak, containerConfig);
if (e) {
emit connectionStateChanged(VpnProtocol::ConnectionState::Error);
return e;