summaryrefslogtreecommitdiffhomepage
path: root/android/src
diff options
context:
space:
mode:
authorJanito Vaqueiro Ferreira Filho <janito@mullvad.net>2019-12-11 22:13:47 +0000
committerJanito Vaqueiro Ferreira Filho <janito@mullvad.net>2019-12-12 12:57:45 +0000
commite94e3dce715a8b40c72f30e0151a6cb12dc5971d (patch)
treea5ae88f0edd273de0dc4fcaa6874e5e46421f1f4 /android/src
parent8c28daae42e6b8a8547f25c850cbb935b2c3155c (diff)
downloadmullvadvpn-e94e3dce715a8b40c72f30e0151a6cb12dc5971d.tar.xz
mullvadvpn-e94e3dce715a8b40c72f30e0151a6cb12dc5971d.zip
Throttle retry attempts to fetch geo. IP location
Diffstat (limited to 'android/src')
-rw-r--r--android/src/main/kotlin/net/mullvad/mullvadvpn/dataproxy/LocationInfoCache.kt23
1 files changed, 23 insertions, 0 deletions
diff --git a/android/src/main/kotlin/net/mullvad/mullvadvpn/dataproxy/LocationInfoCache.kt b/android/src/main/kotlin/net/mullvad/mullvadvpn/dataproxy/LocationInfoCache.kt
index 2183922536..10f7dd7bcf 100644
--- a/android/src/main/kotlin/net/mullvad/mullvadvpn/dataproxy/LocationInfoCache.kt
+++ b/android/src/main/kotlin/net/mullvad/mullvadvpn/dataproxy/LocationInfoCache.kt
@@ -5,6 +5,7 @@ import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.Job
import kotlinx.coroutines.async
+import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import net.mullvad.mullvadvpn.model.GeoIpLocation
import net.mullvad.mullvadvpn.model.TunnelState
@@ -15,6 +16,10 @@ import net.mullvad.mullvadvpn.service.MullvadDaemon
import net.mullvad.talpid.ConnectivityListener
import net.mullvad.talpid.tunnel.ActionAfterDisconnect
+const val DELAY_SCALE: Long = 50
+const val MAX_DELAY: Long = 30 * 60 * 1000
+const val MAX_RETRIES: Int = 17 // ceil(log2(MAX_DELAY / DELAY_SCALE) + 1)
+
class LocationInfoCache(
val daemon: Deferred<MullvadDaemon>,
val connectivityListener: Deferred<ConnectivityListener>,
@@ -98,10 +103,14 @@ class LocationInfoCache(
activeFetch = GlobalScope.launch(Dispatchers.Main) {
var newLocation: GeoIpLocation? = null
+ var retry = 0
previousFetch?.join()
while (newLocation == null && shouldRetryFetch() && state == initialState) {
+ delayFetch(retry)
+ retry += 1
+
newLocation = executeFetch().await()
}
@@ -122,6 +131,20 @@ class LocationInfoCache(
daemon.await().getCurrentLocation()
}
+ private suspend fun delayFetch(retryAttempt: Int) {
+ var duration = 0L
+
+ // The first attempt has no delay
+ if (retryAttempt >= MAX_RETRIES) {
+ duration = MAX_DELAY
+ } else if (retryAttempt >= 1) {
+ val exponent = retryAttempt - 1
+ duration = (1L shl exponent) * DELAY_SCALE
+ }
+
+ delay(duration)
+ }
+
private suspend fun shouldRetryFetch(): Boolean {
val state = this.state