summaryrefslogtreecommitdiffhomepage
path: root/android/src
diff options
context:
space:
mode:
authorJanito Vaqueiro Ferreira Filho <janito@mullvad.net>2021-04-13 14:53:57 -0300
committerJanito Vaqueiro Ferreira Filho <janito@mullvad.net>2021-04-13 14:53:57 -0300
commit4a3e5171461eb2c4079ec3ce7d75a875442b98b0 (patch)
tree8b109f3b6db62b8c1451a3bfba927e7c1aac9826 /android/src
parent57a5481e5d4a6f18ec8d357013d8af004282919c (diff)
parent61f82b45342f640820200c26daee10f7e30246c0 (diff)
downloadmullvadvpn-4a3e5171461eb2c4079ec3ce7d75a875442b98b0.tar.xz
mullvadvpn-4a3e5171461eb2c4079ec3ce7d75a875442b98b0.zip
Merge branch 'split-custom-dns'
Diffstat (limited to 'android/src')
-rw-r--r--android/src/main/kotlin/net/mullvad/mullvadvpn/ipc/Request.kt16
-rw-r--r--android/src/main/kotlin/net/mullvad/mullvadvpn/service/CustomDns.kt95
-rw-r--r--android/src/main/kotlin/net/mullvad/mullvadvpn/service/MullvadVpnService.kt11
-rw-r--r--android/src/main/kotlin/net/mullvad/mullvadvpn/service/ServiceInstance.kt12
-rw-r--r--android/src/main/kotlin/net/mullvad/mullvadvpn/service/endpoint/CustomDns.kt113
-rw-r--r--android/src/main/kotlin/net/mullvad/mullvadvpn/service/endpoint/ServiceEndpoint.kt2
-rw-r--r--android/src/main/kotlin/net/mullvad/mullvadvpn/ui/ServiceDependentFragment.kt2
-rw-r--r--android/src/main/kotlin/net/mullvad/mullvadvpn/ui/customdns/CustomDnsAdapter.kt2
-rw-r--r--android/src/main/kotlin/net/mullvad/mullvadvpn/ui/serviceconnection/CustomDns.kt61
-rw-r--r--android/src/main/kotlin/net/mullvad/mullvadvpn/ui/serviceconnection/ServiceConnection.kt3
10 files changed, 198 insertions, 119 deletions
diff --git a/android/src/main/kotlin/net/mullvad/mullvadvpn/ipc/Request.kt b/android/src/main/kotlin/net/mullvad/mullvadvpn/ipc/Request.kt
index 1937ce424b..fc293e69a3 100644
--- a/android/src/main/kotlin/net/mullvad/mullvadvpn/ipc/Request.kt
+++ b/android/src/main/kotlin/net/mullvad/mullvadvpn/ipc/Request.kt
@@ -2,6 +2,7 @@ package net.mullvad.mullvadvpn.ipc
import android.os.Message as RawMessage
import android.os.Messenger
+import java.net.InetAddress
import kotlinx.parcelize.Parcelize
import org.joda.time.DateTime
@@ -10,6 +11,9 @@ sealed class Request : Message.RequestMessage() {
protected override val messageKey = MESSAGE_KEY
@Parcelize
+ data class AddCustomDnsServer(val address: InetAddress) : Request()
+
+ @Parcelize
object Connect : Request()
@Parcelize
@@ -49,6 +53,18 @@ sealed class Request : Message.RequestMessage() {
data class RemoveAccountFromHistory(val account: String?) : Request()
@Parcelize
+ data class RemoveCustomDnsServer(val address: InetAddress) : Request()
+
+ @Parcelize
+ data class ReplaceCustomDnsServer(
+ val oldAddress: InetAddress,
+ val newAddress: InetAddress
+ ) : Request()
+
+ @Parcelize
+ data class SetEnableCustomDns(val enable: Boolean) : Request()
+
+ @Parcelize
data class SetEnableSplitTunneling(val enable: Boolean) : Request()
@Parcelize
diff --git a/android/src/main/kotlin/net/mullvad/mullvadvpn/service/CustomDns.kt b/android/src/main/kotlin/net/mullvad/mullvadvpn/service/CustomDns.kt
deleted file mode 100644
index 447c215e1c..0000000000
--- a/android/src/main/kotlin/net/mullvad/mullvadvpn/service/CustomDns.kt
+++ /dev/null
@@ -1,95 +0,0 @@
-package net.mullvad.mullvadvpn.service
-
-import java.net.InetAddress
-import java.util.ArrayList
-import kotlin.properties.Delegates.observable
-import net.mullvad.mullvadvpn.model.DnsOptions
-import net.mullvad.mullvadvpn.service.endpoint.SettingsListener
-import net.mullvad.talpid.util.EventNotifier
-
-class CustomDns(val daemon: MullvadDaemon, val settingsListener: SettingsListener) {
- private var enabled by observable(false) { _, oldValue, newValue ->
- if (oldValue != newValue) {
- onEnabledChanged.notify(newValue)
- }
- }
-
- private var dnsServers by observable<ArrayList<InetAddress>>(ArrayList()) { _, _, servers ->
- onDnsServersChanged.notify(servers.toList())
- }
-
- val onEnabledChanged = EventNotifier(false)
- val onDnsServersChanged = EventNotifier<List<InetAddress>>(emptyList())
-
- init {
- settingsListener.dnsOptionsNotifier.subscribe(this) { maybeDnsOptions ->
- maybeDnsOptions?.let { dnsOptions ->
- enabled = dnsOptions.custom
- dnsServers = dnsOptions.addresses
- }
- }
- }
-
- fun onDestroy() {
- settingsListener.dnsOptionsNotifier.unsubscribe(this)
- }
-
- fun enable() {
- synchronized(this) {
- changeDnsOptions(true, dnsServers)
- }
- }
-
- fun disable() {
- synchronized(this) {
- changeDnsOptions(false, dnsServers)
- }
- }
-
- fun addDnsServer(server: InetAddress): Boolean {
- synchronized(this) {
- if (!dnsServers.contains(server)) {
- dnsServers.add(server)
- changeDnsOptions(enabled, dnsServers)
-
- return true
- }
- }
-
- return false
- }
-
- fun replaceDnsServer(oldServer: InetAddress, newServer: InetAddress): Boolean {
- synchronized(this) {
- if (oldServer == newServer) {
- return true
- } else if (!dnsServers.contains(newServer)) {
- val index = dnsServers.indexOf(oldServer)
-
- if (index >= 0) {
- dnsServers.removeAt(index)
- dnsServers.add(index, newServer)
- changeDnsOptions(enabled, dnsServers)
-
- return true
- }
- }
- }
-
- return false
- }
-
- fun removeDnsServer(server: InetAddress) {
- synchronized(this) {
- if (dnsServers.remove(server)) {
- changeDnsOptions(enabled, dnsServers)
- }
- }
- }
-
- private fun changeDnsOptions(enable: Boolean, dnsServers: ArrayList<InetAddress>) {
- val options = DnsOptions(enable, dnsServers)
-
- daemon.setDnsOptions(options)
- }
-}
diff --git a/android/src/main/kotlin/net/mullvad/mullvadvpn/service/MullvadVpnService.kt b/android/src/main/kotlin/net/mullvad/mullvadvpn/service/MullvadVpnService.kt
index 1d379c5775..2d057e2c97 100644
--- a/android/src/main/kotlin/net/mullvad/mullvadvpn/service/MullvadVpnService.kt
+++ b/android/src/main/kotlin/net/mullvad/mullvadvpn/service/MullvadVpnService.kt
@@ -57,8 +57,6 @@ class MullvadVpnService : TalpidVpnService() {
private var instance by observable<ServiceInstance?>(null) { _, oldInstance, newInstance ->
if (newInstance != oldInstance) {
- oldInstance?.onDestroy()
-
accountExpiryNotification = newInstance?.let { instance ->
AccountExpiryNotification(this, instance.daemon, endpoint.accountCache)
}
@@ -237,17 +235,10 @@ class MullvadVpnService : TalpidVpnService() {
}
private suspend fun setUpInstance(daemon: MullvadDaemon, settings: Settings) {
- val customDns = CustomDns(daemon, endpoint.settingsListener)
-
handlePendingAction(settings)
if (state == State.Running) {
- instance = ServiceInstance(
- endpoint.messenger,
- daemon,
- daemonInstance.intermittentDaemon,
- customDns
- )
+ instance = ServiceInstance(endpoint.messenger, daemon)
}
}
diff --git a/android/src/main/kotlin/net/mullvad/mullvadvpn/service/ServiceInstance.kt b/android/src/main/kotlin/net/mullvad/mullvadvpn/service/ServiceInstance.kt
index f4e898d143..383e735b24 100644
--- a/android/src/main/kotlin/net/mullvad/mullvadvpn/service/ServiceInstance.kt
+++ b/android/src/main/kotlin/net/mullvad/mullvadvpn/service/ServiceInstance.kt
@@ -1,15 +1,5 @@
package net.mullvad.mullvadvpn.service
import android.os.Messenger
-import net.mullvad.mullvadvpn.util.Intermittent
-class ServiceInstance(
- val messenger: Messenger,
- val daemon: MullvadDaemon,
- val intermittentDaemon: Intermittent<MullvadDaemon>,
- val customDns: CustomDns,
-) {
- fun onDestroy() {
- customDns.onDestroy()
- }
-}
+class ServiceInstance(val messenger: Messenger, val daemon: MullvadDaemon)
diff --git a/android/src/main/kotlin/net/mullvad/mullvadvpn/service/endpoint/CustomDns.kt b/android/src/main/kotlin/net/mullvad/mullvadvpn/service/endpoint/CustomDns.kt
new file mode 100644
index 0000000000..7c22cef50c
--- /dev/null
+++ b/android/src/main/kotlin/net/mullvad/mullvadvpn/service/endpoint/CustomDns.kt
@@ -0,0 +1,113 @@
+package net.mullvad.mullvadvpn.service.endpoint
+
+import java.net.InetAddress
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.GlobalScope
+import kotlinx.coroutines.channels.Channel
+import kotlinx.coroutines.channels.ClosedReceiveChannelException
+import kotlinx.coroutines.channels.actor
+import kotlinx.coroutines.channels.sendBlocking
+import net.mullvad.mullvadvpn.ipc.Request
+import net.mullvad.mullvadvpn.model.DnsOptions
+
+class CustomDns(private val endpoint: ServiceEndpoint) {
+ private sealed class Command {
+ class AddDnsServer(val server: InetAddress) : Command()
+ class RemoveDnsServer(val server: InetAddress) : Command()
+ class ReplaceDnsServer(val oldServer: InetAddress, val newServer: InetAddress) : Command()
+ class SetEnabled(val enabled: Boolean) : Command()
+ }
+
+ private val commandChannel = spawnActor()
+ private val dnsServers = ArrayList<InetAddress>()
+
+ private val daemon
+ get() = endpoint.intermittentDaemon
+
+ private var enabled = false
+
+ init {
+ endpoint.settingsListener.dnsOptionsNotifier.subscribe(this) { maybeDnsOptions ->
+ maybeDnsOptions?.let { dnsOptions ->
+ enabled = dnsOptions.custom
+ dnsServers.clear()
+ dnsServers.addAll(dnsOptions.addresses)
+ }
+ }
+
+ endpoint.dispatcher.apply {
+ registerHandler(Request.AddCustomDnsServer::class) { request ->
+ commandChannel.sendBlocking(Command.AddDnsServer(request.address))
+ }
+
+ registerHandler(Request.RemoveCustomDnsServer::class) { request ->
+ commandChannel.sendBlocking(Command.RemoveDnsServer(request.address))
+ }
+
+ registerHandler(Request.ReplaceCustomDnsServer::class) { request ->
+ commandChannel.sendBlocking(
+ Command.ReplaceDnsServer(request.oldAddress, request.newAddress)
+ )
+ }
+
+ registerHandler(Request.SetEnableCustomDns::class) { request ->
+ commandChannel.sendBlocking(Command.SetEnabled(request.enable))
+ }
+ }
+ }
+
+ fun onDestroy() {
+ endpoint.settingsListener.dnsOptionsNotifier.unsubscribe(this)
+ commandChannel.close()
+ }
+
+ private fun spawnActor() = GlobalScope.actor<Command>(Dispatchers.Default, Channel.UNLIMITED) {
+ try {
+ while (true) {
+ val command = channel.receive()
+
+ when (command) {
+ is Command.AddDnsServer -> doAddDnsServer(command.server)
+ is Command.RemoveDnsServer -> doRemoveDnsServer(command.server)
+ is Command.ReplaceDnsServer -> {
+ doReplaceDnsServer(command.oldServer, command.newServer)
+ }
+ is Command.SetEnabled -> changeDnsOptions(command.enabled)
+ }
+ }
+ } catch (exception: ClosedReceiveChannelException) {
+ // Closed sender, so stop the actor
+ }
+ }
+
+ private suspend fun doAddDnsServer(server: InetAddress) {
+ if (!dnsServers.contains(server)) {
+ dnsServers.add(server)
+ changeDnsOptions(enabled)
+ }
+ }
+
+ private suspend fun doReplaceDnsServer(oldServer: InetAddress, newServer: InetAddress) {
+ if (oldServer != newServer && !dnsServers.contains(newServer)) {
+ val index = dnsServers.indexOf(oldServer)
+
+ if (index >= 0) {
+ dnsServers.removeAt(index)
+ dnsServers.add(index, newServer)
+ changeDnsOptions(enabled)
+ }
+ }
+ }
+
+ private suspend fun doRemoveDnsServer(server: InetAddress) {
+ if (dnsServers.remove(server)) {
+ changeDnsOptions(enabled)
+ }
+ }
+
+ private suspend fun changeDnsOptions(enable: Boolean) {
+ val options = DnsOptions(enable, dnsServers)
+
+ daemon.await().setDnsOptions(options)
+ }
+}
diff --git a/android/src/main/kotlin/net/mullvad/mullvadvpn/service/endpoint/ServiceEndpoint.kt b/android/src/main/kotlin/net/mullvad/mullvadvpn/service/endpoint/ServiceEndpoint.kt
index 1d7ee77763..0f583d1fc9 100644
--- a/android/src/main/kotlin/net/mullvad/mullvadvpn/service/endpoint/ServiceEndpoint.kt
+++ b/android/src/main/kotlin/net/mullvad/mullvadvpn/service/endpoint/ServiceEndpoint.kt
@@ -40,6 +40,7 @@ class ServiceEndpoint(
val settingsListener = SettingsListener(this)
val accountCache = AccountCache(this)
+ val customDns = CustomDns(this)
val keyStatusListener = KeyStatusListener(this)
val locationInfoCache = LocationInfoCache(this)
val splitTunneling = SplitTunneling(SplitTunnelingPersistence(context), this)
@@ -56,6 +57,7 @@ class ServiceEndpoint(
accountCache.onDestroy()
connectionProxy.onDestroy()
+ customDns.onDestroy()
keyStatusListener.onDestroy()
locationInfoCache.onDestroy()
settingsListener.onDestroy()
diff --git a/android/src/main/kotlin/net/mullvad/mullvadvpn/ui/ServiceDependentFragment.kt b/android/src/main/kotlin/net/mullvad/mullvadvpn/ui/ServiceDependentFragment.kt
index 1927a0490f..fbb09689ca 100644
--- a/android/src/main/kotlin/net/mullvad/mullvadvpn/ui/ServiceDependentFragment.kt
+++ b/android/src/main/kotlin/net/mullvad/mullvadvpn/ui/ServiceDependentFragment.kt
@@ -7,10 +7,10 @@ import android.view.ViewGroup
import net.mullvad.mullvadvpn.R
import net.mullvad.mullvadvpn.dataproxy.AppVersionInfoCache
import net.mullvad.mullvadvpn.dataproxy.RelayListListener
-import net.mullvad.mullvadvpn.service.CustomDns
import net.mullvad.mullvadvpn.service.MullvadDaemon
import net.mullvad.mullvadvpn.ui.serviceconnection.AccountCache
import net.mullvad.mullvadvpn.ui.serviceconnection.ConnectionProxy
+import net.mullvad.mullvadvpn.ui.serviceconnection.CustomDns
import net.mullvad.mullvadvpn.ui.serviceconnection.KeyStatusListener
import net.mullvad.mullvadvpn.ui.serviceconnection.LocationInfoCache
import net.mullvad.mullvadvpn.ui.serviceconnection.ServiceConnection
diff --git a/android/src/main/kotlin/net/mullvad/mullvadvpn/ui/customdns/CustomDnsAdapter.kt b/android/src/main/kotlin/net/mullvad/mullvadvpn/ui/customdns/CustomDnsAdapter.kt
index c66fc04848..8b0ce3b48b 100644
--- a/android/src/main/kotlin/net/mullvad/mullvadvpn/ui/customdns/CustomDnsAdapter.kt
+++ b/android/src/main/kotlin/net/mullvad/mullvadvpn/ui/customdns/CustomDnsAdapter.kt
@@ -8,7 +8,7 @@ import kotlin.properties.Delegates.observable
import kotlinx.coroutines.sync.Mutex
import kotlinx.coroutines.sync.withLock
import net.mullvad.mullvadvpn.R
-import net.mullvad.mullvadvpn.service.CustomDns
+import net.mullvad.mullvadvpn.ui.serviceconnection.CustomDns
import net.mullvad.mullvadvpn.util.JobTracker
import org.apache.commons.validator.routines.InetAddressValidator
diff --git a/android/src/main/kotlin/net/mullvad/mullvadvpn/ui/serviceconnection/CustomDns.kt b/android/src/main/kotlin/net/mullvad/mullvadvpn/ui/serviceconnection/CustomDns.kt
new file mode 100644
index 0000000000..140d1135cd
--- /dev/null
+++ b/android/src/main/kotlin/net/mullvad/mullvadvpn/ui/serviceconnection/CustomDns.kt
@@ -0,0 +1,61 @@
+package net.mullvad.mullvadvpn.ui.serviceconnection
+
+import android.os.Messenger
+import java.net.InetAddress
+import net.mullvad.mullvadvpn.ipc.Request
+import net.mullvad.talpid.util.EventNotifier
+
+class CustomDns(val connection: Messenger, val settingsListener: SettingsListener) {
+ val onEnabledChanged = EventNotifier(false)
+ val onDnsServersChanged = EventNotifier<List<InetAddress>>(emptyList())
+
+ init {
+ settingsListener.dnsOptionsNotifier.subscribe(this) { maybeDnsOptions ->
+ maybeDnsOptions?.let { dnsOptions ->
+ synchronized(this) {
+ onEnabledChanged.notifyIfChanged(dnsOptions.custom)
+ onDnsServersChanged.notifyIfChanged(dnsOptions.addresses)
+ }
+ }
+ }
+ }
+
+ fun enable() {
+ connection.send(Request.SetEnableCustomDns(true).message)
+ }
+
+ fun disable() {
+ connection.send(Request.SetEnableCustomDns(false).message)
+ }
+
+ fun addDnsServer(server: InetAddress): Boolean {
+ val alreadyHadServer = onDnsServersChanged.latestEvent.contains(server)
+
+ connection.send(Request.AddCustomDnsServer(server).message)
+
+ return alreadyHadServer
+ }
+
+ fun replaceDnsServer(oldServer: InetAddress, newServer: InetAddress): Boolean {
+ synchronized(this) {
+ val dnsServers = onDnsServersChanged.latestEvent
+ val containsOldServer = dnsServers.contains(oldServer)
+ val replacementIsValid = oldServer == newServer || !dnsServers.contains(newServer)
+
+ connection.send(Request.ReplaceCustomDnsServer(oldServer, newServer).message)
+
+ return containsOldServer && replacementIsValid
+ }
+ }
+
+ fun removeDnsServer(server: InetAddress) {
+ connection.send(Request.RemoveCustomDnsServer(server).message)
+ }
+
+ fun onDestroy() {
+ onEnabledChanged.unsubscribeAll()
+ onDnsServersChanged.unsubscribeAll()
+
+ settingsListener.dnsOptionsNotifier.unsubscribe(this)
+ }
+}
diff --git a/android/src/main/kotlin/net/mullvad/mullvadvpn/ui/serviceconnection/ServiceConnection.kt b/android/src/main/kotlin/net/mullvad/mullvadvpn/ui/serviceconnection/ServiceConnection.kt
index 6e2cee704f..e3b02a3bb8 100644
--- a/android/src/main/kotlin/net/mullvad/mullvadvpn/ui/serviceconnection/ServiceConnection.kt
+++ b/android/src/main/kotlin/net/mullvad/mullvadvpn/ui/serviceconnection/ServiceConnection.kt
@@ -30,7 +30,6 @@ class ServiceConnection(private val service: ServiceInstance, mainActivity: Main
val daemon = service.daemon
val accountCache = AccountCache(service.messenger, dispatcher)
val connectionProxy = ConnectionProxy(service.messenger, dispatcher)
- val customDns = service.customDns
val keyStatusListener = KeyStatusListener(service.messenger, dispatcher)
val locationInfoCache = LocationInfoCache(dispatcher)
val settingsListener = SettingsListener(dispatcher)
@@ -40,6 +39,7 @@ class ServiceConnection(private val service: ServiceInstance, mainActivity: Main
val vpnPermission = VpnPermission(service.messenger)
val appVersionInfoCache = AppVersionInfoCache(mainActivity, daemon, settingsListener)
+ val customDns = CustomDns(service.messenger, settingsListener)
var relayListListener = RelayListListener(daemon, settingsListener)
init {
@@ -57,6 +57,7 @@ class ServiceConnection(private val service: ServiceInstance, mainActivity: Main
settingsListener.onDestroy()
appVersionInfoCache.onDestroy()
+ customDns.onDestroy()
relayListListener.onDestroy()
}