mirror of
https://github.com/amnezia-vpn/amnezia-client.git
synced 2026-11-12 07:23:19 +09:00
Compare commits
16
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0d91176512 | ||
|
|
6ae5a874eb | ||
|
|
16651e9bf4 | ||
|
|
403d6a49bb | ||
|
|
0777e7f231 | ||
|
|
8c79857d88 | ||
|
|
b933ceda66 | ||
|
|
ca7056868a | ||
|
|
2395c2dbc5 | ||
|
|
ad97f6f209 | ||
|
|
fb17015d21 | ||
|
|
15de902111 | ||
|
|
f581ab8e6e | ||
|
|
df16abf77e | ||
|
|
354d0b7210 | ||
|
|
a8f3f046d1 |
No files matched your search
@@ -61,6 +61,10 @@ void OpenVpnProtocol::cleanupResources()
|
||||
|
||||
void OpenVpnProtocol::stop()
|
||||
{
|
||||
if (guardStop()) {
|
||||
return;
|
||||
}
|
||||
|
||||
qDebug() << "OpenVpnProtocol::stop()";
|
||||
|
||||
const bool wasActive = m_connectionState == Vpn::ConnectionState::Preparing
|
||||
@@ -179,6 +183,8 @@ void OpenVpnProtocol::updateRouteGateway(QString line)
|
||||
|
||||
ErrorCode OpenVpnProtocol::start()
|
||||
{
|
||||
resetStopGuard();
|
||||
|
||||
cleanupResources();
|
||||
|
||||
if (!QFileInfo::exists(configPath())) {
|
||||
|
||||
@@ -26,6 +26,20 @@ VpnProtocol::VpnProtocol(const QJsonObject &configuration, QObject *parent)
|
||||
connect(m_timeoutTimer, &QTimer::timeout, this, &VpnProtocol::onTimeout);
|
||||
}
|
||||
|
||||
bool VpnProtocol::guardStop()
|
||||
{
|
||||
if (m_stopped) {
|
||||
return true;
|
||||
}
|
||||
m_stopped = true;
|
||||
return false;
|
||||
}
|
||||
|
||||
void VpnProtocol::resetStopGuard()
|
||||
{
|
||||
m_stopped = false;
|
||||
}
|
||||
|
||||
void VpnProtocol::setLastError(ErrorCode lastError)
|
||||
{
|
||||
m_lastError = lastError;
|
||||
|
||||
@@ -89,6 +89,11 @@ protected:
|
||||
void startTimeoutTimer();
|
||||
void stopTimeoutTimer();
|
||||
|
||||
bool guardStop();
|
||||
void resetStopGuard();
|
||||
|
||||
bool m_stopped = false;
|
||||
|
||||
Vpn::ConnectionState m_connectionState;
|
||||
|
||||
QString m_routeGateway;
|
||||
|
||||
@@ -50,8 +50,10 @@ WireguardProtocol::~WireguardProtocol()
|
||||
|
||||
void WireguardProtocol::stop()
|
||||
{
|
||||
if (guardStop()) {
|
||||
return;
|
||||
}
|
||||
stopMzImpl();
|
||||
return;
|
||||
}
|
||||
|
||||
ErrorCode WireguardProtocol::startMzImpl()
|
||||
@@ -75,5 +77,6 @@ ErrorCode WireguardProtocol::stopMzImpl()
|
||||
|
||||
ErrorCode WireguardProtocol::start()
|
||||
{
|
||||
resetStopGuard();
|
||||
return startMzImpl();
|
||||
}
|
||||
@@ -66,6 +66,8 @@ XrayProtocol::~XrayProtocol()
|
||||
|
||||
ErrorCode XrayProtocol::start()
|
||||
{
|
||||
resetStopGuard();
|
||||
|
||||
qDebug() << "XrayProtocol::start()";
|
||||
|
||||
// Inject SOCKS5 auth into the inbound before starting xray.
|
||||
@@ -118,6 +120,10 @@ ErrorCode XrayProtocol::start()
|
||||
|
||||
void XrayProtocol::stop()
|
||||
{
|
||||
if (guardStop()) {
|
||||
return;
|
||||
}
|
||||
|
||||
qDebug() << "XrayProtocol::stop()";
|
||||
|
||||
IpcClient::withInterface([](QSharedPointer<IpcInterfaceReplica> iface) {
|
||||
|
||||
@@ -50,7 +50,7 @@ WindowsTunnelService::WindowsTunnelService(QObject* parent) : QObject(parent) {
|
||||
}
|
||||
|
||||
WindowsTunnelService::~WindowsTunnelService() {
|
||||
MZ_COUNT_CTOR(WindowsTunnelService);
|
||||
MZ_COUNT_DTOR(WindowsTunnelService);
|
||||
stop();
|
||||
CloseServiceHandle((SC_HANDLE)m_scm);
|
||||
}
|
||||
@@ -297,6 +297,11 @@ static bool waitForServiceStatus(SC_HANDLE service, DWORD expectedStatus) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (expectedStatus == SERVICE_RUNNING &&
|
||||
status.dwCurrentState == SERVICE_STOPPED) {
|
||||
return false;
|
||||
}
|
||||
|
||||
logger.warning() << "The service is not in the right status yet.";
|
||||
|
||||
Sleep(1000);
|
||||
|
||||
@@ -40,8 +40,13 @@ LRESULT WindowsNetworkWatcher::PowerWndProcCallback(HWND hwnd, UINT uMsg, WPARAM
|
||||
}
|
||||
switch (uMsg) {
|
||||
case WM_POWERBROADCAST:
|
||||
if (wParam == PBT_APMRESUMESUSPEND) {
|
||||
if (wParam == PBT_APMSUSPEND) {
|
||||
obj->m_suspended = true;
|
||||
} else if (wParam == PBT_APMRESUMEAUTOMATIC) {
|
||||
if (obj->m_suspended) {
|
||||
obj->m_suspended = false;
|
||||
emit obj->wakeup();
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
|
||||
@@ -28,6 +28,7 @@ class WindowsNetworkWatcher final : public NetworkWatcherImpl {
|
||||
// to inform about network changes.
|
||||
HANDLE m_wlanHandle = nullptr;
|
||||
QString m_lastBSSID;
|
||||
bool m_suspended = false;
|
||||
};
|
||||
|
||||
#endif // WINDOWSNETWORKWATCHER_H
|
||||
@@ -160,7 +160,7 @@ void WindowsPingSender::sendPing(const QHostAddress& dest, quint16 sequence) {
|
||||
|
||||
DWORD status = GetLastError();
|
||||
if (status != ERROR_IO_PENDING) {
|
||||
QString errmsg = WindowsUtils::getErrorMessage();
|
||||
QString errmsg = WindowsUtils::getErrorMessage(status);
|
||||
logger.error() << "failed to start Code: " << status
|
||||
<< " Message: " << errmsg
|
||||
<< " dest:" << logger.sensitive(dest.toString());
|
||||
@@ -178,7 +178,7 @@ void WindowsPingSender::pingEventReady() {
|
||||
if (error == IP_REQ_TIMED_OUT) {
|
||||
return;
|
||||
}
|
||||
QString errmsg = WindowsUtils::getErrorMessage();
|
||||
QString errmsg = WindowsUtils::getErrorMessage(error);
|
||||
emit criticalPingError();
|
||||
logger.error() << "No ping reply. Code: " << error
|
||||
<< " Message: " << errmsg;
|
||||
|
||||
@@ -85,7 +85,7 @@ bool WindowsServiceManager::startPolling(DWORD goal_state, int max_wait_sec) {
|
||||
return true;
|
||||
}
|
||||
|
||||
logger.debug() << "Polling Status" << m_state_target
|
||||
logger.debug() << "Polling Status" << goal_state
|
||||
<< "wanted, has: " << status.dwCurrentState;
|
||||
Sleep(1000);
|
||||
++tries;
|
||||
@@ -117,7 +117,10 @@ bool WindowsServiceManager::startService() {
|
||||
NULL); // no arguments
|
||||
if (ok) {
|
||||
logger.debug() << ("Service start requested");
|
||||
startPolling(SERVICE_RUNNING, 30);
|
||||
ok = startPolling(SERVICE_RUNNING, 30);
|
||||
if (!ok) {
|
||||
logger.error() << "Timed out waiting for the service to start";
|
||||
}
|
||||
} else {
|
||||
WindowsUtils::windowsLog("StartService failed");
|
||||
}
|
||||
@@ -130,10 +133,14 @@ bool WindowsServiceManager::stopService() {
|
||||
logger.warning() << ("Service stop not possible, as its not running");
|
||||
}
|
||||
|
||||
bool ok = ControlService(m_service, SERVICE_CONTROL_STOP, NULL);
|
||||
SERVICE_STATUS status;
|
||||
bool ok = ControlService(m_service, SERVICE_CONTROL_STOP, &status);
|
||||
if (ok) {
|
||||
logger.debug() << ("Service stop requested");
|
||||
startPolling(SERVICE_STOPPED, 10);
|
||||
ok = startPolling(SERVICE_STOPPED, 10);
|
||||
if (!ok) {
|
||||
logger.error() << "Timed out waiting for the service to stop";
|
||||
}
|
||||
} else {
|
||||
WindowsUtils::windowsLog("StopService failed");
|
||||
}
|
||||
|
||||
@@ -27,20 +27,16 @@ QString WindowsUtils::getErrorMessage(quint32 code) {
|
||||
nullptr, code, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
|
||||
(LPSTR)&messageBuffer, 0, nullptr);
|
||||
|
||||
std::string message(messageBuffer, size);
|
||||
QString result(message.c_str());
|
||||
QString result = QString::fromLocal8Bit(messageBuffer, static_cast<int>(size)).trimmed();
|
||||
LocalFree(messageBuffer);
|
||||
return result;
|
||||
}
|
||||
|
||||
QString WindowsUtils::getErrorMessage() {
|
||||
return getErrorMessage(GetLastError());
|
||||
}
|
||||
|
||||
// A simple function to log windows error messages.
|
||||
void WindowsUtils::windowsLog(const QString& msg) {
|
||||
QString errmsg = getErrorMessage();
|
||||
logger.error() << msg << "-" << errmsg;
|
||||
quint32 code = GetLastError();
|
||||
QString errmsg = getErrorMessage(code);
|
||||
logger.error() << msg << "-" << errmsg << QString("(code %1)").arg(code);
|
||||
}
|
||||
|
||||
// Static
|
||||
|
||||
@@ -9,7 +9,6 @@
|
||||
|
||||
class WindowsUtils final {
|
||||
public:
|
||||
static QString getErrorMessage();
|
||||
static QString getErrorMessage(quint32 code);
|
||||
static void windowsLog(const QString& msg);
|
||||
|
||||
|
||||
+160
-9
@@ -36,6 +36,15 @@
|
||||
|
||||
using namespace ProtocolUtils;
|
||||
|
||||
#ifdef AMNEZIA_DESKTOP
|
||||
namespace {
|
||||
constexpr int RECONNECT_ATTEMPT_TIMEOUT_MSEC = 30 * 1000;
|
||||
constexpr int RECONNECT_RETRY_BASE_MSEC = 1000;
|
||||
constexpr int RECONNECT_RETRY_MAX_MSEC = 60 * 1000;
|
||||
constexpr int RECONNECT_ATTEMPT_MIN_AGE_MSEC = 1000;
|
||||
}
|
||||
#endif
|
||||
|
||||
VpnConnection::VpnConnection(SecureServersRepository* serversRepository, SecureAppSettingsRepository* appSettingsRepository, QObject *parent)
|
||||
: QObject(parent), m_serversRepository(serversRepository), m_appSettingsRepository(appSettingsRepository), m_checkTimer(this)
|
||||
{
|
||||
@@ -44,6 +53,13 @@ VpnConnection::VpnConnection(SecureServersRepository* serversRepository, SecureA
|
||||
connect(IosController::Instance(), &IosController::connectionStateChanged, this, &VpnConnection::setConnectionState);
|
||||
connect(IosController::Instance(), &IosController::bytesChanged, this, &VpnConnection::onBytesChanged);
|
||||
#endif
|
||||
|
||||
#ifdef AMNEZIA_DESKTOP
|
||||
m_reconnectRetryTimer.setSingleShot(true);
|
||||
connect(&m_reconnectRetryTimer, &QTimer::timeout, this, &VpnConnection::startReconnectAttempt);
|
||||
m_reconnectWatchdogTimer.setSingleShot(true);
|
||||
connect(&m_reconnectWatchdogTimer, &QTimer::timeout, this, &VpnConnection::onReconnectWatchdogTimeout);
|
||||
#endif
|
||||
}
|
||||
|
||||
VpnConnection::~VpnConnection()
|
||||
@@ -336,8 +352,9 @@ void VpnConnection::connectToVpn(const QString &serverId, DockerContainer contai
|
||||
m_vpnConfiguration = vpnConfiguration;
|
||||
|
||||
#ifdef AMNEZIA_DESKTOP
|
||||
cancelReconnect();
|
||||
if (m_vpnProtocol) {
|
||||
disconnect(m_vpnProtocol.data(), &VpnProtocol::protocolError, this, &VpnConnection::vpnProtocolError);
|
||||
m_vpnProtocol->disconnect(this);
|
||||
m_vpnProtocol->stop();
|
||||
m_vpnProtocol.reset();
|
||||
}
|
||||
@@ -376,13 +393,14 @@ void VpnConnection::connectToVpn(const QString &serverId, DockerContainer contai
|
||||
void VpnConnection::createProtocolConnections()
|
||||
{
|
||||
connect(m_vpnProtocol.data(), &VpnProtocol::protocolError, this, &VpnConnection::vpnProtocolError);
|
||||
connect(m_vpnProtocol.data(), &VpnProtocol::connectionStateChanged, this, &VpnConnection::setConnectionState);
|
||||
connect(m_vpnProtocol.data(), &VpnProtocol::connectionStateChanged, this, &VpnConnection::onProtocolConnectionStateChanged);
|
||||
connect(m_vpnProtocol.data(), SIGNAL(bytesChanged(quint64, quint64)), this, SLOT(onBytesChanged(quint64, quint64)));
|
||||
|
||||
#ifdef AMNEZIA_DESKTOP
|
||||
IpcClient::withInterface([this](QSharedPointer<IpcInterfaceReplica> rep) {
|
||||
connect(rep.data(), &IpcInterfaceReplica::networkChanged, this, &VpnConnection::reconnectToVpn, Qt::QueuedConnection);
|
||||
connect(rep.data(), &IpcInterfaceReplica::wakeup, this, &VpnConnection::reconnectToVpn, Qt::QueuedConnection);
|
||||
const auto queuedUnique = static_cast<Qt::ConnectionType>(Qt::QueuedConnection | Qt::UniqueConnection);
|
||||
connect(rep.data(), &IpcInterfaceReplica::networkChanged, this, &VpnConnection::onIpcNetworkChanged, queuedUnique);
|
||||
connect(rep.data(), &IpcInterfaceReplica::wakeup, this, &VpnConnection::onIpcWakeup, queuedUnique);
|
||||
});
|
||||
#endif
|
||||
}
|
||||
@@ -549,29 +567,152 @@ QString VpnConnection::bytesPerSecToText(quint64 bytes)
|
||||
return QString("%1 %2").arg(QString::number(mbps, 'f', 2)).arg(tr("Mbps")); // Mbit/s
|
||||
}
|
||||
|
||||
void VpnConnection::reconnectToVpn() {
|
||||
#ifdef AMNEZIA_DESKTOP
|
||||
void VpnConnection::onIpcWakeup()
|
||||
{
|
||||
requestReconnect(QStringLiteral("wakeup"));
|
||||
}
|
||||
|
||||
void VpnConnection::onIpcNetworkChanged()
|
||||
{
|
||||
requestReconnect(QStringLiteral("network change"));
|
||||
}
|
||||
|
||||
void VpnConnection::requestReconnect(const QString &trigger)
|
||||
{
|
||||
if (m_vpnProtocol.isNull())
|
||||
return;
|
||||
|
||||
if (m_reconnectActive) {
|
||||
if (m_reconnectAttemptInFlight && m_reconnectAttemptAge.isValid()
|
||||
&& m_reconnectAttemptAge.elapsed() < RECONNECT_ATTEMPT_MIN_AGE_MSEC) {
|
||||
qDebug() << "Reconnect: new trigger" << trigger << "ignored, current attempt has just started";
|
||||
m_reconnectAttempt = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
qDebug() << "Reconnect: new trigger" << trigger << "while already reconnecting, retrying immediately";
|
||||
m_reconnectAttempt = 0;
|
||||
m_reconnectAttemptInFlight = false;
|
||||
m_reconnectRetryTimer.stop();
|
||||
m_reconnectWatchdogTimer.stop();
|
||||
startReconnectAttempt();
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_connectionState != Vpn::ConnectionState::Connected) {
|
||||
qWarning() << QString("Reconnect triggered on %1 during inappropriate state: %2; ignoring slot")
|
||||
qWarning() << QString("Reconnect triggered by %1 during inappropriate state: %2; ignoring")
|
||||
.arg(trigger)
|
||||
.arg(QMetaEnum::fromType<Vpn::ConnectionState>().valueToKey(m_connectionState));
|
||||
return;
|
||||
}
|
||||
|
||||
qDebug() << "Reconnect triggered. Reconnecting to the server";
|
||||
qDebug() << "Reconnect triggered by" << trigger << ". Reconnecting to the server";
|
||||
|
||||
m_reconnectActive = true;
|
||||
m_reconnectAttempt = 0;
|
||||
setConnectionState(Vpn::ConnectionState::Reconnecting);
|
||||
startReconnectAttempt();
|
||||
}
|
||||
|
||||
void VpnConnection::startReconnectAttempt()
|
||||
{
|
||||
if (!m_reconnectActive)
|
||||
return;
|
||||
|
||||
if (m_vpnProtocol.isNull()) {
|
||||
cancelReconnect();
|
||||
return;
|
||||
}
|
||||
|
||||
++m_reconnectAttempt;
|
||||
qDebug() << "Reconnect: attempt" << m_reconnectAttempt;
|
||||
m_reconnectAttemptAge.start();
|
||||
|
||||
m_vpnProtocol->stop();
|
||||
|
||||
m_reconnectAttemptInFlight = true;
|
||||
if (ErrorCode err = m_vpnProtocol->start(); err != ErrorCode::NoError) {
|
||||
setConnectionState(Vpn::ConnectionState::Error);
|
||||
emit vpnProtocolError(err);
|
||||
qWarning() << "Reconnect: attempt" << m_reconnectAttempt << "failed to start, error" << err;
|
||||
scheduleReconnectRetry();
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_reconnectAttemptInFlight) {
|
||||
m_reconnectWatchdogTimer.start(RECONNECT_ATTEMPT_TIMEOUT_MSEC);
|
||||
}
|
||||
}
|
||||
|
||||
void VpnConnection::onReconnectWatchdogTimeout()
|
||||
{
|
||||
if (!m_reconnectActive || !m_reconnectAttemptInFlight)
|
||||
return;
|
||||
|
||||
qWarning() << "Reconnect: attempt" << m_reconnectAttempt << "did not reach the Connected state in time";
|
||||
scheduleReconnectRetry();
|
||||
}
|
||||
|
||||
void VpnConnection::scheduleReconnectRetry()
|
||||
{
|
||||
m_reconnectWatchdogTimer.stop();
|
||||
m_reconnectAttemptInFlight = false;
|
||||
|
||||
if (!m_reconnectActive)
|
||||
return;
|
||||
|
||||
const int delay = reconnectRetryDelayMsec();
|
||||
qDebug() << "Reconnect: next attempt in" << delay << "ms";
|
||||
m_reconnectRetryTimer.start(delay);
|
||||
}
|
||||
|
||||
void VpnConnection::cancelReconnect()
|
||||
{
|
||||
m_reconnectActive = false;
|
||||
m_reconnectAttemptInFlight = false;
|
||||
m_reconnectRetryTimer.stop();
|
||||
m_reconnectWatchdogTimer.stop();
|
||||
}
|
||||
|
||||
int VpnConnection::reconnectRetryDelayMsec() const
|
||||
{
|
||||
const int exponent = qMin(m_reconnectAttempt > 0 ? m_reconnectAttempt - 1 : 0, 6);
|
||||
return qMin(RECONNECT_RETRY_BASE_MSEC << exponent, RECONNECT_RETRY_MAX_MSEC);
|
||||
}
|
||||
#endif
|
||||
|
||||
void VpnConnection::onProtocolConnectionStateChanged(Vpn::ConnectionState state)
|
||||
{
|
||||
#ifdef AMNEZIA_DESKTOP
|
||||
if (m_reconnectActive) {
|
||||
switch (state) {
|
||||
case Vpn::ConnectionState::Connected:
|
||||
qDebug() << "Reconnect: succeeded on attempt" << m_reconnectAttempt;
|
||||
cancelReconnect();
|
||||
break; // propagate below
|
||||
case Vpn::ConnectionState::Disconnected:
|
||||
case Vpn::ConnectionState::Error:
|
||||
onConnectionStateChanged(state);
|
||||
if (m_reconnectAttemptInFlight) {
|
||||
qWarning() << "Reconnect: attempt" << m_reconnectAttempt << "failed, protocol reported"
|
||||
<< QMetaEnum::fromType<Vpn::ConnectionState>().valueToKey(state);
|
||||
scheduleReconnectRetry();
|
||||
}
|
||||
return;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
setConnectionState(state);
|
||||
}
|
||||
|
||||
void VpnConnection::disconnectFromVpn()
|
||||
{
|
||||
#ifdef AMNEZIA_DESKTOP
|
||||
cancelReconnect();
|
||||
#endif
|
||||
|
||||
#if defined(Q_OS_IOS) || defined(MACOS_NE)
|
||||
// iOS/macOS NE use IosController directly; m_vpnProtocol is not set there.
|
||||
IosController::Instance()->disconnectVpn();
|
||||
@@ -597,6 +738,10 @@ void VpnConnection::disconnectFromVpn()
|
||||
});
|
||||
#endif
|
||||
|
||||
#ifdef AMNEZIA_DESKTOP
|
||||
m_vpnProtocol->disconnect(this);
|
||||
#endif
|
||||
|
||||
m_vpnProtocol->stop();
|
||||
|
||||
#if !defined(Q_OS_ANDROID) && !defined(AMNEZIA_DESKTOP)
|
||||
@@ -604,13 +749,19 @@ void VpnConnection::disconnectFromVpn()
|
||||
#endif
|
||||
|
||||
m_vpnProtocol = nullptr;
|
||||
|
||||
#ifdef AMNEZIA_DESKTOP
|
||||
setConnectionState(Vpn::ConnectionState::Disconnected);
|
||||
#endif
|
||||
}
|
||||
|
||||
void VpnConnection::setConnectionState(Vpn::ConnectionState state) {
|
||||
onConnectionStateChanged(state);
|
||||
|
||||
#ifndef AMNEZIA_DESKTOP
|
||||
if (state == Vpn::Disconnected && m_connectionState == Vpn::Reconnecting)
|
||||
return;
|
||||
#endif
|
||||
|
||||
m_connectionState = state;
|
||||
emit connectionStateChanged(state);
|
||||
|
||||
+24
-1
@@ -6,6 +6,7 @@
|
||||
#include <QString>
|
||||
#include <QScopedPointer>
|
||||
#include <QRemoteObjectNode>
|
||||
#include <QElapsedTimer>
|
||||
#include <QTimer>
|
||||
|
||||
#include "core/protocols/vpnProtocol.h"
|
||||
@@ -50,7 +51,6 @@ public:
|
||||
public slots:
|
||||
void setRepositories(SecureServersRepository* serversRepository, SecureAppSettingsRepository* appSettingsRepository);
|
||||
void connectToVpn(const QString &serverId, DockerContainer container, const QJsonObject &vpnConfiguration);
|
||||
void reconnectToVpn();
|
||||
void disconnectFromVpn();
|
||||
|
||||
void onKillSwitchModeChanged(bool enabled);
|
||||
@@ -69,6 +69,15 @@ protected slots:
|
||||
void onBytesChanged(quint64 receivedBytes, quint64 sentBytes);
|
||||
void onConnectionStateChanged(Vpn::ConnectionState state);
|
||||
|
||||
private slots:
|
||||
void onProtocolConnectionStateChanged(Vpn::ConnectionState state);
|
||||
#ifdef AMNEZIA_DESKTOP
|
||||
void onIpcWakeup();
|
||||
void onIpcNetworkChanged();
|
||||
void startReconnectAttempt();
|
||||
void onReconnectWatchdogTimeout();
|
||||
#endif
|
||||
|
||||
protected:
|
||||
QSharedPointer<VpnProtocol> m_vpnProtocol;
|
||||
|
||||
@@ -96,6 +105,20 @@ private:
|
||||
|
||||
void appendSplitTunnelingConfig();
|
||||
void appendKillSwitchConfig();
|
||||
|
||||
#ifdef AMNEZIA_DESKTOP
|
||||
void requestReconnect(const QString &trigger);
|
||||
void scheduleReconnectRetry();
|
||||
void cancelReconnect();
|
||||
int reconnectRetryDelayMsec() const;
|
||||
|
||||
bool m_reconnectActive = false;
|
||||
bool m_reconnectAttemptInFlight = false;
|
||||
int m_reconnectAttempt = 0;
|
||||
QTimer m_reconnectRetryTimer{this};
|
||||
QTimer m_reconnectWatchdogTimer{this};
|
||||
QElapsedTimer m_reconnectAttemptAge;
|
||||
#endif
|
||||
};
|
||||
|
||||
#endif // VPNCONNECTION_H
|
||||
@@ -22,6 +22,7 @@
|
||||
|
||||
QFile Logger::m_file;
|
||||
QTextStream Logger::m_textStream;
|
||||
QRecursiveMutex Logger::m_fileMutex;
|
||||
QString Logger::m_logFileName = QString("%1.log").arg(APPLICATION_NAME);
|
||||
QString Logger::m_serviceLogFileName = QString("%1.log").arg(SERVICE_NAME);
|
||||
|
||||
@@ -68,6 +69,7 @@ bool Logger::init(bool isServiceLogger)
|
||||
return false;
|
||||
}
|
||||
|
||||
QMutexLocker locker(&m_fileMutex);
|
||||
m_file.setFileName(appDir.filePath(logFileName));
|
||||
if (!m_file.open(QIODevice::Append)) {
|
||||
qWarning() << "Cannot open log file:" << logFileName;
|
||||
@@ -84,6 +86,7 @@ bool Logger::init(bool isServiceLogger)
|
||||
|
||||
void Logger::deInit()
|
||||
{
|
||||
QMutexLocker locker(&m_fileMutex);
|
||||
m_textStream.setDevice(nullptr);
|
||||
m_file.close();
|
||||
}
|
||||
@@ -137,9 +140,11 @@ QString Logger::serviceLogsFilePath()
|
||||
|
||||
QString Logger::getLogFile()
|
||||
{
|
||||
QMutexLocker locker(&m_fileMutex);
|
||||
if (m_file.isOpen()) {
|
||||
m_file.flush();
|
||||
}
|
||||
|
||||
QFile file(userLogsFilePath());
|
||||
|
||||
file.open(QIODevice::ReadOnly);
|
||||
@@ -154,9 +159,11 @@ QString Logger::getLogFile()
|
||||
|
||||
QString Logger::getServiceLogFile()
|
||||
{
|
||||
QMutexLocker locker(&m_fileMutex);
|
||||
if (m_file.isOpen()) {
|
||||
m_file.flush();
|
||||
}
|
||||
|
||||
QFile file(serviceLogsFilePath());
|
||||
|
||||
file.open(QIODevice::ReadOnly);
|
||||
@@ -184,6 +191,8 @@ bool Logger::openLogsFolder(bool isServiceLogger)
|
||||
|
||||
void Logger::clearLogs(bool isServiceLogger)
|
||||
{
|
||||
QMutexLocker locker(&m_fileMutex);
|
||||
|
||||
bool isLogActive = m_file.isOpen();
|
||||
m_file.close();
|
||||
|
||||
@@ -243,9 +252,12 @@ Logger::LogStreamer::~LogStreamer()
|
||||
.arg(QDateTime::currentDateTimeUtc().toString("[yyyy-MM-dd hh:mm:ss.zzzZ]"),
|
||||
logLevelString, m_logger->className(), m_data->m_buffer.trimmed());
|
||||
|
||||
if (m_file.isOpen()) {
|
||||
QTextStream logToFile(&m_file);
|
||||
logToFile << message << Qt::endl << Qt::flush;
|
||||
{
|
||||
QMutexLocker locker(&m_fileMutex);
|
||||
if (m_file.isOpen()) {
|
||||
QTextStream logToFile(&m_file);
|
||||
logToFile << message << Qt::endl << Qt::flush;
|
||||
}
|
||||
}
|
||||
|
||||
QTextStream logToOutput((m_logLevel == LogLevel::Error) ? stderr : stdout);
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
#include <QDebug>
|
||||
#include <QDir>
|
||||
#include <QFile>
|
||||
#include <QRecursiveMutex>
|
||||
#include <QString>
|
||||
#include <QTextStream>
|
||||
|
||||
@@ -104,6 +105,7 @@ private:
|
||||
|
||||
static QFile m_file;
|
||||
static QTextStream m_textStream;
|
||||
static QRecursiveMutex m_fileMutex;
|
||||
static QString m_logFileName;
|
||||
static QString m_serviceLogFileName;
|
||||
|
||||
|
||||
Reference in new issue
Block a user