mirror of
https://github.com/dovecoteescapee/ByeDPIAndroid.git
synced 2024-12-22 06:15:44 +00:00
Improvements and fixes (v 1.2.0):
- Update ByeDPI to versions v0.13 - Added new options to UI editor - Structured UI editor - Changed default split position to 1 - Fixed listen ip validation
This commit is contained in:
parent
9a6254869d
commit
c95be6eb91
@ -29,7 +29,7 @@ height="80">](https://apt.izzysoft.de/fdroid/index/apk/io.github.dovecoteescapee
|
|||||||
|
|
||||||
## Настройки
|
## Настройки
|
||||||
|
|
||||||
Для обхода некоторых блокировок может потребоваться изменить настройки. Подробнее о различных настройках можно прочитать в [документации ByeDPI](https://github.com/hufrea/byedpi/tree/v0.12#readme).
|
Для обхода некоторых блокировок может потребоваться изменить настройки. Подробнее о различных настройках можно прочитать в [документации ByeDPI](https://github.com/hufrea/byedpi/blob/v0.13/README.md).
|
||||||
|
|
||||||
## FAQ
|
## FAQ
|
||||||
|
|
||||||
|
@ -30,7 +30,7 @@ This application runs a SOCKS5 proxy [ByeDPI](https://github.com/hufrea/byedpi)
|
|||||||
|
|
||||||
## Settings
|
## Settings
|
||||||
|
|
||||||
To bypass some blocks, you may need to change the settings. More about the various settings can be found in the [ByeDPI documentation](https://github.com/hufrea/byedpi/tree/v0.12#readme).
|
To bypass some blocks, you may need to change the settings. More about the various settings can be found in the [ByeDPI documentation](https://github.com/hufrea/byedpi/blob/v0.13/README.md).
|
||||||
|
|
||||||
## FAQ
|
## FAQ
|
||||||
|
|
||||||
|
@ -11,8 +11,8 @@ android {
|
|||||||
applicationId = "io.github.dovecoteescapee.byedpi"
|
applicationId = "io.github.dovecoteescapee.byedpi"
|
||||||
minSdk = 21
|
minSdk = 21
|
||||||
targetSdk = 34
|
targetSdk = 34
|
||||||
versionCode = 9
|
versionCode = 10
|
||||||
versionName = "1.1.1"
|
versionName = "1.2.0"
|
||||||
|
|
||||||
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
|
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
|
||||||
|
|
||||||
|
@ -1 +1 @@
|
|||||||
Subproject commit dcf5ed727c996d0073a6cb95d5eec45a793d28a2
|
Subproject commit 078842b084853bc30f33eaaec7acc510cf67e560
|
@ -13,7 +13,10 @@ void clear_params(void);
|
|||||||
|
|
||||||
char *ftob(const char *str, ssize_t *sl);
|
char *ftob(const char *str, ssize_t *sl);
|
||||||
|
|
||||||
char *parse_cform(const char *str, ssize_t *size);
|
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_hosts(char *buffer, size_t size);
|
||||||
|
|
||||||
|
@ -17,6 +17,7 @@ const enum demode DESYNC_METHODS[] = {
|
|||||||
DESYNC_DISORDER,
|
DESYNC_DISORDER,
|
||||||
DESYNC_FAKE,
|
DESYNC_FAKE,
|
||||||
DESYNC_OOB,
|
DESYNC_OOB,
|
||||||
|
DESYNC_DISOOB,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum hosts_mode {
|
enum hosts_mode {
|
||||||
@ -81,7 +82,7 @@ Java_io_github_dovecoteescapee_byedpi_core_ByeDpiProxy_jniCreateSocket(
|
|||||||
jboolean split_at_host,
|
jboolean split_at_host,
|
||||||
jint fake_ttl,
|
jint fake_ttl,
|
||||||
jstring fake_sni,
|
jstring fake_sni,
|
||||||
jstring custom_oob_data,
|
jbyte custom_oob_char,
|
||||||
jboolean host_mixed_case,
|
jboolean host_mixed_case,
|
||||||
jboolean domain_mixed_case,
|
jboolean domain_mixed_case,
|
||||||
jboolean host_remove_spaces,
|
jboolean host_remove_spaces,
|
||||||
@ -91,7 +92,9 @@ Java_io_github_dovecoteescapee_byedpi_core_ByeDpiProxy_jniCreateSocket(
|
|||||||
jint hosts_mode,
|
jint hosts_mode,
|
||||||
jstring hosts,
|
jstring hosts,
|
||||||
jboolean tfo,
|
jboolean tfo,
|
||||||
jint udp_fake_count) {
|
jint udp_fake_count,
|
||||||
|
jboolean drop_sack,
|
||||||
|
jint fake_offset) {
|
||||||
struct sockaddr_ina s;
|
struct sockaddr_ina s;
|
||||||
|
|
||||||
const char *address = (*env)->GetStringUTFChars(env, ip, 0);
|
const char *address = (*env)->GetStringUTFChars(env, ip, 0);
|
||||||
@ -135,7 +138,7 @@ Java_io_github_dovecoteescapee_byedpi_core_ByeDpiProxy_jniCreateSocket(
|
|||||||
}
|
}
|
||||||
|
|
||||||
const char *str = (*env)->GetStringUTFChars(env, hosts, 0);
|
const char *str = (*env)->GetStringUTFChars(env, hosts, 0);
|
||||||
dp->file_ptr = parse_cform(str, &dp->file_size);
|
dp->file_ptr = data_from_str(str, &dp->file_size);
|
||||||
(*env)->ReleaseStringUTFChars(env, hosts, str);
|
(*env)->ReleaseStringUTFChars(env, hosts, str);
|
||||||
dp->hosts = parse_hosts(dp->file_ptr, dp->file_size);
|
dp->hosts = parse_hosts(dp->file_ptr, dp->file_size);
|
||||||
if (!dp->hosts) {
|
if (!dp->hosts) {
|
||||||
@ -158,7 +161,7 @@ Java_io_github_dovecoteescapee_byedpi_core_ByeDpiProxy_jniCreateSocket(
|
|||||||
|
|
||||||
if (hosts_mode == HOSTS_BLACKLIST) {
|
if (hosts_mode == HOSTS_BLACKLIST) {
|
||||||
const char *str = (*env)->GetStringUTFChars(env, hosts, 0);
|
const char *str = (*env)->GetStringUTFChars(env, hosts, 0);
|
||||||
dp->file_ptr = parse_cform(str, &dp->file_size);
|
dp->file_ptr = data_from_str(str, &dp->file_size);
|
||||||
(*env)->ReleaseStringUTFChars(env, hosts, str);
|
(*env)->ReleaseStringUTFChars(env, hosts, str);
|
||||||
dp->hosts = parse_hosts(dp->file_ptr, dp->file_size);
|
dp->hosts = parse_hosts(dp->file_ptr, dp->file_size);
|
||||||
if (!dp->hosts) {
|
if (!dp->hosts) {
|
||||||
@ -170,6 +173,7 @@ Java_io_github_dovecoteescapee_byedpi_core_ByeDpiProxy_jniCreateSocket(
|
|||||||
|
|
||||||
dp->ttl = fake_ttl;
|
dp->ttl = fake_ttl;
|
||||||
dp->udp_fake_count = udp_fake_count;
|
dp->udp_fake_count = udp_fake_count;
|
||||||
|
dp->drop_sack = drop_sack;
|
||||||
dp->proto =
|
dp->proto =
|
||||||
IS_HTTP * desync_http |
|
IS_HTTP * desync_http |
|
||||||
IS_HTTPS * desync_https |
|
IS_HTTPS * desync_https |
|
||||||
@ -216,6 +220,8 @@ Java_io_github_dovecoteescapee_byedpi_core_ByeDpiProxy_jniCreateSocket(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (mode == DESYNC_FAKE) {
|
if (mode == DESYNC_FAKE) {
|
||||||
|
dp->fake_offset = fake_offset;
|
||||||
|
|
||||||
const char *sni = (*env)->GetStringUTFChars(env, fake_sni, 0);
|
const char *sni = (*env)->GetStringUTFChars(env, fake_sni, 0);
|
||||||
LOG(LOG_S, "fake_sni: %s", sni);
|
LOG(LOG_S, "fake_sni: %s", sni);
|
||||||
res = change_tls_sni(sni, fake_tls.data, fake_tls.size);
|
res = change_tls_sni(sni, fake_tls.data, fake_tls.size);
|
||||||
@ -227,17 +233,8 @@ Java_io_github_dovecoteescapee_byedpi_core_ByeDpiProxy_jniCreateSocket(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (mode == DESYNC_OOB) {
|
if (mode == DESYNC_OOB) {
|
||||||
const char *oob = (*env)->GetStringUTFChars(env, custom_oob_data, 0);
|
dp->oob_char[0] = custom_oob_char;
|
||||||
const size_t oob_len = strlen(oob);
|
dp->oob_char[1] = 1;
|
||||||
|
|
||||||
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) {
|
if (dp->proto) {
|
||||||
|
@ -15,9 +15,10 @@ void reset_params(void) {
|
|||||||
params = default_params;
|
params = default_params;
|
||||||
}
|
}
|
||||||
|
|
||||||
extern const struct option options[35];
|
extern const struct option options[38];
|
||||||
|
|
||||||
int parse_args(int argc, char **argv) {
|
int parse_args(int argc, char **argv)
|
||||||
|
{
|
||||||
int optc = sizeof(options)/sizeof(*options);
|
int optc = sizeof(options)/sizeof(*options);
|
||||||
for (int i = 0, e = optc; i < e; i++)
|
for (int i = 0, e = optc; i < e; i++)
|
||||||
optc += options[i].has_arg;
|
optc += options[i].has_arg;
|
||||||
@ -50,8 +51,9 @@ int parse_args(int argc, char **argv) {
|
|||||||
|
|
||||||
optind = optreset = 1;
|
optind = optreset = 1;
|
||||||
|
|
||||||
while (!invalid && (rez = getopt_long_only(
|
while (!invalid && (rez = getopt_long(
|
||||||
argc, argv, opt, options, 0)) != -1) {
|
argc, argv, opt, options, 0)) != -1) {
|
||||||
|
|
||||||
switch (rez) {
|
switch (rez) {
|
||||||
|
|
||||||
case 'N':
|
case 'N':
|
||||||
@ -64,6 +66,15 @@ int parse_args(int argc, char **argv) {
|
|||||||
params.udp = 0;
|
params.udp = 0;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
// case 'h':
|
||||||
|
// printf(help_text);
|
||||||
|
// reset_params();
|
||||||
|
// return 0;
|
||||||
|
// case 'v':
|
||||||
|
// printf("%s\n", VERSION);
|
||||||
|
// reset_params();
|
||||||
|
// return 0;
|
||||||
|
|
||||||
case 'i':
|
case 'i':
|
||||||
if (get_addr(optarg,
|
if (get_addr(optarg,
|
||||||
(struct sockaddr_ina *)¶ms.laddr) < 0)
|
(struct sockaddr_ina *)¶ms.laddr) < 0)
|
||||||
@ -119,10 +130,6 @@ int parse_args(int argc, char **argv) {
|
|||||||
reset_params();
|
reset_params();
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if (!optarg) {
|
|
||||||
dp->detect |= DETECT_TORST;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
end = optarg;
|
end = optarg;
|
||||||
while (end && !invalid) {
|
while (end && !invalid) {
|
||||||
switch (*end) {
|
switch (*end) {
|
||||||
@ -132,14 +139,9 @@ int parse_args(int argc, char **argv) {
|
|||||||
case 'r':
|
case 'r':
|
||||||
dp->detect |= DETECT_HTTP_LOCAT;
|
dp->detect |= DETECT_HTTP_LOCAT;
|
||||||
break;
|
break;
|
||||||
case 'c':
|
|
||||||
dp->detect |= DETECT_HTTP_CLERR;
|
|
||||||
break;
|
|
||||||
case 's':
|
|
||||||
dp->detect |= DETECT_TLS_INVSID;
|
|
||||||
break;
|
|
||||||
case 'a':
|
case 'a':
|
||||||
dp->detect |= DETECT_TLS_ALERT;
|
case 's':
|
||||||
|
dp->detect |= DETECT_TLS_ERR;
|
||||||
break;
|
break;
|
||||||
case 'n':
|
case 'n':
|
||||||
break;
|
break;
|
||||||
@ -161,8 +163,12 @@ int parse_args(int argc, char **argv) {
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case 'T':;
|
case 'T':;
|
||||||
|
#ifdef __linux__
|
||||||
float f = strtof(optarg, &end);
|
float f = strtof(optarg, &end);
|
||||||
val = (long)(f * 1000);
|
val = (long)(f * 1000);
|
||||||
|
#else
|
||||||
|
val = strtol(optarg, &end, 0);
|
||||||
|
#endif
|
||||||
if (val <= 0 || val > UINT_MAX || *end)
|
if (val <= 0 || val > UINT_MAX || *end)
|
||||||
invalid = 1;
|
invalid = 1;
|
||||||
else
|
else
|
||||||
@ -212,6 +218,7 @@ int parse_args(int argc, char **argv) {
|
|||||||
case 's':
|
case 's':
|
||||||
case 'd':
|
case 'd':
|
||||||
case 'o':
|
case 'o':
|
||||||
|
case 'q':
|
||||||
case 'f':
|
case 'f':
|
||||||
;
|
;
|
||||||
struct part *part = add((void *)&dp->parts,
|
struct part *part = add((void *)&dp->parts,
|
||||||
@ -231,6 +238,8 @@ int parse_args(int argc, char **argv) {
|
|||||||
break;
|
break;
|
||||||
case 'o': part->m = DESYNC_OOB;
|
case 'o': part->m = DESYNC_OOB;
|
||||||
break;
|
break;
|
||||||
|
case 'q': part->m = DESYNC_DISOOB;
|
||||||
|
break;
|
||||||
case 'f': part->m = DESYNC_FAKE;
|
case 'f': part->m = DESYNC_FAKE;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -263,13 +272,21 @@ int parse_args(int argc, char **argv) {
|
|||||||
dp->md5sig = 1;
|
dp->md5sig = 1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case 'O':
|
||||||
|
val = strtol(optarg, &end, 0);
|
||||||
|
if (val <= 0 || *end)
|
||||||
|
invalid = 1;
|
||||||
|
else
|
||||||
|
dp->fake_offset = val;
|
||||||
|
break;
|
||||||
|
|
||||||
case 'n':
|
case 'n':
|
||||||
if (change_tls_sni(optarg, fake_tls.data, fake_tls.size)) {
|
if (change_tls_sni(optarg, fake_tls.data, fake_tls.size)) {
|
||||||
fprintf(stderr, "error chsni\n");
|
perror("change_tls_sni");
|
||||||
reset_params();
|
reset_params();
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
printf("sni: %s\n", optarg);
|
LOG(LOG_S, "sni: %s", optarg);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'l':
|
case 'l':
|
||||||
@ -284,14 +301,11 @@ int parse_args(int argc, char **argv) {
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case 'e':
|
case 'e':
|
||||||
if (oob_data.data != oob_char) {
|
val = parse_cform(dp->oob_char, 1, optarg, strlen(optarg));
|
||||||
continue;
|
if (val != 1) {
|
||||||
}
|
|
||||||
oob_data.data = ftob(optarg, &oob_data.size);
|
|
||||||
if (!oob_data.data) {
|
|
||||||
uniperror("read/parse");
|
|
||||||
invalid = 1;
|
invalid = 1;
|
||||||
}
|
}
|
||||||
|
else dp->oob_char[1] = 1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'M':
|
case 'M':
|
||||||
@ -366,6 +380,10 @@ int parse_args(int argc, char **argv) {
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case 'Y':
|
||||||
|
dp->drop_sack = 1;
|
||||||
|
break;
|
||||||
|
|
||||||
case 'w': //
|
case 'w': //
|
||||||
params.sfdelay = strtol(optarg, &end, 0);
|
params.sfdelay = strtol(optarg, &end, 0);
|
||||||
if (params.sfdelay < 0 || optarg == end
|
if (params.sfdelay < 0 || optarg == end
|
||||||
@ -376,9 +394,11 @@ int parse_args(int argc, char **argv) {
|
|||||||
case 'W':
|
case 'W':
|
||||||
params.wait_send = 0;
|
params.wait_send = 0;
|
||||||
break;
|
break;
|
||||||
|
#ifdef __linux__
|
||||||
case 'P':
|
case 'P':
|
||||||
params.protect_path = optarg;
|
params.protect_path = optarg;
|
||||||
break;
|
break;
|
||||||
|
#endif
|
||||||
case 0:
|
case 0:
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -387,13 +407,13 @@ int parse_args(int argc, char **argv) {
|
|||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
printf("?: %c\n", rez);
|
LOG(LOG_S, "Unknown option: -%c", rez);
|
||||||
reset_params();
|
reset_params();
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (invalid) {
|
if (invalid) {
|
||||||
fprintf(stderr, "invalid value: -%c %s\n", rez, optarg);
|
LOG(LOG_S, "invalid value: -%c %s", rez, optarg);
|
||||||
reset_params();
|
reset_params();
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -69,7 +69,7 @@ class ByeDpiProxy {
|
|||||||
splitAtHost = preferences.splitAtHost,
|
splitAtHost = preferences.splitAtHost,
|
||||||
fakeTtl = preferences.fakeTtl,
|
fakeTtl = preferences.fakeTtl,
|
||||||
fakeSni = preferences.fakeSni,
|
fakeSni = preferences.fakeSni,
|
||||||
oobData = preferences.oobData,
|
oobChar = preferences.oobChar,
|
||||||
hostMixedCase = preferences.hostMixedCase,
|
hostMixedCase = preferences.hostMixedCase,
|
||||||
domainMixedCase = preferences.domainMixedCase,
|
domainMixedCase = preferences.domainMixedCase,
|
||||||
hostRemoveSpaces = preferences.hostRemoveSpaces,
|
hostRemoveSpaces = preferences.hostRemoveSpaces,
|
||||||
@ -80,6 +80,8 @@ class ByeDpiProxy {
|
|||||||
hosts = preferences.hosts,
|
hosts = preferences.hosts,
|
||||||
tcpFastOpen = preferences.tcpFastOpen,
|
tcpFastOpen = preferences.tcpFastOpen,
|
||||||
udpFakeCount = preferences.udpFakeCount,
|
udpFakeCount = preferences.udpFakeCount,
|
||||||
|
dropSack = preferences.dropSack,
|
||||||
|
fakeOffset = preferences.fakeOffset,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -101,7 +103,7 @@ class ByeDpiProxy {
|
|||||||
splitAtHost: Boolean,
|
splitAtHost: Boolean,
|
||||||
fakeTtl: Int,
|
fakeTtl: Int,
|
||||||
fakeSni: String,
|
fakeSni: String,
|
||||||
oobData: String,
|
oobChar: Byte,
|
||||||
hostMixedCase: Boolean,
|
hostMixedCase: Boolean,
|
||||||
domainMixedCase: Boolean,
|
domainMixedCase: Boolean,
|
||||||
hostRemoveSpaces: Boolean,
|
hostRemoveSpaces: Boolean,
|
||||||
@ -112,6 +114,8 @@ class ByeDpiProxy {
|
|||||||
hosts: String?,
|
hosts: String?,
|
||||||
tcpFastOpen: Boolean,
|
tcpFastOpen: Boolean,
|
||||||
udpFakeCount: Int,
|
udpFakeCount: Int,
|
||||||
|
dropSack: Boolean,
|
||||||
|
fakeOffset: Int,
|
||||||
): Int
|
): Int
|
||||||
|
|
||||||
private external fun jniStartProxy(fd: Int): Int
|
private external fun jniStartProxy(fd: Int): Int
|
||||||
|
@ -48,7 +48,7 @@ class ByeDpiProxyUIPreferences(
|
|||||||
splitAtHost: Boolean? = null,
|
splitAtHost: Boolean? = null,
|
||||||
fakeTtl: Int? = null,
|
fakeTtl: Int? = null,
|
||||||
fakeSni: String? = null,
|
fakeSni: String? = null,
|
||||||
oobData: String? = null,
|
oobChar: String? = null,
|
||||||
hostMixedCase: Boolean? = null,
|
hostMixedCase: Boolean? = null,
|
||||||
domainMixedCase: Boolean? = null,
|
domainMixedCase: Boolean? = null,
|
||||||
hostRemoveSpaces: Boolean? = null,
|
hostRemoveSpaces: Boolean? = null,
|
||||||
@ -59,6 +59,8 @@ class ByeDpiProxyUIPreferences(
|
|||||||
hosts: String? = null,
|
hosts: String? = null,
|
||||||
tcpFastOpen: Boolean? = null,
|
tcpFastOpen: Boolean? = null,
|
||||||
udpFakeCount: Int? = null,
|
udpFakeCount: Int? = null,
|
||||||
|
dropSack: Boolean? = null,
|
||||||
|
byedpiFakeOffset: Int? = null,
|
||||||
) : ByeDpiProxyPreferences {
|
) : ByeDpiProxyPreferences {
|
||||||
val ip: String = ip ?: "127.0.0.1"
|
val ip: String = ip ?: "127.0.0.1"
|
||||||
val port: Int = port ?: 1080
|
val port: Int = port ?: 1080
|
||||||
@ -71,11 +73,11 @@ class ByeDpiProxyUIPreferences(
|
|||||||
val desyncHttps: Boolean = desyncHttps ?: true
|
val desyncHttps: Boolean = desyncHttps ?: true
|
||||||
val desyncUdp: Boolean = desyncUdp ?: false
|
val desyncUdp: Boolean = desyncUdp ?: false
|
||||||
val desyncMethod: DesyncMethod = desyncMethod ?: DesyncMethod.Disorder
|
val desyncMethod: DesyncMethod = desyncMethod ?: DesyncMethod.Disorder
|
||||||
val splitPosition: Int = splitPosition ?: 2
|
val splitPosition: Int = splitPosition ?: 1
|
||||||
val splitAtHost: Boolean = splitAtHost ?: false
|
val splitAtHost: Boolean = splitAtHost ?: false
|
||||||
val fakeTtl: Int = fakeTtl ?: 8
|
val fakeTtl: Int = fakeTtl ?: 8
|
||||||
val fakeSni: String = fakeSni ?: "www.iana.org"
|
val fakeSni: String = fakeSni ?: "www.iana.org"
|
||||||
val oobData: String = oobData ?: "a"
|
val oobChar: Byte = (oobChar ?: "a")[0].code.toByte()
|
||||||
val hostMixedCase: Boolean = hostMixedCase ?: false
|
val hostMixedCase: Boolean = hostMixedCase ?: false
|
||||||
val domainMixedCase: Boolean = domainMixedCase ?: false
|
val domainMixedCase: Boolean = domainMixedCase ?: false
|
||||||
val hostRemoveSpaces: Boolean = hostRemoveSpaces ?: false
|
val hostRemoveSpaces: Boolean = hostRemoveSpaces ?: false
|
||||||
@ -90,6 +92,8 @@ class ByeDpiProxyUIPreferences(
|
|||||||
else hosts?.trim()
|
else hosts?.trim()
|
||||||
val tcpFastOpen: Boolean = tcpFastOpen ?: false
|
val tcpFastOpen: Boolean = tcpFastOpen ?: false
|
||||||
val udpFakeCount: Int = udpFakeCount ?: 0
|
val udpFakeCount: Int = udpFakeCount ?: 0
|
||||||
|
val dropSack: Boolean = dropSack ?: false
|
||||||
|
val fakeOffset: Int = byedpiFakeOffset ?: 0
|
||||||
|
|
||||||
constructor(preferences: SharedPreferences) : this(
|
constructor(preferences: SharedPreferences) : this(
|
||||||
ip = preferences.getString("byedpi_proxy_ip", null),
|
ip = preferences.getString("byedpi_proxy_ip", null),
|
||||||
@ -107,7 +111,7 @@ class ByeDpiProxyUIPreferences(
|
|||||||
splitAtHost = preferences.getBoolean("byedpi_split_at_host", false),
|
splitAtHost = preferences.getBoolean("byedpi_split_at_host", false),
|
||||||
fakeTtl = preferences.getString("byedpi_fake_ttl", null)?.toIntOrNull(),
|
fakeTtl = preferences.getString("byedpi_fake_ttl", null)?.toIntOrNull(),
|
||||||
fakeSni = preferences.getString("byedpi_fake_sni", null),
|
fakeSni = preferences.getString("byedpi_fake_sni", null),
|
||||||
oobData = preferences.getString("byedpi_oob_data", null),
|
oobChar = preferences.getString("byedpi_oob_data", null),
|
||||||
hostMixedCase = preferences.getBoolean("byedpi_host_mixed_case", false),
|
hostMixedCase = preferences.getBoolean("byedpi_host_mixed_case", false),
|
||||||
domainMixedCase = preferences.getBoolean("byedpi_domain_mixed_case", false),
|
domainMixedCase = preferences.getBoolean("byedpi_domain_mixed_case", false),
|
||||||
hostRemoveSpaces = preferences.getBoolean("byedpi_host_remove_spaces", false),
|
hostRemoveSpaces = preferences.getBoolean("byedpi_host_remove_spaces", false),
|
||||||
@ -126,6 +130,8 @@ class ByeDpiProxyUIPreferences(
|
|||||||
},
|
},
|
||||||
tcpFastOpen = preferences.getBoolean("byedpi_tcp_fast_open", false),
|
tcpFastOpen = preferences.getBoolean("byedpi_tcp_fast_open", false),
|
||||||
udpFakeCount = preferences.getString("byedpi_udp_fake_count", null)?.toIntOrNull(),
|
udpFakeCount = preferences.getString("byedpi_udp_fake_count", null)?.toIntOrNull(),
|
||||||
|
dropSack = preferences.getBoolean("byedpi_drop_sack", false),
|
||||||
|
byedpiFakeOffset = preferences.getString("byedpi_fake_offset", null)?.toIntOrNull(),
|
||||||
)
|
)
|
||||||
|
|
||||||
enum class DesyncMethod {
|
enum class DesyncMethod {
|
||||||
@ -133,7 +139,8 @@ class ByeDpiProxyUIPreferences(
|
|||||||
Split,
|
Split,
|
||||||
Disorder,
|
Disorder,
|
||||||
Fake,
|
Fake,
|
||||||
OOB;
|
OOB,
|
||||||
|
DISOOB;
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
fun fromName(name: String): DesyncMethod {
|
fun fromName(name: String): DesyncMethod {
|
||||||
@ -143,6 +150,7 @@ class ByeDpiProxyUIPreferences(
|
|||||||
"disorder" -> Disorder
|
"disorder" -> Disorder
|
||||||
"fake" -> Fake
|
"fake" -> Fake
|
||||||
"oob" -> OOB
|
"oob" -> OOB
|
||||||
|
"disoob" -> DISOOB
|
||||||
else -> throw IllegalArgumentException("Unknown desync method: $name")
|
else -> throw IllegalArgumentException("Unknown desync method: $name")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -78,7 +78,8 @@ class ByeDpiUISettingsFragment : PreferenceFragmentCompat() {
|
|||||||
val splitAtHost = findPreferenceNotNull<CheckBoxPreference>("byedpi_split_at_host")
|
val splitAtHost = findPreferenceNotNull<CheckBoxPreference>("byedpi_split_at_host")
|
||||||
val ttlFake = findPreferenceNotNull<EditTextPreference>("byedpi_fake_ttl")
|
val ttlFake = findPreferenceNotNull<EditTextPreference>("byedpi_fake_ttl")
|
||||||
val fakeSni = findPreferenceNotNull<EditTextPreference>("byedpi_fake_sni")
|
val fakeSni = findPreferenceNotNull<EditTextPreference>("byedpi_fake_sni")
|
||||||
val oobData = findPreferenceNotNull<EditTextPreference>("byedpi_oob_data")
|
val fakeOffset = findPreferenceNotNull<EditTextPreference>("byedpi_fake_offset")
|
||||||
|
val oobChar = findPreferenceNotNull<EditTextPreference>("byedpi_oob_data")
|
||||||
val udpFakeCount = findPreferenceNotNull<EditTextPreference>("byedpi_udp_fake_count")
|
val udpFakeCount = findPreferenceNotNull<EditTextPreference>("byedpi_udp_fake_count")
|
||||||
val hostMixedCase = findPreferenceNotNull<CheckBoxPreference>("byedpi_host_mixed_case")
|
val hostMixedCase = findPreferenceNotNull<CheckBoxPreference>("byedpi_host_mixed_case")
|
||||||
val domainMixedCase = findPreferenceNotNull<CheckBoxPreference>("byedpi_domain_mixed_case")
|
val domainMixedCase = findPreferenceNotNull<CheckBoxPreference>("byedpi_domain_mixed_case")
|
||||||
@ -89,81 +90,36 @@ class ByeDpiUISettingsFragment : PreferenceFragmentCompat() {
|
|||||||
findPreferenceNotNull<EditTextPreference>("byedpi_tlsrec_position")
|
findPreferenceNotNull<EditTextPreference>("byedpi_tlsrec_position")
|
||||||
val splitTlsRecAtSni = findPreferenceNotNull<CheckBoxPreference>("byedpi_tlsrec_at_sni")
|
val splitTlsRecAtSni = findPreferenceNotNull<CheckBoxPreference>("byedpi_tlsrec_at_sni")
|
||||||
|
|
||||||
when (hostsMode) {
|
hostsBlacklist.isVisible = hostsMode == Blacklist
|
||||||
Disable -> {
|
hostsWhitelist.isVisible = hostsMode == Whitelist
|
||||||
hostsBlacklist.isVisible = false
|
|
||||||
hostsWhitelist.isVisible = false
|
|
||||||
}
|
|
||||||
|
|
||||||
Blacklist -> {
|
val desyncEnabled = desyncMethod != None
|
||||||
hostsBlacklist.isVisible = true
|
splitPosition.isVisible = desyncEnabled
|
||||||
hostsWhitelist.isVisible = false
|
splitAtHost.isVisible = desyncEnabled
|
||||||
}
|
|
||||||
|
|
||||||
Whitelist -> {
|
val isFake = desyncMethod == Fake
|
||||||
hostsBlacklist.isVisible = false
|
ttlFake.isVisible = isFake
|
||||||
hostsWhitelist.isVisible = true
|
fakeSni.isVisible = isFake
|
||||||
}
|
fakeOffset.isVisible = isFake
|
||||||
}
|
|
||||||
|
val isOob = desyncMethod == OOB || desyncMethod == DISOOB
|
||||||
|
oobChar.isVisible = isOob
|
||||||
|
|
||||||
val desyncAllProtocols =
|
val desyncAllProtocols =
|
||||||
!desyncHttp.isChecked && !desyncHttps.isChecked && !desyncUdp.isChecked
|
!desyncHttp.isChecked && !desyncHttps.isChecked && !desyncUdp.isChecked
|
||||||
|
|
||||||
if (desyncAllProtocols || desyncUdp.isChecked) {
|
val desyncHttpEnabled = desyncAllProtocols || desyncHttp.isChecked
|
||||||
udpFakeCount.isVisible = true
|
hostMixedCase.isEnabled = desyncHttpEnabled
|
||||||
} else {
|
domainMixedCase.isEnabled = desyncHttpEnabled
|
||||||
udpFakeCount.isVisible = false
|
hostRemoveSpaces.isEnabled = desyncHttpEnabled
|
||||||
}
|
|
||||||
|
|
||||||
when (desyncMethod) {
|
val desyncUdpEnabled = desyncAllProtocols || desyncUdp.isChecked
|
||||||
None -> {
|
udpFakeCount.isEnabled = desyncUdpEnabled
|
||||||
splitPosition.isVisible = false
|
|
||||||
splitAtHost.isVisible = false
|
|
||||||
ttlFake.isVisible = false
|
|
||||||
fakeSni.isVisible = false
|
|
||||||
oobData.isVisible = false
|
|
||||||
hostMixedCase.isVisible = false
|
|
||||||
domainMixedCase.isVisible = false
|
|
||||||
hostRemoveSpaces.isVisible = false
|
|
||||||
}
|
|
||||||
|
|
||||||
else -> {
|
val desyncHttpsEnabled = desyncAllProtocols || desyncHttps.isChecked
|
||||||
splitPosition.isVisible = true
|
splitTlsRec.isEnabled = desyncHttpsEnabled
|
||||||
splitAtHost.isVisible = true
|
val tlsRecEnabled = desyncHttpsEnabled && splitTlsRec.isChecked
|
||||||
|
splitTlsRecPosition.isEnabled = tlsRecEnabled
|
||||||
if (desyncAllProtocols || desyncHttp.isChecked) {
|
splitTlsRecAtSni.isEnabled = tlsRecEnabled
|
||||||
hostMixedCase.isVisible = true
|
|
||||||
domainMixedCase.isVisible = true
|
|
||||||
hostRemoveSpaces.isVisible = true
|
|
||||||
} else {
|
|
||||||
hostMixedCase.isVisible = false
|
|
||||||
domainMixedCase.isVisible = false
|
|
||||||
hostRemoveSpaces.isVisible = false
|
|
||||||
}
|
|
||||||
|
|
||||||
when (desyncMethod) {
|
|
||||||
Fake -> {
|
|
||||||
ttlFake.isVisible = true
|
|
||||||
fakeSni.isVisible = true
|
|
||||||
oobData.isVisible = false
|
|
||||||
}
|
|
||||||
|
|
||||||
OOB -> {
|
|
||||||
ttlFake.isVisible = false
|
|
||||||
fakeSni.isVisible = false
|
|
||||||
oobData.isVisible = true
|
|
||||||
}
|
|
||||||
|
|
||||||
else -> {
|
|
||||||
ttlFake.isVisible = false
|
|
||||||
fakeSni.isVisible = false
|
|
||||||
oobData.isVisible = false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
splitTlsRecPosition.isVisible = splitTlsRec.isChecked
|
|
||||||
splitTlsRecAtSni.isVisible = splitTlsRec.isChecked
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -39,7 +39,7 @@ class MainSettingsFragment : PreferenceFragmentCompat() {
|
|||||||
setPreferencesFromResource(R.xml.main_settings, rootKey)
|
setPreferencesFromResource(R.xml.main_settings, rootKey)
|
||||||
|
|
||||||
setEditTextPreferenceListener("dns_ip") {
|
setEditTextPreferenceListener("dns_ip") {
|
||||||
it.isBlank() || checkIp(it)
|
it.isBlank() || checkNotLocalIp(it)
|
||||||
}
|
}
|
||||||
|
|
||||||
findPreferenceNotNull<DropDownPreference>("app_theme")
|
findPreferenceNotNull<DropDownPreference>("app_theme")
|
||||||
|
@ -208,12 +208,6 @@ class ByeDpiVpnService : LifecycleVpnService() {
|
|||||||
|
|
||||||
TProxyService.TProxyStartService(configPath.absolutePath, fd.fd)
|
TProxyService.TProxyStartService(configPath.absolutePath, fd.fd)
|
||||||
|
|
||||||
try {
|
|
||||||
File(cacheDir, "config.tmp").delete()
|
|
||||||
} catch (e: SecurityException) {
|
|
||||||
Log.e(TAG, "Failed to delete config file", e)
|
|
||||||
}
|
|
||||||
|
|
||||||
Log.i(TAG, "Tun2Socks started")
|
Log.i(TAG, "Tun2Socks started")
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -222,6 +216,12 @@ class ByeDpiVpnService : LifecycleVpnService() {
|
|||||||
|
|
||||||
TProxyService.TProxyStopService()
|
TProxyService.TProxyStopService()
|
||||||
|
|
||||||
|
try {
|
||||||
|
File(cacheDir, "config.tmp").delete()
|
||||||
|
} catch (e: SecurityException) {
|
||||||
|
Log.e(TAG, "Failed to delete config file", e)
|
||||||
|
}
|
||||||
|
|
||||||
tunFd?.close() ?: Log.w(TAG, "VPN not running")
|
tunFd?.close() ?: Log.w(TAG, "VPN not running")
|
||||||
tunFd = null
|
tunFd = null
|
||||||
|
|
||||||
|
@ -10,6 +10,16 @@ import androidx.preference.PreferenceFragmentCompat
|
|||||||
private const val TAG = "ValidateUtils"
|
private const val TAG = "ValidateUtils"
|
||||||
|
|
||||||
fun checkIp(ip: String): Boolean =
|
fun checkIp(ip: String): Boolean =
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
|
||||||
|
InetAddresses.isNumericAddress(ip)
|
||||||
|
} else {
|
||||||
|
// This pattern doesn't not support IPv6
|
||||||
|
// @Suppress("DEPRECATION")
|
||||||
|
// Patterns.IP_ADDRESS.matcher(ip).matches()
|
||||||
|
true
|
||||||
|
}
|
||||||
|
|
||||||
|
fun checkNotLocalIp(ip: String): Boolean =
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
|
||||||
InetAddresses.isNumericAddress(ip) && InetAddresses.parseNumericAddress(ip).let {
|
InetAddresses.isNumericAddress(ip) && InetAddresses.parseNumericAddress(ip).let {
|
||||||
!it.isAnyLocalAddress && !it.isLoopbackAddress
|
!it.isAnyLocalAddress && !it.isLoopbackAddress
|
||||||
|
@ -26,6 +26,7 @@
|
|||||||
<item name="disorder">Disorder</item>
|
<item name="disorder">Disorder</item>
|
||||||
<item name="fake">Fake</item>
|
<item name="fake">Fake</item>
|
||||||
<item name="oob">Out-of-band</item>
|
<item name="oob">Out-of-band</item>
|
||||||
|
<item name="oob">Disordered out-of-band</item>
|
||||||
</array>
|
</array>
|
||||||
<array name="byedpi_desync_methods_entries">
|
<array name="byedpi_desync_methods_entries">
|
||||||
<item name="none">none</item>
|
<item name="none">none</item>
|
||||||
@ -33,6 +34,7 @@
|
|||||||
<item name="disorder">disorder</item>
|
<item name="disorder">disorder</item>
|
||||||
<item name="fake">fake</item>
|
<item name="fake">fake</item>
|
||||||
<item name="oob">oob</item>
|
<item name="oob">oob</item>
|
||||||
|
<item name="oob">disoob</item>
|
||||||
</array>
|
</array>
|
||||||
|
|
||||||
<array name="byedpi_hosts_modes">
|
<array name="byedpi_hosts_modes">
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
<resources>
|
<resources>
|
||||||
<string name="byedpi_docs">https://github.com/hufrea/byedpi/tree/v0.12#readme</string>
|
<string name="byedpi_docs">https://github.com/hufrea/byedpi/blob/v0.13/README.md</string>
|
||||||
<string name="app_name">ByeDPI</string>
|
<string name="app_name">ByeDPI</string>
|
||||||
<string name="vpn_connect">Connect</string>
|
<string name="vpn_connect">Connect</string>
|
||||||
<string name="vpn_disconnect">Disconnect</string>
|
<string name="vpn_disconnect">Disconnect</string>
|
||||||
@ -65,4 +65,11 @@
|
|||||||
<string name="byedpi_tcp_fast_open_setting">TCP Fast Open</string>
|
<string name="byedpi_tcp_fast_open_setting">TCP Fast Open</string>
|
||||||
<string name="byedpi_udp_fake_count">UDP fake count</string>
|
<string name="byedpi_udp_fake_count">UDP fake count</string>
|
||||||
<string name="ipv6_setting">IPv6</string>
|
<string name="ipv6_setting">IPv6</string>
|
||||||
|
<string name="byedpi_fake_offset_setting">Fake offset</string>
|
||||||
|
<string name="byedpi_drop_sack_setting">Drop SACK</string>
|
||||||
|
<string name="desync_udp_category">UDP</string>
|
||||||
|
<string name="desync_http_category">HTTP</string>
|
||||||
|
<string name="desync_https_category">HTTPS</string>
|
||||||
|
<string name="byedpi_protocols_category">Protocols</string>
|
||||||
|
<string name="byedpi_protocols_hint">Uncheck all to desync all traffic</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
@ -48,6 +48,11 @@
|
|||||||
android:title="@string/byedpi_no_domain_setting"
|
android:title="@string/byedpi_no_domain_setting"
|
||||||
android:defaultValue="false" />
|
android:defaultValue="false" />
|
||||||
|
|
||||||
|
<CheckBoxPreference
|
||||||
|
android:key="byedpi_tcp_fast_open"
|
||||||
|
android:title="@string/byedpi_tcp_fast_open_setting"
|
||||||
|
android:defaultValue="false" />
|
||||||
|
|
||||||
</androidx.preference.PreferenceCategory>
|
</androidx.preference.PreferenceCategory>
|
||||||
|
|
||||||
<androidx.preference.PreferenceCategory
|
<androidx.preference.PreferenceCategory
|
||||||
@ -75,11 +80,6 @@
|
|||||||
android:inputType="textMultiLine"
|
android:inputType="textMultiLine"
|
||||||
app:useSimpleSummaryProvider="true" />
|
app:useSimpleSummaryProvider="true" />
|
||||||
|
|
||||||
<CheckBoxPreference
|
|
||||||
android:key="byedpi_tcp_fast_open"
|
|
||||||
android:title="@string/byedpi_tcp_fast_open_setting"
|
|
||||||
android:defaultValue="false" />
|
|
||||||
|
|
||||||
<com.takisoft.preferencex.EditTextPreference
|
<com.takisoft.preferencex.EditTextPreference
|
||||||
android:key="byedpi_default_ttl"
|
android:key="byedpi_default_ttl"
|
||||||
android:title="@string/byedpi_default_ttl_setting"
|
android:title="@string/byedpi_default_ttl_setting"
|
||||||
@ -95,6 +95,55 @@
|
|||||||
android:defaultValue="disorder"
|
android:defaultValue="disorder"
|
||||||
app:useSimpleSummaryProvider="true" />
|
app:useSimpleSummaryProvider="true" />
|
||||||
|
|
||||||
|
<com.takisoft.preferencex.EditTextPreference
|
||||||
|
android:key="byedpi_split_position"
|
||||||
|
android:title="@string/byedpi_split_position_setting"
|
||||||
|
android:inputType="numberSigned"
|
||||||
|
android:defaultValue="1"
|
||||||
|
app:useSimpleSummaryProvider="true" />
|
||||||
|
|
||||||
|
<CheckBoxPreference
|
||||||
|
android:key="byedpi_split_at_host"
|
||||||
|
android:title="@string/byedpi_split_at_host_setting"
|
||||||
|
android:defaultValue="false" />
|
||||||
|
|
||||||
|
<CheckBoxPreference
|
||||||
|
android:key="byedpi_drop_sack"
|
||||||
|
android:title="@string/byedpi_drop_sack_setting"
|
||||||
|
android:defaultValue="false" />
|
||||||
|
|
||||||
|
<com.takisoft.preferencex.EditTextPreference
|
||||||
|
android:key="byedpi_fake_ttl"
|
||||||
|
android:title="@string/byedpi_fake_ttl_setting"
|
||||||
|
android:inputType="number"
|
||||||
|
android:defaultValue="8"
|
||||||
|
app:useSimpleSummaryProvider="true" />
|
||||||
|
|
||||||
|
<com.takisoft.preferencex.EditTextPreference
|
||||||
|
android:key="byedpi_fake_offset"
|
||||||
|
android:title="@string/byedpi_fake_offset_setting"
|
||||||
|
android:inputType="number"
|
||||||
|
android:defaultValue="0"
|
||||||
|
app:useSimpleSummaryProvider="true" />
|
||||||
|
|
||||||
|
<com.takisoft.preferencex.EditTextPreference
|
||||||
|
android:key="byedpi_fake_sni"
|
||||||
|
android:title="@string/sni_of_fake_packet"
|
||||||
|
android:defaultValue="www.iana.org"
|
||||||
|
app:useSimpleSummaryProvider="true" />
|
||||||
|
|
||||||
|
<com.takisoft.preferencex.EditTextPreference
|
||||||
|
android:key="byedpi_oob_data"
|
||||||
|
android:title="@string/oob_data"
|
||||||
|
android:defaultValue="a"
|
||||||
|
app:useSimpleSummaryProvider="true" />
|
||||||
|
|
||||||
|
</androidx.preference.PreferenceCategory>
|
||||||
|
|
||||||
|
<androidx.preference.PreferenceCategory
|
||||||
|
android:title="@string/byedpi_protocols_category"
|
||||||
|
android:summary="@string/byedpi_protocols_hint">
|
||||||
|
|
||||||
<CheckBoxPreference
|
<CheckBoxPreference
|
||||||
android:key="byedpi_desync_http"
|
android:key="byedpi_desync_http"
|
||||||
android:title="@string/desync_http"
|
android:title="@string/desync_http"
|
||||||
@ -110,43 +159,10 @@
|
|||||||
android:title="@string/desync_udp"
|
android:title="@string/desync_udp"
|
||||||
android:defaultValue="false" />
|
android:defaultValue="false" />
|
||||||
|
|
||||||
<com.takisoft.preferencex.EditTextPreference
|
</androidx.preference.PreferenceCategory>
|
||||||
android:key="byedpi_split_position"
|
|
||||||
android:title="@string/byedpi_split_position_setting"
|
|
||||||
android:inputType="numberSigned"
|
|
||||||
android:defaultValue="2"
|
|
||||||
app:useSimpleSummaryProvider="true" />
|
|
||||||
|
|
||||||
<CheckBoxPreference
|
<androidx.preference.PreferenceCategory
|
||||||
android:key="byedpi_split_at_host"
|
android:title="@string/desync_http_category">
|
||||||
android:title="@string/byedpi_split_at_host_setting"
|
|
||||||
android:defaultValue="false" />
|
|
||||||
|
|
||||||
<com.takisoft.preferencex.EditTextPreference
|
|
||||||
android:key="byedpi_fake_ttl"
|
|
||||||
android:title="@string/byedpi_fake_ttl_setting"
|
|
||||||
android:inputType="number"
|
|
||||||
android:defaultValue="8"
|
|
||||||
app:useSimpleSummaryProvider="true" />
|
|
||||||
|
|
||||||
<com.takisoft.preferencex.EditTextPreference
|
|
||||||
android:key="byedpi_fake_sni"
|
|
||||||
android:title="@string/sni_of_fake_packet"
|
|
||||||
android:defaultValue="www.iana.org"
|
|
||||||
app:useSimpleSummaryProvider="true" />
|
|
||||||
|
|
||||||
<com.takisoft.preferencex.EditTextPreference
|
|
||||||
android:key="byedpi_oob_data"
|
|
||||||
android:title="@string/oob_data"
|
|
||||||
android:defaultValue="a"
|
|
||||||
app:useSimpleSummaryProvider="true" />
|
|
||||||
|
|
||||||
<com.takisoft.preferencex.EditTextPreference
|
|
||||||
android:key="byedpi_udp_fake_count"
|
|
||||||
android:title="@string/byedpi_udp_fake_count"
|
|
||||||
android:inputType="number"
|
|
||||||
android:defaultValue="0"
|
|
||||||
app:useSimpleSummaryProvider="true" />
|
|
||||||
|
|
||||||
<CheckBoxPreference
|
<CheckBoxPreference
|
||||||
android:key="byedpi_host_mixed_case"
|
android:key="byedpi_host_mixed_case"
|
||||||
@ -163,6 +179,11 @@
|
|||||||
android:title="@string/byedpi_host_remove_spaces_setting"
|
android:title="@string/byedpi_host_remove_spaces_setting"
|
||||||
android:defaultValue="false"/>
|
android:defaultValue="false"/>
|
||||||
|
|
||||||
|
</androidx.preference.PreferenceCategory>
|
||||||
|
|
||||||
|
<androidx.preference.PreferenceCategory
|
||||||
|
android:title="@string/desync_https_category">
|
||||||
|
|
||||||
<CheckBoxPreference
|
<CheckBoxPreference
|
||||||
android:key="byedpi_tlsrec_enabled"
|
android:key="byedpi_tlsrec_enabled"
|
||||||
android:title="@string/byedpi_tlsrec_enabled_setting"
|
android:title="@string/byedpi_tlsrec_enabled_setting"
|
||||||
@ -182,4 +203,16 @@
|
|||||||
|
|
||||||
</androidx.preference.PreferenceCategory>
|
</androidx.preference.PreferenceCategory>
|
||||||
|
|
||||||
|
<androidx.preference.PreferenceCategory
|
||||||
|
android:title="@string/desync_udp_category">
|
||||||
|
|
||||||
|
<com.takisoft.preferencex.EditTextPreference
|
||||||
|
android:key="byedpi_udp_fake_count"
|
||||||
|
android:title="@string/byedpi_udp_fake_count"
|
||||||
|
android:inputType="number"
|
||||||
|
android:defaultValue="0"
|
||||||
|
app:useSimpleSummaryProvider="true" />
|
||||||
|
|
||||||
|
</androidx.preference.PreferenceCategory>
|
||||||
|
|
||||||
</PreferenceScreen>
|
</PreferenceScreen>
|
||||||
|
@ -1 +1 @@
|
|||||||
<p><i>ByeDPI</i> runs a local VPN service to bypass DPI (Deep Packet Inspection) and censorship. It runs a SOCKS5 proxy <a href='https://github.com/hufrea/byedpi' target='_blank' rel='nofollow noopener'>ByeDPI</a> and redirects all traffic through it.</p><p>To bypass some blocks, you may need to change the settings. More about the various settings can be found in the <a href='https://github.com/hufrea/byedpi#readme-ov-file' target='_blank' rel='nofollow noopener'>ByeDPI documentation</a>.</p><p>The application uses the VPN mode on Android to redirect traffic, but does not send anything to a remote server. It does not encrypt traffic and does not hide your IP address.</p>
|
<p><i>ByeDPI</i> runs a local VPN service to bypass DPI (Deep Packet Inspection) and censorship. It runs a SOCKS5 proxy <a href='https://github.com/hufrea/byedpi' target='_blank' rel='nofollow noopener'>ByeDPI</a> and redirects all traffic through it.</p><p>To bypass some blocks, you may need to change the settings. More about the various settings can be found in the <a href='https://github.com/hufrea/byedpi/blob/main/README.md' target='_blank' rel='nofollow noopener'>ByeDPI documentation</a>.</p><p>The application uses the VPN mode on Android to redirect traffic, but does not send anything to a remote server. It does not encrypt traffic and does not hide your IP address.</p>
|
@ -1 +1 @@
|
|||||||
<p><i>ByeDPI</i> runs a local VPN service to bypass DPI (Deep Packet Inspection) and censorship. It runs a SOCKS5 proxy <a href='https://github.com/hufrea/byedpi' target='_blank' rel='nofollow noopener'>ByeDPI</a> and redirects all traffic through it.</p><p>To bypass some blocks, you may need to change the settings. More about the various settings can be found in the <a href='https://github.com/hufrea/byedpi#readme-ov-file' target='_blank' rel='nofollow noopener'>ByeDPI documentation</a>.</p><p>The application uses the VPN mode on Android to redirect traffic, but does not send anything to a remote server. It does not encrypt traffic and does not hide your IP address.</p>
|
<p><i>ByeDPI</i> runs a local VPN service to bypass DPI (Deep Packet Inspection) and censorship. It runs a SOCKS5 proxy <a href='https://github.com/hufrea/byedpi' target='_blank' rel='nofollow noopener'>ByeDPI</a> and redirects all traffic through it.</p><p>To bypass some blocks, you may need to change the settings. More about the various settings can be found in the <a href='https://github.com/hufrea/byedpi/blob/main/README.md' target='_blank' rel='nofollow noopener'>ByeDPI documentation</a>.</p><p>The application uses the VPN mode on Android to redirect traffic, but does not send anything to a remote server. It does not encrypt traffic and does not hide your IP address.</p>
|
Loading…
Reference in New Issue
Block a user