Prioritize Android VPN control packets

This commit is contained in:
2026-05-15 19:12:33 +03:00
parent be25ff5725
commit 1dfeb79d53
3 changed files with 24 additions and 12 deletions
+2 -2
View File
@@ -30,8 +30,8 @@ android {
applicationId "su.cin.rapvpn"
minSdk 26
targetSdk 35
versionCode 204
versionName "0.2.204"
versionCode 205
versionName "0.2.205"
buildConfigField "String", "DEFAULT_BACKEND_URL", "\"${normalizeGradleString(defaultBackendUrl)}\""
buildConfigField "String", "DEFAULT_CLUSTER_ID", "\"${normalizeGradleString(defaultClusterId)}\""
buildConfigField "String", "DEFAULT_ORGANIZATION_ID", "\"${normalizeGradleString(defaultOrganizationId)}\""
@@ -442,7 +442,7 @@ public class RapDiagnosticService extends Service {
} else if ("http_get".equals(type)) {
result = runHttpGet(params.optString("url", "http://192.168.200.61:18080/"));
} else if ("vpn_http_get".equals(type)) {
result = runVPNHttpGet(params.optString("url", "http://192.168.200.61:18080/"));
result = runVPNHttpGet(params.optString("url", "http://192.168.200.61:18080/"), params.optInt("timeout_ms", 15000));
} else if ("vpn_page_probe".equals(type)) {
result = runVPNPageProbe(params);
} else if ("vpn_tcp_connect".equals(type) || "vpn_rdp_probe".equals(type)) {
@@ -679,7 +679,7 @@ public class RapDiagnosticService extends Service {
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/"));
return runVPNHttpGet(payload.optString("url", "http://192.168.200.61:18080/"), payload.optInt("timeout_ms", 15000));
}
if ("vpn_page_probe".equals(type)) {
return runVPNPageProbe(payload);
@@ -1167,8 +1167,8 @@ public class RapDiagnosticService extends Service {
result.append("network={").append(deviceNetworkSnapshot()).append("}");
result.append(" | stats=").append(collectVPNStats(client, clusterId));
result.append(" | dns=").append(runVPNDNSLookup(host));
result.append(" | vpn_http=").append(runVPNHttpGet(url));
result.append(" | vpn_local_http=").append(runVPNHttpGet(localUrl));
result.append(" | vpn_http=").append(runVPNHttpGet(url, 15000));
result.append(" | vpn_local_http=").append(runVPNHttpGet(localUrl, 15000));
result.append(" | download=").append(runVPNDownloadTest(payload.optString("download_url", "http://192.168.200.61:18080/downloads/rap-android-rdp-vpn-build.json")));
return compact(result.toString(), 2500);
}
@@ -1501,7 +1501,10 @@ public class RapDiagnosticService extends Service {
}
}
private String runVPNHttpGet(String target) {
private String runVPNHttpGet(String target, int timeoutMs) {
int effectiveTimeoutMs = Math.max(1000, Math.min(timeoutMs, 30000));
int connectTimeoutMs = Math.max(1000, Math.min(effectiveTimeoutMs, 10000));
int readTimeoutMs = Math.max(1000, effectiveTimeoutMs - connectTimeoutMs);
try {
Network vpn = vpnNetwork();
if (vpn == null) {
@@ -1521,8 +1524,8 @@ public class RapDiagnosticService extends Service {
connection = (HttpURLConnection) vpn.openConnection(url);
}
try {
connection.setConnectTimeout(15000);
connection.setReadTimeout(15000);
connection.setConnectTimeout(connectTimeoutMs);
connection.setReadTimeout(readTimeoutMs);
connection.setInstanceFollowRedirects(false);
int code = connection.getResponseCode();
connection.disconnect();
@@ -1535,8 +1538,8 @@ public class RapDiagnosticService extends Service {
URL resolvedURL = new URL(url.getProtocol(), fallbackResolved, url.getPort(), url.getFile());
connection = (HttpURLConnection) vpn.openConnection(resolvedURL);
connection.setRequestProperty("Host", hostHeader(url));
connection.setConnectTimeout(15000);
connection.setReadTimeout(15000);
connection.setConnectTimeout(connectTimeoutMs);
connection.setReadTimeout(readTimeoutMs);
connection.setInstanceFollowRedirects(false);
int code = connection.getResponseCode();
connection.disconnect();
@@ -2281,7 +2281,16 @@ public class RapVpnService extends VpnService {
boolean syn = (flow.flags & 0x02) != 0;
boolean fin = (flow.flags & 0x01) != 0;
boolean rst = (flow.flags & 0x04) != 0;
return syn || fin || rst;
boolean ack = (flow.flags & 0x10) != 0;
boolean psh = (flow.flags & 0x08) != 0;
int ipTotalLength = u16(packet, 2);
if (ipTotalLength <= 0 || ipTotalLength > length) {
ipTotalLength = length;
}
int ihl = (packet[0] & 0x0f) * 4;
int tcpHeaderLength = ((packet[ihl + 12] >> 4) & 0x0f) * 4;
int tcpPayloadLength = Math.max(0, ipTotalLength - ihl - tcpHeaderLength);
return syn || fin || rst || (ack && tcpPayloadLength == 0) || (psh && tcpPayloadLength <= 96);
}
private boolean clampIPv4TCPMSS(byte[] packet, int length, int maxMss) {