diff --git a/README-ru.md b/README-ru.md index 49c0fe0..39f7a1d 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 e725b61..dc621bd 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 330c540..d7b4fbc 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 dcf5ed7..078842b 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 5952df9..263041e 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 e615a0c..283c826 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 dff4d36..ae06186 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 db78011..80331f4 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 3f2b17d..6df4c1c 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 ae68339..315335c 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 - } + val desyncHttpEnabled = desyncAllProtocols || desyncHttp.isChecked + hostMixedCase.isEnabled = desyncHttpEnabled + domainMixedCase.isEnabled = desyncHttpEnabled + hostRemoveSpaces.isEnabled = desyncHttpEnabled - 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 desyncUdpEnabled = desyncAllProtocols || desyncUdp.isChecked + udpFakeCount.isEnabled = desyncUdpEnabled - 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 - } - } - } - } - - 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 4aa5bf2..e3d4caa 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 eaa5a59..d2abdfd 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 8ca4c2f..57b50d5 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 e6091da..0b1744c 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 b2e4341..dc26369 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 ed1d2ee..0473b0c 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 af220ee..bfd6553 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 af220ee..bfd6553 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