diff --git a/background.js b/background.js index 6c8136a..0445880 100644 --- a/background.js +++ b/background.js @@ -10,6 +10,8 @@ var PROXY_PORT = 1080; // TCP Server Management var serverSocketId = null; var isListening = false; +var isInitialized = false; // Prevent double initialization +var handlersSetup = false; // Prevent duplicate event listeners // SOCKS5 Connection States var ConnectionState = { @@ -383,7 +385,13 @@ function setupConnectionHandlers() { chrome.sockets.tcp.onReceiveError.addListener(function(info) { var socketId = info.socketId; var resultCode = info.resultCode; - console.error('[Proxy] Receive error on socket ' + socketId + ': ' + resultCode); + + // Error code -100 is ERR_CONNECTION_CLOSED - normal disconnect, not an error + if (resultCode === -100) { + console.log('[Proxy] Socket ' + socketId + ' connection closed'); + } else { + console.error('[Proxy] Receive error on socket ' + socketId + ': ' + resultCode); + } // Clean up connections if (connections[socketId]) { @@ -424,16 +432,29 @@ function setupConnectionHandlers() { } function initializeProxy() { + // Prevent double initialization + if (isInitialized) { + console.log('[Proxy] Already initialized or initializing...'); + return; + } + isInitialized = true; + console.log('[Proxy] Initializing Chrome SOCKS Proxy (with tunneling)...'); createServer(PROXY_HOST, PROXY_PORT, function(error, socketId) { if (error) { console.error('[Proxy] Failed to initialize:', error); + isInitialized = false; // Allow retry on failure return; } console.log('[Proxy] SOCKS proxy is running on ' + PROXY_HOST + ':' + PROXY_PORT); - setupConnectionHandlers(); + + // Setup handlers only once + if (!handlersSetup) { + setupConnectionHandlers(); + handlersSetup = true; + } }); } @@ -443,7 +464,79 @@ chrome.app.runtime.onLaunched.addListener(function() { initializeProxy(); }); +// Chrome App lifecycle - restart when app is restarted +chrome.app.runtime.onRestarted.addListener(function() { + console.log('[Proxy] App restarted'); + // Reset state and reinitialize + isListening = false; + isInitialized = false; + serverSocketId = null; + initializeProxy(); +}); + +// Handle the app window being closed +chrome.app.window.onClosed.addListener(function() { + console.log('[Proxy] App window closed'); + // Clean up connections + for (var socketId in connections) { + try { + chrome.sockets.tcp.close(parseInt(socketId)); + } catch(e) {} + } + connections = {}; + reverseConnections = {}; + + // Close server socket + if (serverSocketId !== null) { + try { + chrome.sockets.tcpServer.close(serverSocketId); + } catch(e) {} + serverSocketId = null; + } + isListening = false; + isInitialized = false; +}); + // Also initialize on startup (for apps that are already running) initializeProxy(); +// ============================================================================ +// KEEP-ALIVE MECHANISM +// ============================================================================ + +// Setup keep-alive alarm to prevent Chrome from suspending the app +chrome.alarms.create('keepAlive', { periodInMinutes: 1 }); + +chrome.alarms.onAlarm.addListener(function(alarm) { + if (alarm.name === 'keepAlive') { + // Heartbeat: log activity to keep the app alive + console.log('[Proxy] Heartbeat - Proxy is ' + (isListening ? 'active' : 'inactive')); + + // Check if server is still listening, restart if needed + if (!isListening && !isInitialized) { + console.log('[Proxy] Server not listening, reinitializing...'); + initializeProxy(); + } + + // Request keep awake to prevent system sleep (optional) + chrome.power.requestKeepAwake('system'); + } +}); + +// Handle when app is suspended and resumed +chrome.runtime.onSuspend.addListener(function() { + console.log('[Proxy] App being suspended...'); +}); + +chrome.runtime.onSuspendCanceled.addListener(function() { + console.log('[Proxy] Suspend canceled - app is active again'); + + // Reinitialize if needed after unsuspend + if (!isListening) { + console.log('[Proxy] Reinitializing after unsuspend...'); + isInitialized = false; + initializeProxy(); + } +}); + console.log('[Proxy] Background script loaded'); diff --git a/manifest.json b/manifest.json index 593c268..479c970 100644 --- a/manifest.json +++ b/manifest.json @@ -16,5 +16,5 @@ "listen": ["*:*"] } }, - "permissions": ["storage", ""] + "permissions": ["storage", "", "alarms", "power"] }