From 5f3ebb2aded70201a85e5d2981af4d71bc7f8490 Mon Sep 17 00:00:00 2001 From: klockky Date: Tue, 14 Jul 2026 12:31:23 +0300 Subject: [PATCH] fix(vpn): arm bypass proactively on detected tunnel, drop post-failure fallback --- lib/backend/api.dart | 32 ++++---------------------------- lib/main.dart | 6 +++--- 2 files changed, 7 insertions(+), 31 deletions(-) diff --git a/lib/backend/api.dart b/lib/backend/api.dart index 78b03ae..1d2fb6b 100644 --- a/lib/backend/api.dart +++ b/lib/backend/api.dart @@ -90,9 +90,6 @@ class Api { int get sessionEpoch => _sessionEpoch; - /// Залипает на время сессии: VPN-путь не сработал — идём мимо туннеля. - bool _bypassActive = false; - int _nextSeq() => _seq = (_seq + 1) & 0xFFFF; // Публичное API @@ -110,20 +107,17 @@ class Api { _armConnectWatchdog(gen); try { - bool bypassArmed; + bool useBypass; try { - bypassArmed = await VpnBypassService.instance.shouldArm().timeout( + useBypass = await VpnBypassService.instance.shouldArm().timeout( _shouldArmTimeout, ); } catch (e) { logger.w('connect: shouldArm завис/упал ($e) — без обхода VPN'); - bypassArmed = false; + useBypass = false; } if (gen != _connectGen) return; - if (!bypassArmed) _bypassActive = false; - final useBypass = _bypassActive && bypassArmed; - ({String host, int port}) endpoint; try { endpoint = await ServerConfig.loadEndpoint().timeout(_endpointTimeout); @@ -168,13 +162,7 @@ class Api { info = await session.connect(); } catch (e) { if (gen != _connectGen) return; - await _handleConnectFailure( - e, - phase: 'Ошибка хэндшейка', - bypassArmed: bypassArmed, - useBypass: useBypass, - bypassWhy: 'хэндшейк не прошёл', - ); + await _handleConnectFailure(e, phase: 'Ошибка хэндшейка'); return; } finally { if (useBypass) { @@ -242,31 +230,19 @@ class Api { Future _handleConnectFailure( Object error, { required String phase, - required bool bypassArmed, - required bool useBypass, - required String bypassWhy, }) async { logger.e('$phase: $error'); _cancelConnectWatchdog(); if (_sessionState != SessionState.disconnected) { _cleanup(); _setSessionState(SessionState.disconnected); - _armBypassIfPossible(bypassArmed, useBypass, bypassWhy); _scheduleReconnect(); } } - void _armBypassIfPossible(bool armed, bool alreadyBypassing, String why) { - if (armed && !alreadyBypassing && !_bypassActive) { - _bypassActive = true; - logger.w('VPN bypass: $why — следующая попытка мимо VPN'); - } - } - /// Отключается без автореконнекта. Future disconnect() async { _autoReconnect = false; - _bypassActive = false; _connectGen++; _reconnectTimer?.cancel(); _cleanup(); diff --git a/lib/main.dart b/lib/main.dart index 5ba9f01..9c0f192 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -428,9 +428,9 @@ class KometAppState extends State _vpnBypassSub = VpnBypassService.instance.events.listen((r) { final msg = r.bound - ? 'Соединение через VPN не работает — ' - 'используется ${r.boundInterface ?? r.transport ?? 'прямое подключение'}' - : 'Соединение через VPN не работает, обойти не удалось' + ? 'Обход VPN включён — прямое подключение через ' + '${r.boundInterface ?? r.transport ?? 'сеть без VPN'}' + : 'Обход VPN не удался, подключение через туннель' '${r.reason != null ? ' (${r.reason})' : ''}'; final now = DateTime.now();