Merge d64eeff5f8 into efcc0b7efc
This commit is contained in:
commit
68b2789eef
3 changed files with 107 additions and 6 deletions
|
|
@ -111,10 +111,20 @@ extension PacketTunnelProvider {
|
||||||
settingsDictionary[pair[0]] = pair[1]
|
settingsDictionary[pair[0]] = pair[1]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let lastHandshakeString = settingsDictionary["last_handshake_time_sec"]
|
||||||
|
let lastHandshake: Int64
|
||||||
|
|
||||||
|
if let lastHandshakeValue = lastHandshakeString, let handshakeValue = Int64(lastHandshakeValue) {
|
||||||
|
lastHandshake = handshakeValue
|
||||||
|
} else {
|
||||||
|
lastHandshake = -2
|
||||||
|
}
|
||||||
|
|
||||||
let response: [String: Any] = [
|
let response: [String: Any] = [
|
||||||
"rx_bytes": settingsDictionary["rx_bytes"] ?? "0",
|
"rx_bytes": settingsDictionary["rx_bytes"] ?? "0",
|
||||||
"tx_bytes": settingsDictionary["tx_bytes"] ?? "0"
|
"tx_bytes": settingsDictionary["tx_bytes"] ?? "0",
|
||||||
|
"last_handshake_time_sec": lastHandshake
|
||||||
]
|
]
|
||||||
|
|
||||||
completionHandler(try? JSONSerialization.data(withJSONObject: response, options: []))
|
completionHandler(try? JSONSerialization.data(withJSONObject: response, options: []))
|
||||||
|
|
|
||||||
|
|
@ -55,6 +55,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);
|
||||||
|
|
@ -62,7 +65,6 @@ signals:
|
||||||
void importBackupFromOutside(const QString);
|
void importBackupFromOutside(const QString);
|
||||||
|
|
||||||
void finished();
|
void finished();
|
||||||
|
|
||||||
protected slots:
|
protected slots:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
||||||
|
|
@ -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"
|
||||||
|
|
||||||
|
|
@ -58,6 +58,7 @@ Vpn::ConnectionState iosStatusToState(NEVPNStatus status) {
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
IosController* s_instance = nullptr;
|
IosController* s_instance = nullptr;
|
||||||
|
QTimer *m_handshakeTimer = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
IosController::IosController() : QObject()
|
IosController::IosController() : QObject()
|
||||||
|
|
@ -237,7 +238,6 @@ void IosController::disconnectVpn()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void IosController::checkStatus()
|
void IosController::checkStatus()
|
||||||
{
|
{
|
||||||
NSString *actionKey = [NSString stringWithUTF8String:MessageKey::action];
|
NSString *actionKey = [NSString stringWithUTF8String:MessageKey::action];
|
||||||
|
|
@ -258,10 +258,15 @@ void IosController::checkStatus()
|
||||||
void IosController::vpnStatusDidChange(void *pNotification)
|
void IosController::vpnStatusDidChange(void *pNotification)
|
||||||
{
|
{
|
||||||
NETunnelProviderSession *session = (NETunnelProviderSession *)pNotification;
|
NETunnelProviderSession *session = (NETunnelProviderSession *)pNotification;
|
||||||
|
NETunnelProviderProtocol *tunnelProtocol = (NETunnelProviderProtocol *)m_currentTunnel.protocolConfiguration;
|
||||||
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 (tunnelProtocol.providerConfiguration[@"wireguard"] != nil &&
|
||||||
|
(session.status == NEVPNStatusConnected || session.status == NEVPNStatusConnecting))
|
||||||
|
{
|
||||||
|
// use last_handshake_time for check status connected for WireGuard
|
||||||
|
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) {
|
||||||
|
|
@ -356,6 +361,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));
|
||||||
|
|
@ -641,6 +647,7 @@ bool IosController::startWireGuard(const QString &config)
|
||||||
|
|
||||||
m_currentTunnel.protocolConfiguration = tunnelProtocol;
|
m_currentTunnel.protocolConfiguration = tunnelProtocol;
|
||||||
|
|
||||||
|
waitForHandshake();
|
||||||
startTunnel();
|
startTunnel();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -667,6 +674,8 @@ void IosController::startTunnel()
|
||||||
protocolName = @"WireGuard";
|
protocolName = @"WireGuard";
|
||||||
} else if (tunnelProtocol.providerConfiguration[@"ovpn"] != nil) {
|
} else if (tunnelProtocol.providerConfiguration[@"ovpn"] != nil) {
|
||||||
protocolName = @"OpenVPN";
|
protocolName = @"OpenVPN";
|
||||||
|
} else if (tunnelProtocol.providerConfiguration[@"xray"] != nil) {
|
||||||
|
protocolName = @"XRay";
|
||||||
}
|
}
|
||||||
|
|
||||||
m_rxBytes = 0;
|
m_rxBytes = 0;
|
||||||
|
|
@ -863,3 +872,83 @@ void IosController::requestInetAccess() {
|
||||||
}];
|
}];
|
||||||
[task resume];
|
[task resume];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void IosController::stopForHandshake() {
|
||||||
|
if (m_handshakeTimer) {
|
||||||
|
if (QThread::currentThread() != m_handshakeTimer->thread()) {
|
||||||
|
QMetaObject::invokeMethod(m_handshakeTimer, "stop", Qt::QueuedConnection);
|
||||||
|
QMetaObject::invokeMethod(m_handshakeTimer, "deleteLater", Qt::QueuedConnection);
|
||||||
|
m_handshakeTimer = nullptr;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
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";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue