summaryrefslogtreecommitdiffhomepage
path: root/android/src
diff options
context:
space:
mode:
authorJanito Vaqueiro Ferreira Filho <janito@mullvad.net>2019-05-28 13:06:23 +0000
committerJanito Vaqueiro Ferreira Filho <janito@mullvad.net>2019-05-29 13:58:25 +0000
commit6b4583d50104d8eb531947d597c12c8572d06a8f (patch)
treec8bde6b2866d959e964098a70382a658a2e04a5c /android/src
parent0aad05f95e8950a8ea1771f3e936f8d797279076 (diff)
downloadmullvadvpn-6b4583d50104d8eb531947d597c12c8572d06a8f.tar.xz
mullvadvpn-6b4583d50104d8eb531947d597c12c8572d06a8f.zip
Create `MullvadVpnService` service
Diffstat (limited to 'android/src')
-rw-r--r--android/src/main/kotlin/net/mullvad/mullvadvpn/MullvadVpnService.kt79
1 files changed, 79 insertions, 0 deletions
diff --git a/android/src/main/kotlin/net/mullvad/mullvadvpn/MullvadVpnService.kt b/android/src/main/kotlin/net/mullvad/mullvadvpn/MullvadVpnService.kt
new file mode 100644
index 0000000000..dcd4935ee4
--- /dev/null
+++ b/android/src/main/kotlin/net/mullvad/mullvadvpn/MullvadVpnService.kt
@@ -0,0 +1,79 @@
+package net.mullvad.mullvadvpn
+
+import java.net.InetAddress
+
+import kotlinx.coroutines.runBlocking
+import kotlinx.coroutines.CompletableDeferred
+
+import android.app.Activity
+import android.content.Context
+import android.content.Intent
+import android.net.VpnService
+
+import net.mullvad.mullvadvpn.model.TunConfig
+
+var INNER_VPN_SERVICE = CompletableDeferred<MullvadVpnService.InnerVpnService>()
+var SERVICE_NOT_RUNNING = true
+
+class MullvadVpnService(val context: Context) {
+ class InnerVpnService : VpnService() {
+ override fun onStartCommand(intent: Intent, flags: Int, startId: Int): Int {
+ INNER_VPN_SERVICE.complete(this)
+
+ return super.onStartCommand(intent, flags, startId)
+ }
+
+ override fun onDestroy() {
+ INNER_VPN_SERVICE = CompletableDeferred<MullvadVpnService.InnerVpnService>()
+ SERVICE_NOT_RUNNING = true
+ super.onDestroy()
+ }
+
+ fun builder(): Builder {
+ return Builder()
+ }
+ }
+
+ fun createTun(config: TunConfig): Int {
+ return createTun(config, startService())
+ }
+
+ fun bypass(socket: Int): Boolean {
+ return startService().protect(socket)
+ }
+
+ private fun startService(): InnerVpnService {
+ lateinit var service: InnerVpnService
+
+ if (SERVICE_NOT_RUNNING) {
+ SERVICE_NOT_RUNNING = false
+ context.startService(Intent(context, InnerVpnService::class.java))
+ }
+
+ runBlocking { service = INNER_VPN_SERVICE.await() }
+
+ return service
+ }
+
+ private fun createTun(config: TunConfig, service: InnerVpnService): Int {
+ val builder = service.builder().apply {
+ for (address in config.addresses) {
+ addAddress(address, 32)
+ }
+
+ for (dnsServer in config.dnsServers) {
+ addDnsServer(dnsServer)
+ }
+
+ for (route in config.routes) {
+ addRoute(route.address, route.prefixLength as Int)
+ }
+
+ setMtu(config.mtu)
+ }
+
+ val vpnInterface = builder.establish()
+
+ return vpnInterface.detachFd()
+ }
+}