mirror of
https://github.com/amnezia-vpn/amnezia-client.git
synced 2026-06-22 02:01:08 +07:00
fix: outbound freedom for xray (#2479)
* fix: outbound freedom for xray on linux * fix: outbound freedom for xray on macOS * build: auto-generate pf rules based on the build type
This commit is contained in:
+33
-4
@@ -1,5 +1,8 @@
|
||||
#include "xray.h"
|
||||
#include "core/utils/networkUtilities.h"
|
||||
#ifdef Q_OS_MAC
|
||||
#include "router_mac.h"
|
||||
#endif
|
||||
|
||||
#include <QDebug>
|
||||
#include <QNetworkInterface>
|
||||
@@ -25,18 +28,34 @@
|
||||
#endif
|
||||
#ifdef Q_OS_LINUX
|
||||
#include <sys/socket.h>
|
||||
#include "xray_defs.h"
|
||||
#endif
|
||||
|
||||
bool Xray::startXray(const QString &cfg)
|
||||
{
|
||||
qDebug() << "Xray::startXray()";
|
||||
|
||||
auto defaultIface = NetworkUtilities::getGatewayAndIface().second;
|
||||
const auto gatewayAndIface = NetworkUtilities::getGatewayAndIface();
|
||||
const QString defaultGateway = gatewayAndIface.first;
|
||||
const QNetworkInterface defaultIface = gatewayAndIface.second;
|
||||
#ifdef Q_OS_LINUX
|
||||
m_defaultIfaceName = defaultIface.name().toUtf8();
|
||||
#else
|
||||
m_defaultIfaceIdx = defaultIface.index();
|
||||
#endif
|
||||
if (defaultIface.index() > 0) {
|
||||
qDebug() << "[xray] using uplink interface:" << defaultIface.name() << "(" << defaultIface.index() << ")";
|
||||
}
|
||||
|
||||
#ifdef Q_OS_MAC
|
||||
m_uplinkIfaceName = defaultIface.name();
|
||||
m_uplinkGateway = defaultGateway;
|
||||
if (!m_uplinkIfaceName.isEmpty()) {
|
||||
const bool installed = RouterMac::Instance().routeAddXray(m_uplinkIfaceName, m_uplinkGateway);
|
||||
if (!installed) {
|
||||
qWarning() << "[xray] failed to install xray routes on" << m_uplinkIfaceName;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (auto err = amnezia_xray_setsockcallback(ctxSockCallback, this); err != nullptr) {
|
||||
qDebug() << "[xray] sockopt failed: " << err;
|
||||
@@ -65,13 +84,22 @@ bool Xray::startXray(const QString &cfg)
|
||||
bool Xray::stopXray()
|
||||
{
|
||||
qDebug() << "Xray::stopXray()";
|
||||
bool success = true;
|
||||
if (auto err = amnezia_xray_stop(); err != nullptr) {
|
||||
qDebug() << "[xray] failed to stop: " << err;
|
||||
amnezia_xray_free(err);
|
||||
return false;
|
||||
success = false;
|
||||
}
|
||||
|
||||
return true;
|
||||
#ifdef Q_OS_MAC
|
||||
if (!m_uplinkIfaceName.isEmpty()) {
|
||||
RouterMac::Instance().routeDeleteXray(m_uplinkIfaceName, m_uplinkGateway);
|
||||
}
|
||||
m_uplinkIfaceName.clear();
|
||||
m_uplinkGateway.clear();
|
||||
#endif
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
void Xray::logHandler(char* str)
|
||||
@@ -99,6 +127,7 @@ void Xray::sockCallback(uintptr_t fd)
|
||||
#ifdef Q_OS_LINUX
|
||||
if (!m_defaultIfaceName.isEmpty()) {
|
||||
setsockopt(fd, SOL_SOCKET, SO_BINDTODEVICE, m_defaultIfaceName.data(), m_defaultIfaceName.size());
|
||||
setsockopt(fd, SOL_SOCKET, SO_MARK, &amnezia::xray::xrayTrafficMark, sizeof(amnezia::xray::xrayTrafficMark));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user