Make Android VPN watchdog conservative under load

This commit is contained in:
2026-05-15 13:34:54 +03:00
parent e4a3e08876
commit 64c795f233
2 changed files with 33 additions and 2 deletions
+2 -2
View File
@@ -30,8 +30,8 @@ android {
applicationId "su.cin.rapvpn"
minSdk 26
targetSdk 35
versionCode 194
versionName "0.2.194"
versionCode 195
versionName "0.2.195"
buildConfigField "String", "DEFAULT_BACKEND_URL", "\"${normalizeGradleString(defaultBackendUrl)}\""
buildConfigField "String", "DEFAULT_CLUSTER_ID", "\"${normalizeGradleString(defaultClusterId)}\""
buildConfigField "String", "DEFAULT_ORGANIZATION_ID", "\"${normalizeGradleString(defaultOrganizationId)}\""
@@ -78,6 +78,9 @@ public class RapVpnService extends VpnService {
private static final int RUNTIME_STATUS_INTERVAL_MS = 500;
private static final int RUNTIME_WATCHDOG_INTERVAL_MS = 2000;
private static final int RUNTIME_WATCHDOG_STALE_SYNACK_MS = 7000;
private static final int RUNTIME_WATCHDOG_STALE_ROUNDS_BEFORE_RECOVERY = 3;
private static final int RUNTIME_WATCHDOG_STALE_SYNACKS_BEFORE_RECOVERY = 4;
private static final int RUNTIME_WATCHDOG_MAX_STALE_ROUNDS_BEFORE_RECOVERY = 6;
private static final int RUNTIME_WATCHDOG_RECOVERY_COOLDOWN_MS = 20000;
private static final int RUNTIME_WATCHDOG_HARD_RESTART_COOLDOWN_MS = 60000;
private static final int DIAGNOSTIC_WATCHDOG_INTERVAL_MS = 5000;
@@ -218,6 +221,9 @@ public class RapVpnService extends VpnService {
private volatile String shutdownReason = "service destroyed";
private volatile long lastRuntimeWatchdogRecoveryAt;
private volatile long lastRuntimeWatchdogHardRestartAt;
private volatile long lastRuntimeWatchdogDownlinkPackets;
private volatile long lastRuntimeWatchdogUplinkPackets;
private volatile int runtimeWatchdogStaleRounds;
private volatile long lastDiagnosticEnsureAt;
private volatile long lastDiagnosticStatusEnsureAt;
private volatile long lastDiagnosticRestartAt;
@@ -1360,6 +1366,11 @@ public class RapVpnService extends VpnService {
tcpHandshakeStalls.set(0);
runtimeWatchdogHardRestarts.set(0);
hardRuntimeRestartInProgress.set(false);
lastRuntimeWatchdogRecoveryAt = 0;
lastRuntimeWatchdogHardRestartAt = 0;
lastRuntimeWatchdogDownlinkPackets = 0;
lastRuntimeWatchdogUplinkPackets = 0;
runtimeWatchdogStaleRounds = 0;
downlinkDroppedPackets.set(0);
downlinkDroppedBytes.set(0);
downlinkTransportChecksumRepairs.set(0);
@@ -1539,12 +1550,32 @@ public class RapVpnService extends VpnService {
}
long now = System.currentTimeMillis();
int stale = staleTCPHandshakeCount();
long downlinkPackets = downlinkReceivedPackets.get();
long uplinkPackets = uplinkSentPackets.get();
boolean downlinkProgressed = downlinkPackets > lastRuntimeWatchdogDownlinkPackets;
boolean uplinkProgressed = uplinkPackets > lastRuntimeWatchdogUplinkPackets;
lastRuntimeWatchdogDownlinkPackets = downlinkPackets;
lastRuntimeWatchdogUplinkPackets = uplinkPackets;
if (stale <= 0) {
runtimeWatchdogStaleRounds = 0;
continue;
}
if (downlinkProgressed) {
runtimeWatchdogStaleRounds = 0;
writeRuntimeDetail("watchdog_observed_downlink", "stale=" + stale + " downlink_progress=true uplink_progress=" + uplinkProgressed, "watchdog", runtimeWatchdogRecoveries.get(), tcpHandshakeStalls.get(), "", -1);
continue;
}
runtimeWatchdogStaleRounds++;
if (runtimeWatchdogStaleRounds < RUNTIME_WATCHDOG_STALE_ROUNDS_BEFORE_RECOVERY
|| (stale < RUNTIME_WATCHDOG_STALE_SYNACKS_BEFORE_RECOVERY
&& runtimeWatchdogStaleRounds < RUNTIME_WATCHDOG_MAX_STALE_ROUNDS_BEFORE_RECOVERY)) {
writeRuntimeDetail("watchdog_waiting", "stale=" + stale + " rounds=" + runtimeWatchdogStaleRounds + " uplink_progress=" + uplinkProgressed, "watchdog", runtimeWatchdogRecoveries.get(), tcpHandshakeStalls.get(), "", -1);
continue;
}
if (now - lastRuntimeWatchdogRecoveryAt < RUNTIME_WATCHDOG_RECOVERY_COOLDOWN_MS) {
continue;
}
runtimeWatchdogStaleRounds = 0;
tcpHandshakeStalls.addAndGet(stale);
runtimeWatchdogRecoveries.incrementAndGet();
lastRuntimeWatchdogRecoveryAt = now;