migrate to netstack

This commit is contained in:
Kr328 committed 2020-01-11 21:05:59 +08:00
1 parent 00163fbfd4
commit 2ba82ebd97
15 files changed
+80 -319

No files matched your search

+7 -6
View File
@@ -13,8 +13,8 @@ android {
applicationId "com.github.kr328.clash"
minSdkVersion 24
targetSdkVersion 29
versionCode 10029
versionName "1.0.29-alpha"
versionCode 10035
versionName "1.0.35-alpha"
}
buildTypes {
release {
@@ -42,18 +42,19 @@ dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
implementation "androidx.lifecycle:lifecycle-livedata:2.1.0"
implementation "androidx.lifecycle:lifecycle-common-java8:2.1.0"
implementation 'androidx.browser:browser:1.0.0'
implementation 'androidx.browser:browser:1.2.0'
implementation 'androidx.preference:preference:1.1.0'
implementation 'androidx.recyclerview:recyclerview:1.1.0'
implementation 'androidx.core:core-ktx:1.2.0-rc01'
implementation 'androidx.fragment:fragment-ktx:1.2.0-rc03'
implementation 'androidx.fragment:fragment-ktx:1.2.0-rc05'
implementation 'androidx.appcompat:appcompat:1.1.0'
implementation 'androidx.constraintlayout:constraintlayout:2.0.0-beta3'
implementation 'androidx.constraintlayout:constraintlayout:2.0.0-beta4'
implementation "androidx.room:room-runtime:$room_version"
implementation "androidx.preference:preference-ktx:1.1.0"
implementation "androidx.swiperefreshlayout:swiperefreshlayout:1.0.0"
implementation "org.jetbrains.kotlinx:kotlinx-serialization-runtime:0.14.0"
implementation "com.charleskorn.kaml:kaml:0.14.0"
implementation "com.google.android.material:material:1.2.0-alpha02"
implementation "com.google.android.material:material:1.2.0-alpha03"
implementation 'com.google.firebase:firebase-analytics:17.2.1'
implementation 'com.crashlytics.sdk.android:crashlytics:2.10.1'
}
+1 -1
View File
@@ -3,7 +3,7 @@
buildscript {
ext {
kotlin_version = '1.3.61'
room_version = '2.2.2'
room_version = '2.2.3'
}
repositories {
google()
+23 -3
View File
@@ -16,11 +16,9 @@ open class GolangBindTask : DefaultTask() {
require (
github.com/kr328/cfa v0.0.0 // redirect
github.com/Dreamacro/clash v0.0.0 // redirect
)
replace github.com/kr328/cfa v0.0.0 => {SOURCE_PATH}
replace github.com/Dreamacro/clash v0.0.0 => {SOURCE_PATH}/clash
""".trimIndent()
private val STUB_GO_FILE_CONTENT = """
package main
@@ -29,6 +27,8 @@ open class GolangBindTask : DefaultTask() {
func main() {}
""".trimIndent()
private val REGEX_REPLACE_TARGET_LOCAL = Regex("=>\\s+\\./")
private val REGEX_REPLACE_SOURCE_VERSION = Regex("v.+\\s+=>")
}
private val javaOutput: File
@@ -90,7 +90,7 @@ open class GolangBindTask : DefaultTask() {
"go get golang.org/x/mobile/cmd/gomobile".exec()
FileWriter(goBindPath.resolve("go.mod")).use {
it.write(STUB_GO_MOD_CONTENT.replace("{SOURCE_PATH}", sourcePath.absolutePath))
it.write(appendReplace(sourcePath))
}
FileWriter(goBindPath.resolve("main.go")).use {
it.write(STUB_GO_FILE_CONTENT)
@@ -152,6 +152,26 @@ open class GolangBindTask : DefaultTask() {
?: throw GradleException("Android SDK not found.")
}
private fun appendReplace(source: File): String {
val replaces = source.walk()
.filter { it.name == "go.mod" }
.flatMap { file ->
file.readLines()
.asSequence()
.filter { line -> line.startsWith("replace") }
.map { replace ->
replace.replace(REGEX_REPLACE_TARGET_LOCAL, "=> " + file.parentFile.absolutePath + "/")
}
.map { replace ->
replace.replace(REGEX_REPLACE_SOURCE_VERSION, " =>")
}
}
.joinToString("\n")
return STUB_GO_MOD_CONTENT.replace("{SOURCE_PATH}", source.absolutePath) +
"\n\n" + replaces
}
private fun String.exec(pwd: File = File(".")) {
val process = with(ProcessBuilder()) {
if (Os.isFamily(Os.FAMILY_WINDOWS))
+1 -1
View File
@@ -8,7 +8,7 @@ import java.net.URL
open class MMDBDowloadTask : DefaultTask() {
companion object {
const val URL = "http://geolite.maxmind.com/download/geoip/database/GeoLite2-Country.tar.gz"
const val URL = "https://github.com/Dreamacro/maxmind-geoip/releases/latest/download/Country.mmdb"
}
var output: String = ""
+4 -29
View File
@@ -45,41 +45,16 @@ dependencies {
afterEvaluate {
def ds = tasks.register("downloadMMDB", MMDBDowloadTask.class) {
onlyIf {
System.currentTimeMillis() - file("$buildDir/intermediates/cache/Country.tar.gz").lastModified() > 24 * 3600 * 1000L
System.currentTimeMillis() - file("$buildDir/intermediates/dynamic_assets/Country.mmdb").lastModified() > 24 * 3600 * 1000L
}
output = "$buildDir/intermediates/cache/Country.tar.gz"
}
def es = tasks.register("extractMMDB", Copy.class) {
onlyIf {
file("$buildDir/intermediates/cache/Country.tar.gz").lastModified() > file("$buildDir/intermediates/dynamic_assets/Country.mmdb").lastModified()
}
from(tarTree("$buildDir/intermediates/cache/Country.tar.gz")) {
include "**/*.mmdb"
}
into "$buildDir/intermediates/cache/mmdb"
doLast {
file("$buildDir/intermediates/dynamic_assets").mkdirs()
fileTree("$buildDir/intermediates/cache/mmdb").visit { FileVisitDetails details ->
if ( details.path.endsWith("Country.mmdb") )
details.file.renameTo(file("$buildDir/intermediates/dynamic_assets/Country.mmdb"))
}
}
dependsOn ds
}
for ( task in tasks ) {
if ( task.name.contains("generate") && task.name.contains("Assets") )
task.dependsOn(es)
output = "$buildDir/intermediates/dynamic_assets/Country.mmdb"
}
def gs = tasks.register("golangBind", GolangBindTask.class)
preBuild.dependsOn(gs)
preBuild.dependsOn(ds, gs)
}
repositories {
+2 -2
View File
@@ -6,11 +6,11 @@ import "github.com/kr328/cfa/profile"
import "github.com/Dreamacro/clash/tunnel"
func Init(home string) {
func SetBaseDir(home string) {
constant.SetHomeDir(home)
}
func Reset() {
profile.LoadDefault()
tunnel.DefaultManager.Reset()
tunnel.DefaultManager.ResetStatistic()
}
+2 -6
View File
@@ -4,12 +4,8 @@ import (
"github.com/kr328/cfa/tun"
)
type TunCallback interface {
OnNewSocket(fd int)
}
func StartTunDevice(fd, mtu int, gateway string, dns string, callback TunCallback) error {
return tun.StartTunDevice(fd, mtu, gateway, dns, callback)
func StartTunDevice(fd, mtu int, dns string) error {
return tun.StartTunDevice(fd, mtu, dns)
}
func StopTunDevice() {
+4 -2
View File
@@ -7,7 +7,9 @@ require (
github.com/go-chi/render v1.0.1
github.com/google/go-cmp v0.3.1 // indirect
golang.org/x/mobile v0.0.0-20191210151939-1a1fef82734d // indirect
golang.org/x/sys v0.0.0-20191128015809-6d18c012aee9
golang.org/x/sys v0.0.0-20191224085550-c709ea063b76
)
replace github.com/Dreamacro/clash v0.0.0 => ./clash
replace github.com/Dreamacro/clash => ./clash
replace github.com/google/netstack => github.com/comzyh/netstack v0.0.0-20191217044024-67c27819ada4
+12
View File
@@ -10,6 +10,8 @@ github.com/Dreamacro/go-shadowsocks2 v0.1.5 h1:BizWSjmwzAyQoslz6YhJYMiAGT99j9cnm
github.com/Dreamacro/go-shadowsocks2 v0.1.5/go.mod h1:LSXCjyHesPY3pLjhwff1mQX72ItcBT/N2xNC685cYeU=
github.com/aead/chacha20 v0.0.0-20180709150244-8b13a72661da h1:KjTM2ks9d14ZYCvmHS9iAKVt9AyzRSqNU1qabPih5BY=
github.com/aead/chacha20 v0.0.0-20180709150244-8b13a72661da/go.mod h1:eHEWzANqSiWQsof+nXEI9bUVUyV6F53Fp89EuCh2EAA=
github.com/comzyh/netstack v0.0.0-20191217044024-67c27819ada4 h1:30ykXB9NWubvyVWE5pe/YakDgEdu6wJkBZlZYDtV464=
github.com/comzyh/netstack v0.0.0-20191217044024-67c27819ada4/go.mod h1:jMMWEkl1smElz5KtnrIWDHxc8gtMIO/Pd8+pLyGRzT8=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
@@ -46,14 +48,20 @@ github.com/miekg/dns v1.1.22 h1:Jm64b3bO9kP43ddLjL2EY3Io6bmy1qGb9Xxz6TqS6rc=
github.com/miekg/dns v1.1.22/go.mod h1:bPDLeHnStXmXAq1m/Ch/hvfNHr14JKNPMBo3VZKjuso=
github.com/miekg/dns v1.1.24 h1:6G8Eop/HM8hpagajbn0rFQvAKZWiiCa8P6N2I07+wwI=
github.com/miekg/dns v1.1.24/go.mod h1:bPDLeHnStXmXAq1m/Ch/hvfNHr14JKNPMBo3VZKjuso=
github.com/miekg/dns v1.1.26 h1:gPxPSwALAeHJSjarOs00QjVdV9QoBvc1D2ujQUr5BzU=
github.com/miekg/dns v1.1.26/go.mod h1:bPDLeHnStXmXAq1m/Ch/hvfNHr14JKNPMBo3VZKjuso=
github.com/oschwald/geoip2-golang v1.2.1 h1:3iz+jmeJc6fuCyWeKgtXSXu7+zvkxJbHFXkMT5FVebU=
github.com/oschwald/geoip2-golang v1.2.1/go.mod h1:0LTTzix/Ao1uMvOhAV4iLU0Lz7eCrP94qZWBTDKf0iE=
github.com/oschwald/geoip2-golang v1.3.0 h1:D+Hsdos1NARPbzZ2aInUHZL+dApIzo8E0ErJVsWcku8=
github.com/oschwald/geoip2-golang v1.3.0/go.mod h1:0LTTzix/Ao1uMvOhAV4iLU0Lz7eCrP94qZWBTDKf0iE=
github.com/oschwald/geoip2-golang v1.4.0 h1:5RlrjCgRyIGDz/mBmPfnAF4h8k0IAcRv9PvrpOfz+Ug=
github.com/oschwald/geoip2-golang v1.4.0/go.mod h1:8QwxJvRImBH+Zl6Aa6MaIcs5YdlZSTKtzmPGzQqi9ng=
github.com/oschwald/maxminddb-golang v1.3.0 h1:oTh8IBSj10S5JNlUDg5WjJ1QdBMdeaZIkPEVfESSWgE=
github.com/oschwald/maxminddb-golang v1.3.0/go.mod h1:3jhIUymTJ5VREKyIhWm66LJiQt04F0UCDdodShpjWsY=
github.com/oschwald/maxminddb-golang v1.5.0 h1:rmyoIV6z2/s9TCJedUuDiKht2RN12LWJ1L7iRGtWY64=
github.com/oschwald/maxminddb-golang v1.5.0/go.mod h1:3jhIUymTJ5VREKyIhWm66LJiQt04F0UCDdodShpjWsY=
github.com/oschwald/maxminddb-golang v1.6.0 h1:KAJSjdHQ8Kv45nFIbtoLGrGWqHFajOIm7skTyz/+Dls=
github.com/oschwald/maxminddb-golang v1.6.0/go.mod h1:DUJFucBg2cvqx42YmDa/+xHvb0elJtOm3o4aFQ/nb/w=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/sirupsen/logrus v1.4.1 h1:GL2rEmy6nsikmW0r8opw9JIRScdMF5hA8cOYLH7In1k=
@@ -98,6 +106,8 @@ golang.org/x/net v0.0.0-20191126235420-ef20fe5d7933 h1:e6HwijUxhDe+hPNjZQQn9bA5P
golang.org/x/net v0.0.0-20191126235420-ef20fe5d7933/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20191207000613-e7e4b65ae663 h1:Dd5RoEW+yQi+9DMybroBctIdyiwuNT7sJFMC27/6KxI=
golang.org/x/net v0.0.0-20191207000613-e7e4b65ae663/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553 h1:efeOvDhwQ29Dj3SdAV/MJf8oukgn+8D8WgaCaRMchF8=
golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e h1:vcxGaoTs7kV8m5Np9uUNQin4BrLOthgV7252N8V+FwY=
@@ -111,6 +121,8 @@ golang.org/x/sys v0.0.0-20190924154521-2837fb4f24fe h1:6fAMxZRR6sl1Uq8U61gxU+kPT
golang.org/x/sys v0.0.0-20190924154521-2837fb4f24fe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191128015809-6d18c012aee9 h1:ZBzSG/7F4eNKz2L3GE9o300RX0Az1Bw5HF7PDraD+qU=
golang.org/x/sys v0.0.0-20191128015809-6d18c012aee9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191224085550-c709ea063b76 h1:Dho5nD6R3PcW2SH1or8vS0dszDaXRxIw55lBX7XiE5g=
golang.org/x/sys v0.0.0-20191224085550-c709ea063b76/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
+1 -1
View File
@@ -68,7 +68,7 @@ func LoadFromFile(path string) error {
if dns.DefaultResolver == nil {
_, ipnet, _ := net.ParseCIDR("198.18.0.1/16")
pool, _ := fakeip.New(ipnet, 1000)
pool, _ := fakeip.New(ipnet, 1000, nil)
var defaultDNSResolver = dns.New(dns.Config{
Main: []dns.NameServer{
+9 -41
View File
@@ -1,55 +1,28 @@
package tun
import (
"net"
"strconv"
"syscall"
"github.com/Dreamacro/clash/global"
"github.com/Dreamacro/clash/dns"
"github.com/Dreamacro/clash/log"
"github.com/Dreamacro/clash/proxy/tun"
)
type Callback interface {
OnNewSocket(fd int)
}
var tunInstance *tun.TunAdapter
var dnsAddress string
var tunInstance *tun.TUN
func StartTunDevice(fd, mtu int, gateway string, dnsGateway string, callback Callback) error {
func StartTunDevice(fd, mtu int, dns string) error {
if tunInstance != nil {
return nil
}
ip, n, err := net.ParseCIDR(gateway)
t, err := tun.NewTunProxy("fd://" + strconv.Itoa(fd) + "?mtu=" + strconv.Itoa(mtu))
if err != nil {
return err
}
n.IP = ip.To4()
global.DefaultDialer.Control = func(network, address string, c syscall.RawConn) error {
return c.Control(func(fd uintptr) {
callback.OnNewSocket(int(fd))
})
}
global.DefaultListenConfig.Control = func(network, address string, c syscall.RawConn) error {
return c.Control(func(fd uintptr) {
callback.OnNewSocket(int(fd))
})
}
dnsGatewayIP := net.ParseIP(dnsGateway)
t, err := tun.NewTunProxy("fd://"+strconv.Itoa(fd)+"?mtu="+strconv.Itoa(mtu), *n, dnsGatewayIP)
if err != nil {
global.DefaultDialer.Control = nil
global.DefaultListenConfig.Control = nil
return err
}
tunInstance = t
tunInstance = &t
dnsAddress = dns + ":53"
ResetDnsRedirect()
@@ -64,12 +37,7 @@ func StopTunDevice() {
return
}
t.Close()
global.DefaultDialer.Control = nil
global.DefaultListenConfig.Control = nil
tunInstance = nil
(*t).Close()
}
func ResetDnsRedirect() {
@@ -77,5 +45,5 @@ func ResetDnsRedirect() {
return
}
tunInstance.ResetDnsServer()
(*tunInstance).ReCreateDNSServer(dns.DefaultResolver, dnsAddress)
}
@@ -1,72 +0,0 @@
package com.github.kr328.clash.core
import android.net.LocalSocket
import android.net.LocalSocketAddress
import com.github.kr328.clash.core.utils.Log
import java.io.DataInputStream
import java.io.DataOutputStream
import java.io.File
@Suppress("SameParameterValue")
abstract class BaseClash(private val controllerPath: File) {
protected fun <R> runControl(
command: Int,
block: (LocalSocket, DataInputStream, DataOutputStream) -> R
): R {
val socket = LocalSocket()
socket.connect(
LocalSocketAddress(
controllerPath.absolutePath,
LocalSocketAddress.Namespace.FILESYSTEM
)
)
val input = DataInputStream(socket.inputStream)
val output = DataOutputStream(socket.outputStream)
output.writeInt(command)
val result = block(socket, input, output)
runCatching {
socket.close()
}
return result
}
protected fun runControl(command: Int) {
return runControl(command) { _, _, _ -> }
}
protected fun <R> runControlNoException(
command: Int,
block: (LocalSocket, DataInputStream, DataOutputStream) -> R
): R? {
return try {
runControl(command, block)
} catch (ignored: Exception) { null }
}
protected fun runControlNoException(command: Int) {
try {
runControl(command)
} catch (ignored: Exception) {}
}
protected fun DataOutputStream.writeString(string: String) {
val buffer = string.toByteArray(Charsets.UTF_8)
this.writeInt(buffer.size)
this.write(buffer)
}
protected fun DataInputStream.readString(): String {
val len = this.readInt()
val buffer = ByteArray(len)
this.readFully(buffer)
return String(buffer)
}
}
@@ -47,7 +47,7 @@ class Clash(
}
}
Bridge.init(home.absolutePath)
Bridge.setBaseDir(home.absolutePath)
}
fun getCurrentProcessStatus(): ProcessEvent {
@@ -79,15 +79,11 @@ class Clash(
fun startTunDevice(
fd: Int,
mtu: Int,
gateway: String,
dns: String,
onSocket: (Int) -> Unit
dns: String
) {
enforceStarted()
Bridge.startTunDevice(fd.toLong(), mtu.toLong(), gateway, dns) {
onSocket(it.toInt())
}
Bridge.startTunDevice(fd.toLong(), mtu.toLong(), dns)
}
fun stopTunDevice() {
@@ -1,133 +0,0 @@
package com.github.kr328.clash.core
import android.content.Context
import com.github.kr328.clash.core.event.ProcessEvent
import com.github.kr328.clash.core.utils.Log
import java.io.File
import java.io.FileOutputStream
import java.io.IOException
import kotlin.concurrent.thread
class ClashProcess(
private val context: Context,
private val clashDir: File,
private val controllerPath: File,
private val listener: (ProcessEvent) -> Unit
) {
companion object {
private const val CONTROLLER_STATUS_PREFIX = "[CONTROLLER]"
private val PID_PATTERN = Regex("\\[PID]\\s*(\\d+)")
private val CONTROLLER_ERROR_PATTERN = Regex("\\[CONTROLLER] ERROR=\\{(.+)\\}")
}
private var pid: Int = 0
private var process: Process? = null
@Synchronized
fun start() {
if (pid > 0)
return
try {
clashDir.mkdirs()
controllerPath.parentFile?.mkdirs()
controllerPath.delete()
extractMMDB()
val clashPath =
File(context.applicationInfo.nativeLibraryDir, "libclash.so").absolutePath
val p = ProcessBuilder().apply {
command(clashPath, controllerPath.absolutePath)
directory(clashDir)
}.start()
Log.i("Starting clash [$clashPath]")
val reader = p.inputStream.bufferedReader()
var line = ""
// Parse pid
var currentPid = 0
while (reader.readLine()?.apply { line = this.trim() } != null) {
Log.i(line)
if (PID_PATTERN.matchEntire(line)?.apply {
currentPid = groups[1]!!.value.toInt()
} != null)
break
}
while (reader.readLine()?.apply { line = this.trim() } != null) {
Log.i(line)
if (line.startsWith(CONTROLLER_STATUS_PREFIX)) {
val error = CONTROLLER_ERROR_PATTERN.matchEntire(line)?.groups?.get(1)?.value
if (error != null)
throw IOException("Controller: $error")
break
}
}
process = p
pid = currentPid
listener(ProcessEvent.STARTED)
Log.i("Clash started pid = $pid")
thread {
// Redirect stdout to log
while (reader.readLine()?.apply { line = this } != null) {
Log.i(line.trim())
}
synchronized(this@ClashProcess) {
p.destroy()
process = null
pid = -1
}
listener(ProcessEvent.STOPPED)
}
} catch (e: Exception) {
listener(ProcessEvent.STOPPED)
throw e
}
}
@Synchronized
fun getProcessStatus(): ProcessEvent {
return if (pid > 0)
ProcessEvent.STARTED
else
ProcessEvent.STOPPED
}
@Synchronized
fun stop() {
if ( getProcessStatus() == ProcessEvent.STOPPED )
listener(ProcessEvent.STOPPED)
android.os.Process.killProcess(pid)
}
private fun extractMMDB() {
if (context.packageManager.getPackageInfo(context.packageName, 0).lastUpdateTime
< clashDir.resolve("Country.mmdb").lastModified()
)
return
clashDir.resolve("ui").mkdirs()
context.resources.assets.open("Country.mmdb").use { input ->
FileOutputStream(clashDir.resolve("Country.mmdb")).use { output ->
input.copyTo(output)
}
}
}
}
@@ -10,8 +10,6 @@ import android.os.*
import com.github.kr328.clash.core.event.*
import com.github.kr328.clash.core.utils.Log
import com.github.kr328.clash.service.net.DefaultNetworkObserver
import java.net.Inet4Address
import java.net.InetAddress
class TunService : VpnService(), IClashEventObserver {
companion object {
@@ -118,18 +116,14 @@ class TunService : VpnService(), IClashEventObserver {
if ( settings.isDnsHijackingEnabled ) {
clash.clash.startTunDevice(
fileDescriptor.fd, VPN_MTU,
"$PRIVATE_VLAN4_CLIENT/$PRIVATE_VLAN4_SUBNET", VLAN4_ANY
) {
protect(it.toInt())
}
VLAN4_ANY
)
}
else {
clash.clash.startTunDevice(
fileDescriptor.fd, VPN_MTU,
"$PRIVATE_VLAN4_CLIENT/$PRIVATE_VLAN4_SUBNET", PRIVATE_VLAN_DNS
) {
protect(it.toInt())
}
PRIVATE_VLAN_DNS
)
}
fileDescriptor.close()
@@ -170,11 +164,13 @@ class TunService : VpnService(), IClashEventObserver {
addDisallowedApplication(app)
}
}
addDisallowedApplication(packageName)
}
ClashSettingService.ACCESS_CONTROL_MODE_ALLOW -> {
addAllowedApplication(packageName)
for ( app in (settings.accessControlApps.toSet() -
resources.getStringArray(R.array.default_disallow_application)) ) {
for ( app in settings.accessControlApps.toSet() -
resources.getStringArray(R.array.default_disallow_application) -
setOf(packageName) ) {
runCatching {
addAllowedApplication(app)
}.onFailure {
@@ -183,15 +179,15 @@ class TunService : VpnService(), IClashEventObserver {
}
}
ClashSettingService.ACCESS_CONTROL_MODE_DISALLOW -> {
for ( app in (settings.accessControlApps.toSet() +
resources.getStringArray(R.array.default_disallow_application) -
listOf(packageName)) ) {
for ( app in settings.accessControlApps.toSet() +
resources.getStringArray(R.array.default_disallow_application) ) {
runCatching {
addDisallowedApplication(app)
}.onFailure {
Log.w("Package $app not found")
}
}
addDisallowedApplication(packageName)
}
}