Recover Android VPN probes after first stall
This commit is contained in:
@@ -30,8 +30,8 @@ android {
|
||||
applicationId "su.cin.rapvpn"
|
||||
minSdk 26
|
||||
targetSdk 35
|
||||
versionCode 185
|
||||
versionName "0.2.185"
|
||||
versionCode 186
|
||||
versionName "0.2.186"
|
||||
buildConfigField "String", "DEFAULT_BACKEND_URL", "\"${normalizeGradleString(defaultBackendUrl)}\""
|
||||
buildConfigField "String", "DEFAULT_CLUSTER_ID", "\"${normalizeGradleString(defaultClusterId)}\""
|
||||
buildConfigField "String", "DEFAULT_ORGANIZATION_ID", "\"${normalizeGradleString(defaultOrganizationId)}\""
|
||||
|
||||
@@ -69,6 +69,10 @@ public class RapDiagnosticService extends Service {
|
||||
private static final long COMMAND_STALE_MS = 45000;
|
||||
private static final long COMMAND_ORPHAN_MS = 60000;
|
||||
private static final long POLL_FORCE_MS = 45000;
|
||||
private static final int RECOVERY_TCP_TIMEOUT_MS = 8000;
|
||||
private static final int RECOVERY_PAGE_TIMEOUT_MS = 25000;
|
||||
private static final int RECOVERY_DOWNLOAD_CONNECT_TIMEOUT_MS = 8000;
|
||||
private static final int RECOVERY_DOWNLOAD_READ_TIMEOUT_MS = 12000;
|
||||
private volatile boolean running;
|
||||
private Thread worker;
|
||||
private Thread supervisor;
|
||||
@@ -478,14 +482,14 @@ public class RapDiagnosticService extends Service {
|
||||
}
|
||||
if (isRecoverableVPNProbe(type) && looksLikeVPNStall(result)) {
|
||||
String firstResult = result;
|
||||
Thread.sleep(1500);
|
||||
String fastRetry = runVPNProbeCommand(type, params);
|
||||
if (!looksLikeVPNStall(fastRetry)) {
|
||||
result = firstResult + " | fast_retry=" + fastRetry;
|
||||
} else {
|
||||
String recovery = controlledRestartVPNRuntime(client, clusterId);
|
||||
Thread.sleep(4000);
|
||||
result = firstResult + " | fast_retry=" + fastRetry + " | recovery=" + recovery + " | retry=" + runVPNProbeCommand(type, params);
|
||||
Thread.sleep(2500);
|
||||
String recoveryRetry = runVPNProbeCommand(type, recoveryProbePayload(type, params), true);
|
||||
if (!looksLikeVPNStall(recoveryRetry)) {
|
||||
result = firstResult + " | recovery=" + recovery + " | recovery_retry=" + recoveryRetry;
|
||||
} else {
|
||||
Thread.sleep(1500);
|
||||
result = firstResult + " | recovery=" + recovery + " | recovery_retry=" + recoveryRetry + " | final_retry=" + runVPNProbeCommand(type, recoveryProbePayload(type, params), true);
|
||||
}
|
||||
}
|
||||
lastCommandType = type;
|
||||
@@ -661,6 +665,10 @@ public class RapDiagnosticService extends Service {
|
||||
}
|
||||
|
||||
private String runVPNProbeCommand(String type, JSONObject payload) {
|
||||
return runVPNProbeCommand(type, payload, false);
|
||||
}
|
||||
|
||||
private String runVPNProbeCommand(String type, JSONObject payload, boolean recoveryAttempt) {
|
||||
if ("vpn_http_get".equals(type)) {
|
||||
return runVPNHttpGet(payload.optString("url", "http://192.168.200.61:18080/"));
|
||||
}
|
||||
@@ -671,11 +679,37 @@ public class RapDiagnosticService extends Service {
|
||||
return runVPNTCPConnect(payload.optString("host", "192.168.200.95"), payload.optInt("port", 3389), payload.optInt("timeout_ms", 7000));
|
||||
}
|
||||
if ("vpn_download_test".equals(type)) {
|
||||
if (recoveryAttempt) {
|
||||
return runVPNDownloadTest(
|
||||
payload.optString("url", "http://192.168.200.61:18080/downloads/rap-android-rdp-vpn-build.json"),
|
||||
RECOVERY_DOWNLOAD_CONNECT_TIMEOUT_MS,
|
||||
RECOVERY_DOWNLOAD_READ_TIMEOUT_MS);
|
||||
}
|
||||
return runVPNDownloadTest(payload.optString("url", "http://192.168.200.61:18080/downloads/rap-android-rdp-vpn-build.json"));
|
||||
}
|
||||
return "retry skipped: unsupported probe " + type;
|
||||
}
|
||||
|
||||
private JSONObject recoveryProbePayload(String type, JSONObject payload) {
|
||||
JSONObject copy;
|
||||
try {
|
||||
copy = payload == null ? new JSONObject() : new JSONObject(payload.toString());
|
||||
} catch (Exception e) {
|
||||
copy = new JSONObject();
|
||||
}
|
||||
try {
|
||||
if ("vpn_tcp_connect".equals(type) || "vpn_rdp_probe".equals(type)) {
|
||||
int requested = copy.optInt("timeout_ms", RECOVERY_TCP_TIMEOUT_MS);
|
||||
copy.put("timeout_ms", Math.max(1000, Math.min(requested, RECOVERY_TCP_TIMEOUT_MS)));
|
||||
} else if ("vpn_page_probe".equals(type)) {
|
||||
int requested = copy.optInt("timeout_ms", RECOVERY_PAGE_TIMEOUT_MS);
|
||||
copy.put("timeout_ms", Math.max(10000, Math.min(requested, RECOVERY_PAGE_TIMEOUT_MS)));
|
||||
}
|
||||
} catch (Exception ignored) {
|
||||
}
|
||||
return copy;
|
||||
}
|
||||
|
||||
private String controlledRestartVPNRuntime(RapApiClient client, String clusterId) {
|
||||
SharedPreferences prefs = getSharedPreferences(PREFS, MODE_PRIVATE);
|
||||
String connectionId = prefs.getString(PREF_VPN_CONNECTION_ID, "");
|
||||
@@ -1051,6 +1085,10 @@ public class RapDiagnosticService extends Service {
|
||||
}
|
||||
|
||||
private String runVPNDownloadTest(String target) {
|
||||
return runVPNDownloadTest(target, 15000, 20000);
|
||||
}
|
||||
|
||||
private String runVPNDownloadTest(String target, int connectTimeoutMs, int readTimeoutMs) {
|
||||
try {
|
||||
Network vpn = waitForVPNNetwork(5000);
|
||||
if (vpn == null) {
|
||||
@@ -1058,8 +1096,8 @@ public class RapDiagnosticService extends Service {
|
||||
}
|
||||
URL url = new URL(target);
|
||||
HttpURLConnection connection = (HttpURLConnection) vpn.openConnection(url);
|
||||
connection.setConnectTimeout(15000);
|
||||
connection.setReadTimeout(20000);
|
||||
connection.setConnectTimeout(Math.max(1000, connectTimeoutMs));
|
||||
connection.setReadTimeout(Math.max(1000, readTimeoutMs));
|
||||
connection.setInstanceFollowRedirects(false);
|
||||
int code = connection.getResponseCode();
|
||||
int bytes = 0;
|
||||
|
||||
Reference in New Issue
Block a user