This commit is contained in:
Macbook 2024-12-18 21:45:46 +07:00 committed by Yaroslav Yashin
parent 1b2abe1b14
commit 5b663f6397
5 changed files with 108 additions and 28 deletions

View file

@ -84,12 +84,12 @@ set_target_properties(${PROJECT} PROPERTIES
XCODE_ATTRIBUTE_LD_RUNPATH_SEARCH_PATHS "@executable_path/../Frameworks" XCODE_ATTRIBUTE_LD_RUNPATH_SEARCH_PATHS "@executable_path/../Frameworks"
XCODE_EMBED_APP_EXTENSIONS networkextension XCODE_EMBED_APP_EXTENSIONS networkextension
# XCODE_ATTRIBUTE_CODE_SIGN_STYLE Automatic XCODE_ATTRIBUTE_CODE_SIGN_STYLE Automatic
XCODE_ATTRIBUTE_CODE_SIGN_STYLE Manual # XCODE_ATTRIBUTE_CODE_SIGN_STYLE Manual
XCODE_ATTRIBUTE_CODE_SIGN_IDENTITY "Apple Distribution: Privacy Technologies OU (X7UJ388FXK)" # XCODE_ATTRIBUTE_CODE_SIGN_IDENTITY "Apple Distribution: Privacy Technologies OU (X7UJ388FXK)"
XCODE_ATTRIBUTE_CODE_SIGN_IDENTITY[variant=Debug] "Apple Development: TRAN VIET ANH (Y372SYT4WL)" # XCODE_ATTRIBUTE_CODE_SIGN_IDENTITY[variant=Debug] "Apple Development: TRAN VIET ANH (Y372SYT4WL)"
XCODE_ATTRIBUTE_PROVISIONING_PROFILE_SPECIFIER "Mac AppStore AmneziaVPN" # XCODE_ATTRIBUTE_PROVISIONING_PROFILE_SPECIFIER "Mac AppStore AmneziaVPN"
XCODE_ATTRIBUTE_PROVISIONING_PROFILE_SPECIFIER[variant=Debug] "org.amnezia.AmneziaVPNManual" # XCODE_ATTRIBUTE_PROVISIONING_PROFILE_SPECIFIER[variant=Debug] "org.amnezia.AmneziaVPNManual"
) )
set_target_properties(${PROJECT} PROPERTIES set_target_properties(${PROJECT} PROPERTIES
XCODE_ATTRIBUTE_SWIFT_VERSION "5.0" XCODE_ATTRIBUTE_SWIFT_VERSION "5.0"

View file

@ -29,12 +29,12 @@ set_target_properties(networkextension PROPERTIES
XCODE_ATTRIBUTE_APPLICATION_EXTENSION_API_ONLY "YES" XCODE_ATTRIBUTE_APPLICATION_EXTENSION_API_ONLY "YES"
XCODE_ATTRIBUTE_ENABLE_BITCODE "NO" XCODE_ATTRIBUTE_ENABLE_BITCODE "NO"
# XCODE_ATTRIBUTE_CODE_SIGN_STYLE Automatic XCODE_ATTRIBUTE_CODE_SIGN_STYLE Automatic
XCODE_ATTRIBUTE_CODE_SIGN_STYLE Manual # XCODE_ATTRIBUTE_CODE_SIGN_STYLE Manual
XCODE_ATTRIBUTE_PROVISIONING_PROFILE_SPECIFIER "Mac AppStore network-extension" # XCODE_ATTRIBUTE_PROVISIONING_PROFILE_SPECIFIER "Mac AppStore network-extension"
XCODE_ATTRIBUTE_PROVISIONING_PROFILE_SPECIFIER[variant=Debug] "amnezia.AmneziaVPN.network-extensionManual" # XCODE_ATTRIBUTE_PROVISIONING_PROFILE_SPECIFIER[variant=Debug] "amnezia.AmneziaVPN.network-extensionManual"
XCODE_ATTRIBUTE_CODE_SIGN_IDENTITY "Apple Distribution: Privacy Technologies OU (X7UJ388FXK)" # XCODE_ATTRIBUTE_CODE_SIGN_IDENTITY "Apple Distribution: Privacy Technologies OU (X7UJ388FXK)"
XCODE_ATTRIBUTE_CODE_SIGN_IDENTITY[variant=Debug] "Apple Development: TRAN VIET ANH (Y372SYT4WL)" # XCODE_ATTRIBUTE_CODE_SIGN_IDENTITY[variant=Debug] "Apple Development: TRAN VIET ANH (Y372SYT4WL)"
XCODE_ATTRIBUTE_INFOPLIST_FILE ${CMAKE_CURRENT_SOURCE_DIR}/Info.plist.in XCODE_ATTRIBUTE_INFOPLIST_FILE ${CMAKE_CURRENT_SOURCE_DIR}/Info.plist.in

View file

@ -118,7 +118,7 @@ extension PacketTunnelProvider {
if let lastHandshakeValue = lastHandshakeString, let handshakeValue = Int64(lastHandshakeValue) { if let lastHandshakeValue = lastHandshakeString, let handshakeValue = Int64(lastHandshakeValue) {
lastHandshake = handshakeValue lastHandshake = handshakeValue
} else { } else {
lastHandshake = -2 // Tr v li nếu không có giá tr last_handshake_time_sec lastHandshake = -2
} }
let response: [String: Any] = [ let response: [String: Any] = [

View file

@ -46,6 +46,7 @@ public:
void disconnectVpn(); void disconnectVpn();
void vpnStatusDidChange(void *pNotification); void vpnStatusDidChange(void *pNotification);
void vpnConfigurationDidChange(void *pNotification); void vpnConfigurationDidChange(void *pNotification);
void getBackendLogs(std::function<void(const QString &)> &&callback); void getBackendLogs(std::function<void(const QString &)> &&callback);
@ -55,6 +56,9 @@ public:
QString openFile(); QString openFile();
void requestInetAccess(); void requestInetAccess();
void stopForHandshake();
void waitForHandshake();
signals: signals:
void connectionStateChanged(Vpn::ConnectionState state); void connectionStateChanged(Vpn::ConnectionState state);
void bytesChanged(quint64 receivedBytes, quint64 sentBytes); void bytesChanged(quint64 receivedBytes, quint64 sentBytes);

View file

@ -7,7 +7,7 @@
#include <QJsonObject> #include <QJsonObject>
#include <QThread> #include <QThread>
#include <QEventLoop> #include <QEventLoop>
#include <QTimer>
#include "../protocols/vpnprotocol.h" #include "../protocols/vpnprotocol.h"
#import "ios_controller_wrapper.h" #import "ios_controller_wrapper.h"
@ -60,6 +60,8 @@ Vpn::ConnectionState iosStatusToState(NEVPNStatus status) {
namespace { namespace {
IosController* s_instance = nullptr; IosController* s_instance = nullptr;
QTimer *m_handshakeTimer = nullptr;
bool is_WireGuard = false;
} }
IosController::IosController() : QObject() IosController::IosController() : QObject()
@ -207,21 +209,27 @@ bool IosController::connectVpn(amnezia::Proto proto, const QJsonObject& configur
if (proto == amnezia::Proto::OpenVpn) { if (proto == amnezia::Proto::OpenVpn) {
is_WireGuard = false;
return setupOpenVPN(); return setupOpenVPN();
} }
if (proto == amnezia::Proto::Cloak) { if (proto == amnezia::Proto::Cloak) {
is_WireGuard = false;
return setupCloak(); return setupCloak();
} }
if (proto == amnezia::Proto::WireGuard) { if (proto == amnezia::Proto::WireGuard) {
is_WireGuard = true;
return setupWireGuard(); return setupWireGuard();
} }
if (proto == amnezia::Proto::Awg) { if (proto == amnezia::Proto::Awg) {
is_WireGuard = true;
return setupAwg(); return setupAwg();
} }
if (proto == amnezia::Proto::Xray) { if (proto == amnezia::Proto::Xray) {
is_WireGuard = false;
return setupXray(); return setupXray();
} }
if (proto == amnezia::Proto::SSXray) { if (proto == amnezia::Proto::SSXray) {
is_WireGuard = false;
return setupSSXray(); return setupSSXray();
} }
@ -252,31 +260,98 @@ void IosController::checkStatus()
uint64_t txBytes = [response[@"tx_bytes"] intValue]; uint64_t txBytes = [response[@"tx_bytes"] intValue];
uint64_t rxBytes = [response[@"rx_bytes"] intValue]; uint64_t rxBytes = [response[@"rx_bytes"] intValue];
uint64_t last_handshake_time_sec = 0;
if (response[@"last_handshake_time_sec"] && ![response[@"last_handshake_time_sec"] isKindOfClass:[NSNull class]]) {
last_handshake_time_sec = [response[@"last_handshake_time_sec"] intValue];
} else {
qDebug() << "Key last_handshake_time_sec is missing or null";
}
if (last_handshake_time_sec < 0) {
disconnectVpn();
qDebug() << "Invalid handshake time, disconnecting VPN.";
}
emit bytesChanged(rxBytes - m_rxBytes, txBytes - m_txBytes); emit bytesChanged(rxBytes - m_rxBytes, txBytes - m_txBytes);
m_rxBytes = rxBytes; m_rxBytes = rxBytes;
m_txBytes = txBytes; m_txBytes = txBytes;
}); });
} }
void IosController::stopForHandshake() {
if (m_handshakeTimer) {
if (m_handshakeTimer->isActive()) {
m_handshakeTimer->stop();
}
m_handshakeTimer->deleteLater();
m_handshakeTimer = nullptr;
qDebug() << "Handshake monitoring stopped.";
} else {
qDebug() << "No active handshake monitoring to stop.";
}
}
void IosController::waitForHandshake() {
qDebug() << "Waiting for last_handshake_time_sec to be greater than 0...";
// Initialize the timer if it's null
if (!m_handshakeTimer) {
m_handshakeTimer = new QTimer(this);
// Connect the timer's timeout signal to perform handshake checking
connect(m_handshakeTimer, &QTimer::timeout, this, [this]() {
// Prepare the message to check status
NSString *actionKey = [NSString stringWithUTF8String:MessageKey::action];
NSString *actionValue = [NSString stringWithUTF8String:Action::getStatus];
NSString *tunnelIdKey = [NSString stringWithUTF8String:MessageKey::tunnelId];
NSString *tunnelIdValue = !m_tunnelId.isEmpty() ? m_tunnelId.toNSString() : @"";
NSDictionary *message = @{actionKey: actionValue, tunnelIdKey: tunnelIdValue};
// Lambda to handle the response
auto checkHandshake = [this](NSDictionary *response) {
uint64_t last_handshake_time_sec = 0;
if (response && response[@"last_handshake_time_sec"] &&
![response[@"last_handshake_time_sec"] isKindOfClass:[NSNull class]]) {
last_handshake_time_sec = [response[@"last_handshake_time_sec"] unsignedLongLongValue];
}
qDebug() << "last_handshake_time_sec:" << last_handshake_time_sec;
if (last_handshake_time_sec > 0) {
// Handshake successful, update state
qDebug() << "Handshake detected, updating state to CONNECTED.";
emit connectionStateChanged(Vpn::ConnectionState::Connected);
stopForHandshake();
return;
} else {
if (last_handshake_time_sec == 0) {
// Keep retrying
emit connectionStateChanged(Vpn::ConnectionState::Connecting);
} else {
// Handle handshake failure and stop monitoring
emit connectionStateChanged(Vpn::ConnectionState::Disconnected);
stopForHandshake();
return;
}
}
};
// Send the message to the VPN extension
sendVpnExtensionMessage(message, checkHandshake);
});
qDebug() << "Handshake timer initialized.";
}
// Start the timer only if it's not already active
if (m_handshakeTimer && !m_handshakeTimer->isActive()) {
m_handshakeTimer->start(1000); // Retry every 1 second
qDebug() << "Handshake timer Retry every 1 second";
}
}
void IosController::vpnStatusDidChange(void *pNotification) void IosController::vpnStatusDidChange(void *pNotification)
{ {
NETunnelProviderSession *session = (NETunnelProviderSession *)pNotification; NETunnelProviderSession *session = (NETunnelProviderSession *)pNotification;
if (session /* && session == TunnelManager.session */ ) { if (session /* && session == TunnelManager.session */ ) {
qDebug() << "IosController::vpnStatusDidChange" << iosStatusToState(session.status) << session; qDebug() << "IosController::vpnStatusDidChange" << iosStatusToState(session.status) << session;
if (is_WireGuard && session.status == NEVPNStatusConnected)
{
// use last_handshake_time
return;
}
if (session.status == NEVPNStatusDisconnected) { if (session.status == NEVPNStatusDisconnected) {
if (@available(iOS 16.0, *)) { if (@available(iOS 16.0, *)) {
[session fetchLastDisconnectErrorWithCompletionHandler:^(NSError * _Nullable error) { [session fetchLastDisconnectErrorWithCompletionHandler:^(NSError * _Nullable error) {
@ -371,6 +446,7 @@ void IosController::vpnStatusDidChange(void *pNotification)
} else { } else {
qDebug() << "Disconnect error is unavailable on iOS < 16.0"; qDebug() << "Disconnect error is unavailable on iOS < 16.0";
} }
stopForHandshake();
} }
emit connectionStateChanged(iosStatusToState(session.status)); emit connectionStateChanged(iosStatusToState(session.status));
@ -655,7 +731,7 @@ bool IosController::startWireGuard(const QString &config)
tunnelProtocol.serverAddress = m_serverAddress; tunnelProtocol.serverAddress = m_serverAddress;
m_currentTunnel.protocolConfiguration = tunnelProtocol; m_currentTunnel.protocolConfiguration = tunnelProtocol;
waitForHandshake();
startTunnel(); startTunnel();
} }