android: the diagnostics row «Russian sites» no longer shows a stale verdict: the screen waited a fixed 2.5 s for the direct probe round and then read whatever the last round had left, and a round with a timed-out foreign probe takes 6.7 s or more, so a «do not open» recorded during a network outage was shown minutes later on a working network; it now waits for a round that finished after the request (up to 8 s) and shows «unknown» otherwise; the «Direct round» line goes to diag.log; the report gives its checks 15 s instead of 10
Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>
This commit is contained in:
1 parent
76000dfc49
commit
72de26d732
3 files changed
+32
-8
No files matched your search
+25
-2
@@ -38,11 +38,14 @@ import kotlinx.coroutines.coroutineScope
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.StateFlow
|
||||
import kotlinx.coroutines.flow.first
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.sync.Mutex
|
||||
import kotlinx.coroutines.withTimeoutOrNull
|
||||
import org.json.JSONArray
|
||||
import org.json.JSONException
|
||||
import org.json.JSONObject
|
||||
import org.strongswan.android.logic.DiagLog
|
||||
import org.strongswan.android.logic.VpnStateService
|
||||
import org.strongswan.android.logic.events.Events
|
||||
import java.util.concurrent.ConcurrentHashMap
|
||||
@@ -351,6 +354,23 @@ class WhiteListManager private constructor(private val context: Context) : VpnSt
|
||||
scope.launch { runCheck(force = true) }
|
||||
}
|
||||
|
||||
/**
|
||||
* Runs a probe round and waits for its result: the state of a round that
|
||||
* finished after this call, or null when none did within [timeoutMs]
|
||||
* (checks disabled, or the round is slower). A round already in flight
|
||||
* counts, so a busy cycle does not cost the whole timeout for nothing.
|
||||
*/
|
||||
suspend fun checkFresh(timeoutMs: Long): WhiteListState?
|
||||
{
|
||||
if (!running || !config.enabled)
|
||||
{
|
||||
return null
|
||||
}
|
||||
val before = _state.value.lastCheckMs
|
||||
checkNow()
|
||||
return withTimeoutOrNull(timeoutMs) { _state.first { it.lastCheckMs != before } }
|
||||
}
|
||||
|
||||
override fun stateChanged()
|
||||
{
|
||||
handler.post { onStateChanged() }
|
||||
@@ -434,8 +454,11 @@ class WhiteListManager private constructor(private val context: Context) : VpnSt
|
||||
val foreignLog = round.foreignOks.mapIndexed { index, ok ->
|
||||
"${targets.getOrNull(index)?.host ?: index}=${ok ?: "?"}/${round.foreignRttMs.getOrNull(index) ?: "-"}ms"
|
||||
}
|
||||
Log.i(TAG, "Direct round: ${foreignLog.joinToString(" ")}, " +
|
||||
"domestic=${round.domesticOk}/${round.domesticRttMs ?: "-"}ms -> $candidate")
|
||||
val roundLog = "Direct round: ${foreignLog.joinToString(" ")}, " +
|
||||
"domestic=${round.domesticOk}/${round.domesticRttMs ?: "-"}ms -> $candidate"
|
||||
Log.i(TAG, roundLog)
|
||||
/* also in the report: tells a stale verdict from a real failure */
|
||||
DiagLog.i(TAG, roundLog)
|
||||
val before = machine
|
||||
machine = before.advance(candidate)
|
||||
publish(round)
|
||||
|
||||
@@ -128,8 +128,8 @@ class ReportViewModel(app: Application) : AndroidViewModel(app)
|
||||
val note = comment
|
||||
val diag = attachDiag
|
||||
job = viewModelScope.launch {
|
||||
/* the same checks as the Diagnostics screen (~3 s); a hang must not block the report */
|
||||
val checks = if (!diag) null else withTimeoutOrNull(10_000) {
|
||||
/* the same checks as the Diagnostics screen (1-8 s); a hang must not block the report */
|
||||
val checks = if (!diag) null else withTimeoutOrNull(15_000) {
|
||||
runCatching { runDiagnostics(app) }.getOrNull()?.steps?.map { ReportContent.Check(it.title, it.value, it.ok) }
|
||||
}
|
||||
val result = withContext(Dispatchers.IO) {
|
||||
|
||||
+5
-4
@@ -97,13 +97,14 @@ internal suspend fun runDiagnostics(context: Context): DiagReport = coroutineSco
|
||||
val vpnUp = vpn?.state == VpnStateService.State.CONNECTED
|
||||
val gateway = (vpn?.profile)?.gateway
|
||||
val whiteList = WhiteListManager.getInstance(context)
|
||||
whiteList.checkNow()
|
||||
val server = async { if (gateway != null) ConnectivityProbe.probe(ProbeTarget.SERVER, 3000, context, gateway) else null }
|
||||
val foreign = async { ConnectivityProbe.probe(ProbeTarget.GOOGLE, 3000, context, null) }
|
||||
val network = withContext(Dispatchers.Default) { networkLabel(context) }
|
||||
/* the whitelist check runs its own direct round; give it a moment */
|
||||
delay(2500)
|
||||
val wl = whiteList.state.value
|
||||
/* the whitelist check runs its own direct round: wait for that very round, a
|
||||
* verdict left from an earlier one (say, a network outage) is not shown.
|
||||
* 8 s covers a round whose foreign probes time out and are retried. */
|
||||
val fresh = whiteList.checkFresh(8000)
|
||||
val wl = fresh ?: whiteList.state.value.copy(domesticDirectOk = null, domesticDirectRttMs = null)
|
||||
val serverResult = server.await()
|
||||
val foreignResult = foreign.await()
|
||||
val steps = listOf(
|
||||
|
||||
Reference in new issue
Block a user