mirror of
https://github.com/dovecoteescapee/ByeDPIAndroid.git
synced 2026-09-12 19:50:54 +05:00
Improvements and fixes: - Added Hosts to UI editor - Allowed not to specify DNS - Changed the level of saved logs to Debug - Fixed bug with Reset button
295 lines
7.6 KiB
C
295 lines
7.6 KiB
C
#include <string.h>
|
|
#include <netdb.h>
|
|
|
|
#include <jni.h>
|
|
#include <android/log.h>
|
|
|
|
#include "byedpi/error.h"
|
|
#include "byedpi/proxy.h"
|
|
#include "byedpi/params.h"
|
|
#include "byedpi/packets.h"
|
|
#include "main.h"
|
|
#include "utils.h"
|
|
|
|
const enum demode DESYNC_METHODS[] = {
|
|
DESYNC_NONE,
|
|
DESYNC_SPLIT,
|
|
DESYNC_DISORDER,
|
|
DESYNC_FAKE,
|
|
DESYNC_OOB,
|
|
};
|
|
|
|
enum hosts_mode {
|
|
HOSTS_DISABLE,
|
|
HOSTS_BLACKLIST,
|
|
HOSTS_WHITELIST,
|
|
};
|
|
|
|
JNIEXPORT jint JNI_OnLoad(
|
|
__attribute__((unused)) JavaVM *vm,
|
|
__attribute__((unused)) void *reserved) {
|
|
default_params = params;
|
|
return JNI_VERSION_1_6;
|
|
}
|
|
|
|
JNIEXPORT jint JNICALL
|
|
Java_io_github_dovecoteescapee_byedpi_core_ByeDpiProxy_jniCreateSocketWithCommandLine(
|
|
JNIEnv *env,
|
|
__attribute__((unused)) jobject thiz,
|
|
jobjectArray args) {
|
|
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((struct sockaddr_ina *)¶ms.laddr);
|
|
if (fd < 0) {
|
|
uniperror("listen_socket");
|
|
return -1;
|
|
}
|
|
LOG(LOG_S, "listen_socket, fd: %d", fd);
|
|
|
|
return fd;
|
|
}
|
|
|
|
JNIEXPORT jint JNICALL
|
|
Java_io_github_dovecoteescapee_byedpi_core_ByeDpiProxy_jniCreateSocket(
|
|
JNIEnv *env,
|
|
__attribute__((unused)) jobject thiz,
|
|
jstring ip,
|
|
jint port,
|
|
jint max_connections,
|
|
jint buffer_size,
|
|
jint default_ttl,
|
|
jboolean custom_ttl,
|
|
jboolean no_domain,
|
|
jboolean desync_http,
|
|
jboolean desync_https,
|
|
jboolean desync_udp,
|
|
jint desync_method,
|
|
jint split_position,
|
|
jboolean split_at_host,
|
|
jint fake_ttl,
|
|
jstring fake_sni,
|
|
jstring custom_oob_data,
|
|
jboolean host_mixed_case,
|
|
jboolean domain_mixed_case,
|
|
jboolean host_remove_spaces,
|
|
jboolean tls_record_split,
|
|
jint tls_record_split_position,
|
|
jboolean tls_record_split_at_sni,
|
|
jint hosts_mode,
|
|
jstring hosts) {
|
|
struct sockaddr_ina s;
|
|
|
|
const char *address = (*env)->GetStringUTFChars(env, ip, 0);
|
|
int res = get_addr(address, &s);
|
|
(*env)->ReleaseStringUTFChars(env, ip, address);
|
|
if (res < 0) {
|
|
uniperror("get_addr");
|
|
return -1;
|
|
}
|
|
|
|
s.in.sin_port = htons(port);
|
|
|
|
params.max_open = max_connections;
|
|
params.bfsize = buffer_size;
|
|
params.resolve = !no_domain;
|
|
|
|
if (custom_ttl) {
|
|
params.def_ttl = default_ttl;
|
|
params.custom_ttl = 1;
|
|
}
|
|
|
|
if (!params.def_ttl) {
|
|
if ((params.def_ttl = get_default_ttl()) < 1) {
|
|
uniperror("get_default_ttl");
|
|
reset_params();
|
|
return -1;
|
|
}
|
|
}
|
|
|
|
if (hosts_mode == HOSTS_WHITELIST) {
|
|
struct desync_params *dp = add(
|
|
(void *) ¶ms.dp,
|
|
¶ms.dp_count,
|
|
sizeof(struct desync_params)
|
|
);
|
|
if (!dp) {
|
|
uniperror("add");
|
|
reset_params();
|
|
return -1;
|
|
}
|
|
|
|
const char *str = (*env)->GetStringUTFChars(env, hosts, 0);
|
|
dp->file_ptr = parse_cform(str, &dp->file_size);
|
|
(*env)->ReleaseStringUTFChars(env, hosts, str);
|
|
dp->hosts = parse_hosts(dp->file_ptr, dp->file_size);
|
|
if (!dp->hosts) {
|
|
perror("parse_hosts");
|
|
clear_params();
|
|
return -1;
|
|
}
|
|
}
|
|
|
|
struct desync_params *dp = add(
|
|
(void *) ¶ms.dp,
|
|
¶ms.dp_count,
|
|
sizeof(struct desync_params)
|
|
);
|
|
if (!dp) {
|
|
uniperror("add");
|
|
reset_params();
|
|
return -1;
|
|
}
|
|
|
|
if (hosts_mode == HOSTS_BLACKLIST) {
|
|
const char *str = (*env)->GetStringUTFChars(env, hosts, 0);
|
|
dp->file_ptr = parse_cform(str, &dp->file_size);
|
|
(*env)->ReleaseStringUTFChars(env, hosts, str);
|
|
dp->hosts = parse_hosts(dp->file_ptr, dp->file_size);
|
|
if (!dp->hosts) {
|
|
perror("parse_hosts");
|
|
clear_params();
|
|
return -1;
|
|
}
|
|
}
|
|
|
|
dp->ttl = fake_ttl;
|
|
dp->proto =
|
|
IS_HTTP * desync_http |
|
|
IS_HTTPS * desync_https |
|
|
IS_UDP * desync_udp;
|
|
dp->mod_http =
|
|
MH_HMIX * host_mixed_case |
|
|
MH_DMIX * domain_mixed_case |
|
|
MH_SPACE * host_remove_spaces;
|
|
|
|
struct part *part = add(
|
|
(void *) &dp->parts,
|
|
&dp->parts_n,
|
|
sizeof(struct part)
|
|
);
|
|
if (!part) {
|
|
uniperror("add");
|
|
reset_params();
|
|
return -1;
|
|
}
|
|
|
|
enum demode mode = DESYNC_METHODS[desync_method];
|
|
|
|
int offset_flag = dp->proto || desync_https ? OFFSET_SNI : OFFSET_HOST;
|
|
|
|
part->flag = split_at_host ? offset_flag : 0;
|
|
part->pos = split_position;
|
|
part->m = mode;
|
|
|
|
if (tls_record_split) {
|
|
struct part *tlsrec_part = add(
|
|
(void *) &dp->tlsrec,
|
|
&dp->tlsrec_n,
|
|
sizeof(struct part)
|
|
);
|
|
|
|
if (!tlsrec_part) {
|
|
uniperror("add");
|
|
reset_params();
|
|
return -1;
|
|
}
|
|
|
|
tlsrec_part->flag = tls_record_split_at_sni ? offset_flag : 0;
|
|
tlsrec_part->pos = tls_record_split_position;
|
|
}
|
|
|
|
if (mode == DESYNC_FAKE) {
|
|
const char *sni = (*env)->GetStringUTFChars(env, fake_sni, 0);
|
|
LOG(LOG_S, "fake_sni: %s", sni);
|
|
res = change_tls_sni(sni, fake_tls.data, fake_tls.size);
|
|
(*env)->ReleaseStringUTFChars(env, fake_sni, sni);
|
|
if (res) {
|
|
fprintf(stderr, "error chsni\n");
|
|
return -1;
|
|
}
|
|
}
|
|
|
|
if (mode == DESYNC_OOB) {
|
|
const char *oob = (*env)->GetStringUTFChars(env, custom_oob_data, 0);
|
|
const size_t oob_len = strlen(oob);
|
|
|
|
oob_data.size = oob_len;
|
|
oob_data.data = malloc(oob_len);
|
|
if (oob_data.data == NULL) {
|
|
uniperror("malloc");
|
|
return -1;
|
|
}
|
|
memcpy(oob_data.data, oob, oob_len);
|
|
(*env)->ReleaseStringUTFChars(env, custom_oob_data, oob);
|
|
}
|
|
|
|
if (dp->proto) {
|
|
dp = add((void *)¶ms.dp,
|
|
¶ms.dp_count, sizeof(struct desync_params));
|
|
if (!dp) {
|
|
uniperror("add");
|
|
clear_params();
|
|
return -1;
|
|
}
|
|
}
|
|
|
|
params.mempool = mem_pool(0);
|
|
if (!params.mempool) {
|
|
uniperror("mem_pool");
|
|
clear_params();
|
|
return -1;
|
|
}
|
|
|
|
int fd = listen_socket(&s);
|
|
if (fd < 0) {
|
|
uniperror("listen_socket");
|
|
return -1;
|
|
}
|
|
LOG(LOG_S, "listen_socket, fd: %d", fd);
|
|
|
|
return fd;
|
|
}
|
|
|
|
JNIEXPORT jint JNICALL
|
|
Java_io_github_dovecoteescapee_byedpi_core_ByeDpiProxy_jniStartProxy(
|
|
__attribute__((unused)) JNIEnv *env,
|
|
__attribute__((unused)) jobject thiz,
|
|
jint fd) {
|
|
LOG(LOG_S, "start_proxy, fd: %d", fd);
|
|
NOT_EXIT = 1;
|
|
if (event_loop(fd) < 0) {
|
|
uniperror("event_loop");
|
|
return get_e();
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
JNIEXPORT jint JNICALL
|
|
Java_io_github_dovecoteescapee_byedpi_core_ByeDpiProxy_jniStopProxy(
|
|
__attribute__((unused)) JNIEnv *env,
|
|
__attribute__((unused)) jobject thiz,
|
|
jint fd) {
|
|
LOG(LOG_S, "stop_proxy, fd: %d", fd);
|
|
|
|
int res = shutdown(fd, SHUT_RDWR);
|
|
reset_params();
|
|
|
|
if (res < 0) {
|
|
uniperror("shutdown");
|
|
return get_e();
|
|
}
|
|
return 0;
|
|
} |