hiddify-next icon indicating copy to clipboard operation
hiddify-next copied to clipboard

VPN Connection Dies After Periods of Inactivity

Open AshkanRafiee opened this issue 1 year ago • 0 comments

Search first

  • [x] I searched and no similar issues were found

What Happened?

The app's VPN connection automatically dies after a few minutes of inactivity. Users must manually disable and re-enable the VPN to restore connectivity. This issue affects the user experience by requiring frequent manual intervention to maintain a stable VPN connection.

Reproduce the Bug

  1. Open the app and connect to the VPN (WARP Method).
  2. Leave the VPN connected without transferring any data or using the device for a few minutes.
  3. Observe that the VPN connection dies, indicated by a loss of internet connectivity.

Expected Behavior

The VPN connection should remain active and stable, even during periods of inactivity, until the user decides to disconnect manually.

Version

v0.15.4

Platform/OS

Android

Additional Context

To address the issue of the VPN connection dying after minutes of not using it, you might need to implement or adjust several aspects of your application. Here are some suggestions based on the potential areas identified:

1. Enhancing VPN Service Persistence

Foreground Service: Ensure your VPNService runs as a foreground service with a persistent notification. This makes it less likely for the system to kill your service due to inactivity or when freeing up resources. In VPNService.kt, ensure you're calling startForeground() with a proper notification to keep the service running in the foreground.

val notification = Notification.Builder(this, CHANNEL_ID) // Customize this startForeground(NOTIF_ID, notification.build())

Service Restart: Implement logic to automatically restart the VPN service if it gets disconnected or killed by the system. This can be done by listening for system broadcast actions indicating that your app's process has been killed and then restarting the service.

2. Improving Network Monitoring and Handling

Reliable Network Change Detection: Ensure that DefaultNetworkMonitor.kt accurately detects network changes and appropriately handles them. Consider registering for network change callbacks using ConnectivityManager.NetworkCallback to get more reliable network change events.

Reconnection Strategy: Implement a reconnection strategy in case of network changes or when the VPN connection drops. This could involve automatically attempting to re-establish the VPN connection upon detecting network availability.

3. Service Binding Robustness

Persistent Connection: In ServiceBinder.kt and related service connection components, ensure that the app maintains a persistent connection to the VPN service. Implement re-binding logic in case the service connection is lost.

4. Adapting to Power Management

Whitelisting from Battery Optimizations: Prompt users to whitelist your app from battery optimizations. This can help prevent the system from stopping your VPN service. You can prompt users with an intent to the battery optimization settings:

val intent = Intent(Settings.ACTION_IGNORE_BATTERY_OPTIMIZATION_SETTINGS) startActivity(intent)

5. Settings and Configuration Management

Dynamic Configuration: Ensure that the app dynamically adjusts its settings based on current conditions. For example, if Settings.kt indicates that a certain proxy mode is less stable under certain network conditions, provide logic to switch modes or adjust settings for better stability.

Code Changes

Here are some code snippets to illustrate the changes:

Foreground Service Notification Setup in VPNService.kt

override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
    // Create a notification channel for Android O and above
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
        val serviceChannel = NotificationChannel(
            CHANNEL_ID,
            "VPN Service Channel",
            NotificationManager.IMPORTANCE_DEFAULT
        )
        val manager = getSystemService(NotificationManager::class.java)
        manager.createNotificationChannel(serviceChannel)
    }

    val notificationIntent = Intent(this, MainActivity::class.java)
    val pendingIntent = PendingIntent.getActivity(
        this,
        0, notificationIntent, 0
    )

    val notification = NotificationCompat.Builder(this, CHANNEL_ID)
        .setContentTitle("VPN Service Running")
        .setContentText("Tap to return to the app.")
        .setSmallIcon(R.drawable.ic_vpn)
        .setContentIntent(pendingIntent)
        .build()

    startForeground(1, notification)

    return super.onStartCommand(intent, flags, startId)
}

Network Change Handling in DefaultNetworkMonitor.kt

fun registerNetworkCallback() {
    val connectivityManager = context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
    val networkRequest = NetworkRequest.Builder()
        .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
        .build()
    connectivityManager.registerNetworkCallback(networkRequest, networkCallback)
}

private val networkCallback = object : ConnectivityManager.NetworkCallback() {
    override fun onAvailable(network: Network) {
        super.onAvailable(network)
        // Handle network available
    }

    override fun onLost(network: Network) {
        super.onLost(network)
        // Handle network lost, attempt to reconnect or adjust settings
    }
}

Implementing these changes should help in making the VPN service more resilient to disconnections and system interventions.

Relevant log output

No response

Are you willing to submit a PR? If you know how to fix the bug.

  • [ ] I'm willing to submit a PR (Thank you!)

AshkanRafiee avatar Feb 13 '24 05:02 AshkanRafiee