diff --git a/README-ru.md b/README-ru.md index 49c0fe0a..39f7a1dc 100644 --- a/README-ru.md +++ b/README-ru.md @@ -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 diff --git a/README.md b/README.md index e725b616..dc621bd9 100644 --- a/README.md +++ b/README.md @@ -30,7 +30,7 @@ This application runs a SOCKS5 proxy [ByeDPI](https://github.com/hufrea/byedpi) ## 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 diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 330c5402..d7b4fbc5 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -11,8 +11,8 @@ android { applicationId = "io.github.dovecoteescapee.byedpi" minSdk = 21 targetSdk = 34 - versionCode = 9 - versionName = "1.1.1" + versionCode = 10 + versionName = "1.2.0" testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" diff --git a/app/src/main/cpp/byedpi b/app/src/main/cpp/byedpi index dcf5ed72..078842b0 160000 --- a/app/src/main/cpp/byedpi +++ b/app/src/main/cpp/byedpi @@ -1 +1 @@ -Subproject commit dcf5ed727c996d0073a6cb95d5eec45a793d28a2 +Subproject commit 078842b084853bc30f33eaaec7acc510cf67e560 diff --git a/app/src/main/cpp/main.h b/app/src/main/cpp/main.h index 5952df9f..263041ef 100644 --- a/app/src/main/cpp/main.h +++ b/app/src/main/cpp/main.h @@ -13,7 +13,10 @@ void clear_params(void); 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); diff --git a/app/src/main/cpp/native-lib.c b/app/src/main/cpp/native-lib.c index e615a0c3..283c826d 100644 --- a/app/src/main/cpp/native-lib.c +++ b/app/src/main/cpp/native-lib.c @@ -17,6 +17,7 @@ const enum demode DESYNC_METHODS[] = { DESYNC_DISORDER, DESYNC_FAKE, DESYNC_OOB, + DESYNC_DISOOB, }; enum hosts_mode { @@ -81,7 +82,7 @@ Java_io_github_dovecoteescapee_byedpi_core_ByeDpiProxy_jniCreateSocket( jboolean split_at_host, jint fake_ttl, jstring fake_sni, - jstring custom_oob_data, + jbyte custom_oob_char, jboolean host_mixed_case, jboolean domain_mixed_case, jboolean host_remove_spaces, @@ -91,7 +92,9 @@ Java_io_github_dovecoteescapee_byedpi_core_ByeDpiProxy_jniCreateSocket( jint hosts_mode, jstring hosts, jboolean tfo, - jint udp_fake_count) { + jint udp_fake_count, + jboolean drop_sack, + jint fake_offset) { struct sockaddr_ina s; 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); - dp->file_ptr = parse_cform(str, &dp->file_size); + dp->file_ptr = data_from_str(str, &dp->file_size); (*env)->ReleaseStringUTFChars(env, hosts, str); dp->hosts = parse_hosts(dp->file_ptr, dp->file_size); if (!dp->hosts) { @@ -158,7 +161,7 @@ Java_io_github_dovecoteescapee_byedpi_core_ByeDpiProxy_jniCreateSocket( if (hosts_mode == HOSTS_BLACKLIST) { 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); dp->hosts = parse_hosts(dp->file_ptr, dp->file_size); if (!dp->hosts) { @@ -170,6 +173,7 @@ Java_io_github_dovecoteescapee_byedpi_core_ByeDpiProxy_jniCreateSocket( dp->ttl = fake_ttl; dp->udp_fake_count = udp_fake_count; + dp->drop_sack = drop_sack; dp->proto = IS_HTTP * desync_http | IS_HTTPS * desync_https | @@ -216,6 +220,8 @@ Java_io_github_dovecoteescapee_byedpi_core_ByeDpiProxy_jniCreateSocket( } if (mode == DESYNC_FAKE) { + dp->fake_offset = fake_offset; + 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); @@ -227,17 +233,8 @@ Java_io_github_dovecoteescapee_byedpi_core_ByeDpiProxy_jniCreateSocket( } 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); + dp->oob_char[0] = custom_oob_char; + dp->oob_char[1] = 1; } if (dp->proto) { diff --git a/app/src/main/cpp/utils.c b/app/src/main/cpp/utils.c index dff4d360..ae06186f 100644 --- a/app/src/main/cpp/utils.c +++ b/app/src/main/cpp/utils.c @@ -15,9 +15,10 @@ void reset_params(void) { 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); for (int i = 0, e = optc; i < e; i++) optc += options[i].has_arg; @@ -50,8 +51,9 @@ int parse_args(int argc, char **argv) { optind = optreset = 1; - while (!invalid && (rez = getopt_long_only( + while (!invalid && (rez = getopt_long( argc, argv, opt, options, 0)) != -1) { + switch (rez) { case 'N': @@ -64,6 +66,15 @@ int parse_args(int argc, char **argv) { params.udp = 0; break; +// case 'h': +// printf(help_text); +// reset_params(); +// return 0; +// case 'v': +// printf("%s\n", VERSION); +// reset_params(); +// return 0; + case 'i': if (get_addr(optarg, (struct sockaddr_ina *)¶ms.laddr) < 0) @@ -119,10 +130,6 @@ int parse_args(int argc, char **argv) { reset_params(); return -1; } - if (!optarg) { - dp->detect |= DETECT_TORST; - break; - } end = optarg; while (end && !invalid) { switch (*end) { @@ -132,14 +139,9 @@ int parse_args(int argc, char **argv) { case 'r': dp->detect |= DETECT_HTTP_LOCAT; break; - case 'c': - dp->detect |= DETECT_HTTP_CLERR; - break; - case 's': - dp->detect |= DETECT_TLS_INVSID; - break; case 'a': - dp->detect |= DETECT_TLS_ALERT; + case 's': + dp->detect |= DETECT_TLS_ERR; break; case 'n': break; @@ -161,8 +163,12 @@ int parse_args(int argc, char **argv) { break; case 'T':; +#ifdef __linux__ float f = strtof(optarg, &end); val = (long)(f * 1000); +#else + val = strtol(optarg, &end, 0); +#endif if (val <= 0 || val > UINT_MAX || *end) invalid = 1; else @@ -212,6 +218,7 @@ int parse_args(int argc, char **argv) { case 's': case 'd': case 'o': + case 'q': case 'f': ; struct part *part = add((void *)&dp->parts, @@ -231,6 +238,8 @@ int parse_args(int argc, char **argv) { break; case 'o': part->m = DESYNC_OOB; break; + case 'q': part->m = DESYNC_DISOOB; + break; case 'f': part->m = DESYNC_FAKE; } break; @@ -263,13 +272,21 @@ int parse_args(int argc, char **argv) { dp->md5sig = 1; break; + case 'O': + val = strtol(optarg, &end, 0); + if (val <= 0 || *end) + invalid = 1; + else + dp->fake_offset = val; + break; + case 'n': if (change_tls_sni(optarg, fake_tls.data, fake_tls.size)) { - fprintf(stderr, "error chsni\n"); + perror("change_tls_sni"); reset_params(); return -1; } - printf("sni: %s\n", optarg); + LOG(LOG_S, "sni: %s", optarg); break; case 'l': @@ -284,14 +301,11 @@ int parse_args(int argc, char **argv) { break; case 'e': - if (oob_data.data != oob_char) { - continue; - } - oob_data.data = ftob(optarg, &oob_data.size); - if (!oob_data.data) { - uniperror("read/parse"); + val = parse_cform(dp->oob_char, 1, optarg, strlen(optarg)); + if (val != 1) { invalid = 1; } + else dp->oob_char[1] = 1; break; case 'M': @@ -366,6 +380,10 @@ int parse_args(int argc, char **argv) { } break; + case 'Y': + dp->drop_sack = 1; + break; + case 'w': // params.sfdelay = strtol(optarg, &end, 0); if (params.sfdelay < 0 || optarg == end @@ -376,9 +394,11 @@ int parse_args(int argc, char **argv) { case 'W': params.wait_send = 0; break; +#ifdef __linux__ case 'P': params.protect_path = optarg; break; +#endif case 0: break; @@ -387,13 +407,13 @@ int parse_args(int argc, char **argv) { return -1; default: - printf("?: %c\n", rez); + LOG(LOG_S, "Unknown option: -%c", rez); reset_params(); return -1; } } if (invalid) { - fprintf(stderr, "invalid value: -%c %s\n", rez, optarg); + LOG(LOG_S, "invalid value: -%c %s", rez, optarg); reset_params(); return -1; } diff --git a/app/src/main/java/io/github/dovecoteescapee/byedpi/core/ByeDpiProxy.kt b/app/src/main/java/io/github/dovecoteescapee/byedpi/core/ByeDpiProxy.kt index db780114..80331f4e 100644 --- a/app/src/main/java/io/github/dovecoteescapee/byedpi/core/ByeDpiProxy.kt +++ b/app/src/main/java/io/github/dovecoteescapee/byedpi/core/ByeDpiProxy.kt @@ -69,7 +69,7 @@ class ByeDpiProxy { splitAtHost = preferences.splitAtHost, fakeTtl = preferences.fakeTtl, fakeSni = preferences.fakeSni, - oobData = preferences.oobData, + oobChar = preferences.oobChar, hostMixedCase = preferences.hostMixedCase, domainMixedCase = preferences.domainMixedCase, hostRemoveSpaces = preferences.hostRemoveSpaces, @@ -80,6 +80,8 @@ class ByeDpiProxy { hosts = preferences.hosts, tcpFastOpen = preferences.tcpFastOpen, udpFakeCount = preferences.udpFakeCount, + dropSack = preferences.dropSack, + fakeOffset = preferences.fakeOffset, ) } @@ -101,7 +103,7 @@ class ByeDpiProxy { splitAtHost: Boolean, fakeTtl: Int, fakeSni: String, - oobData: String, + oobChar: Byte, hostMixedCase: Boolean, domainMixedCase: Boolean, hostRemoveSpaces: Boolean, @@ -112,6 +114,8 @@ class ByeDpiProxy { hosts: String?, tcpFastOpen: Boolean, udpFakeCount: Int, + dropSack: Boolean, + fakeOffset: Int, ): Int private external fun jniStartProxy(fd: Int): Int diff --git a/app/src/main/java/io/github/dovecoteescapee/byedpi/core/ByeDpiProxyPreferences.kt b/app/src/main/java/io/github/dovecoteescapee/byedpi/core/ByeDpiProxyPreferences.kt index 3f2b17d3..6df4c1c5 100644 --- a/app/src/main/java/io/github/dovecoteescapee/byedpi/core/ByeDpiProxyPreferences.kt +++ b/app/src/main/java/io/github/dovecoteescapee/byedpi/core/ByeDpiProxyPreferences.kt @@ -48,7 +48,7 @@ class ByeDpiProxyUIPreferences( splitAtHost: Boolean? = null, fakeTtl: Int? = null, fakeSni: String? = null, - oobData: String? = null, + oobChar: String? = null, hostMixedCase: Boolean? = null, domainMixedCase: Boolean? = null, hostRemoveSpaces: Boolean? = null, @@ -59,6 +59,8 @@ class ByeDpiProxyUIPreferences( hosts: String? = null, tcpFastOpen: Boolean? = null, udpFakeCount: Int? = null, + dropSack: Boolean? = null, + byedpiFakeOffset: Int? = null, ) : ByeDpiProxyPreferences { val ip: String = ip ?: "127.0.0.1" val port: Int = port ?: 1080 @@ -71,11 +73,11 @@ class ByeDpiProxyUIPreferences( val desyncHttps: Boolean = desyncHttps ?: true val desyncUdp: Boolean = desyncUdp ?: false val desyncMethod: DesyncMethod = desyncMethod ?: DesyncMethod.Disorder - val splitPosition: Int = splitPosition ?: 2 + val splitPosition: Int = splitPosition ?: 1 val splitAtHost: Boolean = splitAtHost ?: false val fakeTtl: Int = fakeTtl ?: 8 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 domainMixedCase: Boolean = domainMixedCase ?: false val hostRemoveSpaces: Boolean = hostRemoveSpaces ?: false @@ -90,6 +92,8 @@ class ByeDpiProxyUIPreferences( else hosts?.trim() val tcpFastOpen: Boolean = tcpFastOpen ?: false val udpFakeCount: Int = udpFakeCount ?: 0 + val dropSack: Boolean = dropSack ?: false + val fakeOffset: Int = byedpiFakeOffset ?: 0 constructor(preferences: SharedPreferences) : this( ip = preferences.getString("byedpi_proxy_ip", null), @@ -107,7 +111,7 @@ class ByeDpiProxyUIPreferences( splitAtHost = preferences.getBoolean("byedpi_split_at_host", false), fakeTtl = preferences.getString("byedpi_fake_ttl", null)?.toIntOrNull(), 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), domainMixedCase = preferences.getBoolean("byedpi_domain_mixed_case", false), hostRemoveSpaces = preferences.getBoolean("byedpi_host_remove_spaces", false), @@ -126,6 +130,8 @@ class ByeDpiProxyUIPreferences( }, tcpFastOpen = preferences.getBoolean("byedpi_tcp_fast_open", false), 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 { @@ -133,7 +139,8 @@ class ByeDpiProxyUIPreferences( Split, Disorder, Fake, - OOB; + OOB, + DISOOB; companion object { fun fromName(name: String): DesyncMethod { @@ -143,6 +150,7 @@ class ByeDpiProxyUIPreferences( "disorder" -> Disorder "fake" -> Fake "oob" -> OOB + "disoob" -> DISOOB else -> throw IllegalArgumentException("Unknown desync method: $name") } } diff --git a/app/src/main/java/io/github/dovecoteescapee/byedpi/fragments/ByeDpiUISettingsFragment.kt b/app/src/main/java/io/github/dovecoteescapee/byedpi/fragments/ByeDpiUISettingsFragment.kt index ae683391..315335c9 100644 --- a/app/src/main/java/io/github/dovecoteescapee/byedpi/fragments/ByeDpiUISettingsFragment.kt +++ b/app/src/main/java/io/github/dovecoteescapee/byedpi/fragments/ByeDpiUISettingsFragment.kt @@ -78,7 +78,8 @@ class ByeDpiUISettingsFragment : PreferenceFragmentCompat() { val splitAtHost = findPreferenceNotNull("byedpi_split_at_host") val ttlFake = findPreferenceNotNull("byedpi_fake_ttl") val fakeSni = findPreferenceNotNull("byedpi_fake_sni") - val oobData = findPreferenceNotNull("byedpi_oob_data") + val fakeOffset = findPreferenceNotNull("byedpi_fake_offset") + val oobChar = findPreferenceNotNull("byedpi_oob_data") val udpFakeCount = findPreferenceNotNull("byedpi_udp_fake_count") val hostMixedCase = findPreferenceNotNull("byedpi_host_mixed_case") val domainMixedCase = findPreferenceNotNull("byedpi_domain_mixed_case") @@ -89,81 +90,36 @@ class ByeDpiUISettingsFragment : PreferenceFragmentCompat() { findPreferenceNotNull("byedpi_tlsrec_position") val splitTlsRecAtSni = findPreferenceNotNull("byedpi_tlsrec_at_sni") - when (hostsMode) { - Disable -> { - hostsBlacklist.isVisible = false - hostsWhitelist.isVisible = false - } + hostsBlacklist.isVisible = hostsMode == Blacklist + hostsWhitelist.isVisible = hostsMode == Whitelist - Blacklist -> { - hostsBlacklist.isVisible = true - hostsWhitelist.isVisible = false - } + val desyncEnabled = desyncMethod != None + splitPosition.isVisible = desyncEnabled + splitAtHost.isVisible = desyncEnabled - Whitelist -> { - hostsBlacklist.isVisible = false - hostsWhitelist.isVisible = true - } - } + val isFake = desyncMethod == Fake + ttlFake.isVisible = isFake + fakeSni.isVisible = isFake + fakeOffset.isVisible = isFake + + val isOob = desyncMethod == OOB || desyncMethod == DISOOB + oobChar.isVisible = isOob val desyncAllProtocols = !desyncHttp.isChecked && !desyncHttps.isChecked && !desyncUdp.isChecked - if (desyncAllProtocols || desyncUdp.isChecked) { - udpFakeCount.isVisible = true - } else { - udpFakeCount.isVisible = false - } - - when (desyncMethod) { - None -> { - splitPosition.isVisible = false - splitAtHost.isVisible = false - ttlFake.isVisible = false - fakeSni.isVisible = false - oobData.isVisible = false - hostMixedCase.isVisible = false - domainMixedCase.isVisible = false - hostRemoveSpaces.isVisible = false - } + val desyncHttpEnabled = desyncAllProtocols || desyncHttp.isChecked + hostMixedCase.isEnabled = desyncHttpEnabled + domainMixedCase.isEnabled = desyncHttpEnabled + hostRemoveSpaces.isEnabled = desyncHttpEnabled - else -> { - splitPosition.isVisible = true - splitAtHost.isVisible = true - - if (desyncAllProtocols || desyncHttp.isChecked) { - 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 - } - } - } - } + val desyncUdpEnabled = desyncAllProtocols || desyncUdp.isChecked + udpFakeCount.isEnabled = desyncUdpEnabled - splitTlsRecPosition.isVisible = splitTlsRec.isChecked - splitTlsRecAtSni.isVisible = splitTlsRec.isChecked + val desyncHttpsEnabled = desyncAllProtocols || desyncHttps.isChecked + splitTlsRec.isEnabled = desyncHttpsEnabled + val tlsRecEnabled = desyncHttpsEnabled && splitTlsRec.isChecked + splitTlsRecPosition.isEnabled = tlsRecEnabled + splitTlsRecAtSni.isEnabled = tlsRecEnabled } } diff --git a/app/src/main/java/io/github/dovecoteescapee/byedpi/fragments/MainSettingsFragment.kt b/app/src/main/java/io/github/dovecoteescapee/byedpi/fragments/MainSettingsFragment.kt index 4aa5bf26..e3d4caa2 100644 --- a/app/src/main/java/io/github/dovecoteescapee/byedpi/fragments/MainSettingsFragment.kt +++ b/app/src/main/java/io/github/dovecoteescapee/byedpi/fragments/MainSettingsFragment.kt @@ -39,7 +39,7 @@ class MainSettingsFragment : PreferenceFragmentCompat() { setPreferencesFromResource(R.xml.main_settings, rootKey) setEditTextPreferenceListener("dns_ip") { - it.isBlank() || checkIp(it) + it.isBlank() || checkNotLocalIp(it) } findPreferenceNotNull("app_theme") diff --git a/app/src/main/java/io/github/dovecoteescapee/byedpi/services/ByeDpiVpnService.kt b/app/src/main/java/io/github/dovecoteescapee/byedpi/services/ByeDpiVpnService.kt index eaa5a59f..d2abdfdf 100644 --- a/app/src/main/java/io/github/dovecoteescapee/byedpi/services/ByeDpiVpnService.kt +++ b/app/src/main/java/io/github/dovecoteescapee/byedpi/services/ByeDpiVpnService.kt @@ -208,12 +208,6 @@ class ByeDpiVpnService : LifecycleVpnService() { 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") } @@ -222,6 +216,12 @@ class ByeDpiVpnService : LifecycleVpnService() { 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 = null diff --git a/app/src/main/java/io/github/dovecoteescapee/byedpi/utility/ValidateUtils.kt b/app/src/main/java/io/github/dovecoteescapee/byedpi/utility/ValidateUtils.kt index 8ca4c2f5..57b50d52 100644 --- a/app/src/main/java/io/github/dovecoteescapee/byedpi/utility/ValidateUtils.kt +++ b/app/src/main/java/io/github/dovecoteescapee/byedpi/utility/ValidateUtils.kt @@ -10,6 +10,16 @@ import androidx.preference.PreferenceFragmentCompat private const val TAG = "ValidateUtils" 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) { InetAddresses.isNumericAddress(ip) && InetAddresses.parseNumericAddress(ip).let { !it.isAnyLocalAddress && !it.isLoopbackAddress diff --git a/app/src/main/res/values/arrays.xml b/app/src/main/res/values/arrays.xml index e6091dad..0b1744c4 100644 --- a/app/src/main/res/values/arrays.xml +++ b/app/src/main/res/values/arrays.xml @@ -26,6 +26,7 @@ Disorder Fake Out-of-band + Disordered out-of-band none @@ -33,6 +34,7 @@ disorder fake oob + disoob diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index b2e4341e..dc263692 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -1,5 +1,5 @@ - https://github.com/hufrea/byedpi/tree/v0.12#readme + https://github.com/hufrea/byedpi/blob/v0.13/README.md ByeDPI Connect Disconnect @@ -65,4 +65,11 @@ TCP Fast Open UDP fake count IPv6 + Fake offset + Drop SACK + UDP + HTTP + HTTPS + Protocols + Uncheck all to desync all traffic diff --git a/app/src/main/res/xml/byedpi_ui_settings.xml b/app/src/main/res/xml/byedpi_ui_settings.xml index ed1d2eed..0473b0c8 100644 --- a/app/src/main/res/xml/byedpi_ui_settings.xml +++ b/app/src/main/res/xml/byedpi_ui_settings.xml @@ -48,6 +48,11 @@ android:title="@string/byedpi_no_domain_setting" android:defaultValue="false" /> + + - - - - - - - - + + + + - + + + + + + + + + + + + + + + + + + + + + + + diff --git a/fastlane/metadata/android/en-US/full_description.txt b/fastlane/metadata/android/en-US/full_description.txt index af220eee..bfd6553d 100644 --- a/fastlane/metadata/android/en-US/full_description.txt +++ b/fastlane/metadata/android/en-US/full_description.txt @@ -1 +1 @@ -

ByeDPI runs a local VPN service to bypass DPI (Deep Packet Inspection) and censorship. It runs a SOCKS5 proxy ByeDPI and redirects all traffic through it.

To bypass some blocks, you may need to change the settings. More about the various settings can be found in the ByeDPI documentation.

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.

\ No newline at end of file +

ByeDPI runs a local VPN service to bypass DPI (Deep Packet Inspection) and censorship. It runs a SOCKS5 proxy ByeDPI and redirects all traffic through it.

To bypass some blocks, you may need to change the settings. More about the various settings can be found in the ByeDPI documentation.

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.

\ No newline at end of file diff --git a/fastlane/metadata/android/ru-RU/full_description.txt b/fastlane/metadata/android/ru-RU/full_description.txt index af220eee..bfd6553d 100644 --- a/fastlane/metadata/android/ru-RU/full_description.txt +++ b/fastlane/metadata/android/ru-RU/full_description.txt @@ -1 +1 @@ -

ByeDPI runs a local VPN service to bypass DPI (Deep Packet Inspection) and censorship. It runs a SOCKS5 proxy ByeDPI and redirects all traffic through it.

To bypass some blocks, you may need to change the settings. More about the various settings can be found in the ByeDPI documentation.

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.

\ No newline at end of file +

ByeDPI runs a local VPN service to bypass DPI (Deep Packet Inspection) and censorship. It runs a SOCKS5 proxy ByeDPI and redirects all traffic through it.

To bypass some blocks, you may need to change the settings. More about the various settings can be found in the ByeDPI documentation.

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.

\ No newline at end of file