mirror of
https://github.com/bolucat/Archive.git
synced 2025-12-24 13:28:37 +08:00
Update On Wed Sep 11 20:35:31 CEST 2024
This commit is contained in:
@@ -27,7 +27,6 @@ class ClashService : BaseService() {
|
||||
val close = install(CloseModule(self))
|
||||
val config = install(ConfigurationModule(self))
|
||||
val network = install(NetworkObserveModule(self))
|
||||
val sideload = install(SideloadDatabaseModule(self))
|
||||
|
||||
if (store.dynamicNotification)
|
||||
install(DynamicNotificationModule(self))
|
||||
@@ -49,11 +48,6 @@ class ClashService : BaseService() {
|
||||
|
||||
true
|
||||
}
|
||||
sideload.onEvent {
|
||||
reason = it.message
|
||||
|
||||
true
|
||||
}
|
||||
network.onEvent {
|
||||
false
|
||||
}
|
||||
|
||||
@@ -33,7 +33,6 @@ class TunService : VpnService(), CoroutineScope by CoroutineScope(Dispatchers.De
|
||||
val tun = install(TunModule(self))
|
||||
val config = install(ConfigurationModule(self))
|
||||
val network = install(NetworkObserveModule(self))
|
||||
val sideload = install(SideloadDatabaseModule(self))
|
||||
|
||||
if (store.dynamicNotification)
|
||||
install(DynamicNotificationModule(self))
|
||||
@@ -57,11 +56,6 @@ class TunService : VpnService(), CoroutineScope by CoroutineScope(Dispatchers.De
|
||||
|
||||
true
|
||||
}
|
||||
sideload.onEvent {
|
||||
reason = it.message
|
||||
|
||||
true
|
||||
}
|
||||
network.onEvent { n ->
|
||||
if (Build.VERSION.SDK_INT in 22..28) @TargetApi(22) {
|
||||
setUnderlyingNetworks(n?.let { arrayOf(it) })
|
||||
@@ -132,17 +126,31 @@ class TunService : VpnService(), CoroutineScope by CoroutineScope(Dispatchers.De
|
||||
val device = with(Builder()) {
|
||||
// Interface address
|
||||
addAddress(TUN_GATEWAY, TUN_SUBNET_PREFIX)
|
||||
if (store.allowIpv6) {
|
||||
addAddress(TUN_GATEWAY6, TUN_SUBNET_PREFIX6)
|
||||
}
|
||||
|
||||
// Route
|
||||
if (store.bypassPrivateNetwork) {
|
||||
resources.getStringArray(R.array.bypass_private_route).map(::parseCIDR).forEach {
|
||||
addRoute(it.ip, it.prefix)
|
||||
}
|
||||
if (store.allowIpv6) {
|
||||
resources.getStringArray(R.array.bypass_private_route6).map(::parseCIDR).forEach {
|
||||
addRoute(it.ip, it.prefix)
|
||||
}
|
||||
}
|
||||
|
||||
// Route of virtual DNS
|
||||
addRoute(TUN_DNS, 32)
|
||||
if (store.allowIpv6) {
|
||||
addRoute(TUN_DNS6, 128)
|
||||
}
|
||||
} else {
|
||||
addRoute(NET_ANY, 0)
|
||||
if (store.allowIpv6) {
|
||||
addRoute(NET_ANY6, 0)
|
||||
}
|
||||
}
|
||||
|
||||
// Access Control
|
||||
@@ -171,6 +179,9 @@ class TunService : VpnService(), CoroutineScope by CoroutineScope(Dispatchers.De
|
||||
|
||||
// Virtual Dns Server
|
||||
addDnsServer(TUN_DNS)
|
||||
if (store.allowIpv6) {
|
||||
addDnsServer(TUN_DNS6)
|
||||
}
|
||||
|
||||
// Open MainActivity
|
||||
setConfigureIntent(
|
||||
@@ -207,9 +218,10 @@ class TunService : VpnService(), CoroutineScope by CoroutineScope(Dispatchers.De
|
||||
TunModule.TunDevice(
|
||||
fd = establish()?.detachFd()
|
||||
?: throw NullPointerException("Establish VPN rejected by system"),
|
||||
gateway = "$TUN_GATEWAY/$TUN_SUBNET_PREFIX",
|
||||
portal = TUN_PORTAL,
|
||||
dns = if (store.dnsHijacking) NET_ANY else TUN_DNS,
|
||||
stack = store.tunStackMode,
|
||||
gateway = "$TUN_GATEWAY/$TUN_SUBNET_PREFIX" + if (store.allowIpv6) ",$TUN_GATEWAY6/$TUN_SUBNET_PREFIX6" else "",
|
||||
portal = TUN_PORTAL + if (store.allowIpv6) ",$TUN_PORTAL6" else "",
|
||||
dns = if (store.dnsHijacking) NET_ANY else (TUN_DNS + if (store.allowIpv6) ",$TUN_DNS6" else ""),
|
||||
)
|
||||
}
|
||||
|
||||
@@ -220,9 +232,14 @@ class TunService : VpnService(), CoroutineScope by CoroutineScope(Dispatchers.De
|
||||
private const val TUN_MTU = 9000
|
||||
private const val TUN_SUBNET_PREFIX = 30
|
||||
private const val TUN_GATEWAY = "172.19.0.1"
|
||||
private const val TUN_SUBNET_PREFIX6 = 126
|
||||
private const val TUN_GATEWAY6 = "fdfe:dcba:9876::1"
|
||||
private const val TUN_PORTAL = "172.19.0.2"
|
||||
private const val TUN_PORTAL6 = "fdfe:dcba:9876::2"
|
||||
private const val TUN_DNS = TUN_PORTAL
|
||||
private const val TUN_DNS6 = TUN_PORTAL6
|
||||
private const val NET_ANY = "0.0.0.0"
|
||||
private const val NET_ANY6 = "::"
|
||||
|
||||
private val HTTP_PROXY_LOCAL_LIST: List<String> = listOf(
|
||||
"localhost",
|
||||
|
||||
@@ -1,87 +0,0 @@
|
||||
package com.github.kr328.clash.service.clash.module
|
||||
|
||||
import android.app.Service
|
||||
import android.content.Intent
|
||||
import com.github.kr328.clash.common.constants.Intents
|
||||
import com.github.kr328.clash.common.log.Log
|
||||
import com.github.kr328.clash.core.Clash
|
||||
import com.github.kr328.clash.service.sideload.readGeoipDatabaseFrom
|
||||
import com.github.kr328.clash.service.store.ServiceStore
|
||||
import com.github.kr328.clash.service.util.packageName
|
||||
import kotlinx.coroutines.channels.Channel
|
||||
import kotlinx.coroutines.selects.select
|
||||
import java.io.FileNotFoundException
|
||||
import java.io.IOException
|
||||
|
||||
class SideloadDatabaseModule(service: Service) :
|
||||
Module<SideloadDatabaseModule.LoadException>(service) {
|
||||
data class LoadException(val message: String)
|
||||
|
||||
private val store = ServiceStore(service)
|
||||
|
||||
private var current: String = ""
|
||||
|
||||
override suspend fun run() {
|
||||
val packagesChanged = receiveBroadcast(false) {
|
||||
addAction(Intent.ACTION_PACKAGE_ADDED)
|
||||
addAction(Intent.ACTION_PACKAGE_REPLACED)
|
||||
addAction(Intent.ACTION_PACKAGE_FULLY_REMOVED)
|
||||
addDataScheme("package")
|
||||
}
|
||||
val profileChanged = receiveBroadcast(capacity = Channel.CONFLATED) {
|
||||
addAction(Intents.ACTION_PROFILE_CHANGED)
|
||||
}
|
||||
val initial = Channel<Unit>(1).apply { send(Unit) }
|
||||
|
||||
while (true) {
|
||||
val (reload, force) = select<Pair<Boolean, Boolean>> {
|
||||
packagesChanged.onReceive {
|
||||
when (it.action) {
|
||||
Intent.ACTION_PACKAGE_ADDED ->
|
||||
(it.packageName == store.sideloadGeoip) to true
|
||||
Intent.ACTION_PACKAGE_REPLACED ->
|
||||
(it.packageName == current) to true
|
||||
Intent.ACTION_PACKAGE_FULLY_REMOVED ->
|
||||
(it.packageName == current) to true
|
||||
else -> false to false
|
||||
}
|
||||
}
|
||||
profileChanged.onReceive {
|
||||
true to false
|
||||
}
|
||||
initial.onReceive {
|
||||
true to true
|
||||
}
|
||||
}
|
||||
|
||||
if (!reload) continue
|
||||
|
||||
val pkg = store.sideloadGeoip
|
||||
|
||||
try {
|
||||
if (!force && pkg == current)
|
||||
continue
|
||||
|
||||
current = pkg
|
||||
|
||||
if (pkg.isNotBlank()) {
|
||||
val data = service.readGeoipDatabaseFrom(pkg)
|
||||
|
||||
Clash.installSideloadGeoip(data)
|
||||
|
||||
if (data != null) {
|
||||
Log.d("Sideload geoip loaded, pkg = $pkg")
|
||||
} else {
|
||||
Log.d("Sideload geoip not found")
|
||||
}
|
||||
}
|
||||
} catch (e: FileNotFoundException) {
|
||||
return enqueueEvent(LoadException("file $pkg/assets/${e.message} not found"))
|
||||
} catch (e: IOException) {
|
||||
return enqueueEvent(LoadException("read data from $pkg: ${e.message}"))
|
||||
} catch (e: Exception) {
|
||||
return enqueueEvent(LoadException(e.toString()))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -15,6 +15,7 @@ import java.security.SecureRandom
|
||||
class TunModule(private val vpn: VpnService) : Module<Unit>(vpn) {
|
||||
data class TunDevice(
|
||||
val fd: Int,
|
||||
var stack: String,
|
||||
val gateway: String,
|
||||
val portal: String,
|
||||
val dns: String,
|
||||
@@ -56,6 +57,7 @@ class TunModule(private val vpn: VpnService) : Module<Unit>(vpn) {
|
||||
fun attach(device: TunDevice) {
|
||||
Clash.startTun(
|
||||
fd = device.fd,
|
||||
stack = device.stack,
|
||||
gateway = device.gateway,
|
||||
portal = device.portal,
|
||||
dns = device.dns,
|
||||
|
||||
@@ -1,21 +0,0 @@
|
||||
package com.github.kr328.clash.service.sideload
|
||||
|
||||
import android.content.Context
|
||||
import android.content.pm.PackageManager
|
||||
import com.github.kr328.clash.common.constants.Metadata
|
||||
import com.github.kr328.clash.common.log.Log
|
||||
import java.io.InputStream
|
||||
|
||||
fun Context.readGeoipDatabaseFrom(packageName: String): ByteArray? {
|
||||
return try {
|
||||
val appInfo = packageManager.getApplicationInfo(packageName, PackageManager.GET_META_DATA)
|
||||
val path = appInfo.metaData.getString(Metadata.GEOIP_FILE_NAME) ?: return null
|
||||
|
||||
createPackageContext(packageName, 0)
|
||||
.resources.assets.open(path).use(InputStream::readBytes)
|
||||
} catch (e: PackageManager.NameNotFoundException) {
|
||||
Log.w("Sideload geoip: $packageName not found", e)
|
||||
|
||||
null
|
||||
}
|
||||
}
|
||||
@@ -51,13 +51,18 @@ class ServiceStore(context: Context) {
|
||||
defaultValue = true
|
||||
)
|
||||
|
||||
var allowIpv6 by store.boolean(
|
||||
key = "allow_ipv6",
|
||||
defaultValue = false
|
||||
)
|
||||
|
||||
var tunStackMode by store.string(
|
||||
key = "tun_stack_mode",
|
||||
defaultValue = "system"
|
||||
)
|
||||
|
||||
var dynamicNotification by store.boolean(
|
||||
key = "dynamic_notification",
|
||||
defaultValue = true
|
||||
)
|
||||
|
||||
var sideloadGeoip by store.string(
|
||||
key = "sideload_geoip",
|
||||
defaultValue = ""
|
||||
)
|
||||
}
|
||||
@@ -77,4 +77,15 @@
|
||||
<item>255.255.255.252/31</item>
|
||||
<item>255.255.255.254/32</item>
|
||||
</string-array>
|
||||
<!-- exclude fc00::/7, fe80::/10, ff00::/8 -->
|
||||
<string-array name="bypass_private_route6" translatable="false">
|
||||
<item>::/1</item>
|
||||
<item>8000::/2</item>
|
||||
<item>c000::/3</item>
|
||||
<item>e000::/4</item>
|
||||
<item>f000::/5</item>
|
||||
<item>f800::/6</item>
|
||||
<item>fe00::/9</item>
|
||||
<item>fec0::/10</item>
|
||||
</string-array>
|
||||
</resources>
|
||||
|
||||
Reference in New Issue
Block a user