mirror of
https://github.com/amnezia-vpn/amnezia-client.git
synced 2026-06-24 02:00:24 +07:00
refactor: route OpenVPN and IKEv2 through Tunnel/TrafficGuard
This commit is contained in:
@@ -137,6 +137,14 @@ VpnProtocol *VpnProtocol::factory(DockerContainer container, const QJsonObject &
|
||||
}
|
||||
}
|
||||
|
||||
void VpnProtocol::setPrimary(const QJsonObject &config)
|
||||
{
|
||||
Q_UNUSED(config)
|
||||
QMetaObject::invokeMethod(this, [this]() {
|
||||
emit primaryReady();
|
||||
}, Qt::QueuedConnection);
|
||||
}
|
||||
|
||||
QString VpnProtocol::routeGateway() const
|
||||
{
|
||||
return m_routeGateway;
|
||||
|
||||
@@ -61,7 +61,7 @@ public:
|
||||
virtual bool isDisconnected() const;
|
||||
virtual ErrorCode start() = 0;
|
||||
virtual void stop() = 0;
|
||||
virtual void setPrimary(const QJsonObject& config) { Q_UNUSED(config) }
|
||||
virtual void setPrimary(const QJsonObject& config);
|
||||
|
||||
Vpn::ConnectionState connectionState() const;
|
||||
ErrorCode lastError() const;
|
||||
|
||||
@@ -43,6 +43,13 @@ void Tunnel::prepare() {
|
||||
connect(m_protocol.data(), &VpnProtocol::primaryFailed,
|
||||
this, &Tunnel::onPrimaryFailed);
|
||||
|
||||
const amnezia::ErrorCode prepareErr = m_protocol->prepare();
|
||||
if (prepareErr != amnezia::ErrorCode::NoError) {
|
||||
setState(State::Failed);
|
||||
emit failed(prepareErr);
|
||||
return;
|
||||
}
|
||||
|
||||
startActivationDeadline(ACTIVATION_TIMEOUT_MSEC);
|
||||
|
||||
const amnezia::ErrorCode err = m_protocol->start();
|
||||
|
||||
@@ -192,7 +192,10 @@ void VpnTrafficGuard::applyKillSwitch(Tunnel* tunnel, const QString &gateway, co
|
||||
QJsonObject updatedConfig = m_config;
|
||||
IpcClient::withInterface([&](QSharedPointer<IpcInterfaceReplica> iface) {
|
||||
#ifdef Q_OS_WIN
|
||||
const QString ifname = updatedConfig.value("ifname").toString();
|
||||
const bool engineNamedInterface = tunnel
|
||||
&& (VpnProtocol::isWireGuardBased(tunnel->container())
|
||||
|| VpnProtocol::isXrayBased(tunnel->container()));
|
||||
const QString ifname = engineNamedInterface ? updatedConfig.value("ifname").toString() : QString();
|
||||
if (!ifname.isEmpty()) {
|
||||
updatedConfig.insert("vpnGateway", gateway);
|
||||
updatedConfig.insert("vpnServer", NetworkUtilities::getIPAddress(updatedConfig.value(configKey::hostName).toString()));
|
||||
@@ -330,7 +333,9 @@ void VpnTrafficGuard::reserve(Tunnel* tunnel)
|
||||
{
|
||||
if (!tunnel) return;
|
||||
#ifdef AMNEZIA_DESKTOP
|
||||
allowEndpoint(tunnel->remoteAddress(), tunnel->ifname());
|
||||
const bool engineNamedInterface = VpnProtocol::isWireGuardBased(tunnel->container())
|
||||
|| VpnProtocol::isXrayBased(tunnel->container());
|
||||
allowEndpoint(tunnel->remoteAddress(), engineNamedInterface ? tunnel->ifname() : QString());
|
||||
#else
|
||||
Q_UNUSED(tunnel)
|
||||
#endif
|
||||
@@ -341,9 +346,11 @@ void VpnTrafficGuard::release(Tunnel* tunnel)
|
||||
if (!tunnel) return;
|
||||
disconnect(tunnel, nullptr, this, nullptr);
|
||||
#ifdef AMNEZIA_DESKTOP
|
||||
const bool engineNamedInterface = VpnProtocol::isWireGuardBased(tunnel->container())
|
||||
|| VpnProtocol::isXrayBased(tunnel->container());
|
||||
m_allowedEndpoints.removeAll(tunnel->remoteAddress());
|
||||
IpcClient::withInterface([this, &tunnel](QSharedPointer<IpcInterfaceReplica> iface) {
|
||||
iface->disableKillSwitchForTunnel(tunnel->ifname(), m_allowedEndpoints);
|
||||
IpcClient::withInterface([this, &tunnel, engineNamedInterface](QSharedPointer<IpcInterfaceReplica> iface) {
|
||||
iface->disableKillSwitchForTunnel(engineNamedInterface ? tunnel->ifname() : QString(), m_allowedEndpoints);
|
||||
});
|
||||
#else
|
||||
Q_UNUSED(tunnel)
|
||||
@@ -384,6 +391,10 @@ void VpnTrafficGuard::applyPolicy(Tunnel* tunnel)
|
||||
return;
|
||||
}
|
||||
|
||||
if (!VpnProtocol::isWireGuardBased(tunnel->container())) {
|
||||
return;
|
||||
}
|
||||
|
||||
const QJsonObject activate = LocalSocketController::buildActivateJson(tunnel->config(), tunnel->ifname());
|
||||
const QStringList prefixes = allowedIpPrefixesFor(activate);
|
||||
const QStringList excluded = excludedAddressesFor(activate);
|
||||
@@ -427,6 +438,10 @@ void VpnTrafficGuard::revokePolicy(Tunnel* tunnel)
|
||||
return;
|
||||
}
|
||||
|
||||
if (!VpnProtocol::isWireGuardBased(tunnel->container())) {
|
||||
return;
|
||||
}
|
||||
|
||||
const QJsonObject activate = LocalSocketController::buildActivateJson(tunnel->config(), tunnel->ifname());
|
||||
const QStringList prefixes = allowedIpPrefixesFor(activate);
|
||||
const QStringList excluded = excludedAddressesFor(activate);
|
||||
|
||||
@@ -185,7 +185,11 @@ void VpnConnection::connectToVpn(const QString &serverId, DockerContainer contai
|
||||
#ifdef AMNEZIA_DESKTOP
|
||||
const bool isWg = VpnProtocol::isWireGuardBased(container);
|
||||
const bool isXray = VpnProtocol::isXrayBased(container);
|
||||
const bool useTunnelPath = isWg || isXray;
|
||||
const bool targetIsSwitchable = isWg || isXray;
|
||||
const bool activeIsSwitchable = m_active
|
||||
&& (VpnProtocol::isWireGuardBased(m_active->container())
|
||||
|| VpnProtocol::isXrayBased(m_active->container()));
|
||||
const bool useTunnelPath = true;
|
||||
const QString preAllocatedIfname = useTunnelPath ? allocateIfname() : QString();
|
||||
if (useTunnelPath && preAllocatedIfname.isEmpty()) {
|
||||
setConnectionState(Vpn::ConnectionState::Error);
|
||||
@@ -195,7 +199,8 @@ void VpnConnection::connectToVpn(const QString &serverId, DockerContainer contai
|
||||
|
||||
if (m_active
|
||||
&& m_connectionState == Vpn::ConnectionState::Connected
|
||||
&& useTunnelPath) {
|
||||
&& targetIsSwitchable
|
||||
&& activeIsSwitchable) {
|
||||
if (!m_trafficGuard->allowEndpoint(resolvedRemote, preAllocatedIfname)) {
|
||||
releaseIfname(preAllocatedIfname);
|
||||
setConnectionState(Vpn::ConnectionState::Error);
|
||||
@@ -221,16 +226,11 @@ void VpnConnection::connectToVpn(const QString &serverId, DockerContainer contai
|
||||
if (m_active) {
|
||||
const QString oldIfname = m_active->ifname();
|
||||
m_trafficGuard->tearDown(m_active);
|
||||
m_trafficGuard->flushAll();
|
||||
delete m_active;
|
||||
m_active = nullptr;
|
||||
releaseIfname(oldIfname);
|
||||
}
|
||||
if (m_vpnProtocol) {
|
||||
disconnect(m_vpnProtocol.data(), &VpnProtocol::protocolError, this, &VpnConnection::vpnProtocolError);
|
||||
m_trafficGuard->flushAll();
|
||||
m_vpnProtocol->stop();
|
||||
m_vpnProtocol.reset();
|
||||
}
|
||||
#endif
|
||||
|
||||
appendKillSwitchConfig(config);
|
||||
@@ -261,14 +261,6 @@ void VpnConnection::connectToVpn(const QString &serverId, DockerContainer contai
|
||||
m_trafficGuard->bringUp(m_active);
|
||||
return;
|
||||
}
|
||||
|
||||
m_vpnProtocol.reset(VpnProtocol::factory(container, m_vpnConfiguration));
|
||||
if (!m_vpnProtocol) {
|
||||
setConnectionState(Vpn::ConnectionState::Error);
|
||||
return;
|
||||
}
|
||||
m_vpnProtocol->prepare();
|
||||
m_trafficGuard->setConfig(m_vpnConfiguration);
|
||||
#elif defined Q_OS_ANDROID
|
||||
androidVpnProtocol = createDefaultAndroidVpnProtocol();
|
||||
createAndroidConnections();
|
||||
|
||||
Reference in New Issue
Block a user