From 2ba82ebd97bdb8bf73867e9d77bea752b714c5ea Mon Sep 17 00:00:00 2001 From: Kr328 <39107975+Kr328@users.noreply.github.com> Date: Sat, 11 Jan 2020 21:05:59 +0800 Subject: [PATCH] migrate to netstack --- app/build.gradle | 13 +- build.gradle | 2 +- buildSrc/src/main/java/GolangBindTask.kt | 26 +++- buildSrc/src/main/java/MMDBDowloadTask.kt | 2 +- core/build.gradle | 33 +---- core/src/main/golang/bridge/init.go | 4 +- core/src/main/golang/bridge/tun.go | 8 +- core/src/main/golang/go.mod | 6 +- core/src/main/golang/go.sum | 12 ++ core/src/main/golang/profile/load.go | 2 +- core/src/main/golang/tun/tun.go | 50 ++----- .../com/github/kr328/clash/core/BaseClash.kt | 72 ---------- .../java/com/github/kr328/clash/core/Clash.kt | 10 +- .../github/kr328/clash/core/ClashProcess.kt | 133 ------------------ .../github/kr328/clash/service/TunService.kt | 26 ++-- 15 files changed, 80 insertions(+), 319 deletions(-) delete mode 100644 core/src/main/java/com/github/kr328/clash/core/BaseClash.kt delete mode 100644 core/src/main/java/com/github/kr328/clash/core/ClashProcess.kt diff --git a/app/build.gradle b/app/build.gradle index 11e1a0e..9beda17 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -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' } diff --git a/build.gradle b/build.gradle index f21d4e7..835c2fc 100644 --- a/build.gradle +++ b/build.gradle @@ -3,7 +3,7 @@ buildscript { ext { kotlin_version = '1.3.61' - room_version = '2.2.2' + room_version = '2.2.3' } repositories { google() diff --git a/buildSrc/src/main/java/GolangBindTask.kt b/buildSrc/src/main/java/GolangBindTask.kt index 6aaf2bd..3452a02 100644 --- a/buildSrc/src/main/java/GolangBindTask.kt +++ b/buildSrc/src/main/java/GolangBindTask.kt @@ -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)) diff --git a/buildSrc/src/main/java/MMDBDowloadTask.kt b/buildSrc/src/main/java/MMDBDowloadTask.kt index 45af3a2..7e6991b 100644 --- a/buildSrc/src/main/java/MMDBDowloadTask.kt +++ b/buildSrc/src/main/java/MMDBDowloadTask.kt @@ -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 = "" diff --git a/core/build.gradle b/core/build.gradle index 1c754e1..c02b234 100644 --- a/core/build.gradle +++ b/core/build.gradle @@ -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 { diff --git a/core/src/main/golang/bridge/init.go b/core/src/main/golang/bridge/init.go index e1fa614..9b301f6 100644 --- a/core/src/main/golang/bridge/init.go +++ b/core/src/main/golang/bridge/init.go @@ -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() } diff --git a/core/src/main/golang/bridge/tun.go b/core/src/main/golang/bridge/tun.go index 4bd4865..7cc5278 100644 --- a/core/src/main/golang/bridge/tun.go +++ b/core/src/main/golang/bridge/tun.go @@ -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() { diff --git a/core/src/main/golang/go.mod b/core/src/main/golang/go.mod index 68e9756..0624a48 100644 --- a/core/src/main/golang/go.mod +++ b/core/src/main/golang/go.mod @@ -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 diff --git a/core/src/main/golang/go.sum b/core/src/main/golang/go.sum index 3668920..be4383c 100644 --- a/core/src/main/golang/go.sum +++ b/core/src/main/golang/go.sum @@ -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= diff --git a/core/src/main/golang/profile/load.go b/core/src/main/golang/profile/load.go index 52b5926..672bb2a 100644 --- a/core/src/main/golang/profile/load.go +++ b/core/src/main/golang/profile/load.go @@ -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{ diff --git a/core/src/main/golang/tun/tun.go b/core/src/main/golang/tun/tun.go index 64a8b68..b36baa3 100644 --- a/core/src/main/golang/tun/tun.go +++ b/core/src/main/golang/tun/tun.go @@ -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) } diff --git a/core/src/main/java/com/github/kr328/clash/core/BaseClash.kt b/core/src/main/java/com/github/kr328/clash/core/BaseClash.kt deleted file mode 100644 index 104d3b4..0000000 --- a/core/src/main/java/com/github/kr328/clash/core/BaseClash.kt +++ /dev/null @@ -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 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 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) - } -} \ No newline at end of file diff --git a/core/src/main/java/com/github/kr328/clash/core/Clash.kt b/core/src/main/java/com/github/kr328/clash/core/Clash.kt index d524e29..d3a1edb 100644 --- a/core/src/main/java/com/github/kr328/clash/core/Clash.kt +++ b/core/src/main/java/com/github/kr328/clash/core/Clash.kt @@ -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() { diff --git a/core/src/main/java/com/github/kr328/clash/core/ClashProcess.kt b/core/src/main/java/com/github/kr328/clash/core/ClashProcess.kt deleted file mode 100644 index 90e9ec9..0000000 --- a/core/src/main/java/com/github/kr328/clash/core/ClashProcess.kt +++ /dev/null @@ -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) - } - } - } -} \ No newline at end of file diff --git a/service/src/main/java/com/github/kr328/clash/service/TunService.kt b/service/src/main/java/com/github/kr328/clash/service/TunService.kt index f4e5f4b..f9c56b8 100644 --- a/service/src/main/java/com/github/kr328/clash/service/TunService.kt +++ b/service/src/main/java/com/github/kr328/clash/service/TunService.kt @@ -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) } }