From 6646593c5b14aba5959e99e736113cd996b75e47 Mon Sep 17 00:00:00 2001 From: Kr328 <39107975+Kr328@users.noreply.github.com> Date: Sun, 24 Nov 2019 12:54:58 +0800 Subject: [PATCH] add query proxies --- core/build.gradle | 2 ++ core/src/main/golang/server/proxies.go | 15 ++++++--- core/src/main/golang/server/server.go | 4 +-- .../com/github/kr328/clash/core/BaseClash.kt | 20 +++++++++++- .../java/com/github/kr328/clash/core/Clash.kt | 31 +++++++++++++------ .../github/kr328/clash/core/transact/Proxy.kt | 9 ++++++ .../kr328/clash/service/ClashService.kt | 21 +++++++++---- 7 files changed, 77 insertions(+), 25 deletions(-) create mode 100644 core/src/main/java/com/github/kr328/clash/core/transact/Proxy.kt diff --git a/core/build.gradle b/core/build.gradle index 6bba2f4..f93f497 100644 --- a/core/build.gradle +++ b/core/build.gradle @@ -1,6 +1,7 @@ apply plugin: 'com.android.library' apply plugin: 'kotlin-android-extensions' apply plugin: 'kotlin-android' +apply plugin: 'kotlinx-serialization' android { compileSdkVersion 29 @@ -37,6 +38,7 @@ android { dependencies { implementation "androidx.core:core-ktx:1.1.0" implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version" + implementation "org.jetbrains.kotlinx:kotlinx-serialization-runtime:0.14.0" } afterEvaluate { diff --git a/core/src/main/golang/server/proxies.go b/core/src/main/golang/server/proxies.go index 669cdef..2100b1b 100644 --- a/core/src/main/golang/server/proxies.go +++ b/core/src/main/golang/server/proxies.go @@ -12,12 +12,12 @@ func handleQueryProxies(client *net.UnixConn) { proxies := tunnel.Instance().Proxies() var root struct { - proxies []map[string]interface{} `json:"proxies"` + Proxies map[string]interface{} `json:"proxies"` } - root.proxies = make([]map[string]interface{}, len(proxies)) + root.Proxies = make(map[string]interface{}) - for _, p := range proxies { + for k, p := range proxies { inner, err := p.MarshalJSON() if err != nil { @@ -27,8 +27,13 @@ func handleQueryProxies(client *net.UnixConn) { mapping := map[string]interface{}{} json.Unmarshal(inner, &mapping) - - root.proxies = append(root.proxies, mapping) + root.Proxies[k] = mapping } + data, err := json.Marshal(&root) + if err != nil { + log.Errorln("MarshJSON failure %s", err.Error()) + } + + writeCommandPacket(client, data) } diff --git a/core/src/main/golang/server/server.go b/core/src/main/golang/server/server.go index c66a4f1..de34c8e 100644 --- a/core/src/main/golang/server/server.go +++ b/core/src/main/golang/server/server.go @@ -24,7 +24,7 @@ func init() { handlers[commandTunStop] = handleTunStop // tun.go handlers[commandProfileDefault] = handleProfileDefault // profile.go handlers[commandProfileReload] = handleProfileReload // profile.go - handlers[commandQueryProxies] = handleQueryProxies + handlers[commandQueryProxies] = handleQueryProxies // proxies.go } // Start local control server @@ -66,6 +66,4 @@ func handleConnection(client *net.UnixConn) { } handler(client) - - client.Close() } 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 index 02e8642..bdf1712 100644 --- a/core/src/main/java/com/github/kr328/clash/core/BaseClash.kt +++ b/core/src/main/java/com/github/kr328/clash/core/BaseClash.kt @@ -2,6 +2,8 @@ package com.github.kr328.clash.core import android.net.LocalSocket import android.net.LocalSocketAddress +import android.util.Log +import com.github.kr328.clash.core.Constants.TAG import java.io.DataInputStream import java.io.DataOutputStream import java.io.File @@ -39,6 +41,20 @@ abstract class BaseClash(private val controllerPath: File) { return runControl(command) { _, _, _ -> } } + protected fun runControlNoException( + command: Int, + block: (LocalSocket, DataInputStream, DataOutputStream) -> R + ): R? { + return runCatching { + runControl(command, block) + }.getOrNull() + } + + protected fun runControlNoException(command: Int) { + runCatching { + runControl(command) + } + } protected fun DataOutputStream.writeString(string: String) { this.writeInt(string.length) @@ -49,7 +65,9 @@ abstract class BaseClash(private val controllerPath: File) { val len = this.readInt() val buffer = ByteArray(len) - this.read(buffer) + Log.d(TAG, "Read $len") + + this.readFully(buffer) return String(buffer) } 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 5320c98..e745126 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 @@ -3,8 +3,13 @@ package com.github.kr328.clash.core import android.content.Context import android.util.Log import com.github.kr328.clash.core.Constants.TAG +import com.github.kr328.clash.core.transact.Proxy +import kotlinx.serialization.json.Json +import kotlinx.serialization.json.JsonConfiguration import org.json.JSONObject -import java.io.* +import java.io.File +import java.io.FileDescriptor +import java.io.IOException class Clash( context: Context, @@ -25,14 +30,9 @@ class Clash( val process = ClashProcess(context, clashDir, controllerPath, listener) fun ping(): Boolean { - try { - return runControl(COMMAND_PING) { _, input, _ -> - input.readInt() == PING_REPLY - } - } catch (e: IOException) { - Log.w(TAG, "Clash ping failure", e) - } - return false + return runControlNoException(COMMAND_PING) { _, input, _ -> + input.readInt() == PING_REPLY + } ?: false } fun loadProfile(file: File) { @@ -48,6 +48,17 @@ class Clash( } } + fun queryProxies(): Proxy.Packet { + return runControl(COMMAND_QUERY_PROXIES) { _, input, _ -> + val data = input.readString() + + Log.d(TAG, data) + + Json(JsonConfiguration.Stable.copy(strictMode = false)) + .parse(Proxy.Packet.serializer(), data) + } + } + fun startTunDevice(fd: FileDescriptor, mtu: Int) { runControl(COMMAND_TUN_START) { socket, _, output -> socket.setFileDescriptorsForSend(arrayOf(fd)) @@ -59,6 +70,6 @@ class Clash( } fun stopTunDevice() { - runControl(COMMAND_TUN_STOP) + runControlNoException(COMMAND_TUN_STOP) } } \ No newline at end of file diff --git a/core/src/main/java/com/github/kr328/clash/core/transact/Proxy.kt b/core/src/main/java/com/github/kr328/clash/core/transact/Proxy.kt new file mode 100644 index 0000000..9e752f3 --- /dev/null +++ b/core/src/main/java/com/github/kr328/clash/core/transact/Proxy.kt @@ -0,0 +1,9 @@ +package com.github.kr328.clash.core.transact + +import kotlinx.serialization.Serializable + +@Serializable +data class Proxy(val type: String) { + @Serializable + data class Packet(val proxies: Map) +} \ No newline at end of file diff --git a/service/src/main/java/com/github/kr328/clash/service/ClashService.kt b/service/src/main/java/com/github/kr328/clash/service/ClashService.kt index 9d93f9f..3d5da35 100644 --- a/service/src/main/java/com/github/kr328/clash/service/ClashService.kt +++ b/service/src/main/java/com/github/kr328/clash/service/ClashService.kt @@ -14,10 +14,12 @@ import androidx.lifecycle.LiveData import androidx.lifecycle.Observer import com.github.kr328.clash.core.Clash import com.github.kr328.clash.core.ClashProcessStatus +import com.github.kr328.clash.core.Constants import com.github.kr328.clash.service.data.ClashDatabase import com.github.kr328.clash.service.data.ClashProfileEntity import java.io.File import java.io.IOException +import java.lang.Exception import java.util.concurrent.Executors class ClashService : Service() { @@ -54,7 +56,7 @@ class ClashService : Service() { override fun onChanged(file: ClashProfileEntity?) { executor.submit { if (file == null){ - clash.stop() + clash.process.stop() return@submit } @@ -63,10 +65,17 @@ class ClashService : Service() { try { clash.loadProfile(File(file.cache)) } catch (e: IOException) { - clash.stop() + clash.process.stop() Log.w(TAG, "Load profile failure", e) } + try { + Log.d(Constants.TAG, clash.queryProxies().toString()) + } + catch (e: Exception) { + Log.e(Constants.TAG, "NMSL" ,e) + } + handler.post(this@ClashService::updateNotification) } } @@ -107,7 +116,7 @@ class ClashService : Service() { override fun start() { try { - clash.start() + clash.process.start() } catch (e: IOException) { Log.e(TAG, "Start failure", e) @@ -116,7 +125,7 @@ class ClashService : Service() { } override fun stop() { - clash.stop() + clash.process.stop() } override fun getClashProcessStatus(): ClashProcessStatus { @@ -166,7 +175,7 @@ class ClashService : Service() { override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int { super.onStartCommand(intent, flags, startId) - clash.start() + clash.process.start() return START_NOT_STICKY } @@ -176,7 +185,7 @@ class ClashService : Service() { } override fun onDestroy() { - clash.stop() + clash.process.stop() executor.shutdown() super.onDestroy()