Recover Android VPN faster on RDP stalls

This commit is contained in:
2026-05-15 23:04:14 +03:00
parent d2cd83a2be
commit fdf176bc5d
2 changed files with 25 additions and 4 deletions
+2 -2
View File
@@ -30,8 +30,8 @@ android {
applicationId "su.cin.rapvpn"
minSdk 26
targetSdk 35
versionCode 208
versionName "0.2.208"
versionCode 209
versionName "0.2.209"
buildConfigField "String", "DEFAULT_BACKEND_URL", "\"${normalizeGradleString(defaultBackendUrl)}\""
buildConfigField "String", "DEFAULT_CLUSTER_ID", "\"${normalizeGradleString(defaultClusterId)}\""
buildConfigField "String", "DEFAULT_ORGANIZATION_ID", "\"${normalizeGradleString(defaultOrganizationId)}\""
@@ -79,6 +79,7 @@ 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_RDP_STALE_SYNACK_MS = 4000;
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;
@@ -1601,6 +1602,7 @@ public class RapVpnService extends VpnService {
}
long now = System.currentTimeMillis();
int stale = staleTCPHandshakeCount();
int rdpStale = staleRdpTCPHandshakeCount();
long downlinkPackets = downlinkReceivedPackets.get();
long uplinkPackets = uplinkSentPackets.get();
boolean downlinkProgressed = downlinkPackets > lastRuntimeWatchdogDownlinkPackets;
@@ -1616,10 +1618,18 @@ public class RapVpnService extends VpnService {
}
if (downlinkProgressed) {
runtimeWatchdogStaleRounds = 0;
writeRuntimeDetail("watchdog_observed_downlink", "stale=" + stale + " downlink_progress=true uplink_progress=" + uplinkProgressed, "watchdog", runtimeWatchdogRecoveries.get(), tcpHandshakeStalls.get(), "", -1);
writeRuntimeDetail("watchdog_observed_downlink", "stale=" + stale + " rdp_stale=" + rdpStale + " downlink_progress=true uplink_progress=" + uplinkProgressed, "watchdog", runtimeWatchdogRecoveries.get(), tcpHandshakeStalls.get(), "", -1);
continue;
}
runtimeWatchdogStaleRounds++;
if (rdpStale > 0 && now - lastRuntimeWatchdogRecoveryAt >= RUNTIME_WATCHDOG_RECOVERY_COOLDOWN_MS) {
runtimeWatchdogStaleRounds = 0;
tcpHandshakeStalls.addAndGet(rdpStale);
runtimeWatchdogRecoveries.incrementAndGet();
lastRuntimeWatchdogRecoveryAt = now;
recoverPacketRelayRuntime(clusterId, vpnConnectionId, "rdp_tcp_handshake_stall stale=" + rdpStale);
continue;
}
boolean relayOpen = isPacketWebSocketRelayOpen();
boolean recentDownlink = lastRuntimeWatchdogDownlinkProgressAt > 0
&& now - lastRuntimeWatchdogDownlinkProgressAt < RUNTIME_WATCHDOG_RECENT_DOWNLINK_GRACE_MS;
@@ -1795,6 +1805,14 @@ public class RapVpnService extends VpnService {
}
private int staleTCPHandshakeCount() {
return staleTCPHandshakeCount(RUNTIME_WATCHDOG_STALE_SYNACK_MS, false);
}
private int staleRdpTCPHandshakeCount() {
return staleTCPHandshakeCount(RUNTIME_WATCHDOG_RDP_STALE_SYNACK_MS, true);
}
private int staleTCPHandshakeCount(int staleAfterMs, boolean rdpOnly) {
long now = System.currentTimeMillis();
int stale = 0;
synchronized (pendingTcpHandshakes) {
@@ -1811,7 +1829,10 @@ public class RapVpnService extends VpnService {
remove.add(entry.getKey());
continue;
}
if (age >= RUNTIME_WATCHDOG_STALE_SYNACK_MS) {
if (rdpOnly && !entry.getKey().contains("|3389|")) {
continue;
}
if (age >= staleAfterMs) {
stale++;
}
}