Improvements and fixes (#96)

Improvements and fixes:
- Added Hosts to UI editor
- Allowed not to specify DNS
- Changed the level of saved logs to Debug
- Fixed bug with Reset button
This commit is contained in:
dovecoteescapee 2024-08-19 01:09:08 +03:00 committed by GitHub
parent 31d75606bc
commit 88e1b75dd5
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
16 changed files with 165 additions and 16 deletions

View File

@ -12,7 +12,7 @@ android {
minSdk = 21 minSdk = 21
targetSdk = 34 targetSdk = 34
versionCode = 8 versionCode = 8
versionName = "1.1.0-beta" versionName = "1.1.0"
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"

View File

@ -13,6 +13,8 @@ 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);
struct mphdr *parse_hosts(char *buffer, size_t size); struct mphdr *parse_hosts(char *buffer, size_t size);
int parse_offset(struct part *part, const char *str); int parse_offset(struct part *part, const char *str);

View File

@ -12,11 +12,17 @@
#include "utils.h" #include "utils.h"
const enum demode DESYNC_METHODS[] = { const enum demode DESYNC_METHODS[] = {
DESYNC_NONE, DESYNC_NONE,
DESYNC_SPLIT, DESYNC_SPLIT,
DESYNC_DISORDER, DESYNC_DISORDER,
DESYNC_FAKE, DESYNC_FAKE,
DESYNC_OOB, DESYNC_OOB,
};
enum hosts_mode {
HOSTS_DISABLE,
HOSTS_BLACKLIST,
HOSTS_WHITELIST,
}; };
JNIEXPORT jint JNI_OnLoad( JNIEXPORT jint JNI_OnLoad(
@ -81,8 +87,9 @@ Java_io_github_dovecoteescapee_byedpi_core_ByeDpiProxy_jniCreateSocket(
jboolean host_remove_spaces, jboolean host_remove_spaces,
jboolean tls_record_split, jboolean tls_record_split,
jint tls_record_split_position, jint tls_record_split_position,
jboolean tls_record_split_at_sni) { jboolean tls_record_split_at_sni,
jint hosts_mode,
jstring hosts) {
struct sockaddr_ina s; struct sockaddr_ina s;
const char *address = (*env)->GetStringUTFChars(env, ip, 0); const char *address = (*env)->GetStringUTFChars(env, ip, 0);
@ -112,6 +119,29 @@ Java_io_github_dovecoteescapee_byedpi_core_ByeDpiProxy_jniCreateSocket(
} }
} }
if (hosts_mode == HOSTS_WHITELIST) {
struct desync_params *dp = add(
(void *) &params.dp,
&params.dp_count,
sizeof(struct desync_params)
);
if (!dp) {
uniperror("add");
reset_params();
return -1;
}
const char *str = (*env)->GetStringUTFChars(env, hosts, 0);
dp->file_ptr = parse_cform(str, &dp->file_size);
(*env)->ReleaseStringUTFChars(env, hosts, str);
dp->hosts = parse_hosts(dp->file_ptr, dp->file_size);
if (!dp->hosts) {
perror("parse_hosts");
clear_params();
return -1;
}
}
struct desync_params *dp = add( struct desync_params *dp = add(
(void *) &params.dp, (void *) &params.dp,
&params.dp_count, &params.dp_count,
@ -123,6 +153,18 @@ Java_io_github_dovecoteescapee_byedpi_core_ByeDpiProxy_jniCreateSocket(
return -1; return -1;
} }
if (hosts_mode == HOSTS_BLACKLIST) {
const char *str = (*env)->GetStringUTFChars(env, hosts, 0);
dp->file_ptr = parse_cform(str, &dp->file_size);
(*env)->ReleaseStringUTFChars(env, hosts, str);
dp->hosts = parse_hosts(dp->file_ptr, dp->file_size);
if (!dp->hosts) {
perror("parse_hosts");
clear_params();
return -1;
}
}
dp->ttl = fake_ttl; dp->ttl = fake_ttl;
dp->proto = dp->proto =
IS_HTTP * desync_http | IS_HTTP * desync_http |

View File

@ -38,7 +38,7 @@ class MainActivity : AppCompatActivity() {
private fun collectLogs(): String? = private fun collectLogs(): String? =
try { try {
Runtime.getRuntime() Runtime.getRuntime()
.exec("logcat *:I -d") .exec("logcat *:D -d")
.inputStream.bufferedReader() .inputStream.bufferedReader()
.use { it.readText() } .use { it.readText() }
} catch (e: Exception) { } catch (e: Exception) {

View File

@ -4,6 +4,7 @@ import android.os.Bundle
import android.view.Menu import android.view.Menu
import android.view.MenuItem import android.view.MenuItem
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import androidx.fragment.app.FragmentManager
import io.github.dovecoteescapee.byedpi.R import io.github.dovecoteescapee.byedpi.R
import io.github.dovecoteescapee.byedpi.fragments.MainSettingsFragment import io.github.dovecoteescapee.byedpi.fragments.MainSettingsFragment
import io.github.dovecoteescapee.byedpi.utility.getPreferences import io.github.dovecoteescapee.byedpi.utility.getPreferences
@ -35,6 +36,7 @@ class SettingsActivity : AppCompatActivity() {
R.id.action_reset_settings -> { R.id.action_reset_settings -> {
getPreferences().edit().clear().apply() getPreferences().edit().clear().apply()
supportFragmentManager.popBackStack(null, FragmentManager.POP_BACK_STACK_INCLUSIVE)
supportFragmentManager supportFragmentManager
.beginTransaction() .beginTransaction()
.replace(R.id.settings, MainSettingsFragment()) .replace(R.id.settings, MainSettingsFragment())

View File

@ -76,6 +76,8 @@ class ByeDpiProxy {
tlsRecordSplit = preferences.tlsRecordSplit, tlsRecordSplit = preferences.tlsRecordSplit,
tlsRecordSplitPosition = preferences.tlsRecordSplitPosition, tlsRecordSplitPosition = preferences.tlsRecordSplitPosition,
tlsRecordSplitAtSni = preferences.tlsRecordSplitAtSni, tlsRecordSplitAtSni = preferences.tlsRecordSplitAtSni,
hostsMode = preferences.hostsMode.ordinal,
hosts = preferences.hosts
) )
} }
@ -104,6 +106,8 @@ class ByeDpiProxy {
tlsRecordSplit: Boolean, tlsRecordSplit: Boolean,
tlsRecordSplitPosition: Int, tlsRecordSplitPosition: Int,
tlsRecordSplitAtSni: Boolean, tlsRecordSplitAtSni: Boolean,
hostsMode: Int,
hosts: String?
): Int ): Int
private external fun jniStartProxy(fd: Int): Int private external fun jniStartProxy(fd: Int): Int

View File

@ -55,6 +55,8 @@ class ByeDpiProxyUIPreferences(
tlsRecordSplit: Boolean? = null, tlsRecordSplit: Boolean? = null,
tlsRecordSplitPosition: Int? = null, tlsRecordSplitPosition: Int? = null,
tlsRecordSplitAtSni: Boolean? = null, tlsRecordSplitAtSni: Boolean? = null,
hostsMode: HostsMode? = null,
hosts: String? = 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
@ -78,6 +80,12 @@ class ByeDpiProxyUIPreferences(
val tlsRecordSplit: Boolean = tlsRecordSplit ?: false val tlsRecordSplit: Boolean = tlsRecordSplit ?: false
val tlsRecordSplitPosition: Int = tlsRecordSplitPosition ?: 0 val tlsRecordSplitPosition: Int = tlsRecordSplitPosition ?: 0
val tlsRecordSplitAtSni: Boolean = tlsRecordSplitAtSni ?: false val tlsRecordSplitAtSni: Boolean = tlsRecordSplitAtSni ?: false
val hostsMode: HostsMode =
if (hosts?.isBlank() != false) HostsMode.Disable
else hostsMode ?: HostsMode.Disable
val hosts: String? =
if (this.hostsMode == HostsMode.Disable) null
else hosts?.trim()
constructor(preferences: SharedPreferences) : this( constructor(preferences: SharedPreferences) : this(
ip = preferences.getString("byedpi_proxy_ip", null), ip = preferences.getString("byedpi_proxy_ip", null),
@ -103,6 +111,15 @@ class ByeDpiProxyUIPreferences(
tlsRecordSplitPosition = preferences.getString("byedpi_tlsrec_position", null) tlsRecordSplitPosition = preferences.getString("byedpi_tlsrec_position", null)
?.toIntOrNull(), ?.toIntOrNull(),
tlsRecordSplitAtSni = preferences.getBoolean("byedpi_tlsrec_at_sni", false), tlsRecordSplitAtSni = preferences.getBoolean("byedpi_tlsrec_at_sni", false),
hostsMode = preferences.getString("byedpi_hosts_mode", null)
?.let { HostsMode.fromName(it) },
hosts = preferences.getString("byedpi_hosts_mode", null)?.let {
when (HostsMode.fromName(it)) {
HostsMode.Blacklist -> preferences.getString("byedpi_hosts_blacklist", null)
HostsMode.Whitelist -> preferences.getString("byedpi_hosts_whitelist", null)
else -> null
}
}
) )
enum class DesyncMethod { enum class DesyncMethod {
@ -125,4 +142,21 @@ class ByeDpiProxyUIPreferences(
} }
} }
} }
enum class HostsMode {
Disable,
Blacklist,
Whitelist;
companion object {
fun fromName(name: String): HostsMode {
return when (name) {
"disable" -> Disable
"blacklist" -> Blacklist
"whitelist" -> Whitelist
else -> throw IllegalArgumentException("Unknown hosts mode: $name")
}
}
}
}
} }

View File

@ -1,4 +1,4 @@
package io.github.dovecoteescapee.byedpi.services package io.github.dovecoteescapee.byedpi.core
object TProxyService { object TProxyService {
init { init {

View File

@ -6,6 +6,7 @@ import androidx.preference.*
import io.github.dovecoteescapee.byedpi.R import io.github.dovecoteescapee.byedpi.R
import io.github.dovecoteescapee.byedpi.core.ByeDpiProxyUIPreferences import io.github.dovecoteescapee.byedpi.core.ByeDpiProxyUIPreferences
import io.github.dovecoteescapee.byedpi.core.ByeDpiProxyUIPreferences.DesyncMethod.* import io.github.dovecoteescapee.byedpi.core.ByeDpiProxyUIPreferences.DesyncMethod.*
import io.github.dovecoteescapee.byedpi.core.ByeDpiProxyUIPreferences.HostsMode.*
import io.github.dovecoteescapee.byedpi.utility.* import io.github.dovecoteescapee.byedpi.utility.*
class ByeDpiUISettingsFragment : PreferenceFragmentCompat() { class ByeDpiUISettingsFragment : PreferenceFragmentCompat() {
@ -65,7 +66,11 @@ class ByeDpiUISettingsFragment : PreferenceFragmentCompat() {
val desyncMethod = val desyncMethod =
findPreferenceNotNull<ListPreference>("byedpi_desync_method") findPreferenceNotNull<ListPreference>("byedpi_desync_method")
.value.let { ByeDpiProxyUIPreferences.DesyncMethod.fromName(it) } .value.let { ByeDpiProxyUIPreferences.DesyncMethod.fromName(it) }
val hostsMode = findPreferenceNotNull<ListPreference>("byedpi_hosts_mode")
.value.let { ByeDpiProxyUIPreferences.HostsMode.fromName(it) }
val hostsBlacklist = findPreferenceNotNull<EditTextPreference>("byedpi_hosts_blacklist")
val hostsWhitelist = findPreferenceNotNull<EditTextPreference>("byedpi_hosts_whitelist")
val desyncHttp = findPreferenceNotNull<CheckBoxPreference>("byedpi_desync_http") val desyncHttp = findPreferenceNotNull<CheckBoxPreference>("byedpi_desync_http")
val desyncHttps = findPreferenceNotNull<CheckBoxPreference>("byedpi_desync_https") val desyncHttps = findPreferenceNotNull<CheckBoxPreference>("byedpi_desync_https")
val desyncUdp = findPreferenceNotNull<CheckBoxPreference>("byedpi_desync_udp") val desyncUdp = findPreferenceNotNull<CheckBoxPreference>("byedpi_desync_udp")
@ -83,6 +88,23 @@ 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) {
Disable -> {
hostsBlacklist.isVisible = false
hostsWhitelist.isVisible = false
}
Blacklist -> {
hostsBlacklist.isVisible = true
hostsWhitelist.isVisible = false
}
Whitelist -> {
hostsBlacklist.isVisible = false
hostsWhitelist.isVisible = true
}
}
when (desyncMethod) { when (desyncMethod) {
None -> { None -> {
desyncHttp.isVisible = false desyncHttp.isVisible = false

View File

@ -38,7 +38,9 @@ class MainSettingsFragment : PreferenceFragmentCompat() {
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) { override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
setPreferencesFromResource(R.xml.main_settings, rootKey) setPreferencesFromResource(R.xml.main_settings, rootKey)
setEditTextPreferenceListener("dns_ip") { checkIp(it) } setEditTextPreferenceListener("dns_ip") {
it.isBlank() || checkIp(it)
}
findPreferenceNotNull<DropDownPreference>("app_theme") findPreferenceNotNull<DropDownPreference>("app_theme")
.setOnPreferenceChangeListener { _, newValue -> .setOnPreferenceChangeListener { _, newValue ->

View File

@ -12,6 +12,7 @@ import io.github.dovecoteescapee.byedpi.R
import io.github.dovecoteescapee.byedpi.activities.MainActivity import io.github.dovecoteescapee.byedpi.activities.MainActivity
import io.github.dovecoteescapee.byedpi.core.ByeDpiProxy import io.github.dovecoteescapee.byedpi.core.ByeDpiProxy
import io.github.dovecoteescapee.byedpi.core.ByeDpiProxyPreferences import io.github.dovecoteescapee.byedpi.core.ByeDpiProxyPreferences
import io.github.dovecoteescapee.byedpi.core.TProxyService
import io.github.dovecoteescapee.byedpi.data.* import io.github.dovecoteescapee.byedpi.data.*
import io.github.dovecoteescapee.byedpi.utility.* import io.github.dovecoteescapee.byedpi.utility.*
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
@ -268,6 +269,7 @@ class ByeDpiVpnService : LifecycleVpnService() {
) )
private fun createBuilder(dns: String): Builder { private fun createBuilder(dns: String): Builder {
Log.d(TAG, "DNS: $dns")
val builder = Builder() val builder = Builder()
builder.setSession("ByeDPI") builder.setSession("ByeDPI")
builder.setConfigureIntent( builder.setConfigureIntent(
@ -282,7 +284,9 @@ class ByeDpiVpnService : LifecycleVpnService() {
builder.addAddress("10.10.10.10", 32) builder.addAddress("10.10.10.10", 32)
builder.addRoute("0.0.0.0", 0) builder.addRoute("0.0.0.0", 0)
builder.addRoute("0:0:0:0:0:0:0:0", 0) builder.addRoute("0:0:0:0:0:0:0:0", 0)
builder.addDnsServer(dns) if (dns.isNotBlank()) {
builder.addDnsServer(dns)
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
builder.setMetered(false) builder.setMetered(false)
} }

View File

@ -16,6 +16,6 @@
APP_OPTIM := release APP_OPTIM := release
APP_PLATFORM := android-21 APP_PLATFORM := android-21
APP_ABI := armeabi-v7a arm64-v8a x86 x86_64 APP_ABI := armeabi-v7a arm64-v8a x86 x86_64
APP_CFLAGS := -O3 -DPKGNAME=io/github/dovecoteescapee/byedpi/services APP_CFLAGS := -O3 -DPKGNAME=io/github/dovecoteescapee/byedpi/core
APP_CPPFLAGS := -O3 -std=c++11 APP_CPPFLAGS := -O3 -std=c++11
NDK_TOOLCHAIN_VERSION := clang NDK_TOOLCHAIN_VERSION := clang

View File

@ -34,4 +34,15 @@
<item name="fake">fake</item> <item name="fake">fake</item>
<item name="oob">oob</item> <item name="oob">oob</item>
</array> </array>
<array name="byedpi_hosts_modes">
<item name="disable">Disable</item>
<item name="blacklist">Blacklist</item>
<item name="whitelist">Whitelist</item>
</array>
<array name="byedpi_hosts_modes_entries">
<item name="disable">disable</item>
<item name="blacklist">blacklist</item>
<item name="whitelist">whitelist</item>
</array>
</resources> </resources>

View File

@ -57,4 +57,8 @@
<string name="sni_of_fake_packet">SNI of fake packet</string> <string name="sni_of_fake_packet">SNI of fake packet</string>
<string name="byedpi_proxy">Proxy</string> <string name="byedpi_proxy">Proxy</string>
<string name="byedpi_desync">Desync</string> <string name="byedpi_desync">Desync</string>
<string name="command_line_arguments">Command line arguments</string>
<string name="byedpi_hosts_mode_setting">Hosts</string>
<string name="byedpi_hosts_blacklist_setting">Hosts blacklist</string>
<string name="byedpi_hosts_whitelist_setting">Hosts whitelist</string>
</resources> </resources>

View File

@ -17,8 +17,8 @@
<com.takisoft.preferencex.EditTextPreference <com.takisoft.preferencex.EditTextPreference
android:key="byedpi_cmd_args" android:key="byedpi_cmd_args"
android:title="Command line arguments" android:title="@string/command_line_arguments"
android:dialogTitle="Command line arguments" android:dialogTitle="@string/command_line_arguments"
android:inputType="textMultiLine" android:inputType="textMultiLine"
app:useSimpleSummaryProvider="true" /> app:useSimpleSummaryProvider="true" />

View File

@ -53,6 +53,28 @@
<androidx.preference.PreferenceCategory <androidx.preference.PreferenceCategory
android:title="@string/byedpi_desync"> android:title="@string/byedpi_desync">
<DropDownPreference
android:key="byedpi_hosts_mode"
android:title="@string/byedpi_hosts_mode_setting"
android:entries="@array/byedpi_hosts_modes"
android:entryValues="@array/byedpi_hosts_modes_entries"
android:defaultValue="disable"
app:useSimpleSummaryProvider="true" />
<com.takisoft.preferencex.EditTextPreference
android:key="byedpi_hosts_blacklist"
android:title="@string/byedpi_hosts_blacklist_setting"
android:dialogTitle="@string/byedpi_hosts_blacklist_setting"
android:inputType="textMultiLine"
app:useSimpleSummaryProvider="true" />
<com.takisoft.preferencex.EditTextPreference
android:key="byedpi_hosts_whitelist"
android:title="@string/byedpi_hosts_whitelist_setting"
android:dialogTitle="@string/byedpi_hosts_whitelist_setting"
android:inputType="textMultiLine"
app:useSimpleSummaryProvider="true" />
<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"