mirror of
https://github.com/CherretGit/zaprett-app.git
synced 2025-12-10 13:39:41 +05:00
rewrite JNI to Rust
This commit is contained in:
2
.gitmodules
vendored
2
.gitmodules
vendored
@@ -1,5 +1,5 @@
|
||||
[submodule "app/src/main/cpp/byedpi"]
|
||||
path = app/src/main/cpp/byedpi
|
||||
path = app/src/main/rust/byedpi
|
||||
url = https://github.com/hufrea/byedpi
|
||||
[submodule "app/src/main/jni/hev-socks5-tunnel"]
|
||||
path = app/src/main/jni/hev-socks5-tunnel
|
||||
|
||||
4
.idea/deploymentTargetSelector.xml
generated
4
.idea/deploymentTargetSelector.xml
generated
@@ -4,10 +4,10 @@
|
||||
<selectionStates>
|
||||
<SelectionState runConfigName="app">
|
||||
<option name="selectionMode" value="DROPDOWN" />
|
||||
<DropdownSelection timestamp="2025-07-09T09:45:05.074315845Z">
|
||||
<DropdownSelection timestamp="2025-10-03T07:21:08.712998131Z">
|
||||
<Target type="DEFAULT_BOOT">
|
||||
<handle>
|
||||
<DeviceId pluginId="LocalEmulator" identifier="path=/home/white/.android/avd/Pixel_8.avd" />
|
||||
<DeviceId pluginId="LocalEmulator" identifier="path=/home/dimap/.android/avd/Medium_Phone.avd" />
|
||||
</handle>
|
||||
</Target>
|
||||
</DropdownSelection>
|
||||
|
||||
13
.idea/deviceManager.xml
generated
Normal file
13
.idea/deviceManager.xml
generated
Normal file
@@ -0,0 +1,13 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="DeviceTable">
|
||||
<option name="columnSorters">
|
||||
<list>
|
||||
<ColumnSorterState>
|
||||
<option name="column" value="Name" />
|
||||
<option name="order" value="ASCENDING" />
|
||||
</ColumnSorterState>
|
||||
</list>
|
||||
</option>
|
||||
</component>
|
||||
</project>
|
||||
1
.idea/vcs.xml
generated
1
.idea/vcs.xml
generated
@@ -8,5 +8,6 @@
|
||||
<mapping directory="$PROJECT_DIR$/app/src/main/jni/hev-socks5-tunnel/third-part/hev-task-system" vcs="Git" />
|
||||
<mapping directory="$PROJECT_DIR$/app/src/main/jni/hev-socks5-tunnel/third-part/lwip" vcs="Git" />
|
||||
<mapping directory="$PROJECT_DIR$/app/src/main/jni/hev-socks5-tunnel/third-part/yaml" vcs="Git" />
|
||||
<mapping directory="$PROJECT_DIR$/rust/byedpi" vcs="Git" />
|
||||
</component>
|
||||
</project>
|
||||
@@ -5,6 +5,7 @@ plugins {
|
||||
id("com.google.gms.google-services")
|
||||
id("com.google.firebase.crashlytics")
|
||||
kotlin("plugin.serialization") version "2.1.20"
|
||||
id("org.mozilla.rust-android-gradle.rust-android") version "0.9.6"
|
||||
}
|
||||
|
||||
android {
|
||||
@@ -19,15 +20,6 @@ android {
|
||||
versionName = "2.9"
|
||||
|
||||
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
|
||||
ndk {
|
||||
abiFilters += listOf("armeabi-v7a", "arm64-v8a", "x86", "x86_64")
|
||||
}
|
||||
}
|
||||
externalNativeBuild {
|
||||
cmake {
|
||||
path = file("src/main/cpp/CMakeLists.txt")
|
||||
version = "3.22.1"
|
||||
}
|
||||
}
|
||||
buildTypes {
|
||||
release {
|
||||
@@ -75,6 +67,26 @@ tasks.preBuild {
|
||||
dependsOn("runNdkBuild")
|
||||
}
|
||||
|
||||
cargo {
|
||||
module = "../rust"
|
||||
libname = "byedpi"
|
||||
targets = listOf("arm", "arm64", "x86", "x86_64")
|
||||
}
|
||||
|
||||
tasks.preBuild {
|
||||
dependsOn("cargoBuild")
|
||||
}
|
||||
|
||||
tasks.register<Exec>("cargoClean") {
|
||||
workingDir = file("../rust")
|
||||
commandLine("cargo", "clean")
|
||||
group = "build"
|
||||
}
|
||||
|
||||
tasks.named("clean") {
|
||||
dependsOn("cargoClean")
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation(libs.compose.material3)
|
||||
implementation(libs.compose.material3.window.size)
|
||||
|
||||
Submodule app/src/main/cpp/byedpi deleted from 7efde1b129
@@ -1,83 +0,0 @@
|
||||
#define VERSION "17.1"
|
||||
union sockaddr_u;
|
||||
|
||||
int get_default_ttl(void);
|
||||
|
||||
int get_addr(const char *str, union sockaddr_u *addr);
|
||||
|
||||
void *add(void **root, int *n, size_t ss);
|
||||
|
||||
void clear_params(void);
|
||||
|
||||
char *ftob(const char *str, ssize_t *sl);
|
||||
|
||||
char *data_from_str(const char *str, ssize_t *size);
|
||||
|
||||
size_t parse_cform(char *buffer, size_t blen, const char *str, size_t slen);
|
||||
|
||||
struct mphdr *parse_hosts(char *buffer, size_t size);
|
||||
|
||||
struct mphdr *parse_ipset(char *buffer, size_t size);
|
||||
|
||||
int parse_offset(struct part *part, const char *str);
|
||||
|
||||
static const char help_text[] = {
|
||||
" -i, --ip, <ip> Listening IP, default 0.0.0.0\n"
|
||||
" -p, --port <num> Listening port, default 1080\n"
|
||||
#ifdef DAEMON
|
||||
" -D, --daemon Daemonize\n"
|
||||
" -w, --pidfile <filename> Write PID to file\n"
|
||||
#endif
|
||||
#ifdef __linux__
|
||||
" -E, --transparent Transparent proxy mode\n"
|
||||
#endif
|
||||
" -c, --max-conn <count> Connection count limit, default 512\n"
|
||||
" -N, --no-domain Deny domain resolving\n"
|
||||
" -U, --no-udp Deny UDP association\n"
|
||||
" -I --conn-ip <ip> Connection binded IP, default ::\n"
|
||||
" -b, --buf-size <size> Buffer size, default 16384\n"
|
||||
" -x, --debug <level> Print logs, 0, 1 or 2\n"
|
||||
" -g, --def-ttl <num> TTL for all outgoing connections\n"
|
||||
// desync options
|
||||
#ifdef TCP_FASTOPEN_CONNECT
|
||||
" -F, --tfo Enable TCP Fast Open\n"
|
||||
#endif
|
||||
" -A, --auto <t,r,s,n> Try desync params after this option\n"
|
||||
" Detect: torst,redirect,ssl_err,none\n"
|
||||
" -L, --auto-mode <0-3> Mode: 1 - post_resp, 2 - sort, 3 - 1+2\n"
|
||||
" -u, --cache-ttl <sec> Lifetime of cached desync params for IP\n"
|
||||
" -y, --cache-dump <file|-> Dump cache to file or stdout\n"
|
||||
#ifdef TIMEOUT_SUPPORT
|
||||
" -T, --timeout <sec> Timeout waiting for response, after which trigger auto\n"
|
||||
#endif
|
||||
" -K, --proto <t,h,u,i> Protocol whitelist: tls,http,udp,ipv4\n"
|
||||
" -H, --hosts <file|:str> Hosts whitelist, filename or :string\n"
|
||||
" -j, --ipset <file|:str> IP whitelist\n"
|
||||
" -V, --pf <port[-portr]> Ports range whitelist\n"
|
||||
" -R, --round <num[-numr]> Number of request to which desync will be applied\n"
|
||||
" -s, --split <pos_t> Position format: offset[:repeats:skip][+flag1[flag2]]\n"
|
||||
" Flags: +s - SNI offset, +h - HTTP host offset, +n - null\n"
|
||||
" Additional flags: +e - end, +m - middle\n"
|
||||
" -d, --disorder <pos_t> Split and send reverse order\n"
|
||||
" -o, --oob <pos_t> Split and send as OOB data\n"
|
||||
" -q, --disoob <pos_t> Split and send reverse order as OOB data\n"
|
||||
#ifdef FAKE_SUPPORT
|
||||
" -f, --fake <pos_t> Split and send fake packet\n"
|
||||
#ifdef __linux__
|
||||
" -S, --md5sig Add MD5 Signature option for fake packets\n"
|
||||
#endif
|
||||
" -n, --fake-sni <str> Change SNI in fake\n"
|
||||
" Replaced: ? - rand let, # - rand num, * - rand let/num\n"
|
||||
#endif
|
||||
" -t, --ttl <num> TTL of fake packets, default 8\n"
|
||||
" -O, --fake-offset <pos_t> Fake data start offset\n"
|
||||
" -l, --fake-data <f|:str> Set custom fake packet\n"
|
||||
" -Q, --fake-tls-mod <r,o> Modify fake TLS CH: rand,orig\n"
|
||||
" -e, --oob-data <char> Set custom OOB data\n"
|
||||
" -M, --mod-http <h,d,r> Modify HTTP: hcsmix,dcsmix,rmspace\n"
|
||||
" -r, --tlsrec <pos_t> Make TLS record at position\n"
|
||||
" -a, --udp-fake <count> UDP fakes count, default 0\n"
|
||||
#ifdef __linux__
|
||||
" -Y, --drop-sack Drop packets with SACK extension\n"
|
||||
#endif
|
||||
};
|
||||
@@ -1,100 +0,0 @@
|
||||
#include <string.h>
|
||||
|
||||
#include <jni.h>
|
||||
#include <android/log.h>
|
||||
#include <malloc.h>
|
||||
|
||||
#include "byedpi/error.h"
|
||||
#include "byedpi/proxy.h"
|
||||
#include "utils.h"
|
||||
|
||||
static int g_proxy_fd = -1;
|
||||
|
||||
JNIEXPORT jint JNI_OnLoad(
|
||||
__attribute__((unused)) JavaVM *vm,
|
||||
__attribute__((unused)) void *reserved) {
|
||||
default_params = params;
|
||||
return JNI_VERSION_1_6;
|
||||
}
|
||||
|
||||
JNIEXPORT jint JNICALL
|
||||
Java_com_cherret_zaprett_byedpi_NativeBridge_jniCreateSocket(
|
||||
JNIEnv *env,
|
||||
__attribute__((unused)) jobject thiz,
|
||||
jobjectArray args) {
|
||||
|
||||
if (g_proxy_fd != -1) {
|
||||
LOG(LOG_S, "proxy already running, fd: %d", g_proxy_fd);
|
||||
return -1;
|
||||
}
|
||||
|
||||
int argc = (*env)->GetArrayLength(env, args);
|
||||
char *argv[argc];
|
||||
for (int i = 0; i < argc; i++) {
|
||||
jstring arg = (jstring) (*env)->GetObjectArrayElement(env, args, i);
|
||||
const char *arg_str = (*env)->GetStringUTFChars(env, arg, 0);
|
||||
argv[i] = strdup(arg_str);
|
||||
(*env)->ReleaseStringUTFChars(env, arg, arg_str);
|
||||
}
|
||||
|
||||
int res = parse_args(argc, argv);
|
||||
|
||||
if (res < 0) {
|
||||
uniperror("parse_args");
|
||||
return -1;
|
||||
}
|
||||
|
||||
int fd = listen_socket((union sockaddr_u *)¶ms.laddr);
|
||||
|
||||
for (int i = 0; i < argc; i++) {
|
||||
free(argv[i]);
|
||||
}
|
||||
|
||||
if (fd < 0) {
|
||||
uniperror("listen_socket");
|
||||
return -1;
|
||||
}
|
||||
|
||||
g_proxy_fd = fd;
|
||||
LOG(LOG_S, "listen_socket, fd: %d", fd);
|
||||
return fd;
|
||||
}
|
||||
|
||||
JNIEXPORT jint JNICALL
|
||||
Java_com_cherret_zaprett_byedpi_NativeBridge_jniStartProxy(
|
||||
__attribute__((unused)) JNIEnv *env,
|
||||
__attribute__((unused)) jobject thiz) {
|
||||
|
||||
LOG(LOG_S, "start_proxy, fd: %d", g_proxy_fd);
|
||||
|
||||
if (start_event_loop(g_proxy_fd) < 0) {
|
||||
uniperror("event_loop");
|
||||
return get_e();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
JNIEXPORT jint JNICALL
|
||||
Java_com_cherret_zaprett_byedpi_NativeBridge_jniStopProxy(
|
||||
__attribute__((unused)) JNIEnv *env,
|
||||
__attribute__((unused)) jobject thiz) {
|
||||
|
||||
LOG(LOG_S, "stop_proxy, fd: %d", g_proxy_fd);
|
||||
|
||||
if (g_proxy_fd < 0) {
|
||||
LOG(LOG_S, "proxy is not running, fd: %d", g_proxy_fd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
reset_params();
|
||||
int res = shutdown(g_proxy_fd, SHUT_RDWR);
|
||||
g_proxy_fd = -1;
|
||||
|
||||
if (res < 0) {
|
||||
uniperror("shutdown");
|
||||
return get_e();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1,594 +0,0 @@
|
||||
#include <getopt.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "byedpi/params.h"
|
||||
#include "error.h"
|
||||
#include "main.h"
|
||||
#include "packets.h"
|
||||
#include "utils.h"
|
||||
|
||||
struct params default_params;
|
||||
extern const struct option options[46];
|
||||
|
||||
void reset_params(void) {
|
||||
clear_params();
|
||||
params = default_params;
|
||||
}
|
||||
|
||||
static struct desync_params *add_group(struct desync_params *prev)
|
||||
{
|
||||
struct desync_params *dp = calloc(1, sizeof(*prev));
|
||||
if (!dp) {
|
||||
return 0;
|
||||
}
|
||||
if (prev) {
|
||||
dp->prev = prev;
|
||||
prev->next = dp;
|
||||
}
|
||||
params.dp_n++;
|
||||
return dp;
|
||||
}
|
||||
|
||||
int parse_args(int argc, char **argv)
|
||||
{
|
||||
int optc = sizeof(options)/sizeof(*options);
|
||||
for (int i = 0, e = optc; i < e; i++)
|
||||
optc += options[i].has_arg;
|
||||
|
||||
char opt[optc + 1];
|
||||
opt[optc] = 0;
|
||||
|
||||
for (int i = 0, o = 0; o < optc; i++, o++) {
|
||||
opt[o] = options[i].val;
|
||||
for (int c = options[i].has_arg; c; c--) {
|
||||
o++;
|
||||
opt[o] = ':';
|
||||
}
|
||||
}
|
||||
//
|
||||
params.laddr.in.sin_port = htons(1080);
|
||||
if (!ipv6_support()) {
|
||||
params.baddr.sa.sa_family = AF_INET;
|
||||
}
|
||||
|
||||
const char *pid_file = 0;
|
||||
bool daemonize = 0;
|
||||
|
||||
int rez;
|
||||
int invalid = 0;
|
||||
|
||||
long val = 0;
|
||||
char *end = 0;
|
||||
bool all_limited = 1;
|
||||
|
||||
int curr_optind = 1;
|
||||
|
||||
struct desync_params *dp = add_group(0);
|
||||
if (!dp) {
|
||||
reset_params();
|
||||
return -1;
|
||||
}
|
||||
params.dp = dp;
|
||||
|
||||
while (!invalid && (rez = getopt_long(
|
||||
argc, argv, opt, options, 0)) != -1) {
|
||||
switch (rez) {
|
||||
|
||||
case 'N':
|
||||
params.resolve = 0;
|
||||
break;
|
||||
case 'X':
|
||||
params.ipv6 = 0;
|
||||
break;
|
||||
case 'U':
|
||||
params.udp = 0;
|
||||
break;
|
||||
case 'G':
|
||||
params.http_connect = 1;
|
||||
break;
|
||||
#ifdef __linux__
|
||||
case 'E':
|
||||
params.transparent = 1;
|
||||
break;
|
||||
#endif
|
||||
|
||||
#ifdef DAEMON
|
||||
case 'D':
|
||||
daemonize = 1;
|
||||
break;
|
||||
|
||||
case 'w':
|
||||
pid_file = optarg;
|
||||
break;
|
||||
#endif
|
||||
case 'h':
|
||||
printf("%s", help_text);
|
||||
reset_params();
|
||||
return 0;
|
||||
case 'v':
|
||||
printf("%s\n", VERSION);
|
||||
reset_params();
|
||||
return 0;
|
||||
|
||||
case 'i':
|
||||
if (get_addr(optarg, ¶ms.laddr) < 0)
|
||||
invalid = 1;
|
||||
break;
|
||||
|
||||
case 'p':
|
||||
val = strtol(optarg, &end, 0);
|
||||
if (val <= 0 || val > 0xffff || *end)
|
||||
invalid = 1;
|
||||
else
|
||||
params.laddr.in.sin_port = htons(val);
|
||||
break;
|
||||
|
||||
case 'I':
|
||||
if (get_addr(optarg, ¶ms.baddr) < 0)
|
||||
invalid = 1;
|
||||
break;
|
||||
|
||||
case 'b':
|
||||
val = strtol(optarg, &end, 0);
|
||||
if (val <= 0 || val > INT_MAX/4 || *end)
|
||||
invalid = 1;
|
||||
else
|
||||
params.bfsize = val;
|
||||
break;
|
||||
|
||||
case 'c':
|
||||
val = strtol(optarg, &end, 0);
|
||||
if (val <= 0 || val >= (0xffff/2) || *end)
|
||||
invalid = 1;
|
||||
else
|
||||
params.max_open = val;
|
||||
break;
|
||||
|
||||
case 'x': //
|
||||
params.debug = strtol(optarg, 0, 0);
|
||||
if (params.debug < 0)
|
||||
invalid = 1;
|
||||
break;
|
||||
|
||||
case 'y': //
|
||||
params.cache_file = optarg;
|
||||
break;
|
||||
|
||||
// desync options
|
||||
|
||||
case 'F':
|
||||
params.tfo = 1;
|
||||
break;
|
||||
|
||||
case 'L':
|
||||
end = optarg;
|
||||
while (end && !invalid) {
|
||||
switch (*end) {
|
||||
case '0':
|
||||
break;
|
||||
case '1':
|
||||
case 'p':
|
||||
params.auto_level |= AUTO_POST;
|
||||
break;
|
||||
case '2':
|
||||
case 's':
|
||||
params.auto_level |= AUTO_SORT;
|
||||
break;
|
||||
case 'r':
|
||||
params.auto_level = 0;
|
||||
break;
|
||||
case '3':
|
||||
params.auto_level |= (AUTO_POST | AUTO_SORT);
|
||||
break;
|
||||
default:
|
||||
invalid = 1;
|
||||
continue;
|
||||
}
|
||||
end = strchr(end, ',');
|
||||
if (end) end++;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'A':
|
||||
if (optind < curr_optind) {
|
||||
optind = curr_optind;
|
||||
continue;
|
||||
}
|
||||
if (!(dp->hosts || dp->proto || dp->pf[0] || dp->detect || dp->ipset)) {
|
||||
all_limited = 0;
|
||||
}
|
||||
dp = add_group(dp);
|
||||
if (!dp) {
|
||||
reset_params();
|
||||
return -1;
|
||||
}
|
||||
end = optarg;
|
||||
while (end && !invalid) {
|
||||
switch (*end) {
|
||||
case 't':
|
||||
dp->detect |= DETECT_TORST;
|
||||
break;
|
||||
case 'r':
|
||||
dp->detect |= DETECT_HTTP_LOCAT;
|
||||
break;
|
||||
case 'a':
|
||||
case 's':
|
||||
dp->detect |= DETECT_TLS_ERR;
|
||||
break;
|
||||
case 'n':
|
||||
break;
|
||||
default:
|
||||
invalid = 1;
|
||||
continue;
|
||||
}
|
||||
end = strchr(end, ',');
|
||||
if (end) end++;
|
||||
}
|
||||
if (dp->detect) {
|
||||
params.auto_level |= AUTO_RECONN;
|
||||
}
|
||||
dp->_optind = optind;
|
||||
break;
|
||||
|
||||
case 'B':
|
||||
if (optind < curr_optind) {
|
||||
continue;
|
||||
}
|
||||
if (*optarg == 'i') {
|
||||
dp->pf[0] = htons(1);
|
||||
continue;
|
||||
}
|
||||
val = strtol(optarg, &end, 0);
|
||||
struct desync_params *itdp = params.dp;
|
||||
|
||||
while (itdp && itdp->id != val - 1) {
|
||||
itdp = itdp->next;
|
||||
}
|
||||
if (!itdp)
|
||||
invalid = 1;
|
||||
else {
|
||||
curr_optind = optind;
|
||||
optind = itdp->_optind;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'u':
|
||||
val = strtol(optarg, &end, 0);
|
||||
if (val <= 0 || *end)
|
||||
invalid = 1;
|
||||
else
|
||||
params.cache_ttl = val;
|
||||
break;
|
||||
|
||||
case 'T':;
|
||||
#ifdef __linux__
|
||||
float f = strtof(optarg, &end);
|
||||
val = (long)(f * 1000);
|
||||
#else
|
||||
val = strtol(optarg, &end, 0);
|
||||
#endif
|
||||
if (val <= 0 || (unsigned long)val > UINT_MAX || *end)
|
||||
invalid = 1;
|
||||
else
|
||||
params.timeout = val;
|
||||
break;
|
||||
|
||||
case 'K':
|
||||
end = optarg;
|
||||
while (end && !invalid) {
|
||||
switch (*end) {
|
||||
case 't':
|
||||
dp->proto |= IS_TCP | IS_HTTPS;
|
||||
break;
|
||||
case 'h':
|
||||
dp->proto |= IS_TCP | IS_HTTP;
|
||||
break;
|
||||
case 'u':
|
||||
dp->proto |= IS_UDP;
|
||||
break;
|
||||
case 'i':
|
||||
dp->proto |= IS_IPV4;
|
||||
break;
|
||||
default:
|
||||
invalid = 1;
|
||||
continue;
|
||||
}
|
||||
end = strchr(end, ',');
|
||||
if (end) end++;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'H':;
|
||||
if (dp->file_ptr) {
|
||||
continue;
|
||||
}
|
||||
dp->file_ptr = ftob(optarg, &dp->file_size);
|
||||
if (!dp->file_ptr) {
|
||||
uniperror("read/parse");
|
||||
invalid = 1;
|
||||
continue;
|
||||
}
|
||||
dp->hosts = parse_hosts(dp->file_ptr, dp->file_size);
|
||||
if (!dp->hosts) {
|
||||
uniperror("parse_hosts");
|
||||
reset_params();
|
||||
return -1;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'j':;
|
||||
if (dp->ipset) {
|
||||
continue;
|
||||
}
|
||||
ssize_t size;
|
||||
char *data = ftob(optarg, &size);
|
||||
if (!data) {
|
||||
uniperror("read/parse");
|
||||
invalid = 1;
|
||||
continue;
|
||||
}
|
||||
dp->ipset = parse_ipset(data, size);
|
||||
if (!dp->ipset) {
|
||||
uniperror("parse_ipset");
|
||||
invalid = 1;
|
||||
}
|
||||
free(data);
|
||||
break;
|
||||
|
||||
case 's':
|
||||
case 'd':
|
||||
case 'o':
|
||||
case 'q':
|
||||
case 'f':
|
||||
;
|
||||
struct part *part = add((void *)&dp->parts,
|
||||
&dp->parts_n, sizeof(struct part));
|
||||
if (!part) {
|
||||
reset_params();
|
||||
return -1;
|
||||
}
|
||||
if (parse_offset(part, optarg)) {
|
||||
invalid = 1;
|
||||
break;
|
||||
}
|
||||
switch (rez) {
|
||||
case 's': part->m = DESYNC_SPLIT;
|
||||
break;
|
||||
case 'd': part->m = DESYNC_DISORDER;
|
||||
break;
|
||||
case 'o': part->m = DESYNC_OOB;
|
||||
break;
|
||||
case 'q': part->m = DESYNC_DISOOB;
|
||||
break;
|
||||
case 'f': part->m = DESYNC_FAKE;
|
||||
}
|
||||
break;
|
||||
|
||||
case 't':
|
||||
val = strtol(optarg, &end, 0);
|
||||
if (val <= 0 || val > 255 || *end)
|
||||
invalid = 1;
|
||||
else
|
||||
dp->ttl = val;
|
||||
break;
|
||||
|
||||
case 'S':
|
||||
dp->md5sig = 1;
|
||||
break;
|
||||
|
||||
case 'O':
|
||||
if (parse_offset(&dp->fake_offset, optarg)) {
|
||||
invalid = 1;
|
||||
break;
|
||||
} else dp->fake_offset.m = 1;
|
||||
break;
|
||||
|
||||
case 'Q':
|
||||
end = optarg;
|
||||
while (end && !invalid) {
|
||||
switch (*end) {
|
||||
case 'r':
|
||||
dp->fake_mod |= FM_RAND;
|
||||
break;
|
||||
case 'o':
|
||||
dp->fake_mod |= FM_ORIG;
|
||||
break;
|
||||
default:
|
||||
invalid = 1;
|
||||
continue;
|
||||
}
|
||||
end = strchr(end, ',');
|
||||
if (end) end++;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'n':;
|
||||
const char **p = add((void *)&dp->fake_sni_list,
|
||||
&dp->fake_sni_count, sizeof(optarg));
|
||||
if (!p) {
|
||||
invalid = 1;
|
||||
continue;
|
||||
}
|
||||
*p = optarg;
|
||||
break;
|
||||
|
||||
case 'l':
|
||||
if (dp->fake_data.data) {
|
||||
continue;
|
||||
}
|
||||
dp->fake_data.data = ftob(optarg, &dp->fake_data.size);
|
||||
if (!dp->fake_data.data) {
|
||||
uniperror("read/parse");
|
||||
invalid = 1;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'e':
|
||||
val = parse_cform(dp->oob_char, 1, optarg, strlen(optarg));
|
||||
if (val != 1) {
|
||||
invalid = 1;
|
||||
}
|
||||
else dp->oob_char[1] = 1;
|
||||
break;
|
||||
|
||||
case 'M':
|
||||
end = optarg;
|
||||
while (end && !invalid) {
|
||||
switch (*end) {
|
||||
case 'r':
|
||||
dp->mod_http |= MH_SPACE;
|
||||
break;
|
||||
case 'h':
|
||||
dp->mod_http |= MH_HMIX;
|
||||
break;
|
||||
case 'd':
|
||||
dp->mod_http |= MH_DMIX;
|
||||
break;
|
||||
default:
|
||||
invalid = 1;
|
||||
continue;
|
||||
}
|
||||
end = strchr(end, ',');
|
||||
if (end) end++;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'r':
|
||||
part = add((void *)&dp->tlsrec,
|
||||
&dp->tlsrec_n, sizeof(struct part));
|
||||
if (!part) {
|
||||
reset_params();
|
||||
return -1;
|
||||
}
|
||||
if (parse_offset(part, optarg)
|
||||
|| part->pos > 0xffff) {
|
||||
invalid = 1;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'a':
|
||||
val = strtol(optarg, &end, 0);
|
||||
if (val < 0 || val > INT_MAX || *end)
|
||||
invalid = 1;
|
||||
else
|
||||
dp->udp_fake_count = val;
|
||||
break;
|
||||
|
||||
case 'V':
|
||||
val = strtol(optarg, &end, 0);
|
||||
if (val <= 0 || val > USHRT_MAX)
|
||||
invalid = 1;
|
||||
else {
|
||||
dp->pf[0] = htons(val);
|
||||
if (*end == '-') {
|
||||
val = strtol(end + 1, &end, 0);
|
||||
if (val <= 0 || val > USHRT_MAX)
|
||||
invalid = 1;
|
||||
}
|
||||
if (*end)
|
||||
invalid = 1;
|
||||
else
|
||||
dp->pf[1] = htons(val);
|
||||
}
|
||||
break;
|
||||
|
||||
case 'R':
|
||||
val = strtol(optarg, &end, 0);
|
||||
if (val <= 0 || val > INT_MAX)
|
||||
invalid = 1;
|
||||
else {
|
||||
dp->rounds[0] = val;
|
||||
if (*end == '-') {
|
||||
val = strtol(end + 1, &end, 0);
|
||||
if (val <= 0 || val > INT_MAX)
|
||||
invalid = 1;
|
||||
}
|
||||
if (*end)
|
||||
invalid = 1;
|
||||
else
|
||||
dp->rounds[1] = val;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'g':
|
||||
val = strtol(optarg, &end, 0);
|
||||
if (val <= 0 || val > 255 || *end)
|
||||
invalid = 1;
|
||||
else {
|
||||
params.def_ttl = val;
|
||||
params.custom_ttl = 1;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'Y':
|
||||
dp->drop_sack = 1;
|
||||
break;
|
||||
|
||||
case 'Z':
|
||||
params.wait_send = 1;
|
||||
break;
|
||||
|
||||
case 'W':
|
||||
params.await_int = atoi(optarg);
|
||||
break;
|
||||
|
||||
case 'C':
|
||||
if (get_addr(optarg, &dp->custom_dst_addr) < 0)
|
||||
invalid = 1;
|
||||
else
|
||||
dp->custom_dst = 1;
|
||||
break;
|
||||
|
||||
#ifdef __linux__
|
||||
case 'P':
|
||||
params.protect_path = optarg;
|
||||
break;
|
||||
#endif
|
||||
case 0:
|
||||
break;
|
||||
|
||||
case '?':
|
||||
reset_params();
|
||||
return -1;
|
||||
|
||||
default:
|
||||
printf("?: %c\n", rez);
|
||||
reset_params();
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
if (invalid) {
|
||||
fprintf(stderr, "invalid value: -%c %s\n", rez, optarg);
|
||||
reset_params();
|
||||
return -1;
|
||||
}
|
||||
if (all_limited) {
|
||||
dp = add_group(dp);
|
||||
if (!dp) {
|
||||
reset_params();
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
if ((size_t )params.dp_n > sizeof(dp->bit) * 8) {
|
||||
LOG(LOG_E, "too many groups!\n");
|
||||
}
|
||||
if (params.baddr.sa.sa_family != AF_INET6) {
|
||||
params.ipv6 = 0;
|
||||
}
|
||||
if (!params.def_ttl) {
|
||||
if ((params.def_ttl = get_default_ttl()) < 1) {
|
||||
reset_params();
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
params.mempool = mem_pool(MF_EXTRA, CMP_BYTES);
|
||||
if (!params.mempool) {
|
||||
uniperror("mem_pool");
|
||||
reset_params();
|
||||
return -1;
|
||||
}
|
||||
srand((unsigned int)time(0));
|
||||
return 0;
|
||||
}
|
||||
@@ -1,5 +0,0 @@
|
||||
extern struct params default_params;
|
||||
|
||||
void reset_params(void);
|
||||
int parse_args(int argc, char **argv);
|
||||
bool ipv6_support(void);
|
||||
@@ -177,7 +177,7 @@ class ByeDpiVpnService : VpnService() {
|
||||
try {
|
||||
vpnInterface?.close()
|
||||
vpnInterface = null
|
||||
NativeBridge().stopProxy()
|
||||
NativeBridge().jniStopProxy()
|
||||
TProxyService.TProxyStopService()
|
||||
status = ServiceStatus.Disconnected
|
||||
} catch (e: Exception) {
|
||||
@@ -192,7 +192,7 @@ class ByeDpiVpnService : VpnService() {
|
||||
val ipsetSet = if (getHostListMode(sharedPreferences) == "whitelist") getActiveIpsets(sharedPreferences) else getActiveExcludeIpsets(sharedPreferences)
|
||||
CoroutineScope(Dispatchers.IO).launch {
|
||||
val args = parseArgs(socksIp, socksPort, getActiveStrategy(sharedPreferences), prepareList(listSet), prepareIpset(ipsetSet), sharedPreferences)
|
||||
val result = NativeBridge().startProxy(args)
|
||||
val result = NativeBridge().jniStartProxy(args)
|
||||
if (result < 0) {
|
||||
Log.d("proxy","Failed to start byedpi proxy")
|
||||
} else {
|
||||
|
||||
@@ -6,16 +6,7 @@ class NativeBridge {
|
||||
System.loadLibrary("byedpi")
|
||||
}
|
||||
}
|
||||
fun startProxy(args: Array<String>): Int {
|
||||
jniCreateSocket(args)
|
||||
return jniStartProxy()
|
||||
}
|
||||
|
||||
fun stopProxy(): Int {
|
||||
return jniStopProxy()
|
||||
}
|
||||
|
||||
private external fun jniCreateSocket(args: Array<String>): Int
|
||||
private external fun jniStartProxy(): Int
|
||||
private external fun jniStopProxy(): Int
|
||||
external fun jniStartProxy(args: Array<String>): Int
|
||||
external fun jniStopProxy(): Int
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
[versions]
|
||||
agp = "8.13.0"
|
||||
agp = "8.12.0"
|
||||
kotlin = "2.2.10"
|
||||
coreKtx = "1.17.0"
|
||||
junit = "4.13.2"
|
||||
|
||||
@@ -5,7 +5,7 @@ project(byedpi_native)
|
||||
file(GLOB BYE_DPI_SRC byedpi/*.c)
|
||||
list(REMOVE_ITEM BYE_DPI_SRC ${CMAKE_CURRENT_SOURCE_DIR}/byedpi/win_service.c)
|
||||
|
||||
add_library(byedpi SHARED ${BYE_DPI_SRC} native-lib.c utils.c)
|
||||
add_library(byedpi STATIC ${BYE_DPI_SRC})
|
||||
target_include_directories(byedpi PRIVATE byedpi)
|
||||
|
||||
target_compile_options(byedpi PRIVATE -std=c99 -O2 -Wall -Wno-unused -Wextra -Wno-unused-parameter -pedantic)
|
||||
349
rust/Cargo.lock
generated
Normal file
349
rust/Cargo.lock
generated
Normal file
@@ -0,0 +1,349 @@
|
||||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
version = 4
|
||||
|
||||
[[package]]
|
||||
name = "aho-corasick"
|
||||
version = "1.1.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "android_log-sys"
|
||||
version = "0.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "84521a3cf562bc62942e294181d9eef17eb38ceb8c68677bc49f144e4c3d4f8d"
|
||||
|
||||
[[package]]
|
||||
name = "android_logger"
|
||||
version = "0.15.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dbb4e440d04be07da1f1bf44fb4495ebd58669372fe0cffa6e48595ac5bd88a3"
|
||||
dependencies = [
|
||||
"android_log-sys",
|
||||
"env_filter",
|
||||
"log",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "byedpi"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"android_logger",
|
||||
"cmake",
|
||||
"jni",
|
||||
"libc",
|
||||
"log",
|
||||
"once_cell",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bytes"
|
||||
version = "1.10.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d71b6127be86fdcfddb610f7182ac57211d4b18a3e9c82eb2d17662f2227ad6a"
|
||||
|
||||
[[package]]
|
||||
name = "cc"
|
||||
version = "1.2.40"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e1d05d92f4b1fd76aad469d46cdd858ca761576082cd37df81416691e50199fb"
|
||||
dependencies = [
|
||||
"find-msvc-tools",
|
||||
"shlex",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cesu8"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6d43a04d8753f35258c91f8ec639f792891f748a1edbd759cf1dcea3382ad83c"
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
version = "1.0.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2fd1289c04a9ea8cb22300a459a72a385d7c73d3259e2ed7dcb2af674838cfa9"
|
||||
|
||||
[[package]]
|
||||
name = "cmake"
|
||||
version = "0.1.54"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e7caa3f9de89ddbe2c607f4101924c5abec803763ae9534e4f4d7d8f84aa81f0"
|
||||
dependencies = [
|
||||
"cc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "combine"
|
||||
version = "4.6.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ba5a308b75df32fe02788e748662718f03fde005016435c444eea572398219fd"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"memchr",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "env_filter"
|
||||
version = "0.1.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "186e05a59d4c50738528153b83b0b0194d3a29507dfec16eccd4b342903397d0"
|
||||
dependencies = [
|
||||
"log",
|
||||
"regex",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "find-msvc-tools"
|
||||
version = "0.1.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0399f9d26e5191ce32c498bebd31e7a3ceabc2745f0ac54af3f335126c3f24b3"
|
||||
|
||||
[[package]]
|
||||
name = "jni"
|
||||
version = "0.21.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1a87aa2bb7d2af34197c04845522473242e1aa17c12f4935d5856491a7fb8c97"
|
||||
dependencies = [
|
||||
"cesu8",
|
||||
"cfg-if",
|
||||
"combine",
|
||||
"jni-sys",
|
||||
"log",
|
||||
"thiserror",
|
||||
"walkdir",
|
||||
"windows-sys 0.45.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "jni-sys"
|
||||
version = "0.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8eaf4bc02d17cbdd7ff4c7438cafcdf7fb9a4613313ad11b4f8fefe7d3fa0130"
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.176"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "58f929b4d672ea937a23a1ab494143d968337a5f47e56d0815df1e0890ddf174"
|
||||
|
||||
[[package]]
|
||||
name = "log"
|
||||
version = "0.4.28"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "34080505efa8e45a4b816c349525ebe327ceaa8559756f0356cba97ef3bf7432"
|
||||
|
||||
[[package]]
|
||||
name = "memchr"
|
||||
version = "2.7.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f52b00d39961fc5b2736ea853c9cc86238e165017a493d1d5c8eac6bdc4cc273"
|
||||
|
||||
[[package]]
|
||||
name = "once_cell"
|
||||
version = "1.21.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d"
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.101"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "89ae43fd86e4158d6db51ad8e2b80f313af9cc74f5c0e03ccb87de09998732de"
|
||||
dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.41"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ce25767e7b499d1b604768e7cde645d14cc8584231ea6b295e9c9eb22c02e1d1"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex"
|
||||
version = "1.11.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8b5288124840bee7b386bc413c487869b360b2b4ec421ea56425128692f2a82c"
|
||||
dependencies = [
|
||||
"aho-corasick",
|
||||
"memchr",
|
||||
"regex-automata",
|
||||
"regex-syntax",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex-automata"
|
||||
version = "0.4.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "833eb9ce86d40ef33cb1306d8accf7bc8ec2bfea4355cbdebb3df68b40925cad"
|
||||
dependencies = [
|
||||
"aho-corasick",
|
||||
"memchr",
|
||||
"regex-syntax",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex-syntax"
|
||||
version = "0.8.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "caf4aa5b0f434c91fe5c7f1ecb6a5ece2130b02ad2a590589dda5146df959001"
|
||||
|
||||
[[package]]
|
||||
name = "same-file"
|
||||
version = "1.0.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502"
|
||||
dependencies = [
|
||||
"winapi-util",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "shlex"
|
||||
version = "1.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64"
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "2.0.106"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ede7c438028d4436d71104916910f5bb611972c5cfd7f89b8300a8186e6fada6"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thiserror"
|
||||
version = "1.0.69"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52"
|
||||
dependencies = [
|
||||
"thiserror-impl",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thiserror-impl"
|
||||
version = "1.0.69"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unicode-ident"
|
||||
version = "1.0.19"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f63a545481291138910575129486daeaf8ac54aee4387fe7906919f7830c7d9d"
|
||||
|
||||
[[package]]
|
||||
name = "walkdir"
|
||||
version = "2.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b"
|
||||
dependencies = [
|
||||
"same-file",
|
||||
"winapi-util",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winapi-util"
|
||||
version = "0.1.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22"
|
||||
dependencies = [
|
||||
"windows-sys 0.61.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-link"
|
||||
version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "45e46c0661abb7180e7b9c281db115305d49ca1709ab8242adf09666d2173c65"
|
||||
|
||||
[[package]]
|
||||
name = "windows-sys"
|
||||
version = "0.45.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0"
|
||||
dependencies = [
|
||||
"windows-targets",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-sys"
|
||||
version = "0.61.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6f109e41dd4a3c848907eb83d5a42ea98b3769495597450cf6d153507b166f0f"
|
||||
dependencies = [
|
||||
"windows-link",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-targets"
|
||||
version = "0.42.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071"
|
||||
dependencies = [
|
||||
"windows_aarch64_gnullvm",
|
||||
"windows_aarch64_msvc",
|
||||
"windows_i686_gnu",
|
||||
"windows_i686_msvc",
|
||||
"windows_x86_64_gnu",
|
||||
"windows_x86_64_gnullvm",
|
||||
"windows_x86_64_msvc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_gnullvm"
|
||||
version = "0.42.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8"
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_msvc"
|
||||
version = "0.42.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_gnu"
|
||||
version = "0.42.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_msvc"
|
||||
version = "0.42.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnu"
|
||||
version = "0.42.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnullvm"
|
||||
version = "0.42.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_msvc"
|
||||
version = "0.42.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0"
|
||||
17
rust/Cargo.toml
Normal file
17
rust/Cargo.toml
Normal file
@@ -0,0 +1,17 @@
|
||||
[package]
|
||||
name = "byedpi"
|
||||
version = "0.1.0"
|
||||
edition = "2024"
|
||||
|
||||
[dependencies]
|
||||
jni = "0.21.1"
|
||||
libc = "0.2.0"
|
||||
android_logger = "0.15.1"
|
||||
log = "0.4"
|
||||
once_cell = "1.21.3"
|
||||
|
||||
[lib]
|
||||
crate-type = ["cdylib"]
|
||||
|
||||
[build-dependencies]
|
||||
cmake = "0.1.49"
|
||||
8
rust/build.rs
Normal file
8
rust/build.rs
Normal file
@@ -0,0 +1,8 @@
|
||||
use cmake::Config;
|
||||
|
||||
fn main() {
|
||||
let dst = Config::new(".").build_target("byedpi").build();
|
||||
let lib_path = dst.join("build");
|
||||
println!("cargo:rustc-link-search=native={}", lib_path.display());
|
||||
println!("cargo:rustc-link-lib=static=byedpi");
|
||||
}
|
||||
68
rust/src/lib.rs
Normal file
68
rust/src/lib.rs
Normal file
@@ -0,0 +1,68 @@
|
||||
use android_logger::Config;
|
||||
use jni::JNIEnv;
|
||||
use jni::objects::{JClass, JObjectArray, JString};
|
||||
use jni::sys::jint;
|
||||
use libc::{SHUT_RDWR, shutdown};
|
||||
use log::{LevelFilter, info};
|
||||
use std::ffi::CString;
|
||||
use std::os::raw::c_char;
|
||||
use std::sync::atomic::{AtomicBool, Ordering};
|
||||
|
||||
static PROXY_RUNNING: AtomicBool = AtomicBool::new(false);
|
||||
|
||||
#[link(name = "byedpi", kind = "static")]
|
||||
unsafe extern "C" {
|
||||
static mut server_fd: i32;
|
||||
fn main(argc: libc::c_int, argv: *const *const c_char) -> libc::c_int;
|
||||
fn clear_params();
|
||||
}
|
||||
|
||||
fn init_logger() {
|
||||
android_logger::init_once(Config::default().with_max_level(LevelFilter::Info));
|
||||
}
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
pub unsafe extern "system" fn Java_com_cherret_zaprett_byedpi_NativeBridge_jniStartProxy(
|
||||
mut env: JNIEnv,
|
||||
_class: JClass,
|
||||
args: JObjectArray,
|
||||
) -> jint {
|
||||
init_logger();
|
||||
if PROXY_RUNNING.swap(true, Ordering::SeqCst) {
|
||||
info!("proxy already running");
|
||||
return -1;
|
||||
}
|
||||
let argc = env.get_array_length(&args).unwrap_or(0) as usize;
|
||||
let mut cstrings: Vec<CString> = Vec::with_capacity(argc);
|
||||
for i in 0..argc {
|
||||
let jstr: JString = env
|
||||
.get_object_array_element(&args, i as i32)
|
||||
.unwrap()
|
||||
.into();
|
||||
let rust_str: String = env.get_string(&jstr).unwrap().into();
|
||||
cstrings.push(CString::new(rust_str).unwrap());
|
||||
}
|
||||
let mut argv: Vec<*const c_char> = cstrings.iter().map(|s| s.as_ptr()).collect();
|
||||
argv.push(std::ptr::null());
|
||||
info!("starting proxy");
|
||||
PROXY_RUNNING.store(true, Ordering::SeqCst);
|
||||
let ret = unsafe { main(argc as i32, argv.as_ptr()) };
|
||||
PROXY_RUNNING.store(false, Ordering::SeqCst);
|
||||
ret as jint
|
||||
}
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
pub unsafe extern "system" fn Java_com_cherret_zaprett_byedpi_NativeBridge_jniStopProxy(
|
||||
_env: JNIEnv,
|
||||
_class: JClass,
|
||||
) -> jint {
|
||||
init_logger();
|
||||
if !PROXY_RUNNING.load(Ordering::SeqCst) {
|
||||
info!("failed to stop proxy");
|
||||
return -1;
|
||||
}
|
||||
info!("stopping proxy");
|
||||
unsafe { clear_params() };
|
||||
let ret = unsafe { shutdown(server_fd, SHUT_RDWR) };
|
||||
ret as jint
|
||||
}
|
||||
Reference in New Issue
Block a user