fix: improve proxy fallback and kill switch logic

This commit is contained in:
johnysigma 2026-03-30 15:13:46 +03:00
parent 75bd68aa15
commit bb34b67680
2 changed files with 35 additions and 19 deletions

View File

@ -307,6 +307,7 @@ async function handleNextProxy() {
status: 'connected', status: 'connected',
proxy: result.proxy proxy: result.proxy
}); });
} else {
} }
return result; return result;
@ -441,7 +442,7 @@ async function handleSaveSettings(settings) {
Utils.log('warn', 'Custom proxy settings invalid, disconnecting...'); Utils.log('warn', 'Custom proxy settings invalid, disconnecting...');
await ProxyManager.disconnect(); await ProxyManager.disconnect();
await Storage.setProxyEnabled(false); await Storage.setProxyEnabled(false);
broadcastMessage({ broadcastMessage({
action: 'statusUpdate', action: 'statusUpdate',
status: 'error', status: 'error',
error: 'Custom proxy not configured' error: 'Custom proxy not configured'
@ -456,7 +457,7 @@ async function handleSaveSettings(settings) {
); );
if (result) { if (result) {
broadcastMessage({ broadcastMessage({
action: 'statusUpdate', action: 'statusUpdate',
status: 'connected', status: 'connected',
proxy: { host: customProxy.ip, port: customProxy.port }, proxy: { host: customProxy.ip, port: customProxy.port },
@ -466,7 +467,7 @@ async function handleSaveSettings(settings) {
// Failed to apply - disconnect // Failed to apply - disconnect
await ProxyManager.disconnect(); await ProxyManager.disconnect();
await Storage.setProxyEnabled(false); await Storage.setProxyEnabled(false);
broadcastMessage({ broadcastMessage({
action: 'statusUpdate', action: 'statusUpdate',
status: 'error', status: 'error',
error: 'Failed to apply proxy settings' error: 'Failed to apply proxy settings'
@ -556,6 +557,7 @@ function broadcastMessage(message) {
}); });
} }
/** /**
* Handle proxy errors * Handle proxy errors
*/ */
@ -573,14 +575,27 @@ chrome.proxy.onProxyError.addListener(async (details) => {
Utils.log('error', 'Proxy error', details); Utils.log('error', 'Proxy error', details);
// Check if proxy is enabled - don't reconnect if user disconnected
const proxyEnabled = await Storage.isProxyEnabled();
if (!proxyEnabled) {
Utils.log('debug', 'Proxy disabled, ignoring error');
return;
}
// Check current mode - only attempt fallback for public proxies // Check current mode - only attempt fallback for public proxies
const mode = await Storage.getMode(); const mode = await Storage.getMode();
const killSwitch = await Storage.getValue(CONFIG.STORAGE_KEYS.KILL_SWITCH, false); const killSwitch = await Storage.getValue(CONFIG.STORAGE_KEYS.KILL_SWITCH, false);
// For non-fatal errors in public mode, attempt fallback // For public mode, always attempt fallback (regardless of fatal flag)
if (!details.fatal && mode === CONFIG.MODES.PUBLIC) { if (mode === CONFIG.MODES.PUBLIC) {
const result = await ProxyManager.fallbackToNext(); const result = await ProxyManager.fallbackToNext();
if (result.success) { if (result.success) {
// Deactivate kill switch if it was active
const killSwitchActive = await Storage.getValue('killSwitchActive', false);
if (killSwitchActive) {
await applyKillSwitch(false);
Utils.log('info', 'Kill switch deactivated after successful fallback');
}
broadcastMessage({ broadcastMessage({
action: 'statusUpdate', action: 'statusUpdate',
status: 'connected', status: 'connected',
@ -653,23 +668,17 @@ async function applyKillSwitch(activate) {
}; };
await chrome.proxy.settings.set({ value: config, scope: 'regular' }); await chrome.proxy.settings.set({ value: config, scope: 'regular' });
await Storage.setValue('killSwitchActive', true); await Storage.setValue('killSwitchActive', true);
// Show red badge with exclamation mark
await chrome.action.setBadgeText({ text: '!' });
await chrome.action.setBadgeBackgroundColor({ color: '#E74C3C' });
Utils.log('info', 'Kill switch ACTIVATED - all traffic blocked'); Utils.log('info', 'Kill switch ACTIVATED - all traffic blocked');
// Update icon to show blocked state
try {
await chrome.action.setBadgeText({ text: '!' });
await chrome.action.setBadgeBackgroundColor({ color: '#e74c3c' });
} catch (e) {}
} else { } else {
// Deactivate kill switch - clear proxy settings // Deactivate kill switch - clear proxy settings
await chrome.proxy.settings.clear({ scope: 'regular' }); await chrome.proxy.settings.clear({ scope: 'regular' });
await Storage.setValue('killSwitchActive', false); await Storage.setValue('killSwitchActive', false);
// Remove badge
await chrome.action.setBadgeText({ text: '' });
Utils.log('info', 'Kill switch DEACTIVATED - traffic restored'); Utils.log('info', 'Kill switch DEACTIVATED - traffic restored');
// Clear badge
try {
await chrome.action.setBadgeText({ text: '' });
} catch (e) {}
} }
return true; return true;
} catch (error) { } catch (error) {

View File

@ -375,9 +375,10 @@ const ProxyManager = {
/** /**
* Fallback to next proxy * Fallback to next proxy
* @param {number} attemptCount - Number of attempts made
* @returns {Promise<{success: boolean, proxy: object|null, error: string|null}>} * @returns {Promise<{success: boolean, proxy: object|null, error: string|null}>}
*/ */
async fallbackToNext() { async fallbackToNext(attemptCount = 0) {
if (this._proxyList.length === 0) { if (this._proxyList.length === 0) {
return { success: false, proxy: null, error: 'No proxies available. Please refresh the proxy list.' }; return { success: false, proxy: null, error: 'No proxies available. Please refresh the proxy list.' };
} }
@ -386,17 +387,23 @@ const ProxyManager = {
return { success: false, proxy: null, error: 'Only one proxy available' }; return { success: false, proxy: null, error: 'Only one proxy available' };
} }
// Prevent infinite loop - stop after trying all proxies
if (attemptCount >= this._proxyList.length) {
Utils.log('error', 'All proxies failed, no working proxy found');
return { success: false, proxy: null, error: 'All proxies are unavailable' };
}
this._currentIndex = (this._currentIndex + 1) % this._proxyList.length; this._currentIndex = (this._currentIndex + 1) % this._proxyList.length;
const proxy = this._proxyList[this._currentIndex]; const proxy = this._proxyList[this._currentIndex];
Utils.log('info', `Switching to proxy ${this._currentIndex + 1}/${this._proxyList.length}: ${proxy.host}:${proxy.port}`); Utils.log('info', `Switching to proxy ${this._currentIndex + 1}/${this._proxyList.length}: ${proxy.host}:${proxy.port} (attempt ${attemptCount + 1}/${this._proxyList.length})`);
// Test the proxy first to get latency // Test the proxy first to get latency
const testResult = await this.testProxy(proxy); const testResult = await this.testProxy(proxy);
if (!testResult.working) { if (!testResult.working) {
// Try next proxy if this one doesn't work // Try next proxy if this one doesn't work
Utils.log('warn', `Proxy ${proxy.host}:${proxy.port} not working, trying next...`); Utils.log('warn', `Proxy ${proxy.host}:${proxy.port} not working, trying next...`);
return this.fallbackToNext(); return this.fallbackToNext(attemptCount + 1);
} }
// Merge test results (latency) with proxy info // Merge test results (latency) with proxy info