mirror of
https://github.com/dovecoteescapee/ByeDPIAndroid.git
synced 2024-11-20 12:34:39 +00:00
Merge pull request #56 from dovecoteescapee/byedpi-v0.12
Update byedpi core
This commit is contained in:
commit
2809eb3982
26
README-ru.md
26
README-ru.md
@ -2,8 +2,8 @@
|
||||
|
||||
[English](README.md) | **Русский**
|
||||
|
||||
<div align="center">
|
||||
<img src=".github/images/logo.svg" height="200px" width="200px" />
|
||||
<div style="text-align: center;">
|
||||
<img src=".github/images/logo.svg" width="100%" height="200px">
|
||||
</div>
|
||||
|
||||
---
|
||||
@ -55,8 +55,7 @@ DPI (Deep Packet Inspection) - это технология для анализа
|
||||
## Зависимости
|
||||
|
||||
- [ByeDPI](https://github.com/hufrea/byedpi)
|
||||
- [Tun2Socks](https://github.com/dovecoteescapee/tun2socks)*
|
||||
*форк с добавлением раздельного тунелирования TCP и UDP
|
||||
- [Tun2Socks](https://github.com/xjasonlyu/tun2socks)
|
||||
|
||||
## Сборка
|
||||
|
||||
@ -70,8 +69,17 @@ DPI (Deep Packet Inspection) - это технология для анализа
|
||||
|
||||
Сборка приложения:
|
||||
|
||||
1. Клонируйте репозиторий с подмодулями:
|
||||
`git clone --recurse-submodules`
|
||||
2. Запустите скрипт сборки из корня репозитория:
|
||||
`./gradlew assembleRelease`
|
||||
3. APK будет лежать в `app/build/outputs/apk/release/`
|
||||
1. Установите gomobile:
|
||||
```bash
|
||||
go install golang.org/x/mobile/cmd/gomobile@latest
|
||||
gomobile init
|
||||
```
|
||||
2. Клонируйте репозиторий с подмодулями:
|
||||
```bash
|
||||
git clone --recurse-submodules
|
||||
```
|
||||
3. Запустите скрипт сборки из корня репозитория:
|
||||
```bash
|
||||
./gradlew assembleRelease`
|
||||
```
|
||||
4. APK будет лежать в `app/build/outputs/apk/release/`
|
||||
|
26
README.md
26
README.md
@ -2,8 +2,8 @@
|
||||
|
||||
**English** | [Русский](README-ru.md)
|
||||
|
||||
<div align="center">
|
||||
<img src=".github/images/logo.svg" height="200px" width="200px" />
|
||||
<div style="text-align: center;">
|
||||
<img src=".github/images/logo.svg" width="100%" height="200px">
|
||||
</div>
|
||||
|
||||
---
|
||||
@ -55,8 +55,7 @@ DPI (Deep Packet Inspection) is a technology for analyzing and filtering traffic
|
||||
## Dependencies
|
||||
|
||||
- [ByeDPI](https://github.com/hufrea/byedpi)
|
||||
- [Tun2Socks](https://github.com/dovecoteescapee/tun2socks)*
|
||||
*fork with the addition of separate tunneling of TCP and UDP
|
||||
- [Tun2Socks](https://github.com/xjasonlyu/tun2socks)
|
||||
|
||||
## Building
|
||||
|
||||
@ -70,8 +69,17 @@ For building the application, you need:
|
||||
|
||||
To build the application:
|
||||
|
||||
1. Clone the repository with submodules:
|
||||
`git clone --recurse-submodules`
|
||||
2. Run the build script from the root of the repository:
|
||||
`./gradlew assembleRelease`
|
||||
3. The APK will be in `app/build/outputs/apk/release/`
|
||||
1. Install gomobile:
|
||||
```bash
|
||||
go install golang.org/x/mobile/cmd/gomobile@latest
|
||||
gomobile init
|
||||
```
|
||||
2. Clone the repository with submodules:
|
||||
```bash
|
||||
git clone --recurse-submodules
|
||||
```
|
||||
3. Run the build script from the root of the repository:
|
||||
```bash
|
||||
./gradlew assembleRelease
|
||||
```
|
||||
4. The APK will be in `app/build/outputs/apk/release/`
|
||||
|
@ -69,26 +69,75 @@ dependencies {
|
||||
androidTestImplementation("androidx.test.espresso:espresso-core:3.6.1")
|
||||
}
|
||||
|
||||
abstract class BuildTun2Socks : DefaultTask() {
|
||||
@TaskAction
|
||||
fun buildTun2Socks() {
|
||||
val projectDir = project.projectDir
|
||||
val tun2socksDir = projectDir.resolve("libs/tun2socks")
|
||||
val tun2socksOutput = projectDir.resolve("libs/tun2socks.aar")
|
||||
abstract class BaseTun2SocksTask : DefaultTask() {
|
||||
@get:InputDirectory
|
||||
val tun2socksDir: File
|
||||
get() = project.file("libs/tun2socks")
|
||||
|
||||
@get:OutputFile
|
||||
val tun2socksOutput: File
|
||||
get() = project.file("libs/tun2socks.aar")
|
||||
|
||||
@Internal
|
||||
protected fun isUpToDate(): Boolean {
|
||||
if (tun2socksOutput.exists()) {
|
||||
val lastModified = tun2socksOutput.lastModified()
|
||||
return !tun2socksDir.walkTopDown().any {
|
||||
it.isFile && it.lastModified() > lastModified
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
abstract class GetGomobileBind : BaseTun2SocksTask() {
|
||||
@TaskAction
|
||||
fun getBind() {
|
||||
if (isUpToDate()) {
|
||||
logger.lifecycle("No changes detected, skipping getBind.")
|
||||
return
|
||||
}
|
||||
|
||||
project.exec {
|
||||
workingDir = tun2socksDir
|
||||
commandLine("gomobile", "bind", "-o", tun2socksOutput, "-trimpath", "./engine")
|
||||
|
||||
commandLine("go", "get", "golang.org/x/mobile/bind")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
abstract class BuildTun2Socks : BaseTun2SocksTask() {
|
||||
@TaskAction
|
||||
fun buildTun2Socks() {
|
||||
if (isUpToDate()) {
|
||||
logger.lifecycle("No changes detected, skipping buildTun2Socks.")
|
||||
return
|
||||
}
|
||||
|
||||
project.exec {
|
||||
workingDir = tun2socksDir
|
||||
|
||||
commandLine(
|
||||
"gomobile", "bind",
|
||||
"-target", "android",
|
||||
"-androidapi", "21",
|
||||
"-o", tun2socksOutput,
|
||||
"-trimpath",
|
||||
"./engine"
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
tasks.register<GetGomobileBind>("getGomobileBind") {
|
||||
group = "build"
|
||||
description = "Get gomobile bind for compiling tun2socks"
|
||||
}
|
||||
|
||||
tasks.register<BuildTun2Socks>("buildTun2Socks") {
|
||||
group = "build"
|
||||
description = "Build tun2socks"
|
||||
description = "Build tun2socks for Android"
|
||||
dependsOn("getGomobileBind")
|
||||
}
|
||||
|
||||
tasks.withType(KotlinCompile::class).configureEach {
|
||||
|
@ -1 +1 @@
|
||||
Subproject commit b357c5b50ac07aa36aed843b803df06a307fe61a
|
||||
Subproject commit e083dafcf534d85e7fce86b3d48ee5c7a63c604e
|
@ -28,10 +28,13 @@ add_library(${CMAKE_PROJECT_NAME} SHARED
|
||||
# List C/C++ source files with relative paths to this CMakeLists.txt.
|
||||
byedpi/conev.c
|
||||
byedpi/desync.c
|
||||
byedpi/extend.c
|
||||
byedpi/packets.c
|
||||
byedpi/proxy.c
|
||||
byedpi/main.c
|
||||
byedpi/mpool.c
|
||||
native-lib.c
|
||||
utils.c
|
||||
)
|
||||
|
||||
include_directories("byedpi")
|
||||
@ -46,4 +49,5 @@ add_compile_definitions(ANDROID_APP)
|
||||
target_link_libraries(${CMAKE_PROJECT_NAME}
|
||||
# List libraries link to the target library
|
||||
android
|
||||
log)
|
||||
log
|
||||
)
|
@ -1 +1 @@
|
||||
Subproject commit 6b484d598817cffd61344a812721fb00089f5095
|
||||
Subproject commit dcf5ed727c996d0073a6cb95d5eec45a793d28a2
|
12
app/src/main/cpp/main.h
Normal file
12
app/src/main/cpp/main.h
Normal file
@ -0,0 +1,12 @@
|
||||
extern char *oob_char;
|
||||
extern int NOT_EXIT;
|
||||
|
||||
struct sockaddr_ina;
|
||||
|
||||
int get_default_ttl();
|
||||
|
||||
int get_addr(const char *str, struct sockaddr_ina *addr);
|
||||
|
||||
void *add(void **root, int *n, size_t ss);
|
||||
|
||||
void clear_params(void);
|
@ -1,14 +1,16 @@
|
||||
#include <error.h>
|
||||
#include <proxy.h>
|
||||
#include <params.h>
|
||||
#include <packets.h>
|
||||
#include <unistd.h>
|
||||
#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,
|
||||
@ -17,14 +19,9 @@ const enum demode DESYNC_METHODS[] = {
|
||||
DESYNC_OOB,
|
||||
};
|
||||
|
||||
extern int NOT_EXIT;
|
||||
|
||||
extern int get_default_ttl();
|
||||
|
||||
extern int get_addr(const char *str, struct sockaddr_ina *addr);
|
||||
|
||||
JNIEXPORT jint JNI_OnLoad(JavaVM *vm, __attribute__((unused)) void *reserved) {
|
||||
oob_data.data = NULL;
|
||||
default_params = params;
|
||||
return JNI_VERSION_1_6;
|
||||
}
|
||||
|
||||
@ -37,8 +34,8 @@ Java_io_github_dovecoteescapee_byedpi_core_ByeDpiProxy_jniCreateSocket(
|
||||
jint max_connections,
|
||||
jint buffer_size,
|
||||
jint default_ttl,
|
||||
jboolean custom_ttl,
|
||||
jboolean no_domain,
|
||||
jboolean desync_known,
|
||||
jint desync_method,
|
||||
jint split_position,
|
||||
jboolean split_at_host,
|
||||
@ -52,52 +49,90 @@ Java_io_github_dovecoteescapee_byedpi_core_ByeDpiProxy_jniCreateSocket(
|
||||
jint tls_record_split_position,
|
||||
jboolean tls_record_split_at_sni) {
|
||||
|
||||
struct sockaddr_ina s = {
|
||||
.in.sin_family = AF_INET,
|
||||
.in.sin_addr.s_addr = inet_addr("0.0.0.0"),
|
||||
};
|
||||
struct sockaddr_ina s;
|
||||
|
||||
const char *address = (*env)->GetStringUTFChars(env, ip, 0);
|
||||
if (get_addr(address, &s) < 0) {
|
||||
int res = get_addr(address, &s);
|
||||
(*env)->ReleaseStringUTFChars(env, ip, address);
|
||||
if (res < 0) {
|
||||
uniperror("get_addr");
|
||||
return -1;
|
||||
}
|
||||
(*env)->ReleaseStringUTFChars(env, ip, address);
|
||||
|
||||
s.in.sin_port = htons(port);
|
||||
|
||||
params.max_open = max_connections;
|
||||
params.bfsize = buffer_size;
|
||||
params.def_ttl = default_ttl;
|
||||
params.resolve = !no_domain;
|
||||
params.de_known = desync_known;
|
||||
params.attack = DESYNC_METHODS[desync_method];
|
||||
params.split = split_position;
|
||||
params.split_host = split_at_host;
|
||||
params.ttl = fake_ttl;
|
||||
params.mod_http =
|
||||
MH_HMIX * host_mixed_case |
|
||||
MH_DMIX * domain_mixed_case |
|
||||
MH_SPACE * host_remove_spaces;
|
||||
params.tlsrec = tls_record_split;
|
||||
params.tlsrec_pos = tls_record_split_position;
|
||||
params.tlsrec_sni = tls_record_split_at_sni;
|
||||
|
||||
if (!params.def_ttl && params.attack != DESYNC_NONE) {
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
int fd = listen_socket(&s);
|
||||
if (fd < 0) {
|
||||
uniperror("listen_socket");
|
||||
return get_e();
|
||||
struct desync_params *dp = add(
|
||||
(void *) ¶ms.dp,
|
||||
¶ms.dp_count,
|
||||
sizeof(struct desync_params)
|
||||
);
|
||||
if (!dp) {
|
||||
uniperror("add");
|
||||
reset_params();
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (params.attack == DESYNC_FAKE) {
|
||||
dp->ttl = fake_ttl;
|
||||
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];
|
||||
|
||||
part->flag = split_at_host ? OFFSET_SNI : 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_SNI : 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);
|
||||
int res = change_tls_sni(sni, fake_tls.data, fake_tls.size);
|
||||
res = change_tls_sni(sni, fake_tls.data, fake_tls.size);
|
||||
(*env)->ReleaseStringUTFChars(env, fake_sni, sni);
|
||||
if (res) {
|
||||
fprintf(stderr, "error chsni\n");
|
||||
@ -105,14 +140,11 @@ Java_io_github_dovecoteescapee_byedpi_core_ByeDpiProxy_jniCreateSocket(
|
||||
}
|
||||
}
|
||||
|
||||
if (params.attack == DESYNC_OOB) {
|
||||
if (mode == DESYNC_OOB) {
|
||||
const char *oob = (*env)->GetStringUTFChars(env, custom_oob_data, 0);
|
||||
const size_t oob_len = strlen(oob);
|
||||
LOG(LOG_L, "custom_oob_data: %s", oob);
|
||||
|
||||
oob_data.size = oob_len;
|
||||
LOG(LOG_L, "before free");
|
||||
free(oob_data.data);
|
||||
LOG(LOG_L, "after free");
|
||||
oob_data.data = malloc(oob_len);
|
||||
if (oob_data.data == NULL) {
|
||||
uniperror("malloc");
|
||||
@ -122,7 +154,20 @@ Java_io_github_dovecoteescapee_byedpi_core_ByeDpiProxy_jniCreateSocket(
|
||||
(*env)->ReleaseStringUTFChars(env, custom_oob_data, oob);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
@ -134,6 +179,7 @@ Java_io_github_dovecoteescapee_byedpi_core_ByeDpiProxy_jniStartProxy(
|
||||
LOG(LOG_S, "start_proxy, fd: %d", fd);
|
||||
NOT_EXIT = 1;
|
||||
if (event_loop(fd) < 0) {
|
||||
uniperror("event_loop");
|
||||
return get_e();
|
||||
}
|
||||
return 0;
|
||||
@ -145,7 +191,12 @@ Java_io_github_dovecoteescapee_byedpi_core_ByeDpiProxy_jniStopProxy(
|
||||
__attribute__((unused)) jobject thiz,
|
||||
jint fd) {
|
||||
LOG(LOG_S, "stop_proxy, fd: %d", fd);
|
||||
if (shutdown(fd, SHUT_RDWR) < 0) {
|
||||
|
||||
int res = shutdown(fd, SHUT_RDWR);
|
||||
reset_params();
|
||||
|
||||
if (res < 0) {
|
||||
uniperror("shutdown");
|
||||
return get_e();
|
||||
}
|
||||
return 0;
|
||||
|
10
app/src/main/cpp/utils.c
Normal file
10
app/src/main/cpp/utils.c
Normal file
@ -0,0 +1,10 @@
|
||||
#include "utils.h"
|
||||
#include "byedpi/params.h"
|
||||
#include "main.h"
|
||||
|
||||
struct params default_params;
|
||||
|
||||
void reset_params(void) {
|
||||
clear_params();
|
||||
params = default_params;
|
||||
}
|
3
app/src/main/cpp/utils.h
Normal file
3
app/src/main/cpp/utils.h
Normal file
@ -0,0 +1,3 @@
|
||||
extern struct params default_params;
|
||||
|
||||
void reset_params(void);
|
@ -2,7 +2,6 @@ package io.github.dovecoteescapee.byedpi.core
|
||||
|
||||
import kotlinx.coroutines.sync.Mutex
|
||||
import kotlinx.coroutines.sync.withLock
|
||||
import java.io.IOException
|
||||
|
||||
class ByeDpiProxy {
|
||||
companion object {
|
||||
@ -14,8 +13,13 @@ class ByeDpiProxy {
|
||||
private val mutex = Mutex()
|
||||
private var fd = -1
|
||||
|
||||
suspend fun startProxy(preferences: ByeDpiProxyPreferences): Int =
|
||||
jniStartProxy(createSocket(preferences))
|
||||
suspend fun startProxy(preferences: ByeDpiProxyPreferences): Int {
|
||||
val fd = createSocket(preferences)
|
||||
if (fd < 0) {
|
||||
return -1 // TODO: should be error code
|
||||
}
|
||||
return jniStartProxy(fd)
|
||||
}
|
||||
|
||||
suspend fun stopProxy(): Int {
|
||||
mutex.withLock {
|
||||
@ -43,8 +47,8 @@ class ByeDpiProxy {
|
||||
maxConnections = preferences.maxConnections,
|
||||
bufferSize = preferences.bufferSize,
|
||||
defaultTtl = preferences.defaultTtl,
|
||||
customTtl = preferences.customTtl,
|
||||
noDomain = preferences.noDomain,
|
||||
desyncKnown = preferences.desyncKnown,
|
||||
desyncMethod = preferences.desyncMethod.ordinal,
|
||||
splitPosition = preferences.splitPosition,
|
||||
splitAtHost = preferences.splitAtHost,
|
||||
@ -60,7 +64,7 @@ class ByeDpiProxy {
|
||||
)
|
||||
|
||||
if (fd < 0) {
|
||||
throw IOException("Failed to create socket")
|
||||
return -1
|
||||
}
|
||||
|
||||
this.fd = fd
|
||||
@ -73,8 +77,8 @@ class ByeDpiProxy {
|
||||
maxConnections: Int,
|
||||
bufferSize: Int,
|
||||
defaultTtl: Int,
|
||||
customTtl: Boolean,
|
||||
noDomain: Boolean,
|
||||
desyncKnown: Boolean,
|
||||
desyncMethod: Int,
|
||||
splitPosition: Int,
|
||||
splitAtHost: Boolean,
|
||||
|
@ -9,7 +9,6 @@ class ByeDpiProxyPreferences(
|
||||
bufferSize: Int? = null,
|
||||
defaultTtl: Int? = null,
|
||||
noDomain: Boolean? = null,
|
||||
desyncKnown: Boolean? = null,
|
||||
desyncMethod: DesyncMethod? = null,
|
||||
splitPosition: Int? = null,
|
||||
splitAtHost: Boolean? = null,
|
||||
@ -28,8 +27,8 @@ class ByeDpiProxyPreferences(
|
||||
val maxConnections: Int = maxConnections ?: 512
|
||||
val bufferSize: Int = bufferSize ?: 16384
|
||||
val defaultTtl: Int = defaultTtl ?: 0
|
||||
val customTtl: Boolean = defaultTtl != null
|
||||
val noDomain: Boolean = noDomain ?: false
|
||||
val desyncKnown: Boolean = desyncKnown ?: false
|
||||
val desyncMethod: DesyncMethod = desyncMethod ?: DesyncMethod.Disorder
|
||||
val splitPosition: Int = splitPosition ?: 3
|
||||
val splitAtHost: Boolean = splitAtHost ?: false
|
||||
@ -50,7 +49,6 @@ class ByeDpiProxyPreferences(
|
||||
bufferSize = preferences.getString("byedpi_buffer_size", null)?.toIntOrNull(),
|
||||
defaultTtl = preferences.getString("byedpi_default_ttl", null)?.toIntOrNull(),
|
||||
noDomain = preferences.getBoolean("byedpi_no_domain", false),
|
||||
desyncKnown = preferences.getBoolean("byedpi_desync_known", false),
|
||||
desyncMethod = preferences.getString("byedpi_desync_method", null)
|
||||
?.let { DesyncMethod.fromName(it) },
|
||||
splitPosition = preferences.getString("byedpi_split_position", null)?.toIntOrNull(),
|
||||
|
@ -170,7 +170,10 @@ class ByeDpiProxyService : LifecycleService() {
|
||||
when (newStatus) {
|
||||
ServiceStatus.Connected -> AppStatus.Running
|
||||
ServiceStatus.Disconnected,
|
||||
ServiceStatus.Failed -> AppStatus.Halted
|
||||
ServiceStatus.Failed -> {
|
||||
proxyJob = null
|
||||
AppStatus.Halted
|
||||
}
|
||||
},
|
||||
Mode.Proxy
|
||||
)
|
||||
|
@ -224,7 +224,10 @@ class ByeDpiVpnService : LifecycleVpnService() {
|
||||
when (newStatus) {
|
||||
ServiceStatus.Connected -> AppStatus.Running
|
||||
ServiceStatus.Disconnected,
|
||||
ServiceStatus.Failed -> AppStatus.Halted
|
||||
ServiceStatus.Failed -> {
|
||||
proxyJob = null
|
||||
AppStatus.Halted
|
||||
}
|
||||
},
|
||||
Mode.VPN
|
||||
)
|
||||
@ -281,8 +284,7 @@ class ByeDpiVpnService : LifecycleVpnService() {
|
||||
|
||||
setInterface("")
|
||||
logLevel = if (BuildConfig.DEBUG) "debug" else "info"
|
||||
udpProxy = "direct://"
|
||||
tcpProxy = "socks5://127.0.0.1:$port"
|
||||
proxy = "socks5://127.0.0.1:$port"
|
||||
|
||||
restAPI = ""
|
||||
tcpSendBufferSize = ""
|
||||
|
@ -8,10 +8,6 @@
|
||||
<string name="proxy_down">Proxy is down</string>
|
||||
<string name="proxy_start">Start</string>
|
||||
<string name="proxy_stop">Stop</string>
|
||||
<string name="vpn_connecting">Connecting…</string>
|
||||
<string name="vpn_disconnecting">Disconnecting…</string>
|
||||
<string name="proxy_starting">Starting</string>
|
||||
<string name="proxy_stopping">Stopping</string>
|
||||
<string name="settings">Settings</string>
|
||||
<string name="vpn_permission_denied">VPN permission denied</string>
|
||||
<string name="settings_unavailable">Please stop the VPN service before changing settings</string>
|
||||
@ -29,7 +25,6 @@
|
||||
<string name="byedpi_buffer_size_setting">Buffer size</string>
|
||||
<string name="byedpi_default_ttl_setting">Default TTL</string>
|
||||
<string name="byedpi_no_domain_setting">No domain</string>
|
||||
<string name="byedpi_desync_known_setting">Desync only HTTPS and TLS</string>
|
||||
<string name="byedpi_desync_method_setting">Desync method</string>
|
||||
<string name="byedpi_split_position_setting">Split position</string>
|
||||
<string name="byedpi_split_at_host_setting">Split at host</string>
|
||||
|
@ -83,11 +83,6 @@
|
||||
android:title="@string/byedpi_no_domain_setting"
|
||||
android:defaultValue="false"/>
|
||||
|
||||
<CheckBoxPreference
|
||||
android:key="byedpi_desync_known"
|
||||
android:title="@string/byedpi_desync_known_setting"
|
||||
android:defaultValue="false"/>
|
||||
|
||||
<DropDownPreference
|
||||
android:key="byedpi_desync_method"
|
||||
android:title="@string/byedpi_desync_method_setting"
|
||||
|
Loading…
Reference in New Issue
Block a user