Skip to content

Commit

Permalink
Fix for VPN hanging in disconnected state
Browse files Browse the repository at this point in the history
  • Loading branch information
dzolnai committed Nov 3, 2023
1 parent 5703ee9 commit a3995de
Show file tree
Hide file tree
Showing 3 changed files with 29 additions and 9 deletions.
17 changes: 12 additions & 5 deletions app/src/main/java/nl/eduvpn/app/MainActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -42,10 +42,9 @@ import nl.eduvpn.app.fragment.ConnectionStatusFragment
import nl.eduvpn.app.fragment.OrganizationSelectionFragment
import nl.eduvpn.app.fragment.ProfileSelectionFragment
import nl.eduvpn.app.fragment.ServerSelectionFragment
import nl.eduvpn.app.service.BackendService
import nl.eduvpn.app.service.EduVPNOpenVPNService
import nl.eduvpn.app.service.HistoryService
import nl.eduvpn.app.service.VPNService
import nl.eduvpn.app.service.WireGuardService
import nl.eduvpn.app.utils.ErrorDialog.show
import nl.eduvpn.app.viewmodel.MainViewModel
import nl.eduvpn.app.viewmodel.ViewModelFactory
Expand All @@ -66,6 +65,9 @@ class MainActivity : BaseActivity<ActivityMainBinding>() {
@Inject
protected lateinit var eduVPNOpenVPNService: EduVPNOpenVPNService

@Inject
protected lateinit var wireGuardService: WireGuardService

@Inject
protected lateinit var viewModelFactory: ViewModelFactory

Expand Down Expand Up @@ -308,6 +310,10 @@ class MainActivity : BaseActivity<ActivityMainBinding>() {
return super.onOptionsItemSelected(item)
}

override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<out String>, grantResults: IntArray) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults)
}

override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
if (requestCode == REQUEST_CODE_SETTINGS) {
if (resultCode == SettingsActivity.RESULT_APP_DATA_CLEARED) {
Expand All @@ -318,9 +324,10 @@ class MainActivity : BaseActivity<ActivityMainBinding>() {
}
openFragment(OrganizationSelectionFragment(), false)
}
} else {
@Suppress("DEPRECATION")
super.onActivityResult(requestCode, resultCode, data)
} else if (requestCode == 0) {
// Probably VPN permission granted. Can't really check for it
wireGuardService.tryResumeConnecting(this)
}
super.onActivityResult(requestCode, resultCode, data)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ package nl.eduvpn.app.fragment

import android.os.Bundle
import android.view.View
import androidx.core.os.BundleCompat
import androidx.fragment.app.viewModels
import androidx.lifecycle.viewModelScope
import androidx.recyclerview.widget.LinearLayoutManager
Expand Down Expand Up @@ -61,9 +62,7 @@ class ProfileSelectionFragment : BaseFragment<FragmentProfileSelectionBinding>()
val profileAdapter = ProfileAdapter(viewModel.getProfileInstance())
binding.profileList.adapter = profileAdapter

// TODO: fix deprecation when new compat library released https://issuetracker.google.com/issues/242048899
@Suppress("DEPRECATION") val profiles: ArrayList<Profile> =
arguments?.getParcelableArrayList(KEY_PROFILES)!!
val profiles: ArrayList<Profile> = BundleCompat.getParcelableArrayList(requireArguments(), KEY_PROFILES, Profile::class.java)!!

profileAdapter.submitList(profiles)
viewModel.parentAction.observe(viewLifecycleOwner) { parentAction ->
Expand Down
16 changes: 15 additions & 1 deletion app/src/main/java/nl/eduvpn/app/service/WireGuardService.kt
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import com.wireguard.android.backend.GoBackend
import com.wireguard.android.backend.Tunnel
import com.wireguard.config.Config
import com.wireguard.config.Interface
import kotlinx.coroutines.DelicateCoroutinesApi
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.asCoroutineDispatcher
Expand All @@ -32,6 +33,7 @@ import kotlin.jvm.optionals.getOrNull
/**
* Service responsible for managing the WireGuard profiles and the connection.
*/
@OptIn(DelicateCoroutinesApi::class)
class WireGuardService(private val context: Context, timer: Flow<Unit>): VPNService() {

private lateinit var backend : GoBackend
Expand Down Expand Up @@ -59,6 +61,8 @@ class WireGuardService(private val context: Context, timer: Flow<Unit>): VPNServ
setConnectionStatus(tunnelStateToStatus(newTunnelState))
}

private var pendingConfig: Config? = null

init {
GlobalScope.launch(backendDispatcher) {
backend = GoBackend(context)
Expand All @@ -82,7 +86,7 @@ class WireGuardService(private val context: Context, timer: Flow<Unit>): VPNServ
* Ask user for VPN permission
*/
private fun authorizeVPN(activity: Activity) {
val intent = GoBackend.VpnService.prepare(context)
val intent = GoBackend.VpnService.prepare(activity)
if (intent != null) {
activity.startActivityForResult(intent, 0)
}
Expand Down Expand Up @@ -118,6 +122,7 @@ class WireGuardService(private val context: Context, timer: Flow<Unit>): VPNServ
} catch (ex: BackendException) {
if (ex.reason == BackendException.Reason.VPN_NOT_AUTHORIZED) {
withContext(Dispatchers.Main) {
pendingConfig = config
authorizeVPN(activity)
setConnectionStatus(VPNStatus.DISCONNECTED)
}
Expand Down Expand Up @@ -163,6 +168,15 @@ class WireGuardService(private val context: Context, timer: Flow<Unit>): VPNServ
return Protocol.WireGuard
}

fun tryResumeConnecting(activity: Activity) {
GlobalScope.launch(backendDispatcher) {
pendingConfig?.let {
connect(activity, it)
}
pendingConfig = null
}
}

companion object {
private fun calculateTunnelAddress(ipAddress: String?, subnetMask: Int): String? {
if (ipAddress == null) {
Expand Down

0 comments on commit a3995de

Please sign in to comment.