Improve Android VPN mixed-load QoS
This commit is contained in:
@@ -30,8 +30,8 @@ android {
|
||||
applicationId "su.cin.rapvpn"
|
||||
minSdk 26
|
||||
targetSdk 35
|
||||
versionCode 207
|
||||
versionName "0.2.207"
|
||||
versionCode 208
|
||||
versionName "0.2.208"
|
||||
buildConfigField "String", "DEFAULT_BACKEND_URL", "\"${normalizeGradleString(defaultBackendUrl)}\""
|
||||
buildConfigField "String", "DEFAULT_CLUSTER_ID", "\"${normalizeGradleString(defaultClusterId)}\""
|
||||
buildConfigField "String", "DEFAULT_ORGANIZATION_ID", "\"${normalizeGradleString(defaultOrganizationId)}\""
|
||||
|
||||
@@ -21,6 +21,7 @@ import android.os.Looper;
|
||||
import android.provider.Settings;
|
||||
import android.widget.Toast;
|
||||
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import java.net.DatagramPacket;
|
||||
@@ -472,6 +473,8 @@ public class RapDiagnosticService extends Service {
|
||||
result = runVPNDeepTest(client, clusterId, params);
|
||||
} else if ("vpn_download_test".equals(type)) {
|
||||
result = runVPNDownloadTest(params.optString("url", "http://192.168.200.61:18080/downloads/rap-android-rdp-vpn-build.json"));
|
||||
} else if ("vpn_mixed_load_test".equals(type) || "vpn_parallel_http_get".equals(type)) {
|
||||
result = runVPNMixedLoadTest(params);
|
||||
} else if ("launch_telegram".equals(type)) {
|
||||
result = openExternalURL(params.optString("url", "tg://resolve?domain=telegram"));
|
||||
} else if ("remote_assist_start".equals(type)) {
|
||||
@@ -1222,6 +1225,92 @@ public class RapDiagnosticService extends Service {
|
||||
}
|
||||
}
|
||||
|
||||
private String runVPNMixedLoadTest(JSONObject payload) {
|
||||
int parallel = payload.optInt("parallel", 12);
|
||||
if (parallel < 1) {
|
||||
parallel = 1;
|
||||
}
|
||||
if (parallel > 20) {
|
||||
parallel = 20;
|
||||
}
|
||||
int timeoutMs = payload.optInt("timeout_ms", 20000);
|
||||
if (timeoutMs < 3000) {
|
||||
timeoutMs = 3000;
|
||||
}
|
||||
if (timeoutMs > 45000) {
|
||||
timeoutMs = 45000;
|
||||
}
|
||||
String rdpHost = payload.optString("rdp_host", "192.168.200.95");
|
||||
int rdpPort = payload.optInt("rdp_port", 3389);
|
||||
String[] defaults = new String[] {
|
||||
"http://2ip.ru/",
|
||||
"http://example.com/",
|
||||
"http://neverssl.com/",
|
||||
"http://192.168.200.61:18080/downloads/rap-android-rdp-vpn-build.json",
|
||||
"http://192.168.200.61:18080/"
|
||||
};
|
||||
List<String> urls = new ArrayList<>();
|
||||
JSONArray payloadUrls = payload.optJSONArray("urls");
|
||||
if (payloadUrls != null) {
|
||||
for (int i = 0; i < payloadUrls.length(); i++) {
|
||||
String url = payloadUrls.optString(i, "");
|
||||
if (url != null && !url.trim().isEmpty()) {
|
||||
urls.add(url.trim());
|
||||
}
|
||||
}
|
||||
}
|
||||
if (urls.isEmpty()) {
|
||||
for (String url : defaults) {
|
||||
urls.add(url);
|
||||
}
|
||||
}
|
||||
String rdpBefore = runVPNTCPConnect(rdpHost, rdpPort, Math.min(timeoutMs, 10000));
|
||||
String[] results = new String[parallel];
|
||||
Thread[] threads = new Thread[parallel];
|
||||
final int requestTimeoutMs = timeoutMs;
|
||||
long started = System.currentTimeMillis();
|
||||
for (int i = 0; i < parallel; i++) {
|
||||
final int index = i;
|
||||
final String target = urls.get(i % urls.size());
|
||||
threads[i] = new Thread(() -> results[index] = runVPNHttpGet(target, requestTimeoutMs), "rap-vpn-load-test-" + index);
|
||||
threads[i].start();
|
||||
}
|
||||
for (Thread thread : threads) {
|
||||
try {
|
||||
thread.join(timeoutMs + 5000L);
|
||||
} catch (InterruptedException e) {
|
||||
Thread.currentThread().interrupt();
|
||||
break;
|
||||
}
|
||||
}
|
||||
long elapsed = System.currentTimeMillis() - started;
|
||||
int ok = 0;
|
||||
int failed = 0;
|
||||
StringBuilder sample = new StringBuilder();
|
||||
for (int i = 0; i < results.length; i++) {
|
||||
String item = results[i];
|
||||
if (item != null && item.contains("-> HTTP ")) {
|
||||
ok++;
|
||||
} else {
|
||||
failed++;
|
||||
}
|
||||
if (i < 5) {
|
||||
if (sample.length() > 0) {
|
||||
sample.append("; ");
|
||||
}
|
||||
sample.append(item == null ? "timeout/no_result" : item);
|
||||
}
|
||||
}
|
||||
String rdpAfter = runVPNTCPConnect(rdpHost, rdpPort, Math.min(timeoutMs, 10000));
|
||||
return compact("vpn_mixed_load_test parallel=" + parallel
|
||||
+ " ok=" + ok
|
||||
+ " failed=" + failed
|
||||
+ " elapsed_ms=" + elapsed
|
||||
+ " rdp_before={" + rdpBefore + "}"
|
||||
+ " rdp_after={" + rdpAfter + "}"
|
||||
+ " sample={" + sample + "}", 2500);
|
||||
}
|
||||
|
||||
private String openExternalURL(String target) {
|
||||
try {
|
||||
Intent open = new Intent(Intent.ACTION_VIEW, Uri.parse(target));
|
||||
|
||||
@@ -56,7 +56,8 @@ public class RapVpnService extends VpnService {
|
||||
private static final boolean PACKET_WEBSOCKET_DATAPLANE_ENABLED = true;
|
||||
private static final int VPN_BATCH_MAX_PACKETS = 512;
|
||||
private static final int VPN_BATCH_MAX_BYTES = 1024 * 1024;
|
||||
private static final int UPLINK_WORKER_MAX_COUNT = 1;
|
||||
private static final int UPLINK_WORKER_MIN_COUNT = 4;
|
||||
private static final int UPLINK_WORKER_MAX_COUNT = 4;
|
||||
private static final int UPLINK_QUEUE_CAPACITY = 32768;
|
||||
private static final int PRIORITY_QUEUE_CAPACITY = 4096;
|
||||
private static final int UPLINK_SEND_RETRY_COUNT = 2;
|
||||
@@ -1028,10 +1029,7 @@ public class RapVpnService extends VpnService {
|
||||
running = true;
|
||||
long runtimeId = runtimeGeneration.incrementAndGet();
|
||||
runtimeStartedAt = System.currentTimeMillis();
|
||||
uplinkWorkerCount = Math.max(1, Math.min(UPLINK_WORKER_MAX_COUNT, Math.max(1, Runtime.getRuntime().availableProcessors() - 1)));
|
||||
if (uplinkWorkerCount < 2) {
|
||||
uplinkWorkerCount = 1;
|
||||
}
|
||||
uplinkWorkerCount = Math.max(UPLINK_WORKER_MIN_COUNT, Math.min(UPLINK_WORKER_MAX_COUNT, Math.max(1, Runtime.getRuntime().availableProcessors())));
|
||||
uplinkQueueOffersByWorker = createAtomicCounters(uplinkWorkerCount);
|
||||
uplinkQueueDropsByWorker = createAtomicCounters(uplinkWorkerCount);
|
||||
uplinkSenderPacketsByWorker = createAtomicCounters(uplinkWorkerCount);
|
||||
@@ -2290,7 +2288,8 @@ public class RapVpnService extends VpnService {
|
||||
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);
|
||||
boolean rdp = flow.srcPort == 3389 || flow.dstPort == 3389;
|
||||
return rdp || syn || fin || rst || (ack && tcpPayloadLength == 0) || (psh && tcpPayloadLength <= 96);
|
||||
}
|
||||
|
||||
private boolean clampIPv4TCPMSS(byte[] packet, int length, int maxMss) {
|
||||
|
||||
Reference in New Issue
Block a user