mirror of
https://github.com/amnezia-vpn/amnezia-client.git
synced 2026-06-20 02:00:55 +07:00
feat: use per-tunnel ifname instead of hardcoded WG_INTERFACE in platform helpers
This commit is contained in:
@@ -47,7 +47,7 @@ bool IPUtilsLinux::setMTUAndUp(const InterfaceConfig& config) {
|
||||
|
||||
// Setup the interface to interact with
|
||||
struct ifreq ifr;
|
||||
strncpy(ifr.ifr_name, WG_INTERFACE, IFNAMSIZ);
|
||||
strncpy(ifr.ifr_name, config.m_ifname.toUtf8().constData(), IFNAMSIZ);
|
||||
|
||||
// MTU
|
||||
// FIXME: We need to know how many layers deep this particular
|
||||
@@ -76,7 +76,7 @@ bool IPUtilsLinux::addIP4AddressToDevice(const InterfaceConfig& config) {
|
||||
struct sockaddr_in* ifrAddr = (struct sockaddr_in*)&ifr.ifr_addr;
|
||||
|
||||
// Name the interface and set family
|
||||
strncpy(ifr.ifr_name, WG_INTERFACE, IFNAMSIZ);
|
||||
strncpy(ifr.ifr_name, config.m_ifname.toUtf8().constData(), IFNAMSIZ);
|
||||
ifr.ifr_addr.sa_family = AF_INET;
|
||||
|
||||
// Get the device address to add to interface
|
||||
@@ -126,7 +126,7 @@ bool IPUtilsLinux::addIP6AddressToDevice(const InterfaceConfig& config) {
|
||||
|
||||
// Get the index of named ifr and link with ifr6
|
||||
struct ifreq ifr;
|
||||
strncpy(ifr.ifr_name, WG_INTERFACE, IFNAMSIZ);
|
||||
strncpy(ifr.ifr_name, config.m_ifname.toUtf8().constData(), IFNAMSIZ);
|
||||
ifr.ifr_addr.sa_family = AF_INET6;
|
||||
int ret = ioctl(sockfd, SIOGIFINDEX, &ifr);
|
||||
if (ret) {
|
||||
|
||||
@@ -153,7 +153,7 @@ bool LinuxRouteMonitor::rtmSendRoute(int action, int flags, int type,
|
||||
}
|
||||
|
||||
if (rtm->rtm_type == RTN_UNICAST) {
|
||||
int index = if_nametoindex(WG_INTERFACE);
|
||||
int index = if_nametoindex(m_ifname.toUtf8().constData());
|
||||
|
||||
if (index <= 0) {
|
||||
logger.error() << "if_nametoindex() failed:" << strerror(errno);
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
|
||||
#include <QByteArray>
|
||||
#include <QDir>
|
||||
#include <QElapsedTimer>
|
||||
#include <QFile>
|
||||
#include <QLocalSocket>
|
||||
#include <QTimer>
|
||||
@@ -59,19 +60,20 @@ void WireguardUtilsLinux::tunnelErrorOccurred(QProcess::ProcessError error) {
|
||||
}
|
||||
|
||||
bool WireguardUtilsLinux::addInterface(const InterfaceConfig& config) {
|
||||
Q_UNUSED(config);
|
||||
if (m_tunnel.state() != QProcess::NotRunning) {
|
||||
logger.warning() << "Unable to start: tunnel process already running";
|
||||
return false;
|
||||
}
|
||||
|
||||
const QString ifname = config.m_ifname.isEmpty() ? QString(WG_INTERFACE) : config.m_ifname;
|
||||
|
||||
QDir wgRuntimeDir(WG_RUNTIME_DIR);
|
||||
if (!wgRuntimeDir.exists()) {
|
||||
wgRuntimeDir.mkpath(".");
|
||||
}
|
||||
|
||||
QProcessEnvironment pe = QProcessEnvironment::systemEnvironment();
|
||||
QString wgNameFile = wgRuntimeDir.filePath(QString(WG_INTERFACE) + ".sock");
|
||||
QString wgNameFile = wgRuntimeDir.filePath(ifname + ".sock");
|
||||
pe.insert("WG_TUN_NAME_FILE", wgNameFile);
|
||||
#ifdef MZ_DEBUG
|
||||
pe.insert("LOG_LEVEL", "debug");
|
||||
@@ -79,7 +81,7 @@ bool WireguardUtilsLinux::addInterface(const InterfaceConfig& config) {
|
||||
m_tunnel.setProcessEnvironment(pe);
|
||||
|
||||
QDir appPath(QCoreApplication::applicationDirPath());
|
||||
QStringList wgArgs = {"-f", "amn0"};
|
||||
QStringList wgArgs = {"-f", ifname};
|
||||
m_tunnel.start(appPath.filePath("amneziawg-go"), wgArgs);
|
||||
if (!m_tunnel.waitForStarted(WG_TUN_PROC_TIMEOUT)) {
|
||||
logger.error() << "Unable to start tunnel process due to timeout";
|
||||
@@ -194,7 +196,7 @@ bool WireguardUtilsLinux::deleteInterface() {
|
||||
|
||||
// Garbage collect.
|
||||
QDir wgRuntimeDir(WG_RUNTIME_DIR);
|
||||
QFile::remove(wgRuntimeDir.filePath(QString(WG_INTERFACE) + ".name"));
|
||||
QFile::remove(wgRuntimeDir.filePath(m_ifname + ".name"));
|
||||
|
||||
// double-check + ensure our firewall is installed and enabled
|
||||
KillSwitch::instance()->disableKillSwitch();
|
||||
@@ -237,8 +239,10 @@ bool WireguardUtilsLinux::updatePeer(const InterfaceConfig& config) {
|
||||
// Exclude the server address, except for multihop exit servers.
|
||||
if ((config.m_hopType != InterfaceConfig::MultiHopExit) &&
|
||||
(m_rtmonitor != nullptr)) {
|
||||
m_rtmonitor->addExclusionRoute(IPAddress(config.m_serverIpv4AddrIn));
|
||||
m_rtmonitor->addExclusionRoute(IPAddress(config.m_serverIpv6AddrIn));
|
||||
if (!config.m_serverIpv4AddrIn.isEmpty())
|
||||
m_rtmonitor->addExclusionRoute(IPAddress(config.m_serverIpv4AddrIn));
|
||||
if (!config.m_serverIpv6AddrIn.isEmpty())
|
||||
m_rtmonitor->addExclusionRoute(IPAddress(config.m_serverIpv6AddrIn));
|
||||
}
|
||||
|
||||
int err = uapiErrno(uapiCommand(message));
|
||||
@@ -255,8 +259,10 @@ bool WireguardUtilsLinux::deletePeer(const InterfaceConfig& config) {
|
||||
// Clear exclustion routes for this peer.
|
||||
if ((config.m_hopType != InterfaceConfig::MultiHopExit) &&
|
||||
(m_rtmonitor != nullptr)) {
|
||||
m_rtmonitor->deleteExclusionRoute(IPAddress(config.m_serverIpv4AddrIn));
|
||||
m_rtmonitor->deleteExclusionRoute(IPAddress(config.m_serverIpv6AddrIn));
|
||||
if (!config.m_serverIpv4AddrIn.isEmpty())
|
||||
m_rtmonitor->deleteExclusionRoute(IPAddress(config.m_serverIpv4AddrIn));
|
||||
if (!config.m_serverIpv6AddrIn.isEmpty())
|
||||
m_rtmonitor->deleteExclusionRoute(IPAddress(config.m_serverIpv6AddrIn));
|
||||
}
|
||||
|
||||
QString message;
|
||||
@@ -389,13 +395,9 @@ bool WireguardUtilsLinux::excludeLocalNetworks(const QList<IPAddress>& routes) {
|
||||
|
||||
QString WireguardUtilsLinux::uapiCommand(const QString& command) {
|
||||
QLocalSocket socket;
|
||||
QTimer uapiTimeout;
|
||||
QDir wgRuntimeDir(WG_RUNTIME_DIR);
|
||||
QString wgSocketFile = wgRuntimeDir.filePath(m_ifname + ".sock");
|
||||
|
||||
uapiTimeout.setSingleShot(true);
|
||||
uapiTimeout.start(WG_TUN_PROC_TIMEOUT);
|
||||
|
||||
socket.connectToServer(wgSocketFile, QIODevice::ReadWrite);
|
||||
if (!socket.waitForConnected(WG_TUN_PROC_TIMEOUT)) {
|
||||
logger.error() << "QLocalSocket::waitForConnected() failed:"
|
||||
@@ -410,13 +412,15 @@ QString WireguardUtilsLinux::uapiCommand(const QString& command) {
|
||||
}
|
||||
socket.write(message);
|
||||
|
||||
QElapsedTimer elapsed;
|
||||
elapsed.start();
|
||||
QByteArray reply;
|
||||
while (!reply.contains("\n\n")) {
|
||||
if (!uapiTimeout.isActive()) {
|
||||
const qint64 remaining = WG_TUN_PROC_TIMEOUT - elapsed.elapsed();
|
||||
if (remaining <= 0 || !socket.waitForReadyRead(static_cast<int>(remaining))) {
|
||||
logger.error() << "UAPI command timed out";
|
||||
return QString();
|
||||
}
|
||||
QCoreApplication::processEvents(QEventLoop::AllEvents, 100);
|
||||
reply.append(socket.readAll());
|
||||
}
|
||||
|
||||
@@ -442,19 +446,13 @@ QString WireguardUtilsLinux::waitForTunnelName(const QString& filename) {
|
||||
timeout.setSingleShot(true);
|
||||
timeout.start(WG_TUN_PROC_TIMEOUT);
|
||||
|
||||
QFile file(filename);
|
||||
|
||||
while ((m_tunnel.state() == QProcess::Running) && timeout.isActive()) {
|
||||
QCoreApplication::processEvents(QEventLoop::AllEvents, 100);
|
||||
QString ifname = "amn0";
|
||||
|
||||
// Test-connect to the UAPI socket.
|
||||
QLocalSocket sock;
|
||||
QDir wgRuntimeDir(WG_RUNTIME_DIR);
|
||||
QString sockName = wgRuntimeDir.filePath(ifname + ".sock");
|
||||
sock.connectToServer(sockName, QIODevice::ReadWrite);
|
||||
sock.connectToServer(filename, QIODevice::ReadWrite);
|
||||
if (sock.waitForConnected(100)) {
|
||||
return ifname;
|
||||
return QFileInfo(filename).baseName();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
|
||||
#include <QByteArray>
|
||||
#include <QDir>
|
||||
#include <QElapsedTimer>
|
||||
#include <QFile>
|
||||
#include <QLocalSocket>
|
||||
#include <QTimer>
|
||||
@@ -58,19 +59,20 @@ void WireguardUtilsMacos::tunnelErrorOccurred(QProcess::ProcessError error) {
|
||||
}
|
||||
|
||||
bool WireguardUtilsMacos::addInterface(const InterfaceConfig& config) {
|
||||
Q_UNUSED(config);
|
||||
if (m_tunnel.state() != QProcess::NotRunning) {
|
||||
logger.warning() << "Unable to start: tunnel process already running";
|
||||
return false;
|
||||
}
|
||||
|
||||
const QString ifname = config.m_ifname.isEmpty() ? QString(WG_INTERFACE) : config.m_ifname;
|
||||
|
||||
QDir wgRuntimeDir(WG_RUNTIME_DIR);
|
||||
if (!wgRuntimeDir.exists()) {
|
||||
wgRuntimeDir.mkpath(".");
|
||||
}
|
||||
|
||||
QProcessEnvironment pe = QProcessEnvironment::systemEnvironment();
|
||||
QString wgNameFile = wgRuntimeDir.filePath(QString(WG_INTERFACE) + ".name");
|
||||
QString wgNameFile = wgRuntimeDir.filePath(ifname + ".name");
|
||||
pe.insert("WG_TUN_NAME_FILE", wgNameFile);
|
||||
#ifdef MZ_DEBUG
|
||||
pe.insert("LOG_LEVEL", "debug");
|
||||
@@ -92,6 +94,7 @@ bool WireguardUtilsMacos::addInterface(const InterfaceConfig& config) {
|
||||
m_tunnel.kill();
|
||||
return false;
|
||||
}
|
||||
QFile::remove(wgNameFile);
|
||||
logger.debug() << "Created wireguard interface" << m_ifname;
|
||||
|
||||
// Start the routing table monitor.
|
||||
@@ -190,10 +193,6 @@ bool WireguardUtilsMacos::deleteInterface() {
|
||||
m_tunnel.waitForFinished(WG_TUN_PROC_TIMEOUT);
|
||||
}
|
||||
|
||||
// Garbage collect.
|
||||
QDir wgRuntimeDir(WG_RUNTIME_DIR);
|
||||
QFile::remove(wgRuntimeDir.filePath(QString(WG_INTERFACE) + ".name"));
|
||||
|
||||
// double-check + ensure our firewall is installed and enabled
|
||||
KillSwitch::instance()->disableKillSwitch();
|
||||
|
||||
@@ -389,13 +388,9 @@ bool WireguardUtilsMacos::excludeLocalNetworks(const QList<IPAddress>& routes) {
|
||||
|
||||
QString WireguardUtilsMacos::uapiCommand(const QString& command) {
|
||||
QLocalSocket socket;
|
||||
QTimer uapiTimeout;
|
||||
QDir wgRuntimeDir(WG_RUNTIME_DIR);
|
||||
QString wgSocketFile = wgRuntimeDir.filePath(m_ifname + ".sock");
|
||||
|
||||
uapiTimeout.setSingleShot(true);
|
||||
uapiTimeout.start(WG_TUN_PROC_TIMEOUT);
|
||||
|
||||
socket.connectToServer(wgSocketFile, QIODevice::ReadWrite);
|
||||
if (!socket.waitForConnected(WG_TUN_PROC_TIMEOUT)) {
|
||||
logger.error() << "QLocalSocket::waitForConnected() failed:"
|
||||
@@ -410,13 +405,15 @@ QString WireguardUtilsMacos::uapiCommand(const QString& command) {
|
||||
}
|
||||
socket.write(message);
|
||||
|
||||
QElapsedTimer elapsed;
|
||||
elapsed.start();
|
||||
QByteArray reply;
|
||||
while (!reply.contains("\n\n")) {
|
||||
if (!uapiTimeout.isActive()) {
|
||||
const qint64 remaining = WG_TUN_PROC_TIMEOUT - elapsed.elapsed();
|
||||
if (remaining <= 0 || !socket.waitForReadyRead(static_cast<int>(remaining))) {
|
||||
logger.error() << "UAPI command timed out";
|
||||
return QString();
|
||||
}
|
||||
QCoreApplication::processEvents(QEventLoop::AllEvents, 100);
|
||||
reply.append(socket.readAll());
|
||||
}
|
||||
|
||||
|
||||
@@ -117,8 +117,8 @@ bool WireguardUtilsWindows::addInterface(const InterfaceConfig& config) {
|
||||
|
||||
// Determine the interface LUID
|
||||
NET_LUID luid;
|
||||
QString ifAlias = interfaceName();
|
||||
DWORD result = ConvertInterfaceAliasToLuid((wchar_t*)ifAlias.utf16(), &luid);
|
||||
const QString ifname = config.m_ifname.isEmpty() ? interfaceName() : config.m_ifname;
|
||||
DWORD result = ConvertInterfaceAliasToLuid((wchar_t*)ifname.utf16(), &luid);
|
||||
if (result != 0) {
|
||||
logger.error() << "Failed to lookup LUID:" << result;
|
||||
return false;
|
||||
|
||||
Reference in New Issue
Block a user