Compare commits

...

17 Commits

Author SHA1 Message Date
NickVs2015 08138c218c feat: update support arm 64 server 2025-12-05 15:41:48 +03:00
NickVs2015 3119a589fb feat: update support arm 64 new logic 2025-12-03 23:27:55 +03:00
NickVs2015 753a549938 feat: update support arm 64 logic, add upload win64 bin dir 2025-12-03 16:40:20 +03:00
NickVs2015 228dee7680 feat: addd support arm64 back to windeploy 2025-12-03 13:36:26 +03:00
NickVs2015 5133b4d6bb Add arm64 support 2025-12-03 10:02:49 +03:00
NickVs2015 fa50a07693 feat: win arm64 add support 2025-12-02 12:23:37 +03:00
NickVs2015 cf9196777c feat: win arm64 add support vc_redist 2025-12-02 12:23:37 +03:00
NickVs2015 0945997b34 feat: add support arm64 2025-12-02 12:23:37 +03:00
Yaroslav 105c42db1c fix: ipc call in macos ne (#1986) 2025-12-01 10:54:42 +08:00
Mykola Baibuz 89818ff63d fix: app freeze on quit (#1804)
* fix: app freeze on quit

* fix: typo in VpnConnection destructor

* add trace info

* add more trace info

* set timelimit for flushDns

* Refactor IpcClient::Interface access logic

* cleanup unused variable

* cleanup trace info

* fix: remove second disconnect from VPN on app close

* this object will be deleted at app close

* Don't terminate VPN thread on Linux

* Revert "Don't terminate VPN thread on Linux"

This reverts commit 20e4ea2d4a.

* disconnect all signals from vpnconnection on exit

* add interruption request on vpnConnectionThread

* use checktimer only for iOS

* disconnect all signals from vpnconnection on exit

* disconnect signals on exit before VPN disconnect

* add disconnectSlots method

* fix: add allow traffic rules on killswitch disable

* wait for response from service before object destroy

* change disconnect from vpn order

* add delay for connection close

* change disconnect method order

* use stop method for protocol disconnecect

* change disconnect method order

* allow dns traffic after app close

* delete tun on disconnect

---------

Co-authored-by: vkamn <vk@amnezia.org>
2025-12-01 10:49:16 +08:00
vkamn 414c422177 feat: added os signal handler (#2029) 2025-12-01 10:45:06 +08:00
NickVs2015 b39ac8556c feat: add right artifact name (#2018) 2025-11-28 12:08:38 +08:00
MrMirDan 5e1742262d fix: eye icon (#1985)
Co-authored-by: vkamn <vk@amnezia.org>
2025-11-28 11:00:53 +08:00
VoyNaLunu 5a07a1274f fix: GetBestRoute always returning 1231 error (#1981)
* fix GetBestRoute always returning 1231 error

* revert some changes because fix turned out to be simpler
2025-11-26 12:46:55 +08:00
MrMirDan 7b8ff1fd6e fix: checked format after changing protocol (#1937)
* fix: checked format after changing protocol

* update: improved some lines

* fix(ui): restore checkmark for connection format after switching protocol

* fix: correct a typo

* fix(ui): escape regex in client search filter

* refactor: removed redundant lines

---------

Co-authored-by: Mitternacht822 <sb@amnezia.org>
2025-11-26 12:07:24 +08:00
MrMirDan c7221832e0 fix: users search field clears on 'x' button or 'escape' key clicked (#1920) 2025-11-26 11:57:28 +08:00
NickVs2015 eb7d031c7d fix: clear qt cache on start app (#2008)
* Fix/ Cache clear Android

* Fix: Clear cache on start app

* chore: bump version

---------

Co-authored-by: vkamn <vk@amnezia.org>
2025-11-26 11:47:50 +08:00
37 changed files with 911 additions and 159 deletions
+199 -18
View File
@@ -44,6 +44,13 @@ jobs:
submodules: 'true' submodules: 'true'
fetch-depth: 10 fetch-depth: 10
- name: 'Get version from CMakeLists.txt'
id: get_version
run: |
VERSION=$(grep 'set(AMNEZIAVPN_VERSION' CMakeLists.txt | sed -E 's/.*AMNEZIAVPN_VERSION ([0-9]+.[0-9]+.[0-9]+.[0-9]+)\)/\1/')
echo "VERSION=$VERSION" >> $GITHUB_ENV
echo "Version: $VERSION"
- name: 'Setup ccache' - name: 'Setup ccache'
uses: hendrikmuhs/ccache-action@v1.2 uses: hendrikmuhs/ccache-action@v1.2
@@ -55,13 +62,13 @@ jobs:
bash deploy/build_linux.sh bash deploy/build_linux.sh
- name: 'Pack installer' - name: 'Pack installer'
run: cd deploy && tar -cf AmneziaVPN_Linux_Installer.tar AmneziaVPN_Linux_Installer.bin run: cd deploy && tar -cf AmneziaVPN_Linux_Installer.tar AmneziaVPN_Linux_Installer.bin && zip AmneziaVPN_${VERSION}_linux_x64.tar.zip AmneziaVPN_Linux_Installer.tar
- name: 'Upload installer artifact' - name: 'Upload installer artifact'
uses: actions/upload-artifact@v4 uses: actions/upload-artifact@v4
with: with:
name: AmneziaVPN_Linux_installer.tar name: AmneziaVPN_${{ env.VERSION }}_linux_x64.tar.zip
path: deploy/AmneziaVPN_Linux_Installer.tar path: deploy/AmneziaVPN_${{ env.VERSION }}_linux_x64.tar.zip
retention-days: 7 retention-days: 7
- name: 'Upload unpacked artifact' - name: 'Upload unpacked artifact'
@@ -102,6 +109,14 @@ jobs:
submodules: 'true' submodules: 'true'
fetch-depth: 10 fetch-depth: 10
- name: 'Get version from CMakeLists.txt'
id: get_version
shell: bash
run: |
VERSION=$(grep 'set(AMNEZIAVPN_VERSION' CMakeLists.txt | sed -E 's/.*AMNEZIAVPN_VERSION ([0-9]+.[0-9]+.[0-9]+.[0-9]+)\)/\1/')
echo "VERSION=$VERSION" >> $GITHUB_ENV
echo "Version: $VERSION"
- name: 'Setup ccache' - name: 'Setup ccache'
uses: hendrikmuhs/ccache-action@v1.2 uses: hendrikmuhs/ccache-action@v1.2
@@ -117,6 +132,8 @@ jobs:
setup-python: 'true' setup-python: 'true'
tools: 'tools_ifw' tools: 'tools_ifw'
set-env: 'true' set-env: 'true'
aqtversion: '==3.1.21'
py7zrversion: '==0.22.*'
extra: '--external 7z --base ${{ env.QT_MIRROR }}' extra: '--external 7z --base ${{ env.QT_MIRROR }}'
- name: 'Setup mvsc' - name: 'Setup mvsc'
@@ -128,15 +145,20 @@ jobs:
shell: cmd shell: cmd
run: | run: |
set BUILD_ARCH=${{ env.BUILD_ARCH }} set BUILD_ARCH=${{ env.BUILD_ARCH }}
set QT_BIN_DIR="${{ runner.temp }}\\Qt\\${{ env.QT_VERSION }}\\msvc2019_64\\bin" set "QT_BIN_DIR=${{ runner.temp }}\Qt\${{ env.QT_VERSION }}\msvc2019_64\bin"
set QIF_BIN_DIR="${{ runner.temp }}\\Qt\\Tools\\QtInstallerFramework\\${{ env.QIF_VERSION }}\\bin" set "QIF_BIN_DIR=${{ runner.temp }}\Qt\Tools\QtInstallerFramework\${{ env.QIF_VERSION }}\bin"
call deploy\\build_windows.bat call deploy\build_windows.bat
- name: 'Rename Windows installer'
shell: cmd
run: |
copy AmneziaVPN_x${{ env.BUILD_ARCH }}.exe AmneziaVPN_%VERSION%_x${{ env.BUILD_ARCH }}.exe
- name: 'Upload installer artifact' - name: 'Upload installer artifact'
uses: actions/upload-artifact@v4 uses: actions/upload-artifact@v4
with: with:
name: AmneziaVPN_Windows_installer name: AmneziaVPN_${{ env.VERSION }}_x${{ env.BUILD_ARCH }}.exe
path: AmneziaVPN_x${{ env.BUILD_ARCH }}.exe path: AmneziaVPN_${{ env.VERSION }}_x${{ env.BUILD_ARCH }}.exe
retention-days: 7 retention-days: 7
- name: 'Upload unpacked artifact' - name: 'Upload unpacked artifact'
@@ -146,6 +168,136 @@ jobs:
path: deploy\\build_${{ env.BUILD_ARCH }}\\client\\Release path: deploy\\build_${{ env.BUILD_ARCH }}\\client\\Release
retention-days: 7 retention-days: 7
# ------------------------------------------------------
Build-Windows-ARM64:
runs-on: windows-latest
env:
QT_VERSION: 6.8.3
QIF_VERSION: 4.7
BUILD_ARCH: arm64
PROD_AGW_PUBLIC_KEY: ${{ secrets.PROD_AGW_PUBLIC_KEY }}
PROD_S3_ENDPOINT: ${{ secrets.PROD_S3_ENDPOINT }}
DEV_AGW_PUBLIC_KEY: ${{ secrets.DEV_AGW_PUBLIC_KEY }}
DEV_AGW_ENDPOINT: ${{ secrets.DEV_AGW_ENDPOINT }}
DEV_S3_ENDPOINT: ${{ secrets.DEV_S3_ENDPOINT }}
FREE_V2_ENDPOINT: ${{ secrets.FREE_V2_ENDPOINT }}
PREM_V1_ENDPOINT: ${{ secrets.PREM_V1_ENDPOINT }}
steps:
- name: 'Get sources'
uses: actions/checkout@v4
with:
submodules: 'true'
fetch-depth: 10
- name: 'Get 3rd-prebuilt'
shell: bash
run: |
rm -rf client/3rd-prebuilt
- name: 'Checkout 3rd-prebuilt'
uses: actions/checkout@v4
with:
repository: amnezia-vpn/3rd-prebuilt
ref: feature/add-support-arm64
path: client/3rd-prebuilt
- name: 'Get version from CMakeLists.txt'
id: get_version
shell: bash
run: |
VERSION=$(grep 'set(AMNEZIAVPN_VERSION' CMakeLists.txt | sed -E 's/.*AMNEZIAVPN_VERSION ([0-9]+.[0-9]+.[0-9]+.[0-9]+)\)/\1/')
echo "VERSION=$VERSION" >> $GITHUB_ENV
echo "Version: $VERSION"
- name: 'Setup ccache'
uses: hendrikmuhs/ccache-action@v1.2
- name: 'Cleanup Qt directory'
shell: pwsh
run: |
$baseDir = "${{ runner.temp }}"
$qtVersion = "${{ env.QT_VERSION }}"
# Handle both path formats (with \ and /)
$paths = @(
"$baseDir\Qt\$qtVersion\msvc2022_64",
"$baseDir/Qt/$qtVersion/msvc2022_64",
"$baseDir\Qt\$qtVersion\msvc2022_arm64",
"$baseDir/Qt/$qtVersion/msvc2022_arm64"
)
foreach ($path in $paths) {
if (Test-Path $path) {
Write-Host "Removing $path..."
Remove-Item -Path $path -Recurse -Force -ErrorAction SilentlyContinue
}
}
- name: 'Install Qt Desktop (host for cross-compilation)'
uses: jurplel/install-qt-action@v3
with:
version: ${{ env.QT_VERSION }}
host: 'windows'
target: 'desktop'
arch: 'win64_msvc2022_64'
modules: 'qtremoteobjects qt5compat qtshadertools'
dir: ${{ runner.temp }}
setup-python: 'true'
set-env: 'false'
aqtversion: '==3.3.0'
py7zrversion: '==0.22.*'
extra: '--base ${{ env.QT_MIRROR }}'
- name: 'Install Qt ARM64'
uses: jurplel/install-qt-action@v3
with:
version: ${{ env.QT_VERSION }}
host: 'windows'
target: 'desktop'
arch: 'win64_msvc2022_arm64_cross_compiled'
modules: 'qtremoteobjects qt5compat qtshadertools'
dir: ${{ runner.temp }}
setup-python: 'true'
tools: 'tools_ifw'
set-env: 'false'
aqtversion: '==3.3.0'
py7zrversion: '==0.22.*'
extra: '--external 7z --base ${{ env.QT_MIRROR }}'
- name: 'Setup mvsc'
uses: ilammy/msvc-dev-cmd@v1
with:
arch: 'x64_arm64'
- name: 'Build project'
shell: cmd
run: |
set BUILD_ARCH=${{ env.BUILD_ARCH }}
set "QT_BIN_DIR=${{ runner.temp }}\Qt\${{ env.QT_VERSION }}\msvc2022_arm64\bin"
set "QT_HOST_PATH=${{ runner.temp }}\Qt\${{ env.QT_VERSION }}\msvc2022_64"
set "QT_HOST_BIN_DIR=${{ runner.temp }}\Qt\${{ env.QT_VERSION }}\msvc2022_64\bin"
set "QIF_BIN_DIR=${{ runner.temp }}\Qt\Tools\QtInstallerFramework\${{ env.QIF_VERSION }}\bin"
call deploy\build_windows.bat
- name: 'Rename Windows installer'
shell: cmd
run: |
copy AmneziaVPN_x${{ env.BUILD_ARCH }}.exe AmneziaVPN_%VERSION%_x${{ env.BUILD_ARCH }}.exe
- name: 'Upload installer artifact'
uses: actions/upload-artifact@v4
with:
name: AmneziaVPN_${{ env.VERSION }}_x${{ env.BUILD_ARCH }}.exe
path: AmneziaVPN_${{ env.VERSION }}_x${{ env.BUILD_ARCH }}.exe
retention-days: 7
- name: 'Upload unpacked artifact'
uses: actions/upload-artifact@v4
with:
name: AmneziaVPN_Windows_ARM64_unpacked
path: deploy\\build_${{ env.BUILD_ARCH }}\\client\\Release
retention-days: 7
# ------------------------------------------------------ # ------------------------------------------------------
Build-iOS: Build-iOS:
@@ -380,6 +532,13 @@ jobs:
submodules: 'true' submodules: 'true'
fetch-depth: 10 fetch-depth: 10
- name: 'Get version from CMakeLists.txt'
id: get_version
run: |
VERSION=$(grep 'set(AMNEZIAVPN_VERSION' CMakeLists.txt | sed -E 's/.*AMNEZIAVPN_VERSION ([0-9]+.[0-9]+.[0-9]+.[0-9]+)\)/\1/')
echo "VERSION=$VERSION" >> $GITHUB_ENV
echo "Version: $VERSION"
- name: 'Setup ccache' - name: 'Setup ccache'
uses: hendrikmuhs/ccache-action@v1.2 uses: hendrikmuhs/ccache-action@v1.2
@@ -388,11 +547,17 @@ jobs:
export QT_BIN_DIR="${{ runner.temp }}/Qt/${{ env.QT_VERSION }}/macos/bin" export QT_BIN_DIR="${{ runner.temp }}/Qt/${{ env.QT_VERSION }}/macos/bin"
bash deploy/build_macos.sh -n bash deploy/build_macos.sh -n
- name: 'Pack macOS installer'
run: |
cd deploy/build/pkg
zip -r ../../AmneziaVPN_${VERSION}_macos.zip AmneziaVPN.pkg
cd ../../..
- name: 'Upload installer artifact' - name: 'Upload installer artifact'
uses: actions/upload-artifact@v4 uses: actions/upload-artifact@v4
with: with:
name: AmneziaVPN_MacOS_installer name: AmneziaVPN_${{ env.VERSION }}_macos.zip
path: deploy/build/pkg/AmneziaVPN.pkg path: deploy/AmneziaVPN_${{ env.VERSION }}_macos.zip
retention-days: 7 retention-days: 7
- name: 'Upload unpacked artifact' - name: 'Upload unpacked artifact'
@@ -551,6 +716,13 @@ jobs:
with: with:
submodules: 'true' submodules: 'true'
- name: 'Get version from CMakeLists.txt'
id: get_version
run: |
VERSION=$(grep 'set(AMNEZIAVPN_VERSION' CMakeLists.txt | sed -E 's/.*AMNEZIAVPN_VERSION ([0-9]+.[0-9]+.[0-9]+.[0-9]+)\)/\1/')
echo "VERSION=$VERSION" >> $GITHUB_ENV
echo "Version: $VERSION"
- name: 'Setup ccache' - name: 'Setup ccache'
uses: hendrikmuhs/ccache-action@v1.2 uses: hendrikmuhs/ccache-action@v1.2
@@ -584,35 +756,44 @@ jobs:
shell: bash shell: bash
run: ./deploy/build_android.sh --aab --apk all --build-platform ${{ env.ANDROID_BUILD_PLATFORM }} run: ./deploy/build_android.sh --aab --apk all --build-platform ${{ env.ANDROID_BUILD_PLATFORM }}
- name: 'Rename Android APKs'
run: |
cd deploy/build
mv AmneziaVPN-x86_64-release.apk AmneziaVPN_${VERSION}_android9+_x86_64.apk
mv AmneziaVPN-x86-release.apk AmneziaVPN_${VERSION}_android9+_x86.apk
mv AmneziaVPN-arm64-v8a-release.apk AmneziaVPN_${VERSION}_android9+_arm64-v8a.apk
mv AmneziaVPN-armeabi-v7a-release.apk AmneziaVPN_${VERSION}_android9+_armeabi-v7a.apk
cd ../..
- name: 'Upload x86_64 apk' - name: 'Upload x86_64 apk'
uses: actions/upload-artifact@v4 uses: actions/upload-artifact@v4
with: with:
name: AmneziaVPN-android-x86_64 name: AmneziaVPN_${{ env.VERSION }}_android9+_x86_64.apk
path: deploy/build/AmneziaVPN-x86_64-release.apk path: deploy/build/AmneziaVPN_${{ env.VERSION }}_android9+_x86_64.apk
compression-level: 0 compression-level: 0
retention-days: 7 retention-days: 7
- name: 'Upload x86 apk' - name: 'Upload x86 apk'
uses: actions/upload-artifact@v4 uses: actions/upload-artifact@v4
with: with:
name: AmneziaVPN-android-x86 name: AmneziaVPN_${{ env.VERSION }}_android9+_x86.apk
path: deploy/build/AmneziaVPN-x86-release.apk path: deploy/build/AmneziaVPN_${{ env.VERSION }}_android9+_x86.apk
compression-level: 0 compression-level: 0
retention-days: 7 retention-days: 7
- name: 'Upload arm64-v8a apk' - name: 'Upload arm64-v8a apk'
uses: actions/upload-artifact@v4 uses: actions/upload-artifact@v4
with: with:
name: AmneziaVPN-android-arm64-v8a name: AmneziaVPN_${{ env.VERSION }}_android9+_arm64-v8a.apk
path: deploy/build/AmneziaVPN-arm64-v8a-release.apk path: deploy/build/AmneziaVPN_${{ env.VERSION }}_android9+_arm64-v8a.apk
compression-level: 0 compression-level: 0
retention-days: 7 retention-days: 7
- name: 'Upload armeabi-v7a apk' - name: 'Upload armeabi-v7a apk'
uses: actions/upload-artifact@v4 uses: actions/upload-artifact@v4
with: with:
name: AmneziaVPN-android-armeabi-v7a name: AmneziaVPN_${{ env.VERSION }}_android9+_armeabi-v7a.apk
path: deploy/build/AmneziaVPN-armeabi-v7a-release.apk path: deploy/build/AmneziaVPN_${{ env.VERSION }}_android9+_armeabi-v7a.apk
compression-level: 0 compression-level: 0
retention-days: 7 retention-days: 7
+2 -2
View File
@@ -1,7 +1,7 @@
cmake_minimum_required(VERSION 3.25.0 FATAL_ERROR) cmake_minimum_required(VERSION 3.25.0 FATAL_ERROR)
set(PROJECT AmneziaVPN) set(PROJECT AmneziaVPN)
set(AMNEZIAVPN_VERSION 4.8.11.4) set(AMNEZIAVPN_VERSION 4.8.11.5)
project(${PROJECT} VERSION ${AMNEZIAVPN_VERSION} project(${PROJECT} VERSION ${AMNEZIAVPN_VERSION}
DESCRIPTION "AmneziaVPN" DESCRIPTION "AmneziaVPN"
@@ -12,7 +12,7 @@ string(TIMESTAMP CURRENT_DATE "%Y-%m-%d")
set(RELEASE_DATE "${CURRENT_DATE}") set(RELEASE_DATE "${CURRENT_DATE}")
set(APP_MAJOR_VERSION ${CMAKE_PROJECT_VERSION_MAJOR}.${CMAKE_PROJECT_VERSION_MINOR}.${CMAKE_PROJECT_VERSION_PATCH}) set(APP_MAJOR_VERSION ${CMAKE_PROJECT_VERSION_MAJOR}.${CMAKE_PROJECT_VERSION_MINOR}.${CMAKE_PROJECT_VERSION_PATCH})
set(APP_ANDROID_VERSION_CODE 2099) set(APP_ANDROID_VERSION_CODE 2100)
if(${CMAKE_SYSTEM_NAME} STREQUAL "Linux") if(${CMAKE_SYSTEM_NAME} STREQUAL "Linux")
set(MZ_PLATFORM_NAME "linux") set(MZ_PLATFORM_NAME "linux")
+18 -2
View File
@@ -39,6 +39,20 @@ endif()
find_package(Qt6 REQUIRED COMPONENTS ${PACKAGES}) find_package(Qt6 REQUIRED COMPONENTS ${PACKAGES})
# Diagnostic: Print Qt configuration
message(STATUS "=== Qt Configuration Diagnostics ===")
message(STATUS "Qt6_DIR: ${Qt6_DIR}")
message(STATUS "CMAKE_PREFIX_PATH: ${CMAKE_PREFIX_PATH}")
message(STATUS "CMAKE_GENERATOR_PLATFORM: ${CMAKE_GENERATOR_PLATFORM}")
message(STATUS "CMAKE_SYSTEM_PROCESSOR: ${CMAKE_SYSTEM_PROCESSOR}")
if(TARGET Qt6::Core)
get_target_property(Qt6Core_LOCATION Qt6::Core LOCATION)
message(STATUS "Qt6::Core location: ${Qt6Core_LOCATION}")
get_target_property(Qt6Core_IMPLIB Qt6::Core IMPORTED_IMPLIB_RELEASE)
message(STATUS "Qt6::Core import library: ${Qt6Core_IMPLIB}")
endif()
message(STATUS "====================================")
set(LIBS ${LIBS} set(LIBS ${LIBS}
Qt6::Core Qt6::Gui Qt6::Core Qt6::Gui
Qt6::Network Qt6::Xml Qt6::RemoteObjects Qt6::Network Qt6::Xml Qt6::RemoteObjects
@@ -56,7 +70,7 @@ target_include_directories(${PROJECT} PUBLIC
$<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}> $<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}>
) )
if(WIN32 OR (APPLE AND NOT IOS) OR (LINUX AND NOT ANDROID)) if(WIN32 OR (APPLE AND NOT IOS AND NOT MACOS_NE) OR (LINUX AND NOT ANDROID))
qt_add_repc_replicas(${PROJECT} ${CMAKE_CURRENT_LIST_DIR}/../ipc/ipc_interface.rep) qt_add_repc_replicas(${PROJECT} ${CMAKE_CURRENT_LIST_DIR}/../ipc/ipc_interface.rep)
qt_add_repc_replicas(${PROJECT} ${CMAKE_CURRENT_LIST_DIR}/../ipc/ipc_process_interface.rep) qt_add_repc_replicas(${PROJECT} ${CMAKE_CURRENT_LIST_DIR}/../ipc/ipc_process_interface.rep)
qt_add_repc_replicas(${PROJECT} ${CMAKE_CURRENT_LIST_DIR}/../ipc/ipc_process_tun2socks.rep) qt_add_repc_replicas(${PROJECT} ${CMAKE_CURRENT_LIST_DIR}/../ipc/ipc_process_tun2socks.rep)
@@ -199,7 +213,9 @@ target_compile_definitions(${PROJECT} PRIVATE "MZ_$<UPPER_CASE:${MZ_PLATFORM_NAM
# deploy artifacts required to run the application to the debug build folder # deploy artifacts required to run the application to the debug build folder
if(WIN32) if(WIN32)
if("${CMAKE_SIZEOF_VOID_P}" STREQUAL "8") if("${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "ARM64")
set(DEPLOY_PLATFORM_PATH "windows/arm64")
elseif("${CMAKE_SIZEOF_VOID_P}" STREQUAL "8")
set(DEPLOY_PLATFORM_PATH "windows/x64") set(DEPLOY_PLATFORM_PATH "windows/x64")
else() else()
set(DEPLOY_PLATFORM_PATH "windows/x32") set(DEPLOY_PLATFORM_PATH "windows/x32")
+30
View File
@@ -13,6 +13,8 @@
#include <QTimer> #include <QTimer>
#include <QTranslator> #include <QTranslator>
#include <QEvent> #include <QEvent>
#include <QDir>
#include <QSettings>
#include "logger.h" #include "logger.h"
#include "ui/controllers/pageController.h" #include "ui/controllers/pageController.h"
@@ -53,16 +55,44 @@ AmneziaApplication::AmneziaApplication(int &argc, char *argv[]) : AMNEZIA_BASE_C
AmneziaApplication::~AmneziaApplication() AmneziaApplication::~AmneziaApplication()
{ {
if (m_vpnConnection) {
QMetaObject::invokeMethod(m_vpnConnection.get(), "disconnectSlots", Qt::QueuedConnection);
QMetaObject::invokeMethod(m_vpnConnection.get(), "disconnectFromVpn", Qt::QueuedConnection);
QThread::msleep(2000);
}
m_vpnConnectionThread.requestInterruption();
m_vpnConnectionThread.quit(); m_vpnConnectionThread.quit();
if (!m_vpnConnectionThread.wait(3000)) {
m_vpnConnectionThread.terminate();
m_vpnConnectionThread.wait(500);
}
if (m_engine) { if (m_engine) {
QObject::disconnect(m_engine, 0, 0, 0); QObject::disconnect(m_engine, 0, 0, 0);
delete m_engine; delete m_engine;
} }
} }
#ifdef Q_OS_ANDROID
namespace {
static void clearQtCaches()
{
const QString cacheRoot = QStandardPaths::writableLocation(QStandardPaths::CacheLocation);
if (!cacheRoot.isEmpty()) {
QDir(cacheRoot + "/QtShaderCache").removeRecursively();
QDir(cacheRoot + "/qmlcache").removeRecursively();
}
}
}
#endif
void AmneziaApplication::init() void AmneziaApplication::init()
{ {
#ifdef Q_OS_ANDROID
clearQtCaches();
#endif
m_engine = new QQmlApplicationEngine; m_engine = new QQmlApplicationEngine;
const QUrl url(QStringLiteral("qrc:/ui/qml/main2.qml")); const QUrl url(QStringLiteral("qrc:/ui/qml/main2.qml"));
+19 -1
View File
@@ -15,17 +15,35 @@ set(OPENSSL_LIBRARIES_DIR "${OPENSSL_ROOT_DIR}/lib")
if(WIN32) if(WIN32)
set(OPENSSL_INCLUDE_DIR "${OPENSSL_ROOT_DIR}/windows/include") set(OPENSSL_INCLUDE_DIR "${OPENSSL_ROOT_DIR}/windows/include")
if("${CMAKE_SIZEOF_VOID_P}" STREQUAL "8") # Check for ARM64 architecture first (CMAKE_GENERATOR_PLATFORM is set to ARM64 for cross-compilation)
message(STATUS "=== 3rd Party Libraries Configuration ===")
message(STATUS "CMAKE_GENERATOR_PLATFORM: ${CMAKE_GENERATOR_PLATFORM}")
message(STATUS "CMAKE_SYSTEM_PROCESSOR: ${CMAKE_SYSTEM_PROCESSOR}")
message(STATUS "CMAKE_SIZEOF_VOID_P: ${CMAKE_SIZEOF_VOID_P}")
if("${CMAKE_GENERATOR_PLATFORM}" STREQUAL "ARM64" OR "${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "ARM64")
# ARM64: use ARM64 versions for both OpenSSL and libssh
message(STATUS "Building for Windows ARM64")
set(LIBSSH_LIB_PATH "${LIBSSH_ROOT_DIR}/windows/arm64/ssh.lib")
set(LIBSSH_INCLUDE_DIR "${LIBSSH_ROOT_DIR}/windows/arm64")
set(OPENSSL_LIB_SSL_PATH "${OPENSSL_ROOT_DIR}/windows/winarm64/libssl.lib")
set(OPENSSL_LIB_CRYPTO_PATH "${OPENSSL_ROOT_DIR}/windows/winarm64/libcrypto.lib")
message(STATUS "libssh: ${LIBSSH_LIB_PATH}")
message(STATUS "OpenSSL SSL: ${OPENSSL_LIB_SSL_PATH}")
message(STATUS "OpenSSL Crypto: ${OPENSSL_LIB_CRYPTO_PATH}")
elseif("${CMAKE_SIZEOF_VOID_P}" STREQUAL "8")
message(STATUS "Building for Windows x64")
set(LIBSSH_LIB_PATH "${LIBSSH_ROOT_DIR}/windows/x86_64/ssh.lib") set(LIBSSH_LIB_PATH "${LIBSSH_ROOT_DIR}/windows/x86_64/ssh.lib")
set(LIBSSH_INCLUDE_DIR "${LIBSSH_ROOT_DIR}/windows/x86_64") set(LIBSSH_INCLUDE_DIR "${LIBSSH_ROOT_DIR}/windows/x86_64")
set(OPENSSL_LIB_SSL_PATH "${OPENSSL_ROOT_DIR}/windows/win64/libssl.lib") set(OPENSSL_LIB_SSL_PATH "${OPENSSL_ROOT_DIR}/windows/win64/libssl.lib")
set(OPENSSL_LIB_CRYPTO_PATH "${OPENSSL_ROOT_DIR}/windows/win64/libcrypto.lib") set(OPENSSL_LIB_CRYPTO_PATH "${OPENSSL_ROOT_DIR}/windows/win64/libcrypto.lib")
else() else()
message(STATUS "Building for Windows x86")
set(LIBSSH_LIB_PATH "${LIBSSH_ROOT_DIR}/windows/x86/ssh.lib") set(LIBSSH_LIB_PATH "${LIBSSH_ROOT_DIR}/windows/x86/ssh.lib")
set(LIBSSH_INCLUDE_DIR "${LIBSSH_ROOT_DIR}/windows/x86") set(LIBSSH_INCLUDE_DIR "${LIBSSH_ROOT_DIR}/windows/x86")
set(OPENSSL_LIB_SSL_PATH "${OPENSSL_ROOT_DIR}/windows/win32/libssl.lib") set(OPENSSL_LIB_SSL_PATH "${OPENSSL_ROOT_DIR}/windows/win32/libssl.lib")
set(OPENSSL_LIB_CRYPTO_PATH "${OPENSSL_ROOT_DIR}/windows/win32/libcrypto.lib") set(OPENSSL_LIB_CRYPTO_PATH "${OPENSSL_ROOT_DIR}/windows/win32/libcrypto.lib")
endif() endif()
message(STATUS "==========================================")
elseif(APPLE AND NOT IOS) elseif(APPLE AND NOT IOS)
if(MACOS_NE) if(MACOS_NE)
set(LIBSSH_LIB_PATH "${LIBSSH_ROOT_DIR}/macos/universal2/libssh.a") set(LIBSSH_LIB_PATH "${LIBSSH_ROOT_DIR}/macos/universal2/libssh.a")
+14 -1
View File
@@ -28,6 +28,7 @@ set(HEADERS ${HEADERS}
${CLIENT_ROOT_DIR}/../common/logger/logger.h ${CLIENT_ROOT_DIR}/../common/logger/logger.h
${CLIENT_ROOT_DIR}/utils/qmlUtils.h ${CLIENT_ROOT_DIR}/utils/qmlUtils.h
${CLIENT_ROOT_DIR}/core/api/apiUtils.h ${CLIENT_ROOT_DIR}/core/api/apiUtils.h
${CLIENT_ROOT_DIR}/core/osSignalHandler.h
) )
# Mozilla headres # Mozilla headres
@@ -79,6 +80,7 @@ set(SOURCES ${SOURCES}
${CLIENT_ROOT_DIR}/../common/logger/logger.cpp ${CLIENT_ROOT_DIR}/../common/logger/logger.cpp
${CLIENT_ROOT_DIR}/utils/qmlUtils.cpp ${CLIENT_ROOT_DIR}/utils/qmlUtils.cpp
${CLIENT_ROOT_DIR}/core/api/apiUtils.cpp ${CLIENT_ROOT_DIR}/core/api/apiUtils.cpp
${CLIENT_ROOT_DIR}/core/osSignalHandler.cpp
) )
# Mozilla sources # Mozilla sources
@@ -175,7 +177,7 @@ if(WIN32)
) )
endif() endif()
if(WIN32 OR (APPLE AND NOT IOS) OR (LINUX AND NOT ANDROID)) if(WIN32 OR (APPLE AND NOT IOS AND NOT MACOS_NE) OR (LINUX AND NOT ANDROID))
message("Client desktop build") message("Client desktop build")
add_compile_definitions(AMNEZIA_DESKTOP) add_compile_definitions(AMNEZIA_DESKTOP)
@@ -203,3 +205,14 @@ if(WIN32 OR (APPLE AND NOT IOS) OR (LINUX AND NOT ANDROID))
${CLIENT_ROOT_DIR}/protocols/awgprotocol.cpp ${CLIENT_ROOT_DIR}/protocols/awgprotocol.cpp
) )
endif() endif()
if(APPLE AND MACOS_NE)
# Include only the tray notification handler in NE builds
set(HEADERS ${HEADERS}
${CLIENT_ROOT_DIR}/ui/systemtray_notificationhandler.h
)
set(SOURCES ${SOURCES}
${CLIENT_ROOT_DIR}/ui/systemtray_notificationhandler.cpp
)
endif()
+2 -1
View File
@@ -85,8 +85,9 @@ bool IpcClient::init(IpcClient *instance)
} }
qDebug() << "IpcClient::init succeed"; qDebug() << "IpcClient::init succeed";
instance->m_isSocketConnected = (Instance()->m_ipcClient->isReplicaValid() && Instance()->m_Tun2SocksClient->isReplicaValid());
return (Instance()->m_ipcClient->isReplicaValid() && Instance()->m_Tun2SocksClient->isReplicaValid()); return Instance()->isSocketConnected();
} }
QSharedPointer<PrivilegedProcess> IpcClient::CreatePrivilegedProcess() QSharedPointer<PrivilegedProcess> IpcClient::CreatePrivilegedProcess()
+1 -1
View File
@@ -170,7 +170,7 @@ int NetworkUtilities::AdapterIndexTo(const QHostAddress& dst) {
#ifdef Q_OS_WIN #ifdef Q_OS_WIN
qDebug() << "Getting Current Internet Adapter that routes to" qDebug() << "Getting Current Internet Adapter that routes to"
<< dst.toString(); << dst.toString();
quint32_be ipBigEndian; quint32 ipBigEndian;
quint32 ip = dst.toIPv4Address(); quint32 ip = dst.toIPv4Address();
qToBigEndian(ip, &ipBigEndian); qToBigEndian(ip, &ipBigEndian);
_MIB_IPFORWARDROW routeInfo; _MIB_IPFORWARDROW routeInfo;
+159
View File
@@ -0,0 +1,159 @@
#include "osSignalHandler.h"
#include <QCoreApplication>
#include <QSocketNotifier>
#if defined(Q_OS_LINUX) && !defined(Q_OS_ANDROID)
#include <pthread.h>
#include <signal.h>
#include <sys/signalfd.h>
#include <unistd.h>
#elif defined(Q_OS_MACOS)
#include <fcntl.h>
#include <signal.h>
#include <unistd.h>
#endif
#ifdef Q_OS_WIN
#include <QMetaObject>
#include <windows.h>
#endif
namespace
{
static bool initialized = false;
#ifdef Q_OS_WIN
static BOOL WINAPI consoleHandler(DWORD signal)
{
switch (signal) {
case CTRL_CLOSE_EVENT:
case CTRL_C_EVENT:
case CTRL_BREAK_EVENT:
case CTRL_LOGOFF_EVENT:
case CTRL_SHUTDOWN_EVENT:
if (QCoreApplication::instance()) {
QMetaObject::invokeMethod(QCoreApplication::instance(), "quit", Qt::QueuedConnection);
}
return TRUE;
default: return FALSE;
}
}
#endif
#if defined(Q_OS_LINUX) && !defined(Q_OS_ANDROID)
static int signalFd = -1;
static QSocketNotifier *socketNotifier = nullptr;
static void setupUnixSignalHandler()
{
sigset_t set;
sigemptyset(&set);
sigaddset(&set, SIGINT);
sigaddset(&set, SIGTERM);
pthread_sigmask(SIBLOCK, &set, nullptr);
signalFd = signalfd(-1, &set, SFD_NONBLOCK | SFD_CLOEXEC);
if (signalFd < 0)
return;
socketNotifier = new QSocketNotifier(signalFd, QSocketNotifier::Read, QCoreApplication::instance());
QObject::connect(socketNotifier, &QSocketNotifier::activated, QCoreApplication::instance(), [](int) {
signalfd_siginfo fdsi;
::read(signalFd, &fdsi, sizeof(fdsi));
if (fdsi.ssi_signo == SIGINT || fdsi.ssi_signo == SIGTERM) {
QCoreApplication::quit();
}
});
}
#elif defined(Q_OS_MACX)
static int signalPipe[2] = { -1, -1 };
static QSocketNotifier *socketNotifier = nullptr;
static void macSignalHandler(int)
{
const char ch = 1;
::write(signalPipe[1], &ch, sizeof(ch));
}
static void setupUnixSignalHandler()
{
if (::pipe(signalPipe) != 0)
return;
::fcntl(signalPipe[0], F_SETFL, O_NONBLOCK);
::fcntl(signalPipe[1], F_SETFL, O_NONBLOCK);
struct sigaction sa {};
sa.sa_handler = macSignalHandler;
sigemptyset(&sa.sa_mask);
sa.sa_flags = 0;
sigaction(SIGINT, &sa, nullptr);
sigaction(SIGTERM, &sa, nullptr);
socketNotifier = new QSocketNotifier(signalPipe[0], QSocketNotifier::Read, QCoreApplication::instance());
QObject::connect(socketNotifier, &QSocketNotifier::activated, QCoreApplication::instance(), [](int) {
char buf[16];
::read(signalPipe[0], buf, sizeof(buf));
QCoreApplication::quit();
});
}
#endif
static void cleanupUnixSignalHandler()
{
#if defined(Q_OS_LINUX) && !defined(Q_OS_ANDROID)
if (socketNotifier) {
socketNotifier->setEnabled(false);
}
if (signalFd >= 0) {
::close(signalFd);
signalFd = -1;
}
#elif defined(Q_OS_MACOS)
if (socketNotifier) {
socketNotifier->setEnabled(false);
}
if (signalPipe[0] >= 0) {
::close(signalPipe[0]);
signalPipe[0] = -1;
}
if (signalPipe[1] >= 0) {
::close(signalPipe[1]);
signalPipe[1] = -1;
}
#endif
}
}
OsSignalHandler::OsSignalHandler(QObject *parent) : QObject(parent)
{
}
void OsSignalHandler::setup()
{
if (initialized)
return;
initialized = true;
#if (defined(Q_OS_LINUX) && !defined(Q_OS_ANDROID)) || defined(Q_OS_MACX)
setupUnixSignalHandler();
#endif
#ifdef Q_OS_WIN
SetConsoleCtrlHandler(consoleHandler, TRUE);
#endif
QObject::connect(QCoreApplication::instance(), &QCoreApplication::aboutToQuit, [] { cleanupUnixSignalHandler(); });
}
+17
View File
@@ -0,0 +1,17 @@
#ifndef OSSIGNALHANDLER_H
#define OSSIGNALHANDLER_H
#include <QObject>
class OsSignalHandler : public QObject
{
Q_OBJECT
public:
static void setup();
private:
explicit OsSignalHandler(QObject *parent = nullptr);
static void handleSignal(int signal);
};
#endif // OSSIGNALHANDLER_H
+2
View File
@@ -2,6 +2,7 @@
#include <QTimer> #include <QTimer>
#include "amnezia_application.h" #include "amnezia_application.h"
#include "core/osSignalHandler.h"
#include "migrations.h" #include "migrations.h"
#include "version.h" #include "version.h"
@@ -44,6 +45,7 @@ int main(int argc, char *argv[])
#endif #endif
AmneziaApplication app(argc, argv); AmneziaApplication app(argc, argv);
OsSignalHandler::setup();
#if !defined(Q_OS_ANDROID) && !defined(Q_OS_IOS) && !defined(MACOS_NE) #if !defined(Q_OS_ANDROID) && !defined(Q_OS_IOS) && !defined(MACOS_NE)
if (isAnotherInstanceRunning()) { if (isAnotherInstanceRunning()) {
@@ -1,6 +1,5 @@
import Foundation import Foundation
import NetworkExtension import NetworkExtension
import WireGuardKitGo
enum XrayErrors: Error { enum XrayErrors: Error {
case noXrayConfig case noXrayConfig
+2 -1
View File
@@ -56,7 +56,8 @@ void OpenVpnProtocol::stop()
} }
#if defined(Q_OS_WIN) || defined(Q_OS_LINUX) || defined(Q_OS_MACOS) #if defined(Q_OS_WIN) || defined(Q_OS_LINUX) || defined(Q_OS_MACOS)
IpcClient::Interface()->disableKillSwitch(); QRemoteObjectPendingReply<bool> disableKillSwitchResp = IpcClient::Interface()->disableKillSwitch();
disableKillSwitchResp.waitForFinished(1000);
#endif #endif
setConnectionState(Vpn::ConnectionState::Disconnected); setConnectionState(Vpn::ConnectionState::Disconnected);
+12 -4
View File
@@ -166,10 +166,17 @@ ErrorCode XrayProtocol::startTun2Sock()
void XrayProtocol::stop() void XrayProtocol::stop()
{ {
#if defined(Q_OS_WIN) || defined(Q_OS_LINUX) || defined(Q_OS_MACOS) #ifdef AMNEZIA_DESKTOP
IpcClient::Interface()->disableKillSwitch(); QRemoteObjectPendingReply<bool> disableKillSwitchResp = IpcClient::Interface()->disableKillSwitch();
IpcClient::Interface()->StartRoutingIpv6(); disableKillSwitchResp.waitForFinished(1000);
IpcClient::Interface()->restoreResolvers(); QRemoteObjectPendingReply<bool> StartRoutingIpv6Resp = IpcClient::Interface()->StartRoutingIpv6();
StartRoutingIpv6Resp.waitForFinished(1000);
QRemoteObjectPendingReply<bool> restoreResolvers = IpcClient::Interface()->restoreResolvers();
restoreResolvers.waitForFinished(1000);
#if !defined(Q_OS_MACOS)
QRemoteObjectPendingReply<bool> deleteTunResp = IpcClient::Interface()->deleteTun("tun2");
deleteTunResp.waitForFinished(1000);
#endif
#endif #endif
qDebug() << "XrayProtocol::stop()"; qDebug() << "XrayProtocol::stop()";
m_xrayProcess.disconnect(); m_xrayProcess.disconnect();
@@ -177,6 +184,7 @@ void XrayProtocol::stop()
m_xrayProcess.waitForFinished(3000); m_xrayProcess.waitForFinished(3000);
if (m_t2sProcess) { if (m_t2sProcess) {
m_t2sProcess->stop(); m_t2sProcess->stop();
QThread::msleep(200);
} }
setConnectionState(Vpn::ConnectionState::Disconnected); setConnectionState(Vpn::ConnectionState::Disconnected);
@@ -71,6 +71,7 @@ PageType {
clickedFunc: function () { clickedFunc: function () {
clickedHandler() clickedHandler()
buttonImageSource = textField.text !== "" ? imageSource : ""
} }
textField.onFocusChanged: { textField.onFocusChanged: {
@@ -78,8 +79,8 @@ PageType {
} }
textField.onTextChanged: { textField.onTextChanged: {
if (hideContent) { if (headerText == qsTr("Password or SSH private key")) {
buttonImageSource = textField.text !== "" ? (hideContent ? "qrc:/images/controls/eye.svg" : "qrc:/images/controls/eye-off.svg") : "" buttonImageSource = textField.text !== "" ? imageSource : ""
} }
} }
} }
@@ -211,8 +212,10 @@ PageType {
property string title: qsTr("Password or SSH private key") property string title: qsTr("Password or SSH private key")
readonly property string placeholderContent: "" readonly property string placeholderContent: ""
property bool hideContent: true property bool hideContent: true
property string imageSource: "qrc:/images/controls/eye.svg"
readonly property var clickedHandler: function() { readonly property var clickedHandler: function() {
hideContent = !hideContent hideContent = !hideContent
imageSource = hideContent ? "qrc:/images/controls/eye.svg" : "qrc:/images/controls/eye-off.svg"
} }
} }
+32 -14
View File
@@ -311,7 +311,7 @@ PageType {
DropDownType { DropDownType {
id: serverSelector id: serverSelector
signal severSelectorIndexChanged signal serverSelectorIndexChanged
property int currentIndex: -1 property int currentIndex: -1
Layout.fillWidth: true Layout.fillWidth: true
@@ -348,7 +348,7 @@ PageType {
if (serverSelector.currentIndex !== serverSelectorListView.selectedIndex) { if (serverSelector.currentIndex !== serverSelectorListView.selectedIndex) {
serverSelector.currentIndex = serverSelectorListView.selectedIndex serverSelector.currentIndex = serverSelectorListView.selectedIndex
serverSelector.severSelectorIndexChanged() serverSelector.serverSelectorIndexChanged()
} }
serverSelector.closeTriggered() serverSelector.closeTriggered()
@@ -375,6 +375,8 @@ PageType {
DropDownType { DropDownType {
id: protocolSelector id: protocolSelector
signal protocolSelectorTextChanged
Layout.fillWidth: true Layout.fillWidth: true
Layout.topMargin: 16 Layout.topMargin: 16
@@ -414,7 +416,7 @@ PageType {
Connections { Connections {
target: serverSelector target: serverSelector
function onSeverSelectorIndexChanged() { function onServerSelectorIndexChanged() {
var defaultContainer = proxyContainersModel.mapFromSource(ServersModel.getProcessedServerData("defaultContainer")) var defaultContainer = proxyContainersModel.mapFromSource(ServersModel.getProcessedServerData("defaultContainer"))
protocolSelectorListView.selectedIndex = defaultContainer protocolSelectorListView.selectedIndex = defaultContainer
protocolSelectorListView.positionViewAtIndex(selectedIndex, ListView.Beginning) protocolSelectorListView.positionViewAtIndex(selectedIndex, ListView.Beginning)
@@ -436,17 +438,14 @@ PageType {
fillConnectionTypeModel() fillConnectionTypeModel()
if (exportTypeSelector.currentIndex >= root.connectionTypesModel.length) {
exportTypeSelector.currentIndex = 0
exportTypeSelector.text = root.connectionTypesModel[0].name
}
if (accessTypeSelector.currentIndex === 1) { if (accessTypeSelector.currentIndex === 1) {
PageController.showBusyIndicator(true) PageController.showBusyIndicator(true)
ExportController.updateClientManagementModel(ContainersModel.getProcessedContainerIndex(), ExportController.updateClientManagementModel(ContainersModel.getProcessedContainerIndex(),
ServersModel.getProcessedServerCredentials()) ServersModel.getProcessedServerCredentials())
PageController.showBusyIndicator(false) PageController.showBusyIndicator(false)
} }
protocolSelector.protocolSelectorTextChanged()
} }
function fillConnectionTypeModel() { function fillConnectionTypeModel() {
@@ -499,6 +498,14 @@ PageType {
exportTypeSelector.text = exportTypeSelectorListView.selectedText exportTypeSelector.text = exportTypeSelectorListView.selectedText
} }
onModelChanged: {
if (exportTypeSelector.currentIndex >= model.length || exportTypeSelector.currentIndex < 0) {
exportTypeSelector.currentIndex = 0
}
selectedIndex = exportTypeSelector.currentIndex
exportTypeSelector.text = selectedText
}
rootWidth: root.width rootWidth: root.width
imageSource: "qrc:/images/controls/check.svg" imageSource: "qrc:/images/controls/check.svg"
@@ -506,16 +513,23 @@ PageType {
model: root.connectionTypesModel model: root.connectionTypesModel
currentIndex: 0 currentIndex: 0
Connections {
target: protocolSelector
function onProtocolSelectorTextChanged() {
if (exportTypeSelector.currentIndex >= root.connectionTypesModel.length) {
exportTypeSelectorListView.selectedIndex = 0
exportTypeSelector.currentIndex = 0
exportTypeSelector.text = root.connectionTypesModel[0].name
}
}
}
clickedFunction: function() { clickedFunction: function() {
exportTypeSelector.text = exportTypeSelectorListView.selectedText exportTypeSelector.text = exportTypeSelectorListView.selectedText
exportTypeSelector.currentIndex = exportTypeSelectorListView.selectedIndex exportTypeSelector.currentIndex = exportTypeSelectorListView.selectedIndex
exportTypeSelector.closeTriggered() exportTypeSelector.closeTriggered()
} }
Component.onCompleted: {
exportTypeSelector.text = exportTypeSelectorListView.selectedText
exportTypeSelector.currentIndex = exportTypeSelectorListView.selectedIndex
}
} }
} }
@@ -566,6 +580,7 @@ PageType {
textField.placeholderText: qsTr("Search") textField.placeholderText: qsTr("Search")
Keys.onEscapePressed: { Keys.onEscapePressed: {
searchTextField.textField.text = ""
root.isSearchBarVisible = false root.isSearchBarVisible = false
} }
@@ -586,6 +601,7 @@ PageType {
imageColor: AmneziaStyle.color.paleGray imageColor: AmneziaStyle.color.paleGray
function clickedFunc() { function clickedFunc() {
searchTextField.textField.text = ""
root.isSearchBarVisible = false root.isSearchBarVisible = false
} }
@@ -602,6 +618,8 @@ PageType {
visible: accessTypeSelector.currentIndex === 1 visible: accessTypeSelector.currentIndex === 1
function escapeRe(s) { return s.replace(/[.*+?^${}()|[\]\\]/g, '\\$&') }
property bool isFocusable: true property bool isFocusable: true
property bool freezeFilter: false property bool freezeFilter: false
@@ -611,7 +629,7 @@ PageType {
filters: RegExpFilter { filters: RegExpFilter {
roleName: "clientName" roleName: "clientName"
enabled: !clientsListView.freezeFilter enabled: !clientsListView.freezeFilter
pattern: ".*" + searchTextField.textField.text + ".*" pattern: ".*" + clientsListView.escapeRe(searchTextField.textField.text) + ".*"
caseSensitivity: Qt.CaseInsensitive caseSensitivity: Qt.CaseInsensitive
} }
} }
+1 -1
View File
@@ -73,7 +73,7 @@ PageType {
id: serverSelector id: serverSelector
objectName: "serverSelector" objectName: "serverSelector"
signal severSelectorIndexChanged signal serverSelectorIndexChanged
property int currentIndex: 0 property int currentIndex: 0
Layout.fillWidth: true Layout.fillWidth: true
+47 -38
View File
@@ -32,8 +32,8 @@
VpnConnection::VpnConnection(std::shared_ptr<Settings> settings, QObject *parent) VpnConnection::VpnConnection(std::shared_ptr<Settings> settings, QObject *parent)
: QObject(parent), m_settings(settings), m_checkTimer(new QTimer(this)) : QObject(parent), m_settings(settings), m_checkTimer(new QTimer(this))
{ {
m_checkTimer.setInterval(1000);
#if defined(Q_OS_IOS) || defined(MACOS_NE) #if defined(Q_OS_IOS) || defined(MACOS_NE)
m_checkTimer.setInterval(1000);
connect(IosController::Instance(), &IosController::connectionStateChanged, this, &VpnConnection::onConnectionStateChanged); connect(IosController::Instance(), &IosController::connectionStateChanged, this, &VpnConnection::onConnectionStateChanged);
connect(IosController::Instance(), &IosController::bytesChanged, this, &VpnConnection::onBytesChanged); connect(IosController::Instance(), &IosController::bytesChanged, this, &VpnConnection::onBytesChanged);
@@ -42,9 +42,6 @@ VpnConnection::VpnConnection(std::shared_ptr<Settings> settings, QObject *parent
VpnConnection::~VpnConnection() VpnConnection::~VpnConnection()
{ {
#if defined AMNEZIA_DESKTOP
disconnectFromVpn();
#endif
} }
void VpnConnection::onBytesChanged(quint64 receivedBytes, quint64 sentBytes) void VpnConnection::onBytesChanged(quint64 receivedBytes, quint64 sentBytes)
@@ -55,19 +52,7 @@ void VpnConnection::onBytesChanged(quint64 receivedBytes, quint64 sentBytes)
void VpnConnection::onKillSwitchModeChanged(bool enabled) void VpnConnection::onKillSwitchModeChanged(bool enabled)
{ {
#ifdef AMNEZIA_DESKTOP #ifdef AMNEZIA_DESKTOP
if (!m_IpcClient) { if (InterfaceReady()) {
m_IpcClient = new IpcClient(this);
}
if (!m_IpcClient->isSocketConnected()) {
if (!IpcClient::init(m_IpcClient)) {
qWarning() << "Error occurred when init IPC client";
emit serviceIsNotReady();
return;
}
}
if (IpcClient::Interface()) {
qDebug() << "Set KillSwitch Strict mode enabled " << enabled; qDebug() << "Set KillSwitch Strict mode enabled " << enabled;
IpcClient::Interface()->refreshKillSwitch(enabled); IpcClient::Interface()->refreshKillSwitch(enabled);
} }
@@ -80,7 +65,7 @@ void VpnConnection::onConnectionStateChanged(Vpn::ConnectionState state)
#ifdef AMNEZIA_DESKTOP #ifdef AMNEZIA_DESKTOP
auto container = m_settings->defaultContainer(m_settings->defaultServerIndex()); auto container = m_settings->defaultContainer(m_settings->defaultServerIndex());
if (IpcClient::Interface()) { if (InterfaceReady()) {
if (state == Vpn::ConnectionState::Connected) { if (state == Vpn::ConnectionState::Connected) {
IpcClient::Interface()->resetIpStack(); IpcClient::Interface()->resetIpStack();
IpcClient::Interface()->flushDns(); IpcClient::Interface()->flushDns();
@@ -212,14 +197,41 @@ void VpnConnection::deleteRoutes(const QStringList &ips)
#endif #endif
} }
bool VpnConnection::InterfaceReady()
{
#ifdef AMNEZIA_DESKTOP
if (!m_IpcClient) {
m_IpcClient = new IpcClient(this);
}
if (!m_IpcClient->isSocketConnected()) {
if (!IpcClient::init(m_IpcClient)) {
qWarning() << "Error occurred when init IPC client";
emit serviceIsNotReady();
return false;
}
}
return IpcClient::Interface() != nullptr;
#endif
return true;
}
void VpnConnection::flushDns() void VpnConnection::flushDns()
{ {
#ifdef AMNEZIA_DESKTOP #ifdef AMNEZIA_DESKTOP
if (IpcClient::Interface()) if (InterfaceReady())
IpcClient::Interface()->flushDns(); IpcClient::Interface()->flushDns();
#endif #endif
} }
void VpnConnection::disconnectSlots()
{
if (m_vpnProtocol) {
m_vpnProtocol->disconnect();
}
}
ErrorCode VpnConnection::lastError() const ErrorCode VpnConnection::lastError() const
{ {
#ifdef Q_OS_ANDROID #ifdef Q_OS_ANDROID
@@ -240,20 +252,11 @@ void VpnConnection::connectToVpn(int serverIndex, const ServerCredentials &crede
.arg(serverIndex) .arg(serverIndex)
.arg(ContainerProps::containerToString(container)) .arg(ContainerProps::containerToString(container))
<< m_settings->routeMode(); << m_settings->routeMode();
#if !defined(Q_OS_ANDROID) && !defined(Q_OS_IOS) && !defined(MACOS_NE)
if (!m_IpcClient) {
m_IpcClient = new IpcClient(this);
}
if (!m_IpcClient->isSocketConnected()) { if (!InterfaceReady()) {
if (!IpcClient::init(m_IpcClient)) { emit connectionStateChanged(Vpn::ConnectionState::Error);
qWarning() << "Error occurred when init IPC client"; return;
emit serviceIsNotReady();
emit connectionStateChanged(Vpn::ConnectionState::Error);
return;
}
} }
#endif
m_remoteAddress = NetworkUtilities::getIPAddress(credentials.hostName); m_remoteAddress = NetworkUtilities::getIPAddress(credentials.hostName);
emit connectionStateChanged(Vpn::ConnectionState::Connecting); emit connectionStateChanged(Vpn::ConnectionState::Connecting);
@@ -440,13 +443,18 @@ QString VpnConnection::bytesPerSecToText(quint64 bytes)
void VpnConnection::disconnectFromVpn() void VpnConnection::disconnectFromVpn()
{ {
#ifdef AMNEZIA_DESKTOP #ifdef AMNEZIA_DESKTOP
QString proto = m_settings->defaultContainerName(m_settings->defaultServerIndex()); if (InterfaceReady()) {
if (IpcClient::Interface()) {
IpcClient::Interface()->flushDns();
m_vpnProtocol.data()->stop();
qDebug() << "Interface is ready!";
QRemoteObjectPendingReply<bool> flushDnsResp = IpcClient::Interface()->flushDns();
flushDnsResp.waitForFinished(1000);
qDebug() << "Flushed DNS";
// delete cached routes // delete cached routes
QRemoteObjectPendingReply<bool> response = IpcClient::Interface()->clearSavedRoutes(); QRemoteObjectPendingReply<bool> clearSavedRoutesResp = IpcClient::Interface()->clearSavedRoutes();
response.waitForFinished(1000); clearSavedRoutesResp.waitForFinished(1000);
} }
#endif #endif
@@ -475,12 +483,13 @@ void VpnConnection::disconnectFromVpn()
return; return;
} }
#ifndef Q_OS_ANDROID #if !defined(Q_OS_ANDROID) && !defined(AMNEZIA_DESKTOP)
if (m_vpnProtocol) { if (m_vpnProtocol) {
m_vpnProtocol->deleteLater(); m_vpnProtocol->deleteLater();
} }
m_vpnProtocol = nullptr;
#endif #endif
m_vpnProtocol = nullptr;
} }
Vpn::ConnectionState VpnConnection::connectionState() Vpn::ConnectionState VpnConnection::connectionState()
+2
View File
@@ -56,6 +56,7 @@ public slots:
void deleteRoutes(const QStringList &ips); void deleteRoutes(const QStringList &ips);
void flushDns(); void flushDns();
void onKillSwitchModeChanged(bool enabled); void onKillSwitchModeChanged(bool enabled);
void disconnectSlots();
signals: signals:
void bytesChanged(quint64 receivedBytes, quint64 sentBytes); void bytesChanged(quint64 receivedBytes, quint64 sentBytes);
@@ -95,6 +96,7 @@ private:
void appendSplitTunnelingConfig(); void appendSplitTunnelingConfig();
void appendKillSwitchConfig(); void appendKillSwitchConfig();
bool InterfaceReady();
}; };
#endif // VPNCONNECTION_H #endif // VPNCONNECTION_H
+191 -9
View File
@@ -18,12 +18,23 @@ set APP_NAME=AmneziaVPN
set APP_FILENAME=%APP_NAME:"=%.exe set APP_FILENAME=%APP_NAME:"=%.exe
set APP_DOMAIN=org.amneziavpn.package set APP_DOMAIN=org.amneziavpn.package
set OUT_APP_DIR=%WORK_DIR:"=%\client\release set OUT_APP_DIR=%WORK_DIR:"=%\client\release
set PREBILT_DEPLOY_DATA_DIR=%PROJECT_DIR:"=%\client\3rd-prebuilt\deploy-prebuilt\windows\x%BUILD_ARCH:"=%
set DEPLOY_DATA_DIR=%SCRIPT_DIR:"=%\data\windows\x%BUILD_ARCH:"=% REM Determine architecture prefix for paths
if "%BUILD_ARCH%"=="arm64" (
set ARCH_PREFIX=arm64
) else (
set ARCH_PREFIX=x%BUILD_ARCH:"=%
)
set PREBILT_DEPLOY_DATA_DIR=%PROJECT_DIR:"=%\client\3rd-prebuilt\deploy-prebuilt\windows\%ARCH_PREFIX:"=%
set DEPLOY_DATA_DIR=%SCRIPT_DIR:"=%\data\windows\%ARCH_PREFIX:"=%
set INSTALLER_DATA_DIR=%WORK_DIR:"=%\installer\packages\%APP_DOMAIN:"=%\data set INSTALLER_DATA_DIR=%WORK_DIR:"=%\installer\packages\%APP_DOMAIN:"=%\data
set TARGET_FILENAME=%PROJECT_DIR:"=%\%APP_NAME:"=%_x%BUILD_ARCH:"=%.exe set TARGET_FILENAME=%PROJECT_DIR:"=%\%APP_NAME:"=%_x%BUILD_ARCH:"=%.exe
echo "Environment:" echo "Environment:"
echo "BUILD_ARCH: %BUILD_ARCH%"
echo "ARCH_PREFIX: %ARCH_PREFIX%"
if defined QT_HOST_PATH echo "QT_HOST_PATH: %QT_HOST_PATH%"
echo "WORK_DIR: %WORK_DIR%" echo "WORK_DIR: %WORK_DIR%"
echo "APP_FILENAME: %APP_FILENAME%" echo "APP_FILENAME: %APP_FILENAME%"
echo "PROJECT_DIR: %PROJECT_DIR%" echo "PROJECT_DIR: %PROJECT_DIR%"
@@ -39,12 +50,64 @@ del %TARGET_FILENAME%
mkdir %WORK_DIR% mkdir %WORK_DIR%
echo "Checking MSVC environment..."
where cl >nul 2>&1
if %errorlevel% equ 0 (
echo "MSVC compiler found"
cl 2>&1 | findstr /C:"Version"
) else (
echo "ERROR: MSVC compiler not found in PATH"
echo "Please ensure 'Setup mvsc' step in GitHub Actions workflow is configured correctly"
echo "Trying to find cl.exe..."
where cl 2>&1
exit /b 1
)
call "%QT_BIN_DIR:"=%\qt-cmake" --version call "%QT_BIN_DIR:"=%\qt-cmake" --version
"%QT_BIN_DIR:"=%\windeployqt" -v if defined QT_HOST_BIN_DIR (
"%QT_HOST_BIN_DIR:"=%\windeployqt" -v
) else (
"%QT_BIN_DIR:"=%\windeployqt" -v
)
cmake --version cmake --version
set "QT_ROOT_DIR=%QT_BIN_DIR:\bin=%"
cd %PROJECT_DIR% cd %PROJECT_DIR%
call cmake . -B %WORK_DIR% "-DCMAKE_BUILD_TYPE:STRING=Release" "-DCMAKE_PREFIX_PATH:PATH=%QT_BIN_DIR%" if defined QT_HOST_PATH (
REM ARM64 cross-compilation - set generator platform to ARM64
REM CMAKE_PREFIX_PATH must point to Qt root (not bin), so CMake can find lib directory
echo "=== CMake Configuration for ARM64 ==="
echo "QT_BIN_DIR: %QT_BIN_DIR%"
echo "QT_ROOT_DIR: %QT_ROOT_DIR%"
echo "QT_HOST_PATH: %QT_HOST_PATH%"
echo "CMAKE_PREFIX_PATH: %QT_ROOT_DIR%"
echo "Generator Platform: ARM64"
echo "===================================="
REM Verify Qt ARM64 directories exist
if not exist "%QT_ROOT_DIR%" (
echo "ERROR: Qt ARM64 root directory not found at %QT_ROOT_DIR%"
exit /b 1
)
echo "Qt ARM64 root directory exists: %QT_ROOT_DIR%"
if not exist "%QT_ROOT_DIR%\lib" (
echo "ERROR: Qt ARM64 lib directory not found at %QT_ROOT_DIR%\lib"
exit /b 1
)
echo "Building for ARM64"
call cmake . -B %WORK_DIR% -A ARM64 "-DCMAKE_BUILD_TYPE:STRING=Release" "-DCMAKE_PREFIX_PATH:PATH=%QT_ROOT_DIR%" "-DQT_HOST_PATH:PATH=%QT_HOST_PATH%"
) else (
REM x64 build - QT_ROOT_DIR already calculated above
echo "=== CMake Configuration for x64 ==="
echo "QT_ROOT_DIR: %QT_ROOT_DIR%"
echo "===================================="
call cmake . -B %WORK_DIR% "-DCMAKE_BUILD_TYPE:STRING=Release" "-DCMAKE_PREFIX_PATH:PATH=%QT_ROOT_DIR%"
)
cd %WORK_DIR% cd %WORK_DIR%
cmake --build . --config release -- /p:UseMultiToolTask=true /m cmake --build . --config release -- /p:UseMultiToolTask=true /m
@@ -54,16 +117,125 @@ echo "Deploying..."
mkdir "%OUT_APP_DIR%" mkdir "%OUT_APP_DIR%"
copy "%WORK_DIR%\service\server\release\%APP_NAME%-service.exe" "%OUT_APP_DIR%" copy "%WORK_DIR%\service\server\release\%APP_NAME%-service.exe" "%OUT_APP_DIR%"
rem copy "%WORK_DIR%\client\%APP_FILENAME%" "%OUT_APP_DIR%" copy "%WORK_DIR%\client\Release\%APP_FILENAME%" "%OUT_APP_DIR%"
echo "Signing exe" echo "Signing exe"
cd %OUT_APP_DIR% cd %OUT_APP_DIR%
signtool sign /v /n "Privacy Technologies OU" /fd sha256 /tr http://timestamp.comodoca.com/?td=sha256 /td sha256 *.exe REM For ARM64 cross-compilation, use x64 signtool from host (ARM64 signtool won't run on x64 Windows)
if defined QT_HOST_BIN_DIR (
REM Find x64 signtool - look for x64 version in Windows Kits (skip arm64)
set SIGNGTOOL_PATH=
for /f "delims=" %%i in ('dir /b /s "C:\Program Files (x86)\Windows Kits\10\bin\*\x64\signtool.exe" 2^>nul') do (
set SIGNGTOOL_PATH=%%i
goto :found_signtool
)
:found_signtool
if defined SIGNGTOOL_PATH (
echo "Using x64 signtool: %SIGNGTOOL_PATH%"
"%SIGNGTOOL_PATH%" sign /v /n "Privacy Technologies OU" /fd sha256 /tr http://timestamp.comodoca.com/?td=sha256 /td sha256 *.exe
) else (
echo "Warning: Could not find x64 signtool, trying default signtool"
signtool sign /v /n "Privacy Technologies OU" /fd sha256 /tr http://timestamp.comodoca.com/?td=sha256 /td sha256 *.exe 2>nul || echo "Warning: Signing failed, continuing..."
)
) else (
signtool sign /v /n "Privacy Technologies OU" /fd sha256 /tr http://timestamp.comodoca.com/?td=sha256 /td sha256 *.exe
)
"%QT_BIN_DIR:"=%\windeployqt" --release --qmldir "%PROJECT_DIR:"=%\client" --force --no-translations "%OUT_APP_DIR:"=%\%APP_FILENAME:"=%" REM For cross-compiled ARM64, use windeployqt from host Qt (x64) but point to ARM64 Qt libraries
if defined QT_HOST_BIN_DIR (
echo "Using host windeployqt for cross-compilation (to copy ARM64 libraries)"
echo "ARM64 exe file: %OUT_APP_DIR%\%APP_FILENAME%"
echo "ARM64 Qt path: %QT_BIN_DIR%"
REM Verify that ARM64 exe exists before running windeployqt
if not exist "%OUT_APP_DIR%\%APP_FILENAME%" (
echo "ERROR: ARM64 exe file not found: %OUT_APP_DIR%\%APP_FILENAME%"
exit /b 1
)
REM For ARM64 cross-compilation, manually copy all Qt ARM64 libraries
REM windeployqt from x64 host copies x64 libraries, not ARM64
echo "Manually copying ARM64 Qt libraries (windeployqt copies x64 instead)"
echo "ARM64 Qt path: %QT_BIN_DIR:"=%"
REM First, use windeployqt ONLY to detect QML dependencies (--dry-run would be ideal but not supported)
REM We'll let it run to create directory structure, then overwrite with ARM64 DLLs
echo "Running windeployqt to detect QML dependencies..."
"%QT_HOST_BIN_DIR:"=%\windeployqt" --release --qmldir "%PROJECT_DIR:"=%\client" --force --no-translations --compiler-runtime "%OUT_APP_DIR:"=%\%APP_FILENAME:"=%"
REM Now overwrite all x64 DLLs with ARM64 DLLs
echo "Overwriting x64 Qt DLLs with ARM64 versions..."
if exist "%QT_BIN_DIR:"=%\Qt6Core.dll" (
echo "Copying all ARM64 Qt DLLs from %QT_BIN_DIR:"=%"
copy "%QT_BIN_DIR:"=%\*.dll" "%OUT_APP_DIR:"=%\" /y >nul 2>&1
REM Also copy DLLs from Qt root directory (d3dcompiler_47.dll, dxcompiler.dll, etc.)
set "QT_ROOT=%QT_BIN_DIR:"=%\.."
if exist "%QT_ROOT%\*.dll" (
echo "Copying additional ARM64 DLLs from Qt root"
copy "%QT_ROOT%\*.dll" "%OUT_APP_DIR:"=%\" /y >nul 2>&1
)
REM Copy all ARM64 Qt plugins (overwrite x64 versions)
if exist "%QT_BIN_DIR:"=%\..\plugins" (
echo "Copying ARM64 Qt plugins"
xcopy "%QT_BIN_DIR:"=%\..\plugins" "%OUT_APP_DIR:"=%\" /s /e /y /i >nul 2>&1
)
REM Copy ARM64 QML modules
if exist "%QT_BIN_DIR:"=%\..\qml" (
echo "Copying ARM64 QML modules"
xcopy "%QT_BIN_DIR:"=%\..\qml" "%OUT_APP_DIR:"=%\qml\" /s /e /y /i >nul 2>&1
)
REM Copy translations
if exist "%QT_BIN_DIR:"=%\..\translations" (
echo "Copying translations"
xcopy "%QT_BIN_DIR:"=%\..\translations" "%OUT_APP_DIR:"=%\translations\" /s /e /y /i >nul 2>&1
)
REM Copy resources
if exist "%QT_BIN_DIR:"=%\..\resources" (
echo "Copying resources"
xcopy "%QT_BIN_DIR:"=%\..\resources" "%OUT_APP_DIR:"=%\resources\" /s /e /y /i >nul 2>&1
)
REM Copy all additional Qt module directories that exist
echo "Copying additional ARM64 Qt module directories..."
set "QT_ROOT=%QT_BIN_DIR:"=%\.."
REM List of Qt module directories to copy
for %%d in (cloak cygwin generic iconengines imageformats networkinformation openvpn platforms qmltooling ss styles tap tls xray) do (
if exist "%QT_ROOT%\%%d" (
echo "Copying %%d directory"
xcopy "%QT_ROOT%\%%d" "%OUT_APP_DIR:"=%\%%d\" /s /e /y /i >nul 2>&1
)
)
echo "ARM64 Qt libraries copied successfully"
REM Remove ALL debug DLLs recursively (Qt6*d.dll, *d.dll in all subdirectories)
echo "Removing debug DLLs and libraries from output directory (recursive)..."
del /s /q "%OUT_APP_DIR:"=%\*d.dll" >nul 2>&1
) else (
echo "ERROR: ARM64 Qt DLLs not found in %QT_BIN_DIR:"=%"
exit /b 1
)
) else (
"%QT_BIN_DIR:"=%\windeployqt" --release --qmldir "%PROJECT_DIR:"=%\client" --force --no-translations "%OUT_APP_DIR:"=%\%APP_FILENAME:"=%"
)
signtool sign /v /n "Privacy Technologies OU" /fd sha256 /tr http://timestamp.comodoca.com/?td=sha256 /td sha256 *.dll REM Sign DLLs - use x64 signtool for ARM64 cross-compilation
cd %OUT_APP_DIR%
if defined QT_HOST_BIN_DIR (
if defined SIGNGTOOL_PATH (
"%SIGNGTOOL_PATH%" sign /v /n "Privacy Technologies OU" /fd sha256 /tr http://timestamp.comodoca.com/?td=sha256 /td sha256 *.dll
) else (
echo "Warning: Could not find x64 signtool, trying default signtool for DLLs"
signtool sign /v /n "Privacy Technologies OU" /fd sha256 /tr http://timestamp.comodoca.com/?td=sha256 /td sha256 *.dll 2>nul || echo "Warning: DLL signing failed, continuing..."
)
) else (
signtool sign /v /n "Privacy Technologies OU" /fd sha256 /tr http://timestamp.comodoca.com/?td=sha256 /td sha256 *.dll
)
echo "Copying deploy data..." echo "Copying deploy data..."
xcopy %DEPLOY_DATA_DIR% %OUT_APP_DIR% /s /e /y /i /f xcopy %DEPLOY_DATA_DIR% %OUT_APP_DIR% /s /e /y /i /f
@@ -87,7 +259,17 @@ echo "Creating installer..."
timeout 5 timeout 5
cd %PROJECT_DIR% cd %PROJECT_DIR%
signtool sign /v /n "Privacy Technologies OU" /fd sha256 /tr http://timestamp.comodoca.com/?td=sha256 /td sha256 "%TARGET_FILENAME%" REM For ARM64 cross-compilation, use x64 signtool for final installer
if defined QT_HOST_BIN_DIR (
if defined SIGNGTOOL_PATH (
"%SIGNGTOOL_PATH%" sign /v /n "Privacy Technologies OU" /fd sha256 /tr http://timestamp.comodoca.com/?td=sha256 /td sha256 "%TARGET_FILENAME%"
) else (
echo "Warning: Could not find x64 signtool, trying default signtool for installer"
signtool sign /v /n "Privacy Technologies OU" /fd sha256 /tr http://timestamp.comodoca.com/?td=sha256 /td sha256 "%TARGET_FILENAME%" 2>nul || echo "Warning: Installer signing failed, continuing..."
)
) else (
signtool sign /v /n "Privacy Technologies OU" /fd sha256 /tr http://timestamp.comodoca.com/?td=sha256 /td sha256 "%TARGET_FILENAME%"
)
echo "Finished, see %TARGET_FILENAME%" echo "Finished, see %TARGET_FILENAME%"
exit 0 exit 0
@@ -0,0 +1,6 @@
sc stop AmneziaWGTunnel$AmneziaVPN
sc delete AmneziaWGTunnel$AmneziaVPN
taskkill /IM "AmneziaVPN-service.exe" /F
taskkill /IM "AmneziaVPN.exe" /F
exit /b 0
@@ -0,0 +1,33 @@
set AmneziaPath=%~dp0
echo %AmneziaPath%
rem Define directories for logs
set "ORG_DIR=%AppData%\AmneziaVPN.ORG"
set "USER_APP_DIR=%ORG_DIR%\AmneziaVPN"
set "USER_LOG_DIR=%USER_APP_DIR%\log"
set "SYS_APP_DIR=%ProgramData%\AmneziaVPN"
set "SYS_LOG_DIR=%SYS_APP_DIR%\log"
set "SYS_LOG_FILE=%SYS_LOG_DIR%\AmneziaVPN-service.log"
timeout /t 1
sc stop AmneziaVPN-service
sc delete AmneziaVPN-service
sc stop AmneziaWGTunnel$AmneziaVPN
sc delete AmneziaWGTunnel$AmneziaVPN
taskkill /IM "AmneziaVPN-service.exe" /F
taskkill /IM "AmneziaVPN.exe" /F
rem Delete the service log file under ProgramData
if exist "%SYS_LOG_FILE%" del /F /Q "%SYS_LOG_FILE%"
if exist "%SYS_LOG_DIR%" rmdir /S /Q "%SYS_LOG_DIR%"
rem Try to remove application dir if empty
rd "%SYS_APP_DIR%" 2>nul
rem Delete client logs under current user's AppData\Roaming (Organization\Application)
if exist "%USER_LOG_DIR%" rmdir /S /Q "%USER_LOG_DIR%"
rem Try to remove app and org directories if empty
rd "%USER_APP_DIR%" 2>nul
rd "%ORG_DIR%" 2>nul
exit /b 0
@@ -73,12 +73,36 @@ Component.prototype.createOperations = function()
"workingDirectory=@TargetDir@", "iconPath=@TargetDir@\\" + appExecutableFileName(), "iconId=0"); "workingDirectory=@TargetDir@", "iconPath=@TargetDir@\\" + appExecutableFileName(), "iconId=0");
if (!vcRuntimeIsInstalled()) { if (!vcRuntimeIsInstalled()) {
if (systemInfo.currentCpuArchitecture.search("64") < 0) { var targetDir = installer.value("TargetDir").replace(/\//g, '\\');
var vcRedistArm64 = installer.findPath("vc_redist.arm64.exe", [targetDir]);
var vcRedistX86 = installer.findPath("vc_redist.x86.exe", [targetDir]);
var vcRedistX64 = installer.findPath("vc_redist.x64.exe", [targetDir]);
if (vcRedistArm64.length > 0) {
console.log("Found vc_redist.arm64.exe, installing ARM64 redistributable");
component.addElevatedOperation("Execute", "@TargetDir@\\" + "vc_redist.arm64.exe", "/install", "/quiet", "/norestart", "/log", "vc_redist.log");
}
else if (vcRedistX86.length > 0) {
console.log("Found vc_redist.x86.exe, installing x86 redistributable");
component.addElevatedOperation("Execute", "@TargetDir@\\" + "vc_redist.x86.exe", "/install", "/quiet", "/norestart", "/log", "vc_redist.log"); component.addElevatedOperation("Execute", "@TargetDir@\\" + "vc_redist.x86.exe", "/install", "/quiet", "/norestart", "/log", "vc_redist.log");
} }
else { else if (vcRedistX64.length > 0) {
console.log("Found vc_redist.x64.exe, installing x64 redistributable");
component.addElevatedOperation("Execute", "@TargetDir@\\" + "vc_redist.x64.exe", "/install", "/quiet", "/norestart", "/log", "vc_redist.log"); component.addElevatedOperation("Execute", "@TargetDir@\\" + "vc_redist.x64.exe", "/install", "/quiet", "/norestart", "/log", "vc_redist.log");
} }
else {
// Fallback to system architecture detection
console.log("No vc_redist file found, using system architecture: " + systemInfo.currentCpuArchitecture);
if (systemInfo.currentCpuArchitecture.search("arm64") >= 0) {
component.addElevatedOperation("Execute", "@TargetDir@\\" + "vc_redist.arm64.exe", "/install", "/quiet", "/norestart", "/log", "vc_redist.log");
}
else if (systemInfo.currentCpuArchitecture.search("64") < 0) {
component.addElevatedOperation("Execute", "@TargetDir@\\" + "vc_redist.x86.exe", "/install", "/quiet", "/norestart", "/log", "vc_redist.log");
}
else {
component.addElevatedOperation("Execute", "@TargetDir@\\" + "vc_redist.x64.exe", "/install", "/quiet", "/norestart", "/log", "vc_redist.log");
}
}
} else { } else {
console.log("Microsoft Visual C++ 2017 Redistributable already installed"); console.log("Microsoft Visual C++ 2017 Redistributable already installed");
+3 -3
View File
@@ -12,7 +12,7 @@ class IpcInterface
SLOT( int routeAddList(const QString &gw, const QStringList &ips) ); SLOT( int routeAddList(const QString &gw, const QStringList &ips) );
SLOT( bool clearSavedRoutes() ); SLOT( bool clearSavedRoutes() );
SLOT( bool routeDeleteList(const QString &gw, const QStringList &ip) ); SLOT( bool routeDeleteList(const QString &gw, const QStringList &ip) );
SLOT( void flushDns() ); SLOT( bool flushDns() );
SLOT( void resetIpStack() ); SLOT( void resetIpStack() );
SLOT( bool checkAndInstallDriver() ); SLOT( bool checkAndInstallDriver() );
@@ -25,8 +25,8 @@ class IpcInterface
SLOT( bool createTun(const QString &dev, const QString &subnet) ); SLOT( bool createTun(const QString &dev, const QString &subnet) );
SLOT( bool deleteTun(const QString &dev) ); SLOT( bool deleteTun(const QString &dev) );
SLOT( void StartRoutingIpv6() ); SLOT( bool StartRoutingIpv6() );
SLOT( void StopRoutingIpv6() ); SLOT( bool StopRoutingIpv6() );
SLOT( bool disableKillSwitch() ); SLOT( bool disableKillSwitch() );
SLOT( bool disableAllTraffic() ); SLOT( bool disableAllTraffic() );
+6 -5
View File
@@ -83,7 +83,7 @@ bool IpcServer::routeDeleteList(const QString &gw, const QStringList &ips)
return Router::routeDeleteList(gw, ips); return Router::routeDeleteList(gw, ips);
} }
void IpcServer::flushDns() bool IpcServer::flushDns()
{ {
#ifdef MZ_DEBUG #ifdef MZ_DEBUG
qDebug() << "IpcServer::flushDns"; qDebug() << "IpcServer::flushDns";
@@ -161,13 +161,14 @@ bool IpcServer::restoreResolvers() {
return Router::restoreResolvers(); return Router::restoreResolvers();
} }
void IpcServer::StartRoutingIpv6() bool IpcServer::StartRoutingIpv6()
{ {
Router::StartRoutingIpv6(); return Router::StartRoutingIpv6();
} }
void IpcServer::StopRoutingIpv6()
bool IpcServer::StopRoutingIpv6()
{ {
Router::StopRoutingIpv6(); return Router::StopRoutingIpv6();
} }
void IpcServer::setLogsEnabled(bool enabled) void IpcServer::setLogsEnabled(bool enabled)
+3 -3
View File
@@ -23,7 +23,7 @@ public:
virtual int routeAddList(const QString &gw, const QStringList &ips) override; virtual int routeAddList(const QString &gw, const QStringList &ips) override;
virtual bool clearSavedRoutes() override; virtual bool clearSavedRoutes() override;
virtual bool routeDeleteList(const QString &gw, const QStringList &ips) override; virtual bool routeDeleteList(const QString &gw, const QStringList &ips) override;
virtual void flushDns() override; virtual bool flushDns() override;
virtual void resetIpStack() override; virtual void resetIpStack() override;
virtual bool checkAndInstallDriver() override; virtual bool checkAndInstallDriver() override;
virtual QStringList getTapList() override; virtual QStringList getTapList() override;
@@ -32,8 +32,8 @@ public:
virtual void setLogsEnabled(bool enabled) override; virtual void setLogsEnabled(bool enabled) override;
virtual bool createTun(const QString &dev, const QString &subnet) override; virtual bool createTun(const QString &dev, const QString &subnet) override;
virtual bool deleteTun(const QString &dev) override; virtual bool deleteTun(const QString &dev) override;
virtual void StartRoutingIpv6() override; virtual bool StartRoutingIpv6() override;
virtual void StopRoutingIpv6() override; virtual bool StopRoutingIpv6() override;
virtual bool disableAllTraffic() override; virtual bool disableAllTraffic() override;
virtual bool addKillSwitchAllowedRange(QStringList ranges) override; virtual bool addKillSwitchAllowedRange(QStringList ranges) override;
virtual bool resetKillSwitchAllowedRange(QStringList ranges) override; virtual bool resetKillSwitchAllowedRange(QStringList ranges) override;
+14 -12
View File
@@ -18,22 +18,21 @@ set(QSIMPLECRYPTO_DIR ${CMAKE_CURRENT_LIST_DIR}/../../client/3rd/QSimpleCrypto/s
set(OPENSSL_ROOT_DIR "${CMAKE_CURRENT_LIST_DIR}/../../client/3rd-prebuilt/3rd-prebuilt/openssl/") set(OPENSSL_ROOT_DIR "${CMAKE_CURRENT_LIST_DIR}/../../client/3rd-prebuilt/3rd-prebuilt/openssl/")
set(OPENSSL_LIBRARIES_DIR "${OPENSSL_ROOT_DIR}/lib") set(OPENSSL_LIBRARIES_DIR "${OPENSSL_ROOT_DIR}/lib")
set(OPENSSL_INCLUDE_DIR "${OPENSSL_ROOT_DIR}/windows/include")
if("${CMAKE_SIZEOF_VOID_P}" STREQUAL "8")
set(OPENSSL_LIB_SSL_PATH "${OPENSSL_ROOT_DIR}/windows/win64/libssl.lib")
set(OPENSSL_LIB_CRYPTO_PATH "${OPENSSL_ROOT_DIR}/windows/win64/libcrypto.lib")
else()
set(OPENSSL_LIB_SSL_PATH "${OPENSSL_ROOT_DIR}/windows/win32/libssl.lib")
set(OPENSSL_LIB_CRYPTO_PATH "${OPENSSL_ROOT_DIR}/windows/win32/libcrypto.lib")
endif()
if(WIN32) if(WIN32)
set(OPENSSL_INCLUDE_DIR "${OPENSSL_ROOT_DIR}/windows/include") set(OPENSSL_INCLUDE_DIR "${OPENSSL_ROOT_DIR}/windows/include")
if("${CMAKE_SIZEOF_VOID_P}" STREQUAL "8") # Use CMAKE_GENERATOR_PLATFORM for cross-compilation detection (ARM64 on x64 host)
if("${CMAKE_GENERATOR_PLATFORM}" STREQUAL "ARM64" OR "${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "ARM64")
set(OPENSSL_LIB_SSL_PATH "${OPENSSL_ROOT_DIR}/windows/winarm64/libssl.lib")
set(OPENSSL_LIB_CRYPTO_PATH "${OPENSSL_ROOT_DIR}/windows/winarm64/libcrypto.lib")
message(STATUS "Service: Using ARM64 OpenSSL libraries")
elseif("${CMAKE_SIZEOF_VOID_P}" STREQUAL "8")
set(OPENSSL_LIB_SSL_PATH "${OPENSSL_ROOT_DIR}/windows/win64/libssl.lib")
set(OPENSSL_LIB_CRYPTO_PATH "${OPENSSL_ROOT_DIR}/windows/win64/libcrypto.lib") set(OPENSSL_LIB_CRYPTO_PATH "${OPENSSL_ROOT_DIR}/windows/win64/libcrypto.lib")
message(STATUS "Service: Using x64 OpenSSL libraries")
else() else()
set(OPENSSL_LIB_SSL_PATH "${OPENSSL_ROOT_DIR}/windows/win32/libssl.lib")
set(OPENSSL_LIB_CRYPTO_PATH "${OPENSSL_ROOT_DIR}/windows/win32/libcrypto.lib") set(OPENSSL_LIB_CRYPTO_PATH "${OPENSSL_ROOT_DIR}/windows/win32/libcrypto.lib")
message(STATUS "Service: Using x86 OpenSSL libraries")
endif() endif()
elseif(APPLE AND NOT IOS) elseif(APPLE AND NOT IOS)
set(OPENSSL_INCLUDE_DIR "${OPENSSL_ROOT_DIR}/macos/include") set(OPENSSL_INCLUDE_DIR "${OPENSSL_ROOT_DIR}/macos/include")
@@ -360,7 +359,10 @@ qt_add_repc_sources(${PROJECT} ${CMAKE_CURRENT_LIST_DIR}/../../ipc/ipc_process_t
# copy deploy artifacts required to run the application to the debug build folder # copy deploy artifacts required to run the application to the debug build folder
if(WIN32) if(WIN32)
if("${CMAKE_SIZEOF_VOID_P}" STREQUAL "8") # Use CMAKE_GENERATOR_PLATFORM for cross-compilation detection
if("${CMAKE_GENERATOR_PLATFORM}" STREQUAL "ARM64" OR "${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "ARM64")
set(DEPLOY_PLATFORM_PATH "windows/arm64")
elseif("${CMAKE_SIZEOF_VOID_P}" STREQUAL "8")
set(DEPLOY_PLATFORM_PATH "windows/x64") set(DEPLOY_PLATFORM_PATH "windows/x64")
else() else()
set(DEPLOY_PLATFORM_PATH "windows/x32") set(DEPLOY_PLATFORM_PATH "windows/x32")
+11
View File
@@ -98,6 +98,17 @@ bool KillSwitch::disableKillSwitch() {
LinuxFirewall::setAnchorEnabled(LinuxFirewall::IPv4, QStringLiteral("320.allowDNS"), false); LinuxFirewall::setAnchorEnabled(LinuxFirewall::IPv4, QStringLiteral("320.allowDNS"), false);
LinuxFirewall::setAnchorEnabled(LinuxFirewall::Both, QStringLiteral("400.allowPIA"), false); LinuxFirewall::setAnchorEnabled(LinuxFirewall::Both, QStringLiteral("400.allowPIA"), false);
} else { } else {
LinuxFirewall::setAnchorEnabled(LinuxFirewall::Both, QStringLiteral("000.allowLoopback"), true);
LinuxFirewall::setAnchorEnabled(LinuxFirewall::Both, QStringLiteral("100.blockAll"), false);
LinuxFirewall::setAnchorEnabled(LinuxFirewall::IPv4, QStringLiteral("110.allowNets"), false);
LinuxFirewall::setAnchorEnabled(LinuxFirewall::IPv4, QStringLiteral("120.blockNets"), false);
LinuxFirewall::setAnchorEnabled(LinuxFirewall::IPv4, QStringLiteral("200.allowVPN"), false);
LinuxFirewall::setAnchorEnabled(LinuxFirewall::IPv6, QStringLiteral("250.blockIPv6"), false);
LinuxFirewall::setAnchorEnabled(LinuxFirewall::Both, QStringLiteral("290.allowDHCP"), true);
LinuxFirewall::setAnchorEnabled(LinuxFirewall::Both, QStringLiteral("300.allowLAN"), true);
LinuxFirewall::setAnchorEnabled(LinuxFirewall::IPv4, QStringLiteral("310.blockDNS"), false);
LinuxFirewall::setAnchorEnabled(LinuxFirewall::IPv4, QStringLiteral("320.allowDNS"), true);
LinuxFirewall::setAnchorEnabled(LinuxFirewall::Both, QStringLiteral("400.allowPIA"), false);
LinuxFirewall::uninstall(); LinuxFirewall::uninstall();
} }
#endif #endif
+12 -12
View File
@@ -42,14 +42,14 @@ int Router::routeDeleteList(const QString &gw, const QStringList &ips)
#endif #endif
} }
void Router::flushDns() bool Router::flushDns()
{ {
#ifdef Q_OS_WIN #ifdef Q_OS_WIN
RouterWin::Instance().flushDns(); return RouterWin::Instance().flushDns();
#elif defined (Q_OS_MAC) #elif defined (Q_OS_MAC)
RouterMac::Instance().flushDns(); return RouterMac::Instance().flushDns();
#elif defined Q_OS_LINUX #elif defined Q_OS_LINUX
RouterLinux::Instance().flushDns(); return RouterLinux::Instance().flushDns();
#endif #endif
} }
@@ -111,25 +111,25 @@ bool Router::restoreResolvers() {
#endif #endif
} }
void Router::StopRoutingIpv6() bool Router::StopRoutingIpv6()
{ {
#ifdef Q_OS_WIN #ifdef Q_OS_WIN
RouterWin::Instance().StopRoutingIpv6(); return RouterWin::Instance().StopRoutingIpv6();
#elif defined (Q_OS_MAC) #elif defined (Q_OS_MAC)
// todo fixme return true;// todo fixme
#elif defined Q_OS_LINUX #elif defined Q_OS_LINUX
RouterLinux::Instance().StopRoutingIpv6(); return RouterLinux::Instance().StopRoutingIpv6();
#endif #endif
} }
void Router::StartRoutingIpv6() bool Router::StartRoutingIpv6()
{ {
#ifdef Q_OS_WIN #ifdef Q_OS_WIN
RouterWin::Instance().StartRoutingIpv6(); return RouterWin::Instance().StartRoutingIpv6();
#elif defined (Q_OS_MAC) #elif defined (Q_OS_MAC)
// todo fixme return true;// todo fixme
#elif defined Q_OS_LINUX #elif defined Q_OS_LINUX
RouterLinux::Instance().StartRoutingIpv6(); return RouterLinux::Instance().StartRoutingIpv6();
#endif #endif
} }
+3 -3
View File
@@ -19,12 +19,12 @@ public:
static int routeAddList(const QString &gw, const QStringList &ips); static int routeAddList(const QString &gw, const QStringList &ips);
static bool clearSavedRoutes(); static bool clearSavedRoutes();
static int routeDeleteList(const QString &gw, const QStringList &ips); static int routeDeleteList(const QString &gw, const QStringList &ips);
static void flushDns(); static bool flushDns();
static void resetIpStack(); static void resetIpStack();
static bool createTun(const QString &dev, const QString &subnet); static bool createTun(const QString &dev, const QString &subnet);
static bool deleteTun(const QString &dev); static bool deleteTun(const QString &dev);
static void StartRoutingIpv6(); static bool StartRoutingIpv6();
static void StopRoutingIpv6(); static bool StopRoutingIpv6();
static bool updateResolvers(const QString& ifname, const QList<QHostAddress>& resolvers); static bool updateResolvers(const QString& ifname, const QList<QHostAddress>& resolvers);
static bool restoreResolvers(); static bool restoreResolvers();
}; };
+16 -12
View File
@@ -160,7 +160,7 @@ bool RouterLinux::isServiceActive(const QString &serviceName) {
return process.exitCode() == 0; return process.exitCode() == 0;
} }
void RouterLinux::flushDns() bool RouterLinux::flushDns()
{ {
QProcess p; QProcess p;
p.setProcessChannelMode(QProcess::MergedChannels); p.setProcessChannelMode(QProcess::MergedChannels);
@@ -174,7 +174,7 @@ void RouterLinux::flushDns()
p.start("systemctl", { "restart", "systemd-resolved" }); p.start("systemctl", { "restart", "systemd-resolved" });
} else { } else {
qDebug() << "No suitable DNS manager found."; qDebug() << "No suitable DNS manager found.";
return; return false;
} }
p.waitForFinished(); p.waitForFinished();
@@ -183,6 +183,8 @@ void RouterLinux::flushDns()
qDebug().noquote() << "Flush dns completed"; qDebug().noquote() << "Flush dns completed";
else else
qDebug().noquote() << "OUTPUT systemctl restart nscd/systemd-resolved: " + output; qDebug().noquote() << "OUTPUT systemctl restart nscd/systemd-resolved: " + output;
return true;
} }
bool RouterLinux::createTun(const QString &dev, const QString &subnet) { bool RouterLinux::createTun(const QString &dev, const QString &subnet) {
@@ -283,7 +285,7 @@ bool RouterLinux::restoreResolvers() {
return m_dnsUtil->restoreResolvers(); return m_dnsUtil->restoreResolvers();
} }
void RouterLinux::StartRoutingIpv6() bool RouterLinux::StartRoutingIpv6()
{ {
QProcess process; QProcess process;
QStringList commands; QStringList commands;
@@ -293,12 +295,12 @@ void RouterLinux::StartRoutingIpv6()
if (!process.waitForStarted(1000)) if (!process.waitForStarted(1000))
{ {
qDebug().noquote() << "Could not start activate ipv6\n"; qDebug().noquote() << "Could not start activate ipv6\n";
return; return false;
} }
else if (!process.waitForFinished(2000)) else if (!process.waitForFinished(2000))
{ {
qDebug().noquote() << "Could not activate ipv6\n"; qDebug().noquote() << "Could not activate ipv6\n";
return; return false;
} }
commands.clear(); commands.clear();
@@ -307,19 +309,20 @@ void RouterLinux::StartRoutingIpv6()
if (!process.waitForStarted(1000)) if (!process.waitForStarted(1000))
{ {
qDebug().noquote() << "Could not start activate ipv6\n"; qDebug().noquote() << "Could not start activate ipv6\n";
return; return false;
} }
else if (!process.waitForFinished(2000)) else if (!process.waitForFinished(2000))
{ {
qDebug().noquote() << "Could not activate ipv6\n"; qDebug().noquote() << "Could not activate ipv6\n";
return; return false;
} }
commands.clear(); commands.clear();
qDebug().noquote() << "StartRoutingIpv6 OK"; qDebug().noquote() << "StartRoutingIpv6 OK";
return true;
} }
void RouterLinux::StopRoutingIpv6() bool RouterLinux::StopRoutingIpv6()
{ {
QProcess process; QProcess process;
QStringList commands; QStringList commands;
@@ -329,12 +332,12 @@ void RouterLinux::StopRoutingIpv6()
if (!process.waitForStarted(1000)) if (!process.waitForStarted(1000))
{ {
qDebug().noquote() << "Could not start disable ipv6\n"; qDebug().noquote() << "Could not start disable ipv6\n";
return; return false;
} }
else if (!process.waitForFinished(2000)) else if (!process.waitForFinished(2000))
{ {
qDebug().noquote() << "Could not disable ipv6\n"; qDebug().noquote() << "Could not disable ipv6\n";
return; return false;
} }
commands.clear(); commands.clear();
@@ -343,14 +346,15 @@ void RouterLinux::StopRoutingIpv6()
if (!process.waitForStarted(1000)) if (!process.waitForStarted(1000))
{ {
qDebug().noquote() << "Could not start disable ipv6\n"; qDebug().noquote() << "Could not start disable ipv6\n";
return; return false;
} }
else if (!process.waitForFinished(2000)) else if (!process.waitForFinished(2000))
{ {
qDebug().noquote() << "Could not disable ipv6\n"; qDebug().noquote() << "Could not disable ipv6\n";
return; return false;
} }
commands.clear(); commands.clear();
qDebug().noquote() << "StopRoutingIpv6 OK"; qDebug().noquote() << "StopRoutingIpv6 OK";
return true;
} }
+3 -3
View File
@@ -30,11 +30,11 @@ public:
bool routeDelete(const QString &ip, const QString &gw, const int &sock); bool routeDelete(const QString &ip, const QString &gw, const int &sock);
bool routeDeleteList(const QString &gw, const QStringList &ips); bool routeDeleteList(const QString &gw, const QStringList &ips);
QString getgatewayandiface(); QString getgatewayandiface();
void flushDns(); bool flushDns();
bool createTun(const QString &dev, const QString &subnet); bool createTun(const QString &dev, const QString &subnet);
bool deleteTun(const QString &dev); bool deleteTun(const QString &dev);
void StartRoutingIpv6(); bool StartRoutingIpv6();
void StopRoutingIpv6(); bool StopRoutingIpv6();
bool updateResolvers(const QString& ifname, const QList<QHostAddress>& resolvers); bool updateResolvers(const QString& ifname, const QList<QHostAddress>& resolvers);
bool restoreResolvers(); bool restoreResolvers();
public slots: public slots:
+3 -1
View File
@@ -169,7 +169,7 @@ bool RouterMac::deleteTun(const QString &dev)
return true; return true;
} }
void RouterMac::flushDns() bool RouterMac::flushDns()
{ {
// sudo killall -HUP mDNSResponder // sudo killall -HUP mDNSResponder
QProcess p; QProcess p;
@@ -177,5 +177,7 @@ void RouterMac::flushDns()
p.start("killall", QStringList() << "-HUP" << "mDNSResponder"); p.start("killall", QStringList() << "-HUP" << "mDNSResponder");
p.waitForFinished(); p.waitForFinished();
qDebug().noquote() << "OUTPUT killall -HUP mDNSResponder: " + p.readAll(); qDebug().noquote() << "OUTPUT killall -HUP mDNSResponder: " + p.readAll();
return true;
} }
+1 -1
View File
@@ -29,7 +29,7 @@ public:
bool clearSavedRoutes(); bool clearSavedRoutes();
bool routeDelete(const QString &ip, const QString &gw); bool routeDelete(const QString &ip, const QString &gw);
bool routeDeleteList(const QString &gw, const QStringList &ips); bool routeDeleteList(const QString &gw, const QStringList &ips);
void flushDns(); bool flushDns();
bool createTun(const QString &dev, const QString &subnet); bool createTun(const QString &dev, const QString &subnet);
bool deleteTun(const QString &dev); bool deleteTun(const QString &dev);
bool updateResolvers(const QString& ifname, const QList<QHostAddress>& resolvers); bool updateResolvers(const QString& ifname, const QList<QHostAddress>& resolvers);
+6 -3
View File
@@ -273,7 +273,7 @@ int RouterWin::routeDeleteList(const QString &gw, const QStringList &ips)
return success_count; return success_count;
} }
void RouterWin::flushDns() bool RouterWin::flushDns()
{ {
QProcess p; QProcess p;
p.setProcessChannelMode(QProcess::MergedChannels); p.setProcessChannelMode(QProcess::MergedChannels);
@@ -281,6 +281,7 @@ void RouterWin::flushDns()
p.start(command); p.start(command);
p.waitForFinished(); p.waitForFinished();
return true;
//qDebug().noquote() << "OUTPUT ipconfig /flushdns: " + p.readAll(); //qDebug().noquote() << "OUTPUT ipconfig /flushdns: " + p.readAll();
} }
@@ -447,7 +448,7 @@ bool RouterWin::restoreResolvers() {
return m_dnsUtil->restoreResolvers(); return m_dnsUtil->restoreResolvers();
} }
void RouterWin::StopRoutingIpv6() bool RouterWin::StopRoutingIpv6()
{ {
{ {
QProcess p; QProcess p;
@@ -467,9 +468,10 @@ void RouterWin::StopRoutingIpv6()
p.start(command); p.start(command);
p.waitForFinished(); p.waitForFinished();
} }
return true;
} }
void RouterWin::StartRoutingIpv6() bool RouterWin::StartRoutingIpv6()
{ {
{ {
QProcess p; QProcess p;
@@ -489,5 +491,6 @@ void RouterWin::StartRoutingIpv6()
p.start(command); p.start(command);
p.waitForFinished(); p.waitForFinished();
} }
return true;
} }
+3 -3
View File
@@ -39,11 +39,11 @@ public:
int routeAddList(const QString &gw, const QStringList &ips); int routeAddList(const QString &gw, const QStringList &ips);
bool clearSavedRoutes(); bool clearSavedRoutes();
int routeDeleteList(const QString &gw, const QStringList &ips); int routeDeleteList(const QString &gw, const QStringList &ips);
void flushDns(); bool flushDns();
void resetIpStack(); void resetIpStack();
void StartRoutingIpv6(); bool StartRoutingIpv6();
void StopRoutingIpv6(); bool StopRoutingIpv6();
void suspendWcmSvc(bool suspend); void suspendWcmSvc(bool suspend);
bool updateResolvers(const QString& ifname, const QList<QHostAddress>& resolvers); bool updateResolvers(const QString& ifname, const QList<QHostAddress>& resolvers);
+7
View File
@@ -4,6 +4,7 @@
#include <QRegularExpressionMatchIterator> #include <QRegularExpressionMatchIterator>
#include <QCoreApplication> #include <QCoreApplication>
#include <QOperatingSystemVersion> #include <QOperatingSystemVersion>
#include <QSysInfo>
#include "tapcontroller_win.h" #include "tapcontroller_win.h"
@@ -266,6 +267,12 @@ QString TapController::getOpenVpnPath()
QString TapController::getTapDriverDir() QString TapController::getTapDriverDir()
{ {
// For ARM64 architecture, use the arm64-specific tap driver directory
QString cpuArch = QSysInfo::currentCpuArchitecture();
if (cpuArch == "arm64" || cpuArch == "arm64-little-endian") {
return qApp->applicationDirPath() + "\\tap\\arm64";
}
if (oldDriversRequired()) { if (oldDriversRequired()) {
return qApp->applicationDirPath() + "\\tap\\windows_7"; return qApp->applicationDirPath() + "\\tap\\windows_7";
} }