Compare commits

...

4 Commits

Author SHA1 Message Date
2dust
92f33ee3f8 up 1.10.13 2025-08-04 20:21:17 +08:00
2dust
084346b348 Update AndroidLibXrayLite 2025-08-04 19:46:45 +08:00
2dust
15de18b736 Add Enable New TUN Feature option
When enabled, TUN will use hev-socks5-tunnel; otherwise, it will use badvpn-tun2socks
2025-08-04 18:32:16 +08:00
Peyman
b60423d1c0 Update Persian translate (#4791) 2025-08-04 10:00:28 +08:00
23 changed files with 185 additions and 34 deletions

View File

@@ -12,8 +12,8 @@ android {
applicationId = "com.v2ray.ang"
minSdk = 21
targetSdk = 35
versionCode = 662
versionName = "1.10.12"
versionCode = 663
versionName = "1.10.13"
multiDexEnabled = true
val abiFilterList = (properties["ABI_FILTERS"] as? String)?.split(';')

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -62,6 +62,7 @@ object AppConfig {
const val PREF_IS_BOOTED = "pref_is_booted"
const val PREF_CHECK_UPDATE_PRE_RELEASE = "pref_check_update_pre_release"
const val PREF_GEO_FILES_SOURCES = "pref_geo_files_sources"
const val PREF_USE_HEV_TUNNEL = "pref_use_hev_tunnel"
/** Cache keys. */
const val CACHE_SUBSCRIPTION_ID = "cache_subscription_id"

View File

@@ -0,0 +1,96 @@
package com.v2ray.ang.service
import android.content.Context
import android.os.ParcelFileDescriptor
import android.util.Log
import com.v2ray.ang.AppConfig
import com.v2ray.ang.AppConfig.VPN_MTU
import com.v2ray.ang.handler.MmkvManager
import com.v2ray.ang.handler.SettingsManager
import java.io.File
/**
* Manages the tun2socks process that handles VPN traffic
*/
class TProxyService(
private val context: Context,
private val vpnInterface: ParcelFileDescriptor,
private val isRunningProvider: () -> Boolean,
private val restartCallback: () -> Unit
) : Tun2SocksControl {
companion object {
@JvmStatic
@Suppress("FunctionName")
private external fun TProxyStartService(configPath: String, fd: Int)
@JvmStatic
@Suppress("FunctionName")
private external fun TProxyStopService()
@JvmStatic
@Suppress("FunctionName")
private external fun TProxyGetStats(): LongArray?
init {
System.loadLibrary("hev-socks5-tunnel")
}
}
/**
* Starts the tun2socks process with the appropriate parameters.
*/
override fun startTun2Socks() {
Log.i(AppConfig.TAG, "Starting HevSocks5Tunnel via JNI")
val configContent = buildConfig()
val configFile = File(context.filesDir, "hev-socks5-tunnel.yaml").apply {
writeText(configContent)
}
Log.i(AppConfig.TAG, "Config file created: ${configFile.absolutePath}")
Log.d(AppConfig.TAG, "Config content:\n$configContent")
try {
Log.i(AppConfig.TAG, "TProxyStartService...")
TProxyStartService(configFile.absolutePath, vpnInterface.fd)
} catch (e: Exception) {
Log.e(AppConfig.TAG, "HevSocks5Tunnel exception: ${e.message}")
}
}
private fun buildConfig(): String {
val socksPort = SettingsManager.getSocksPort()
val vpnConfig = SettingsManager.getCurrentVpnInterfaceAddressConfig()
return buildString {
appendLine("tunnel:")
appendLine(" mtu: $VPN_MTU")
appendLine(" ipv4: ${vpnConfig.ipv4Client}")
if (MmkvManager.decodeSettingsBool(AppConfig.PREF_PREFER_IPV6) == true) {
appendLine(" ipv6: '${vpnConfig.ipv6Client}'")
}
appendLine("socks5:")
appendLine(" port: ${socksPort}")
appendLine(" address: ${AppConfig.LOOPBACK}")
appendLine(" udp: 'udp'")
MmkvManager.decodeSettingsString(AppConfig.PREF_LOGLEVEL)?.let { logPref ->
if (logPref != "none") {
val logLevel = if (logPref == "warning") "warn" else logPref
appendLine("misc:")
appendLine(" log-level: $logLevel")
}
}
}
}
/**
* Stops the tun2socks process
*/
override fun stopTun2Socks() {
try {
Log.i(AppConfig.TAG, "TProxyStopService...")
TProxyStopService()
} catch (e: Exception) {
Log.e(AppConfig.TAG, "Failed to stop hev-socks5-tunnel", e)
}
}
}

View File

@@ -0,0 +1,19 @@
package com.v2ray.ang.service
/**
* Interface that defines the control operations for tun2socks implementations.
*
* This interface is implemented by different tunnel solutions like:
*/
interface Tun2SocksControl {
/**
* Starts the tun2socks process with the appropriate parameters.
* This initializes the VPN tunnel and connects it to the SOCKS proxy.
*/
fun startTun2Socks()
/**
* Stops the tun2socks process and cleans up resources.
*/
fun stopTun2Socks()
}

View File

@@ -23,7 +23,7 @@ class Tun2SocksService(
private val vpnInterface: ParcelFileDescriptor,
private val isRunningProvider: () -> Boolean,
private val restartCallback: () -> Unit
) {
) : Tun2SocksControl {
companion object {
private const val TUN2SOCKS = "libtun2socks.so"
}
@@ -33,7 +33,7 @@ class Tun2SocksService(
/**
* Starts the tun2socks process with the appropriate parameters.
*/
fun startTun2Socks() {
override fun startTun2Socks() {
Log.i(AppConfig.TAG, "Start run $TUN2SOCKS")
val socksPort = SettingsManager.getSocksPort()
val vpnConfig = SettingsManager.getCurrentVpnInterfaceAddressConfig()
@@ -116,7 +116,7 @@ class Tun2SocksService(
/**
* Stops the tun2socks process
*/
fun stopTun2Socks() {
override fun stopTun2Socks() {
try {
Log.i(AppConfig.TAG, "$TUN2SOCKS destroy")
if (::process.isInitialized) {

View File

@@ -30,7 +30,7 @@ import java.lang.ref.SoftReference
class V2RayVpnService : VpnService(), ServiceControl {
private lateinit var mInterface: ParcelFileDescriptor
private var isRunning = false
private var tun2SocksService: Tun2SocksService? = null
private var tun2SocksService: Tun2SocksControl? = null
/**destroy
* Unfortunately registerDefaultNetworkCallback is going to return our VPN interface: https://android.googlesource.com/platform/frameworks/base/+/dda156ab0c5d66ad82bdcf76cda07cbc0a9c8a2e
@@ -145,20 +145,20 @@ class V2RayVpnService : VpnService(), ServiceControl {
*/
private fun configureVpnService(): Boolean {
val builder = Builder()
// Configure network settings (addresses, routing and DNS)
configureNetworkSettings(builder)
// Configure app-specific settings (session name and per-app proxy)
configurePerAppProxy(builder)
// Close the old interface since the parameters have been changed
try {
mInterface.close()
} catch (ignored: Exception) {
// ignored
}
// Configure platform-specific features
configurePlatformFeatures(builder)
@@ -173,21 +173,21 @@ class V2RayVpnService : VpnService(), ServiceControl {
}
return false
}
/**
* Configures the basic network settings for the VPN.
* This includes IP addresses, routing rules, and DNS servers.
*
*
* @param builder The VPN Builder to configure
*/
private fun configureNetworkSettings(builder: Builder) {
val vpnConfig = SettingsManager.getCurrentVpnInterfaceAddressConfig()
val bypassLan = SettingsManager.routingRulesetsBypassLan()
// Configure IPv4 settings
builder.setMtu(VPN_MTU)
builder.addAddress(vpnConfig.ipv4Client, 30)
// Configure routing rules
if (bypassLan) {
AppConfig.ROUTED_IP_LIST.forEach {
@@ -197,7 +197,7 @@ class V2RayVpnService : VpnService(), ServiceControl {
} else {
builder.addRoute("0.0.0.0", 0)
}
// Configure IPv6 if enabled
if (MmkvManager.decodeSettingsBool(AppConfig.PREF_PREFER_IPV6) == true) {
builder.addAddress(vpnConfig.ipv6Client, 126)
@@ -208,7 +208,7 @@ class V2RayVpnService : VpnService(), ServiceControl {
builder.addRoute("::", 0)
}
}
// Configure DNS servers
//if (MmkvManager.decodeSettingsBool(AppConfig.PREF_LOCAL_DNS_ENABLED) == true) {
// builder.addDnsServer(PRIVATE_VLAN4_ROUTER)
@@ -218,13 +218,13 @@ class V2RayVpnService : VpnService(), ServiceControl {
builder.addDnsServer(it)
}
}
builder.setSession(V2RayServiceManager.getRunningServerName())
}
/**
* Configures platform-specific VPN features for different Android versions.
*
*
* @param builder The VPN Builder to configure
*/
private fun configurePlatformFeatures(builder: Builder) {
@@ -236,7 +236,7 @@ class V2RayVpnService : VpnService(), ServiceControl {
Log.e(AppConfig.TAG, "Failed to request default network", e)
}
}
// Android Q (API 29) and above: Configure metering and HTTP proxy
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
builder.setMetered(false)
@@ -296,14 +296,23 @@ class V2RayVpnService : VpnService(), ServiceControl {
* Starts the tun2socks process with the appropriate parameters.
*/
private fun runTun2socks() {
tun2SocksService = Tun2SocksService(
context = applicationContext,
vpnInterface = mInterface,
isRunningProvider = { isRunning },
restartCallback = { runTun2socks() }
).also {
it.startTun2Socks()
if (MmkvManager.decodeSettingsBool(AppConfig.PREF_USE_HEV_TUNNEL) == true) {
tun2SocksService = TProxyService(
context = applicationContext,
vpnInterface = mInterface,
isRunningProvider = { isRunning },
restartCallback = { runTun2socks() }
)
} else {
tun2SocksService = Tun2SocksService(
context = applicationContext,
vpnInterface = mInterface,
isRunningProvider = { isRunning },
restartCallback = { runTun2socks() }
)
}
tun2SocksService?.startTun2Socks()
}
/**

View File

@@ -242,7 +242,8 @@ class SettingsActivity : BaseActivity() {
AppConfig.PREF_DOUBLE_COLUMN_DISPLAY,
AppConfig.PREF_PREFER_IPV6,
AppConfig.PREF_PROXY_SHARING,
AppConfig.PREF_ALLOW_INSECURE
AppConfig.PREF_ALLOW_INSECURE,
AppConfig.PREF_USE_HEV_TUNNEL
).forEach { key ->
findPreference<CheckBoxPreference>(key)?.isChecked =
MmkvManager.decodeSettingsBool(key, false)

View File

@@ -80,6 +80,7 @@ class SettingsViewModel(application: Application) : AndroidViewModel(application
AppConfig.SUBSCRIPTION_AUTO_UPDATE,
AppConfig.PREF_FRAGMENT_ENABLED,
AppConfig.PREF_MUX_ENABLED,
AppConfig.PREF_USE_HEV_TUNNEL
-> {
MmkvManager.encodeSettings(key, sharedPreferences.getBoolean(key, false))
}

View File

@@ -247,6 +247,8 @@
<string name="title_language">اللغة</string>
<string name="title_ui_settings">إعدادات واجهة المستخدم</string>
<string name="title_pref_ui_mode_night">إعدادات وضع واجهة المستخدم ليلاً</string>
<string name="title_pref_use_hev_tunnel">Enable New TUN Feature</string>
<string name="summary_pref_use_hev_tunnel">When enabled, TUN will use hev-socks5-tunnel; otherwise, it will use badvpn-tun2socks.</string>
<string name="title_logcat">Logcat</string>
<string name="logcat_copy">نسخ</string>

View File

@@ -248,6 +248,8 @@
<string name="title_language">ভাষা</string>
<string name="title_ui_settings">ইউআই সেটিংস</string>
<string name="title_pref_ui_mode_night">ইউআই মোড সেটিংস</string>
<string name="title_pref_use_hev_tunnel">Enable New TUN Feature</string>
<string name="summary_pref_use_hev_tunnel">When enabled, TUN will use hev-socks5-tunnel; otherwise, it will use badvpn-tun2socks.</string>
<string name="title_logcat">লগক্যাট</string>
<string name="logcat_copy">কপি করুন</string>

View File

@@ -248,6 +248,8 @@
<string name="title_language">زووݩ</string>
<string name="title_ui_settings">سامووا رابت منتوری</string>
<string name="title_pref_ui_mode_night">سامووا هالت رابت منتوری</string>
<string name="title_pref_use_hev_tunnel">Enable New TUN Feature</string>
<string name="summary_pref_use_hev_tunnel">When enabled, TUN will use hev-socks5-tunnel; otherwise, it will use badvpn-tun2socks.</string>
<string name="title_logcat">داسووا</string>
<string name="logcat_copy">لف گیری</string>

View File

@@ -245,6 +245,8 @@
<string name="title_language">زبان</string>
<string name="title_ui_settings">تنظیمات رابط کاربری</string>
<string name="title_pref_ui_mode_night">تنظیمات حالت رابط کاربری</string>
<string name="title_pref_use_hev_tunnel">Enable New TUN Feature</string>
<string name="summary_pref_use_hev_tunnel">When enabled, TUN will use hev-socks5-tunnel; otherwise, it will use badvpn-tun2socks.</string>
<string name="title_logcat">گزارشات</string>
<string name="logcat_copy">کپی</string>
@@ -267,7 +269,7 @@
<string name="title_sub_update">به‌روزرسانی گروه فعلی اشتراک</string>
<string name="title_ping_all_server">TCPING کانفیگ های گروه فعلی</string>
<string name="title_real_ping_all_server">تاخیر واقعی کانفیگ های گروه فعلی</string>
<string name="title_create_intelligent_selection_all_server">Creating Intelligent Selection Current Group Configuration</string>
<string name="title_create_intelligent_selection_all_server">ایجاد کانفیگ انتخاب هوشمند برای گروه فعلی</string>
<string name="title_user_asset_setting">فایل های منبع جغرافیایی</string>
<string name="title_sort_by_test_results">مرتب‌ سازی بر اساس نتایج آزمایش</string>
<string name="title_filter_config">فیلتر کردن کانفیگ‌ها</string>
@@ -379,12 +381,12 @@
<item>Resolve and add to DNS Hosts</item>
<item>Resolve and replace domain</item>
</string-array>
<string name="intelligent_selection">Intelligent Selection</string>
<string name="sub_setting_intelligent_selection_filter">Remarks Intelligent Selection regular filter</string>
<string name="title_intelligent_selection_method">Intelligent Selection Method</string>
<string name="intelligent_selection">انتخاب هوشمند</string>
<string name="sub_setting_intelligent_selection_filter">فیلتر نام مستعار برای انتخاب هوشمند</string>
<string name="title_intelligent_selection_method">روش انتخاب هوشمند</string>
<string-array name="intelligent_selection_method">
<item>Least Ping</item>
<item>Least Load</item>
<item>کمترین پینگ</item>
<item>کمترین بار(لود)</item>
</string-array>
</resources>

View File

@@ -247,6 +247,8 @@
<string name="title_language">Язык</string>
<string name="title_ui_settings">Настройки интерфейса</string>
<string name="title_pref_ui_mode_night">Тема интерфейса</string>
<string name="title_pref_use_hev_tunnel">Enable New TUN Feature</string>
<string name="summary_pref_use_hev_tunnel">When enabled, TUN will use hev-socks5-tunnel; otherwise, it will use badvpn-tun2socks.</string>
<string name="title_logcat">Журнал</string>
<string name="logcat_copy">Копировать</string>

View File

@@ -248,6 +248,8 @@
<string name="title_language">Ngôn ngữ</string>
<string name="title_ui_settings">Cài đặt UI</string>
<string name="title_pref_ui_mode_night">Cài đặt chế độ UI</string>
<string name="title_pref_use_hev_tunnel">Enable New TUN Feature</string>
<string name="summary_pref_use_hev_tunnel">When enabled, TUN will use hev-socks5-tunnel; otherwise, it will use badvpn-tun2socks.</string>
<string name="title_logcat">Logcat</string>
<string name="logcat_copy">Sao chép</string>

View File

@@ -245,6 +245,8 @@
<string name="title_language">语言</string>
<string name="title_ui_settings">用户界面设置</string>
<string name="title_pref_ui_mode_night">界面颜色设置</string>
<string name="title_pref_use_hev_tunnel">启用新的 TUN 功能</string>
<string name="summary_pref_use_hev_tunnel">选择启用后 TUN 将使用 hev-socks5-tunnel 否则使用 badvpn-tun2socks</string>
<string name="title_logcat">Logcat</string>
<string name="logcat_copy">复制</string>

View File

@@ -246,6 +246,8 @@
<string name="title_language">語言</string>
<string name="title_ui_settings">介面顏色設定</string>
<string name="title_pref_ui_mode_night">介面顯示模式</string>
<string name="title_pref_use_hev_tunnel">啟用新 TUN 功能</string>
<string name="summary_pref_use_hev_tunnel">選擇啟用後TUN 將使用 hev-socks5-tunnel否則使用 badvpn-tun2socks。</string>
<string name="title_logcat">Logcat</string>
<string name="logcat_copy">複製</string>

View File

@@ -249,6 +249,8 @@
<string name="title_language">Language</string>
<string name="title_ui_settings">UI settings</string>
<string name="title_pref_ui_mode_night">UI mode settings</string>
<string name="title_pref_use_hev_tunnel">Enable New TUN Feature</string>
<string name="summary_pref_use_hev_tunnel">When enabled, TUN will use hev-socks5-tunnel; otherwise, it will use badvpn-tun2socks.</string>
<string name="title_logcat">Logcat</string>
<string name="logcat_copy">Copy</string>

View File

@@ -13,6 +13,7 @@
android:key="pref_route_only_enabled"
android:summary="@string/summary_pref_route_only_enabled"
android:title="@string/title_pref_route_only_enabled" />
<CheckBoxPreference
android:key="pref_is_booted"
android:summary="@string/summary_pref_is_booted"
@@ -254,6 +255,11 @@
android:key="pref_mode"
android:summary="%s"
android:title="@string/title_mode" />
<CheckBoxPreference
android:key="pref_use_hev_tunnel"
android:summary="@string/summary_pref_use_hev_tunnel"
android:title="@string/title_pref_use_hev_tunnel" />
</PreferenceCategory>