diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index aa7df6a..8723a5c 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -27,9 +27,9 @@ jobs: - platform: macos os: macos-latest arch: arm64 - - platform: windows - os: windows-11-arm - arch: arm64 + # - platform: windows + # os: windows-11-arm + # arch: arm64 - platform: linux os: ubuntu-24.04-arm arch: arm64 diff --git a/.gitignore b/.gitignore index 1fc3c53..b568df4 100644 --- a/.gitignore +++ b/.gitignore @@ -45,11 +45,19 @@ app.*.map.json /android/app/debug /android/app/profile /android/app/release +/android/**/.cxx +/android/**/build +/android/common/**/.**/ +/android/common/local.* +/android/core/**/includes/ +/android/core/**/cmake-build-*/ +/android/core/**/jniLibs/ - -#libclash +#FlClash /libclash/ - -#jniLibs /android/app/src/main/jniLibs/ +/services/helper/target +/macos/**/Package.resolved +devtools_options.yaml + diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml index 0c4c9c8..4e2567e 100644 --- a/android/app/src/main/AndroidManifest.xml +++ b/android/app/src/main/AndroidManifest.xml @@ -66,7 +66,6 @@ diff --git a/android/app/src/main/kotlin/com/follow/clash/Service.kt b/android/app/src/main/kotlin/com/follow/clash/Service.kt index 05a6589..758818a 100644 --- a/android/app/src/main/kotlin/com/follow/clash/Service.kt +++ b/android/app/src/main/kotlin/com/follow/clash/Service.kt @@ -3,6 +3,7 @@ package com.follow.clash import com.follow.clash.common.ServiceDelegate import com.follow.clash.common.formatString import com.follow.clash.common.intent +import com.follow.clash.service.IAckInterface import com.follow.clash.service.ICallbackInterface import com.follow.clash.service.IEventInterface import com.follow.clash.service.IRemoteInterface @@ -44,8 +45,11 @@ object Service { return delegate.useService { it.invokeAction( data, object : ICallbackInterface.Stub() { - override fun onResult(result: ByteArray?, isSuccess: Boolean) { + override fun onResult( + result: ByteArray?, isSuccess: Boolean, ack: IAckInterface? + ) { res.add(result ?: byteArrayOf()) + ack?.onAck() if (isSuccess) { cb(res.formatString()) } @@ -61,24 +65,24 @@ object Service { return delegate.useService { it.setEventListener( when (cb != null) { - true -> object : IEventInterface.Stub() { - override fun onEvent( - id: String, data: ByteArray?, isSuccess: Boolean - ) { - if (results[id] == null) { - results[id] = mutableListOf() - } - results[id]?.add(data ?: byteArrayOf()) - if (isSuccess) { - cb(results[id]?.formatString()) - results.remove(id) - } + true -> object : IEventInterface.Stub() { + override fun onEvent( + id: String, data: ByteArray?, isSuccess: Boolean, ack: IAckInterface? + ) { + if (results[id] == null) { + results[id] = mutableListOf() + } + results[id]?.add(data ?: byteArrayOf()) + ack?.onAck() + if (isSuccess) { + cb(results[id]?.formatString()) + results.remove(id) } } - - false -> null } - ) + + false -> null + }) } } diff --git a/android/app/src/main/kotlin/com/follow/clash/TempActivity.kt b/android/app/src/main/kotlin/com/follow/clash/TempActivity.kt index 1e8a519..9fc22c5 100644 --- a/android/app/src/main/kotlin/com/follow/clash/TempActivity.kt +++ b/android/app/src/main/kotlin/com/follow/clash/TempActivity.kt @@ -30,6 +30,6 @@ class TempActivity : Activity(), } } } - finish() + finishAndRemoveTask() } } \ No newline at end of file diff --git a/android/app/src/main/kotlin/com/follow/clash/TileService.kt b/android/app/src/main/kotlin/com/follow/clash/TileService.kt index 84746cb..8fb08bf 100644 --- a/android/app/src/main/kotlin/com/follow/clash/TileService.kt +++ b/android/app/src/main/kotlin/com/follow/clash/TileService.kt @@ -45,8 +45,7 @@ class TileService : TileService() { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) { startActivityAndCollapse(pendingIntent) } else { - @Suppress("DEPRECATION") - startActivityAndCollapse(intent) + @Suppress("DEPRECATION") startActivityAndCollapse(intent) } } diff --git a/android/common/src/main/java/com/follow/clash/common/Ext.kt b/android/common/src/main/java/com/follow/clash/common/Ext.kt index 1d27016..71773d9 100644 --- a/android/common/src/main/java/com/follow/clash/common/Ext.kt +++ b/android/common/src/main/java/com/follow/clash/common/Ext.kt @@ -220,7 +220,6 @@ val Long.formatBytes: String fun String.chunkedForAidl(charset: Charset = Charsets.UTF_8): List { val allBytes = toByteArray(charset) val total = allBytes.size - val maxBytes = when { total <= 100 * 1024 -> total total <= 1024 * 1024 -> 64 * 1024 diff --git a/android/common/src/main/java/com/follow/clash/common/Service.kt b/android/common/src/main/java/com/follow/clash/common/Service.kt index f3e7e68..09433cb 100644 --- a/android/common/src/main/java/com/follow/clash/common/Service.kt +++ b/android/common/src/main/java/com/follow/clash/common/Service.kt @@ -11,6 +11,7 @@ import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.filterNotNull import kotlinx.coroutines.flow.first import kotlinx.coroutines.launch +import kotlinx.coroutines.withContext import kotlinx.coroutines.withTimeout import java.util.concurrent.atomic.AtomicBoolean @@ -59,7 +60,9 @@ class ServiceDelegate( withTimeout(timeoutMillis) { val state = serviceState.filterNotNull().first() state.first?.let { - block(it) + withContext(Dispatchers.Default) { + block(it) + } } ?: throw Exception(state.second) } } diff --git a/android/service/src/main/aidl/com/follow/clash/service/IAckInterface.aidl b/android/service/src/main/aidl/com/follow/clash/service/IAckInterface.aidl new file mode 100644 index 0000000..11efaa9 --- /dev/null +++ b/android/service/src/main/aidl/com/follow/clash/service/IAckInterface.aidl @@ -0,0 +1,8 @@ +// IAckInterface.aidl +package com.follow.clash.service; + +import com.follow.clash.service.IAckInterface; + +interface IAckInterface { + oneway void onAck(); +} \ No newline at end of file diff --git a/android/service/src/main/aidl/com/follow/clash/service/ICallbackInterface.aidl b/android/service/src/main/aidl/com/follow/clash/service/ICallbackInterface.aidl index 179ad1a..5a8cf24 100644 --- a/android/service/src/main/aidl/com/follow/clash/service/ICallbackInterface.aidl +++ b/android/service/src/main/aidl/com/follow/clash/service/ICallbackInterface.aidl @@ -1,6 +1,8 @@ // ICallbackInterface.aidl package com.follow.clash.service; +import com.follow.clash.service.IAckInterface; + interface ICallbackInterface { - oneway void onResult(in byte[] data,in boolean isSuccess); + oneway void onResult(in byte[] data,in boolean isSuccess, in IAckInterface ack); } \ No newline at end of file diff --git a/android/service/src/main/aidl/com/follow/clash/service/IEventInterface.aidl b/android/service/src/main/aidl/com/follow/clash/service/IEventInterface.aidl index 3c01bdb..87c1897 100644 --- a/android/service/src/main/aidl/com/follow/clash/service/IEventInterface.aidl +++ b/android/service/src/main/aidl/com/follow/clash/service/IEventInterface.aidl @@ -1,6 +1,8 @@ // IEventInterface.aidl package com.follow.clash.service; +import com.follow.clash.service.IAckInterface; + interface IEventInterface { - oneway void onEvent(in String id, in byte[] data,in boolean isSuccess); + oneway void onEvent(in String id, in byte[] data,in boolean isSuccess, in IAckInterface ack); } \ No newline at end of file diff --git a/android/service/src/main/java/com/follow/clash/service/RemoteService.kt b/android/service/src/main/java/com/follow/clash/service/RemoteService.kt index ec9e039..5fbb6e1 100644 --- a/android/service/src/main/java/com/follow/clash/service/RemoteService.kt +++ b/android/service/src/main/java/com/follow/clash/service/RemoteService.kt @@ -17,8 +17,10 @@ import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.SupervisorJob import kotlinx.coroutines.launch +import kotlinx.coroutines.suspendCancellableCoroutine import kotlinx.coroutines.sync.withLock import java.util.UUID +import kotlin.coroutines.resume class RemoteService : Service(), CoroutineScope by CoroutineScope(SupervisorJob() + Dispatchers.Default) { @@ -75,11 +77,22 @@ class RemoteService : Service(), private val binder = object : IRemoteInterface.Stub() { override fun invokeAction(data: String, callback: ICallbackInterface) { Core.invokeAction(data) { - runCatching { - val chunks = it?.chunkedForAidl() ?: listOf() - val totalSize = chunks.size - chunks.forEachIndexed { index, chunk -> - callback.onResult(chunk, totalSize - 1 == index) + launch { + runCatching { + val chunks = it?.chunkedForAidl() ?: listOf() + for ((index, chunk) in chunks.withIndex()) { + suspendCancellableCoroutine { cont -> + callback.onResult( + chunk, + index == chunks.lastIndex, + object : IAckInterface.Stub() { + override fun onAck() { + cont.resume(Unit) + } + }, + ) + } + } } } } @@ -89,6 +102,7 @@ class RemoteService : Service(), State.notificationParamsFlow.tryEmit(params) } + override fun startService( options: VpnOptions, runtime: Long, @@ -106,12 +120,24 @@ class RemoteService : Service(), GlobalState.log("RemoveEventListener ${eventListener == null}") when (eventListener != null) { true -> Core.callSetEventListener { - runCatching { - val id = UUID.randomUUID().toString() - val chunks = it?.chunkedForAidl() ?: listOf() - val totalSize = chunks.size - chunks.forEachIndexed { index, chunk -> - eventListener.onEvent(id, chunk, totalSize - 1 == index) + launch { + runCatching { + val id = UUID.randomUUID().toString() + val chunks = it?.chunkedForAidl() ?: listOf() + for ((index, chunk) in chunks.withIndex()) { + suspendCancellableCoroutine { cont -> + eventListener.onEvent( + id, + chunk, + index == chunks.lastIndex, + object : IAckInterface.Stub() { + override fun onAck() { + cont.resume(Unit) + } + }, + ) + } + } } } } diff --git a/android/service/src/main/java/com/follow/clash/service/VpnService.kt b/android/service/src/main/java/com/follow/clash/service/VpnService.kt index 5ffeb65..2194d32 100644 --- a/android/service/src/main/java/com/follow/clash/service/VpnService.kt +++ b/android/service/src/main/java/com/follow/clash/service/VpnService.kt @@ -213,6 +213,7 @@ class VpnService : SystemVpnService(), IBaseService, allowBypass() } if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q && options.systemProxy) { + GlobalState.log("Open http proxy") setHttpProxy( ProxyInfo.buildDirectProxy( "127.0.0.1", options.port, options.bypassDomain diff --git a/core/Clash.Meta b/core/Clash.Meta index 5734897..168fc42 160000 --- a/core/Clash.Meta +++ b/core/Clash.Meta @@ -1 +1 @@ -Subproject commit 573489787b0b0b0f04cbe165857a1ea58b3cc1dc +Subproject commit 168fc4232c86f80facbeef3e022db172b2f4da68 diff --git a/core/action.go b/core/action.go index c392070..c3e200f 100644 --- a/core/action.go +++ b/core/action.go @@ -53,8 +53,8 @@ func handleAction(action *Action, result ActionResult) { result.success(handleShutdown()) return case validateConfigMethod: - data := []byte(action.Data.(string)) - result.success(handleValidateConfig(data)) + path := action.Data.(string) + result.success(handleValidateConfig(path)) return case updateConfigMethod: data := []byte(action.Data.(string)) diff --git a/core/go.mod b/core/go.mod index f243d29..bb2e096 100644 --- a/core/go.mod +++ b/core/go.mod @@ -18,8 +18,8 @@ require ( github.com/buger/jsonparser v1.1.1 // indirect github.com/coreos/go-iptables v0.8.0 // indirect github.com/dlclark/regexp2 v1.11.5 // indirect - github.com/ebitengine/purego v0.8.4 // indirect - github.com/enfein/mieru/v3 v3.19.1 // indirect + github.com/ebitengine/purego v0.9.0 // indirect + github.com/enfein/mieru/v3 v3.20.0 // indirect github.com/ericlagergren/aegis v0.0.0-20250325060835-cd0defd64358 // indirect github.com/ericlagergren/polyval v0.0.0-20220411101811-e25bc10ba391 // indirect github.com/ericlagergren/siv v0.0.0-20220507050439-0b757b3aa5f1 // indirect @@ -34,43 +34,46 @@ require ( github.com/gobwas/pool v0.2.1 // indirect github.com/gobwas/ws v1.4.0 // indirect github.com/gofrs/uuid/v5 v5.3.2 // indirect + github.com/golang/snappy v1.0.0 // indirect github.com/google/btree v1.1.3 // indirect github.com/google/go-cmp v0.6.0 // indirect github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38 // indirect - github.com/hashicorp/yamux v0.1.2 // indirect github.com/insomniacslk/dhcp v0.0.0-20250109001534-8abf58130905 // indirect github.com/josharian/native v1.1.0 // indirect github.com/klauspost/compress v1.17.9 // indirect - github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 // indirect + github.com/klauspost/cpuid/v2 v2.2.6 // indirect + github.com/klauspost/reedsolomon v1.12.3 // indirect github.com/mailru/easyjson v0.7.7 // indirect github.com/mdlayher/netlink v1.7.2 // indirect github.com/mdlayher/socket v0.4.1 // indirect - github.com/metacubex/amneziawg-go v0.0.0-20250820070344-732c0c9d418a // indirect + github.com/metacubex/amneziawg-go v0.0.0-20250902133113-a7f637c14281 // indirect github.com/metacubex/ascon v0.1.0 // indirect - github.com/metacubex/bart v0.20.5 // indirect + github.com/metacubex/bart v0.24.0 // indirect github.com/metacubex/bbolt v0.0.0-20250725135710-010dbbbb7a5b // indirect github.com/metacubex/blake3 v0.1.0 // indirect github.com/metacubex/chacha v0.1.5 // indirect github.com/metacubex/fswatch v0.1.1 // indirect github.com/metacubex/gopacket v1.1.20-0.20230608035415-7e2f98a3e759 // indirect - github.com/metacubex/gvisor v0.0.0-20250324165734-5857f47bd43b // indirect + github.com/metacubex/gvisor v0.0.0-20250919004547-6122b699a301 // indirect + github.com/metacubex/kcp-go v0.0.0-20250923001605-1ba6f691c45b // indirect github.com/metacubex/nftables v0.0.0-20250503052935-30a69ab87793 // indirect github.com/metacubex/quic-go v0.54.1-0.20250730114134-a1ae705fe295 // indirect github.com/metacubex/randv2 v0.2.0 // indirect github.com/metacubex/restls-client-go v0.1.7 // indirect - github.com/metacubex/sing v0.5.5 // indirect - github.com/metacubex/sing-mux v0.3.3-0.20250813083925-d7c9aeaeeaac // indirect - github.com/metacubex/sing-quic v0.0.0-20250718154553-1b193bec4cbb // indirect + github.com/metacubex/sing v0.5.6 // indirect + github.com/metacubex/sing-mux v0.3.4 // indirect + github.com/metacubex/sing-quic v0.0.0-20250909002258-06122df8f231 // indirect github.com/metacubex/sing-shadowsocks v0.2.12 // indirect - github.com/metacubex/sing-shadowsocks2 v0.2.6 // indirect + github.com/metacubex/sing-shadowsocks2 v0.2.7 // indirect github.com/metacubex/sing-shadowtls v0.0.0-20250503063515-5d9f966d17a2 // indirect - github.com/metacubex/sing-tun v0.4.7 // indirect - github.com/metacubex/sing-vmess v0.2.4-0.20250822020810-4856053566f0 // indirect + github.com/metacubex/sing-tun v0.4.8 // indirect + github.com/metacubex/sing-vmess v0.2.4 // indirect github.com/metacubex/sing-wireguard v0.0.0-20250503063753-2dc62acc626f // indirect - github.com/metacubex/smux v0.0.0-20250503055512-501391591dee // indirect - github.com/metacubex/tfo-go v0.0.0-20250827083229-aa432b865617 // indirect - github.com/metacubex/utls v1.8.1-0.20250823120917-12f5ba126142 // indirect + github.com/metacubex/smux v0.0.0-20250922175018-15c9a6a78719 // indirect + github.com/metacubex/tfo-go v0.0.0-20250921095601-b102db4216c0 // indirect + github.com/metacubex/utls v1.8.1 // indirect github.com/metacubex/wireguard-go v0.0.0-20250820062549-a6cecdd7f57f // indirect + github.com/metacubex/yamux v0.0.0-20250918083631-dd5f17c0be49 // indirect github.com/miekg/dns v1.1.63 // indirect github.com/mroth/weightedrand/v2 v2.1.0 // indirect github.com/oasisprotocol/deoxysii v0.0.0-20220228165953-2091330c22b7 // indirect @@ -78,24 +81,19 @@ require ( github.com/openacid/low v0.1.21 // indirect github.com/oschwald/maxminddb-golang v1.12.0 // indirect github.com/pierrec/lz4/v4 v4.1.14 // indirect - github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c // indirect github.com/quic-go/qpack v0.4.0 // indirect github.com/sagernet/cors v1.2.1 // indirect github.com/sagernet/netlink v0.0.0-20240612041022-b9a21c07ac6a // indirect github.com/samber/lo v1.51.0 // indirect - github.com/shirou/gopsutil/v4 v4.25.1 // indirect github.com/sina-ghaderi/poly1305 v0.0.0-20220724002748-c5926b03988b // indirect github.com/sina-ghaderi/rabaead v0.0.0-20220730151906-ab6e06b96e8c // indirect github.com/sina-ghaderi/rabbitio v0.0.0-20220730151941-9ce26f4f872e // indirect github.com/sirupsen/logrus v1.9.3 // indirect - github.com/tklauser/go-sysconf v0.3.12 // indirect - github.com/tklauser/numcpus v0.6.1 // indirect github.com/u-root/uio v0.0.0-20230220225925-ffce2a382923 // indirect github.com/vishvananda/netns v0.0.4 // indirect github.com/vmihailenco/msgpack/v5 v5.4.1 // indirect github.com/vmihailenco/tagparser/v2 v2.0.0 // indirect github.com/wk8/go-ordered-map/v2 v2.1.8 // indirect - github.com/yusufpapurcu/wmi v1.2.4 // indirect gitlab.com/go-extension/aes-ccm v0.0.0-20230221065045-e58665ef23c7 // indirect gitlab.com/yawning/bsaes.git v0.0.0-20190805113838-0a714cd429ec // indirect go.uber.org/mock v0.4.0 // indirect diff --git a/core/go.sum b/core/go.sum index 594f6cd..aecf56a 100644 --- a/core/go.sum +++ b/core/go.sum @@ -1,6 +1,7 @@ github.com/RyuaNerin/go-krypto v1.3.0 h1:smavTzSMAx8iuVlGb4pEwl9MD2qicqMzuXR2QWp2/Pg= github.com/RyuaNerin/go-krypto v1.3.0/go.mod h1:9R9TU936laAIqAmjcHo/LsaXYOZlymudOAxjaBf62UM= github.com/RyuaNerin/testingutil v0.1.0 h1:IYT6JL57RV3U2ml3dLHZsVtPOP6yNK7WUVdzzlpNrss= +github.com/RyuaNerin/testingutil v0.1.0/go.mod h1:yTqj6Ta/ycHMPJHRyO12Mz3VrvTloWOsy23WOZH19AA= github.com/Yawning/aez v0.0.0-20211027044916-e49e68abd344 h1:cDVUiFo+npB0ZASqnw4q90ylaVAbnYyx0JYqK4YcGok= github.com/Yawning/aez v0.0.0-20211027044916-e49e68abd344/go.mod h1:9pIqrY6SXNL8vjRQE5Hd/OL5GyK/9MrGUWs87z/eFfk= github.com/ajg/form v1.5.1 h1:t9c7v8JUKu/XxOGBU0yjNpaMloxGEJhUkqFRq0ibGeU= @@ -22,15 +23,16 @@ 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= github.com/dlclark/regexp2 v1.11.5 h1:Q/sSnsKerHeCkc/jSTNq1oCm7KiVgUMZRDUoRu0JQZQ= github.com/dlclark/regexp2 v1.11.5/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8= -github.com/ebitengine/purego v0.8.4 h1:CF7LEKg5FFOsASUj0+QwaXf8Ht6TlFxg09+S9wz0omw= -github.com/ebitengine/purego v0.8.4/go.mod h1:iIjxzd6CiRiOG0UyXP+V1+jWqUXVjPKLAI0mRfJZTmQ= -github.com/enfein/mieru/v3 v3.19.1 h1:19b9kgFC7oJXX9RLEO5Pi1gO6yek5cWlpK7IJVUoE8I= -github.com/enfein/mieru/v3 v3.19.1/go.mod h1:zJBUCsi5rxyvHM8fjFf+GLaEl4OEjjBXr1s5F6Qd3hM= +github.com/ebitengine/purego v0.9.0 h1:mh0zpKBIXDceC63hpvPuGLiJ8ZAa3DfrFTudmfi8A4k= +github.com/ebitengine/purego v0.9.0/go.mod h1:iIjxzd6CiRiOG0UyXP+V1+jWqUXVjPKLAI0mRfJZTmQ= +github.com/enfein/mieru/v3 v3.20.0 h1:1ob7pCIVSH5FYFAfYvim8isLW1vBOS4cFOUF9exJS38= +github.com/enfein/mieru/v3 v3.20.0/go.mod h1:zJBUCsi5rxyvHM8fjFf+GLaEl4OEjjBXr1s5F6Qd3hM= github.com/ericlagergren/aegis v0.0.0-20250325060835-cd0defd64358 h1:kXYqH/sL8dS/FdoFjr12ePjnLPorPo2FsnrHNuXSDyo= github.com/ericlagergren/aegis v0.0.0-20250325060835-cd0defd64358/go.mod h1:hkIFzoiIPZYxdFOOLyDho59b7SrDfo+w3h+yWdlg45I= github.com/ericlagergren/polyval v0.0.0-20220411101811-e25bc10ba391 h1:8j2RH289RJplhA6WfdaPqzg1MjH2K8wX5e0uhAxrw2g= github.com/ericlagergren/polyval v0.0.0-20220411101811-e25bc10ba391/go.mod h1:K2R7GhgxrlJzHw2qiPWsCZXf/kXEJN9PLnQK73Ll0po= github.com/ericlagergren/saferand v0.0.0-20220206064634-960a4dd2bc5c h1:RUzBDdZ+e/HEe2Nh8lYsduiPAZygUfVXJn0Ncj5sHMg= +github.com/ericlagergren/saferand v0.0.0-20220206064634-960a4dd2bc5c/go.mod h1:ETASDWf/FmEb6Ysrtd1QhjNedUU/ZQxBCRLh60bQ/UI= github.com/ericlagergren/siv v0.0.0-20220507050439-0b757b3aa5f1 h1:tlDMEdcPRQKBEz5nGDMvswiajqh7k8ogWRlhRwKy5mY= github.com/ericlagergren/siv v0.0.0-20220507050439-0b757b3aa5f1/go.mod h1:4RfsapbGx2j/vU5xC/5/9qB3kn9Awp1YDiEnN43QrJ4= github.com/ericlagergren/subtle v0.0.0-20220507045147-890d697da010 h1:fuGucgPk5dN6wzfnxl3D0D3rVLw4v2SbBT9jb4VnxzA= @@ -44,7 +46,7 @@ github.com/go-chi/chi/v5 v5.2.3/go.mod h1:L2yAIGWB3H+phAw1NxKwWM+7eUH/lU8pOMm5hH github.com/go-chi/render v1.0.3 h1:AsXqd2a1/INaIfUSKq3G5uA8weYx20FOsM7uSoCyyt4= github.com/go-chi/render v1.0.3/go.mod h1:/gr3hVkmYR0YlEy3LxCuVRFzEu9Ruok+gFqbIofjao0= github.com/go-logr/logr v1.2.4 h1:g01GSCwiDw2xSZfjJ2/T9M+S6pFdcNtFYsp+Y43HYDQ= -github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= +github.com/go-logr/logr v1.2.4/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-ole/go-ole v1.3.0 h1:Dt6ye7+vXGIKZ7Xtk4s6/xVdGDQynvom7xCFEdWr6uE= github.com/go-ole/go-ole v1.3.0/go.mod h1:5LS6F96DhAwUc7C+1HLexzMXY1xGRSryjyPPKW6zv78= github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI= @@ -59,16 +61,17 @@ github.com/gofrs/uuid/v5 v5.3.2 h1:2jfO8j3XgSwlz/wHqemAEugfnTlikAYHhnqQ8Xh4fE0= github.com/gofrs/uuid/v5 v5.3.2/go.mod h1:CDOjlDMVAtN56jqyRUZh58JT31Tiw7/oQyEXZV+9bD8= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= +github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/golang/snappy v1.0.0 h1:Oy607GVXHs7RtbggtPBnr2RmDArIsAefDwvrdWvRhGs= +github.com/golang/snappy v1.0.0/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/google/btree v1.1.3 h1:CVpQJjYgC4VbzxeGVHfvZrv1ctoYCAI8vbl07Fcxlyg= github.com/google/btree v1.1.3/go.mod h1:qOPhT0dTNdNzV6Z/lhRX0YXUafgPLFUh+gZMl761Gm4= -github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38 h1:yAJXTCF9TqKcTiHJAE8dj7HMvPfh66eeA2JYW7eFpSE= github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/tink/go v1.6.1 h1:t7JHqO8Ath2w2ig5vjwQYJzhGEZymedQc90lQXUBa4I= -github.com/hashicorp/yamux v0.1.2 h1:XtB8kyFOyHXYVFnwT5C3+Bdo8gArse7j2AQ0DA0Uey8= -github.com/hashicorp/yamux v0.1.2/go.mod h1:C+zze2n6e/7wshOZep2A70/aQU6QBRWJO/G6FT1wIns= +github.com/google/tink/go v1.6.1/go.mod h1:IGW53kTgag+st5yPhKKwJ6u2l+SSp5/v9XF7spovjlY= github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/insomniacslk/dhcp v0.0.0-20250109001534-8abf58130905 h1:q3OEI9RaN/wwcx+qgGo6ZaoJkCiDYe/gjDLfq7lQQF4= github.com/insomniacslk/dhcp v0.0.0-20250109001534-8abf58130905/go.mod h1:VvGYjkZoJyKqlmT1yzakUs4mfKMNB0XdODP0+rdml6k= @@ -78,20 +81,22 @@ github.com/josharian/native v1.1.0 h1:uuaP0hAbW7Y4l0ZRQ6C9zfb7Mg1mbFKry/xzDAfmtL github.com/josharian/native v1.1.0/go.mod h1:7X/raswPFr05uY3HiLlYeyQntB6OO7E/d2Cu7qoaN2w= github.com/klauspost/compress v1.17.9 h1:6KIumPrER1LHsvBVuDa0r5xaG0Es51mhhB9BQB2qeMA= github.com/klauspost/compress v1.17.9/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw= -github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 h1:6E+4a0GO5zZEnZ81pIr0yLvtUWk2if982qA3F3QD6H4= -github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0/go.mod h1:zJYVVT2jmtg6P3p1VtQj7WsuWi/y4VnjVBn7F8KPB3I= +github.com/klauspost/cpuid/v2 v2.2.6 h1:ndNyv040zDGIDh8thGkXYjnFtiN02M1PVVF+JE/48xc= +github.com/klauspost/cpuid/v2 v2.2.6/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws= +github.com/klauspost/reedsolomon v1.12.3 h1:tzUznbfc3OFwJaTebv/QdhnFf2Xvb7gZ24XaHLBPmdc= +github.com/klauspost/reedsolomon v1.12.3/go.mod h1:3K5rXwABAvzGeR01r6pWZieUALXO/Tq7bFKGIb4m4WI= github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= github.com/mdlayher/netlink v1.7.2 h1:/UtM3ofJap7Vl4QWCPDGXY8d3GIY2UGSDbK+QWmY8/g= github.com/mdlayher/netlink v1.7.2/go.mod h1:xraEF7uJbxLhc5fpHL4cPe221LI2bdttWlU+ZGLfQSw= github.com/mdlayher/socket v0.4.1 h1:eM9y2/jlbs1M615oshPQOHZzj6R6wMT7bX5NPiQvn2U= github.com/mdlayher/socket v0.4.1/go.mod h1:cAqeGjoufqdxWkD7DkpyS+wcefOtmu5OQ8KuoJGIReA= -github.com/metacubex/amneziawg-go v0.0.0-20250820070344-732c0c9d418a h1:c1QSGpacSeQdBdWcEKZKGuWLcqIG2wxHEygAcXuDwS4= -github.com/metacubex/amneziawg-go v0.0.0-20250820070344-732c0c9d418a/go.mod h1:MsM/5czONyXMJ3PRr5DbQ4O/BxzAnJWOIcJdLzW6qHY= +github.com/metacubex/amneziawg-go v0.0.0-20250902133113-a7f637c14281 h1:09EM0sOLb2kfL0KETGhHujsBLB5iy5U/2yHRHsxf/pI= +github.com/metacubex/amneziawg-go v0.0.0-20250902133113-a7f637c14281/go.mod h1:MsM/5czONyXMJ3PRr5DbQ4O/BxzAnJWOIcJdLzW6qHY= github.com/metacubex/ascon v0.1.0 h1:6ZWxmXYszT1XXtwkf6nxfFhc/OTtQ9R3Vyj1jN32lGM= github.com/metacubex/ascon v0.1.0/go.mod h1:eV5oim4cVPPdEL8/EYaTZ0iIKARH9pnhAK/fcT5Kacc= -github.com/metacubex/bart v0.20.5 h1:XkgLZ17QxfxkqKdGsojoM2Zu01mmHyyQSFzt2/calTM= -github.com/metacubex/bart v0.20.5/go.mod h1:DCcyfP4MC+Zy7sLK7XeGuMw+P5K9mIRsYOBgiE8icsI= +github.com/metacubex/bart v0.24.0 h1:EyNiPeVOlg0joSHTzi5oentI0j5M89utUq/5dd76pWM= +github.com/metacubex/bart v0.24.0/go.mod h1:DCcyfP4MC+Zy7sLK7XeGuMw+P5K9mIRsYOBgiE8icsI= github.com/metacubex/bbolt v0.0.0-20250725135710-010dbbbb7a5b h1:j7dadXD8I2KTmMt8jg1JcaP1ANL3JEObJPdANKcSYPY= github.com/metacubex/bbolt v0.0.0-20250725135710-010dbbbb7a5b/go.mod h1:+WmP0VJZDkDszvpa83HzfUp6QzARl/IKkMorH4+nODw= github.com/metacubex/blake3 v0.1.0 h1:KGnjh/56REO7U+cgZA8dnBhxdP7jByrG7hTP+bu6cqY= @@ -102,8 +107,10 @@ github.com/metacubex/fswatch v0.1.1 h1:jqU7C/v+g0qc2RUFgmAOPoVvfl2BXXUXEumn6oQux github.com/metacubex/fswatch v0.1.1/go.mod h1:czrTT7Zlbz7vWft8RQu9Qqh+JoX+Nnb+UabuyN1YsgI= github.com/metacubex/gopacket v1.1.20-0.20230608035415-7e2f98a3e759 h1:cjd4biTvOzK9ubNCCkQ+ldc4YSH/rILn53l/xGBFHHI= github.com/metacubex/gopacket v1.1.20-0.20230608035415-7e2f98a3e759/go.mod h1:UHOv2xu+RIgLwpXca7TLrXleEd4oR3sPatW6IF8wU88= -github.com/metacubex/gvisor v0.0.0-20250324165734-5857f47bd43b h1:RUh4OdVPz/jDrM9MQ2ySuqu2aeBqcA8rtfWUYLZ8RtI= -github.com/metacubex/gvisor v0.0.0-20250324165734-5857f47bd43b/go.mod h1:8LpS0IJW1VmWzUm3ylb0e2SK5QDm5lO/2qwWLZgRpBU= +github.com/metacubex/gvisor v0.0.0-20250919004547-6122b699a301 h1:N5GExQJqYAH3gOCshpp2u/J3CtNYzMctmlb0xK9wtbQ= +github.com/metacubex/gvisor v0.0.0-20250919004547-6122b699a301/go.mod h1:8LpS0IJW1VmWzUm3ylb0e2SK5QDm5lO/2qwWLZgRpBU= +github.com/metacubex/kcp-go v0.0.0-20250923001605-1ba6f691c45b h1:z7JLKjugnQ1qvDOAD8yMA5C8AlJY3bG+VrrgRntRlUY= +github.com/metacubex/kcp-go v0.0.0-20250923001605-1ba6f691c45b/go.mod h1:HIJZW4QMhbBqXuqC1ly6Hn0TEYT2SzRw58ns1yGhXTs= github.com/metacubex/nftables v0.0.0-20250503052935-30a69ab87793 h1:1Qpuy+sU3DmyX9HwI+CrBT/oLNJngvBorR2RbajJcqo= github.com/metacubex/nftables v0.0.0-20250503052935-30a69ab87793/go.mod h1:RjRNb4G52yAgfR+Oe/kp9G4PJJ97Fnj89eY1BFO3YyA= github.com/metacubex/quic-go v0.54.1-0.20250730114134-a1ae705fe295 h1:8JVlYuE8uSJAvmyCd4TjvDxs57xjb0WxEoaWafK5+qs= @@ -113,32 +120,34 @@ github.com/metacubex/randv2 v0.2.0/go.mod h1:kFi2SzrQ5WuneuoLLCMkABtiBu6VRrMrWFq github.com/metacubex/restls-client-go v0.1.7 h1:eCwiXCTQb5WJu9IlgYvDBA1OgrINv58dEe7hcN5H15k= github.com/metacubex/restls-client-go v0.1.7/go.mod h1:BN/U52vPw7j8VTSh2vleD/MnmVKCov84mS5VcjVHH4g= github.com/metacubex/sing v0.5.2/go.mod h1:ypf0mjwlZm0sKdQSY+yQvmsbWa0hNPtkeqyRMGgoN+w= -github.com/metacubex/sing v0.5.5 h1:m5U8iHvRAUxlme3FZlE/LPIGHjU8oMCUzXWGbQQAC1E= -github.com/metacubex/sing v0.5.5/go.mod h1:ypf0mjwlZm0sKdQSY+yQvmsbWa0hNPtkeqyRMGgoN+w= -github.com/metacubex/sing-mux v0.3.3-0.20250813083925-d7c9aeaeeaac h1:wDH/Jh/yqWbzPktqJP+Y1cUG8hchcrzKzUxJiSpnaQs= -github.com/metacubex/sing-mux v0.3.3-0.20250813083925-d7c9aeaeeaac/go.mod h1:3rt1soewn0O6j89GCLmwAQFsq257u0jf2zQSPhTL3Bw= -github.com/metacubex/sing-quic v0.0.0-20250718154553-1b193bec4cbb h1:U/m3h8lp/j7i8zFgfvScLdZa1/Y8dd74oO7iZaQq80s= -github.com/metacubex/sing-quic v0.0.0-20250718154553-1b193bec4cbb/go.mod h1:B60FxaPHjR1SeQB0IiLrgwgvKsaoASfOWdiqhLjmMGA= +github.com/metacubex/sing v0.5.6 h1:mEPDCadsCj3DB8gn+t/EtposlYuALEkExa/LUguw6/c= +github.com/metacubex/sing v0.5.6/go.mod h1:ypf0mjwlZm0sKdQSY+yQvmsbWa0hNPtkeqyRMGgoN+w= +github.com/metacubex/sing-mux v0.3.4 h1:tf4r27CIkzaxq9kBlAXQkgMXq2HPp5Mta60Kb4RCZF0= +github.com/metacubex/sing-mux v0.3.4/go.mod h1:SEJfAuykNj/ozbPqngEYqyggwSr81+L7Nu09NRD5mh4= +github.com/metacubex/sing-quic v0.0.0-20250909002258-06122df8f231 h1:dGvo7UahC/gYBQNBoictr14baJzBjAKUAorP63QFFtg= +github.com/metacubex/sing-quic v0.0.0-20250909002258-06122df8f231/go.mod h1:B60FxaPHjR1SeQB0IiLrgwgvKsaoASfOWdiqhLjmMGA= github.com/metacubex/sing-shadowsocks v0.2.12 h1:Wqzo8bYXrK5aWqxu/TjlTnYZzAKtKsaFQBdr6IHFaBE= github.com/metacubex/sing-shadowsocks v0.2.12/go.mod h1:2e5EIaw0rxKrm1YTRmiMnDulwbGxH9hAFlrwQLQMQkU= -github.com/metacubex/sing-shadowsocks2 v0.2.6 h1:ZR1kYT0f0Vi64iQSS09OdhFfppiNkh7kjgRdMm0SB98= -github.com/metacubex/sing-shadowsocks2 v0.2.6/go.mod h1:vOEbfKC60txi0ca+yUlqEwOGc3Obl6cnSgx9Gf45KjE= +github.com/metacubex/sing-shadowsocks2 v0.2.7 h1:hSuuc0YpsfiqYqt1o+fP4m34BQz4e6wVj3PPBVhor3A= +github.com/metacubex/sing-shadowsocks2 v0.2.7/go.mod h1:vOEbfKC60txi0ca+yUlqEwOGc3Obl6cnSgx9Gf45KjE= github.com/metacubex/sing-shadowtls v0.0.0-20250503063515-5d9f966d17a2 h1:gXU+MYPm7Wme3/OAY2FFzVq9d9GxPHOqu5AQfg/ddhI= github.com/metacubex/sing-shadowtls v0.0.0-20250503063515-5d9f966d17a2/go.mod h1:mbfboaXauKJNIHJYxQRa+NJs4JU9NZfkA+I33dS2+9E= -github.com/metacubex/sing-tun v0.4.7 h1:ZDY/W+1c7PeWWKeKRyUo18fySF/TWjB0i5ui81Ar778= -github.com/metacubex/sing-tun v0.4.7/go.mod h1:xHecZRwBnKWe6zG9amAK9cXf91lF6blgjBqm+VvOrmU= -github.com/metacubex/sing-vmess v0.2.4-0.20250822020810-4856053566f0 h1:WZepq4TOZa6WewB8tGAZrrL+bL2R2ivoBzuEgAeolWc= -github.com/metacubex/sing-vmess v0.2.4-0.20250822020810-4856053566f0/go.mod h1:21R5R1u90uUvBQF0owoooEu96/SAYYD56nDrwm6nFaM= +github.com/metacubex/sing-tun v0.4.8 h1:3PyiUKWXYi37yHptXskzL1723O3OUdyt0Aej4XHVikM= +github.com/metacubex/sing-tun v0.4.8/go.mod h1:L/TjQY5JEGy8nvsuYmy/XgMFMCPiF0+AWSFCYfS6r9w= +github.com/metacubex/sing-vmess v0.2.4 h1:Tx6AGgCiEf400E/xyDuYyafsel6sGbR8oF7RkAaus6I= +github.com/metacubex/sing-vmess v0.2.4/go.mod h1:21R5R1u90uUvBQF0owoooEu96/SAYYD56nDrwm6nFaM= github.com/metacubex/sing-wireguard v0.0.0-20250503063753-2dc62acc626f h1:Sr/DYKYofKHKc4GF3qkRGNuj6XA6c0eqPgEDN+VAsYU= github.com/metacubex/sing-wireguard v0.0.0-20250503063753-2dc62acc626f/go.mod h1:jpAkVLPnCpGSfNyVmj6Cq4YbuZsFepm/Dc+9BAOcR80= -github.com/metacubex/smux v0.0.0-20250503055512-501391591dee h1:lp6hJ+4wCLZu113awp7P6odM2okB5s60HUyF0FMqKmo= -github.com/metacubex/smux v0.0.0-20250503055512-501391591dee/go.mod h1:4bPD8HWx9jPJ9aE4uadgyN7D1/Wz3KmPy+vale8sKLE= -github.com/metacubex/tfo-go v0.0.0-20250827083229-aa432b865617 h1:yN3mQ4cT9sPUciw/rO0Isc/8QlO86DB6g9SEMRgQ8Cw= -github.com/metacubex/tfo-go v0.0.0-20250827083229-aa432b865617/go.mod h1:l9oLnLoEXyGZ5RVLsh7QCC5XsouTUyKk4F2nLm2DHLw= -github.com/metacubex/utls v1.8.1-0.20250823120917-12f5ba126142 h1:csEbKOzRAxJXffOeZnnS3/kA/F55JiTbKv5jcYqCXms= -github.com/metacubex/utls v1.8.1-0.20250823120917-12f5ba126142/go.mod h1:67I3skhEY4Sya8f1YxELwWPoeQdXqZCrWNYLvq8gn2U= +github.com/metacubex/smux v0.0.0-20250922175018-15c9a6a78719 h1:T6qCCfolRDAVJKeaPW/mXwNLjnlo65AYN7WS2jrBNaM= +github.com/metacubex/smux v0.0.0-20250922175018-15c9a6a78719/go.mod h1:4bPD8HWx9jPJ9aE4uadgyN7D1/Wz3KmPy+vale8sKLE= +github.com/metacubex/tfo-go v0.0.0-20250921095601-b102db4216c0 h1:Ui+/2s5Qz0lSnDUBmEL12M5Oi/PzvFxGTNohm8ZcsmE= +github.com/metacubex/tfo-go v0.0.0-20250921095601-b102db4216c0/go.mod h1:l9oLnLoEXyGZ5RVLsh7QCC5XsouTUyKk4F2nLm2DHLw= +github.com/metacubex/utls v1.8.1 h1:RW8GeCGWAegjV0HW5nw9DoqNoeGAXXeYUP6AysmRvx4= +github.com/metacubex/utls v1.8.1/go.mod h1:kncGGVhFaoGn5M3pFe3SXhZCzsbCJayNOH4UEqTKTko= github.com/metacubex/wireguard-go v0.0.0-20250820062549-a6cecdd7f57f h1:FGBPRb1zUabhPhDrlKEjQ9lgIwQ6cHL4x8M9lrERhbk= github.com/metacubex/wireguard-go v0.0.0-20250820062549-a6cecdd7f57f/go.mod h1:oPGcV994OGJedmmxrcK9+ni7jUEMGhR+uVQAdaduIP4= +github.com/metacubex/yamux v0.0.0-20250918083631-dd5f17c0be49 h1:lhlqpYHopuTLx9xQt22kSA9HtnyTDmk5XjjQVCGHe2E= +github.com/metacubex/yamux v0.0.0-20250918083631-dd5f17c0be49/go.mod h1:MBeEa9IVBphH7vc3LNtW6ZujVXFizotPo3OEiHQ+TNU= github.com/miekg/dns v1.1.63 h1:8M5aAw6OMZfFXTT7K5V0Eu5YiiL8l7nUAkyN6C9YwaY= github.com/miekg/dns v1.1.63/go.mod h1:6NGHfjhpmr5lt3XPLuyfDJi5AXbNIPM9PY6H6sF1Nfs= github.com/mroth/weightedrand/v2 v2.1.0 h1:o1ascnB1CIVzsqlfArQQjeMy1U0NcIbBO5rfd5E/OeU= @@ -148,6 +157,7 @@ github.com/oasisprotocol/deoxysii v0.0.0-20220228165953-2091330c22b7/go.mod h1:U github.com/onsi/ginkgo/v2 v2.9.5 h1:+6Hr4uxzP4XIUyAkg61dWBw8lb/gc4/X5luuxN/EC+Q= github.com/onsi/ginkgo/v2 v2.9.5/go.mod h1:tvAoo1QUJwNEU2ITftXTpR7R1RbCzoZUOs3RonqW57k= github.com/onsi/gomega v1.27.6 h1:ENqfyGeS5AX/rlXDd/ETokDz93u0YufY1Pgxuy/PvWE= +github.com/onsi/gomega v1.27.6/go.mod h1:PIQNjfQwkP3aQAH7lf7j87O/5FiNr+ZR8+ipb+qQlhg= github.com/openacid/errors v0.8.1/go.mod h1:GUQEJJOJE3W9skHm8E8Y4phdl2LLEN8iD7c5gcGgdx0= github.com/openacid/low v0.1.21 h1:Tr2GNu4N/+rGRYdOsEHOE89cxUIaDViZbVmKz29uKGo= github.com/openacid/low v0.1.21/go.mod h1:q+MsKI6Pz2xsCkzV4BLj7NR5M4EX0sGz5AqotpZDVh0= @@ -160,8 +170,6 @@ github.com/pierrec/lz4/v4 v4.1.14/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFu github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= 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/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c h1:ncq/mPwQF4JjgDlrVEn3C11VoGHZN7m8qihwgMEtzYw= -github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c/go.mod h1:OmDBASR4679mdNQnz2pUhc2G8CO2JrUAVFDRBDP/hJE= github.com/quic-go/qpack v0.4.0 h1:Cr9BXA1sQS2SmDUWjSofMPNKmvF6IiIfDRmgU0w1ZCo= github.com/quic-go/qpack v0.4.0/go.mod h1:UZVnYIfi5GRk+zI9UMaCPsmZ2xKJP7XBUvVyT1Knj9A= github.com/sagernet/cors v1.2.1 h1:Cv5Z8y9YSD6Gm+qSpNrL3LO4lD3eQVvbFYJSG7JCMHQ= @@ -170,8 +178,6 @@ github.com/sagernet/netlink v0.0.0-20240612041022-b9a21c07ac6a h1:ObwtHN2VpqE0ZN github.com/sagernet/netlink v0.0.0-20240612041022-b9a21c07ac6a/go.mod h1:xLnfdiJbSp8rNqYEdIW/6eDO4mVoogml14Bh2hSiFpM= github.com/samber/lo v1.51.0 h1:kysRYLbHy/MB7kQZf5DSN50JHmMsNEdeY24VzJFu7wI= github.com/samber/lo v1.51.0/go.mod h1:4+MXEGsJzbKGaUEQFKBq2xtfuznW9oz/WrgyzMzRoM0= -github.com/shirou/gopsutil/v4 v4.25.1 h1:QSWkTc+fu9LTAWfkZwZ6j8MSUk4A2LV7rbH0ZqmLjXs= -github.com/shirou/gopsutil/v4 v4.25.1/go.mod h1:RoUCUpndaJFtT+2zsZzzmhvbfGoDCJ7nFXKJf8GqJbI= github.com/sina-ghaderi/poly1305 v0.0.0-20220724002748-c5926b03988b h1:rXHg9GrUEtWZhEkrykicdND3VPjlVbYiLdX9J7gimS8= github.com/sina-ghaderi/poly1305 v0.0.0-20220724002748-c5926b03988b/go.mod h1:X7qrxNQViEaAN9LNZOPl9PfvQtp3V3c7LTo0dvGi0fM= github.com/sina-ghaderi/rabaead v0.0.0-20220730151906-ab6e06b96e8c h1:DjKMC30y6yjG3IxDaeAj3PCoRr+IsO+bzyT+Se2m2Hk= @@ -191,11 +197,8 @@ github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= -github.com/stretchr/testify v1.11.0 h1:ib4sjIrwZKxE5u/Japgo/7SJV3PvgjGiRNAvTVGqQl8= -github.com/tklauser/go-sysconf v0.3.12 h1:0QaGUFOdQaIVdPgfITYzaTegZvdCjmYO52cSFAEVmqU= -github.com/tklauser/go-sysconf v0.3.12/go.mod h1:Ho14jnntGE1fpdOqQEEaiKRpvIavV0hSfmBq8nJbHYI= -github.com/tklauser/numcpus v0.6.1 h1:ng9scYS7az0Bk4OZLvrNXNSAO2Pxr1XXRAPyjhIx+Fk= -github.com/tklauser/numcpus v0.6.1/go.mod h1:1XfjsgE2zo8GVw7POkMbHENHzVg3GzmoZ9fESEdAacY= +github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= +github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= github.com/u-root/uio v0.0.0-20230220225925-ffce2a382923 h1:tHNk7XK9GkmKUR6Gh8gVBKXc2MVSZ4G/NnWLtzw4gNA= github.com/u-root/uio v0.0.0-20230220225925-ffce2a382923/go.mod h1:eLL9Nub3yfAho7qB0MzZizFhTU2QkLeoVsWdHtDW264= github.com/vishvananda/netlink v1.1.0/go.mod h1:cTgwzPIzzgDAYoQrMm0EdrjRUBkTqKYppBueQtXaqoE= @@ -209,8 +212,8 @@ github.com/vmihailenco/tagparser/v2 v2.0.0 h1:y09buUbR+b5aycVFQs/g70pqKVZNBmxwAh github.com/vmihailenco/tagparser/v2 v2.0.0/go.mod h1:Wri+At7QHww0WTrCBeu4J6bNtoV6mEfg5OIWRZA9qds= github.com/wk8/go-ordered-map/v2 v2.1.8 h1:5h/BUHu93oj4gIdvHHHGsScSTMijfx5PeYkE/fJgbpc= github.com/wk8/go-ordered-map/v2 v2.1.8/go.mod h1:5nJHM5DyteebpVlHnWMV0rPz6Zp7+xBAnxjb1X5vnTw= -github.com/yusufpapurcu/wmi v1.2.4 h1:zFUKzehAFReQwLys1b/iSMl+JQGSCSjtVqQn9bBrPo0= -github.com/yusufpapurcu/wmi v1.2.4/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0= +github.com/xtaci/lossyconn v0.0.0-20190602105132-8df528c0c9ae h1:J0GxkO96kL4WF+AIT3M4mfUVinOCPgf2uUWYFUzN0sM= +github.com/xtaci/lossyconn v0.0.0-20190602105132-8df528c0c9ae/go.mod h1:gXtu8J62kEgmN++bm9BVICuT/e8yiLI2KFobd/TRFsE= gitlab.com/go-extension/aes-ccm v0.0.0-20230221065045-e58665ef23c7 h1:UNrDfkQqiEYzdMlNsVvBYOAJWZjdktqFE9tQh5BT2+4= gitlab.com/go-extension/aes-ccm v0.0.0-20230221065045-e58665ef23c7/go.mod h1:E+rxHvJG9H6PUdzq9NRG6csuLN3XUx98BfGOVWNYnXs= gitlab.com/yawning/bsaes.git v0.0.0-20190805113838-0a714cd429ec h1:FpfFs4EhNehiVfzQttTuxanPIT43FtkkCFypIod8LHo= @@ -240,20 +243,18 @@ golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5h golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190606203320-7fc4e5ec1444/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190804053845-51ab0e2deafa/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200217220822-9197077df867/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20201204225414-ed752295db88/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20220622161953-175b2fd9d664/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.30.0 h1:QjkSwP/36a20jFYWkSue1YwXzLmsV5Gfq7Eiy72C1uc= golang.org/x/sys v0.30.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.29.0 h1:L6pJp37ocefwRRtYPKSWOWzOtWSxVajvz2ldH/xi3iU= +golang.org/x/term v0.29.0/go.mod h1:6bl4lRlvVuDgSf3179VpIxBF0o10JUpXWOnI7nErv7s= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.22.0 h1:bofq7m3/HAFvbF51jz3Q9wLg3jkvSPuiZu/pD1XwgtM= golang.org/x/text v0.22.0/go.mod h1:YRoo4H8PVmsu+E3Ou7cqLVH8oXWIHVoX0jqUWALQhfY= @@ -263,7 +264,6 @@ golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapK golang.org/x/tools v0.24.0 h1:J1shsA93PJUEVaUSaay7UXAyE8aimq3GW0pjlolpa24= golang.org/x/tools v0.24.0/go.mod h1:YhNqVBIfWHdzvTLs0d8LCuMhkKUgSUKldakyV7W/WDQ= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= diff --git a/core/hub.go b/core/hub.go index 3b3175a..449615c 100644 --- a/core/hub.go +++ b/core/hub.go @@ -83,8 +83,9 @@ func handleShutdown() bool { return true } -func handleValidateConfig(bytes []byte) string { - _, err := config.UnmarshalRawConfig(bytes) +func handleValidateConfig(path string) string { + buf, err := readFile(path) + _, err = config.UnmarshalRawConfig(buf) if err != nil { return err.Error() } diff --git a/lib/common/function.dart b/lib/common/function.dart index ba8b13e..682db37 100644 --- a/lib/common/function.dart +++ b/lib/common/function.dart @@ -1,5 +1,6 @@ import 'dart:async'; +import 'package:fl_clash/common/common.dart'; import 'package:fl_clash/enum/enum.dart'; class Debouncer { @@ -68,7 +69,7 @@ Future retry({ required Future Function() task, int maxAttempts = 3, required bool Function(T res) retryIf, - Duration delay = Duration.zero, + Duration delay = midDuration, }) async { int attempts = 0; while (attempts < maxAttempts) { @@ -78,7 +79,7 @@ Future retry({ } attempts++; } - throw 'unknown error'; + throw 'retry error'; } final debouncer = Debouncer(); diff --git a/lib/common/path.dart b/lib/common/path.dart index 018e7c8..119e528 100644 --- a/lib/common/path.dart +++ b/lib/common/path.dart @@ -71,6 +71,11 @@ class AppPath { return join(homeDirPath, 'config.json'); } + Future get validateFilePath async { + final homeDirPath = await appPath.homeDirPath; + return join(homeDirPath, 'temp', 'validate${utils.id}.yaml'); + } + Future get sharedPreferencesPath async { final directory = await dataDir.future; return join(directory.path, 'shared_preferences.json'); diff --git a/lib/common/system.dart b/lib/common/system.dart index d38d37f..11b3451 100644 --- a/lib/common/system.dart +++ b/lib/common/system.dart @@ -186,26 +186,26 @@ class Windows { logLevel: LogLevel.warning, ); - if (result < 42) { + if (result <= 32) { return false; } return true; } - Future _killProcess(int port) async { - final result = await Process.run('netstat', ['-ano']); - final lines = result.stdout.toString().trim().split('\n'); - for (final line in lines) { - if (!line.contains(':$port') || !line.contains('LISTENING')) { - continue; - } - final parts = line.trim().split(RegExp(r'\s+')); - final pid = int.tryParse(parts.last); - if (pid != null) { - await Process.run('taskkill', ['/PID', pid.toString(), '/F']); - } - } - } + // Future _killProcess(int port) async { + // final result = await Process.run('netstat', ['-ano']); + // final lines = result.stdout.toString().trim().split('\n'); + // for (final line in lines) { + // if (!line.contains(':$port') || !line.contains('LISTENING')) { + // continue; + // } + // final parts = line.trim().split(RegExp(r'\s+')); + // final pid = int.tryParse(parts.last); + // if (pid != null) { + // await Process.run('taskkill', ['/PID', pid.toString(), '/F']); + // } + // } + // } Future checkService() async { // final qcResult = await Process.run('sc', ['qc', appHelperService]); @@ -231,16 +231,18 @@ class Windows { return true; } - await _killProcess(helperPort); - final command = [ '/c', if (status == WindowsHelperServiceStatus.presence) ...[ - 'sc', + 'taskkill', + '/F', + '/IM', + '$appHelperService.exe' + ' & ' + 'sc', 'delete', appHelperService, - '/force', - '&&', + '&', ], 'sc', 'create', @@ -256,8 +258,12 @@ class Windows { final res = runas('cmd.exe', command); await Future.delayed(Duration(milliseconds: 300)); - - return res; + final retryStatus = await retry( + task: checkService, + retryIf: (status) => status == WindowsHelperServiceStatus.running, + delay: commonDuration, + ); + return res && retryStatus == WindowsHelperServiceStatus.running; } Future registerTask(String appName) async { diff --git a/lib/common/utils.dart b/lib/common/utils.dart index 3dd76fe..280f0b4 100644 --- a/lib/common/utils.dart +++ b/lib/common/utils.dart @@ -322,12 +322,15 @@ class Utils { return SingleActivator(trigger, control: control, meta: !control); } - FutureOr handleWatch(Function function) async { + FutureOr handleWatch({ + required Function function, + required void Function(T data, int elapsedMilliseconds) onWatch, + }) async { if (kDebugMode) { final stopwatch = Stopwatch()..start(); final res = await function(); stopwatch.stop(); - commonPrint.log('耗时:${stopwatch.elapsedMilliseconds} ms'); + onWatch(res, stopwatch.elapsedMilliseconds); return res; } return await function(); diff --git a/lib/core/controller.dart b/lib/core/controller.dart index 0fb0b46..1cf31b6 100644 --- a/lib/core/controller.dart +++ b/lib/core/controller.dart @@ -71,8 +71,20 @@ class CoreController { FutureOr get isInit => _interface.isInit; - FutureOr validateConfig(String data) { - return _interface.validateConfig(data); + Future validateConfig(String data) async { + final path = await appPath.validateFilePath; + await globalState.genValidateFile(path, data); + final res = await _interface.validateConfig(path); + await File(path).delete(); + return res; + } + + Future validateConfigFormBytes(Uint8List bytes) async { + final path = await appPath.validateFilePath; + await globalState.genValidateFileFormBytes(path, bytes); + final res = await _interface.validateConfig(path); + await File(path).delete(); + return res; } Future updateConfig(UpdateParams updateParams) async { diff --git a/lib/core/interface.dart b/lib/core/interface.dart index a619e5f..20bbc41 100644 --- a/lib/core/interface.dart +++ b/lib/core/interface.dart @@ -5,6 +5,7 @@ import 'dart:isolate'; import 'package:fl_clash/common/common.dart'; import 'package:fl_clash/enum/enum.dart'; import 'package:fl_clash/models/models.dart'; +import 'package:flutter/foundation.dart'; mixin CoreInterface { Future init(InitParams params); @@ -17,7 +18,7 @@ mixin CoreInterface { Future forceGc(); - Future validateConfig(String data); + Future validateConfig(String path); Future getConfig(String path); @@ -86,7 +87,18 @@ abstract class CoreHandlerInterface with CoreInterface { Duration? timeout, }) async { await connected; - return invoke(method: method, data: data, timeout: timeout); + if (kDebugMode) { + commonPrint.log('Invoke ${method.name} ${DateTime.now()} $data'); + } + + return utils.handleWatch( + function: () async { + return await invoke(method: method, data: data, timeout: timeout); + }, + onWatch: (data, elapsedMilliseconds) { + commonPrint.log('Invoke ${method.name} ${elapsedMilliseconds}ms'); + }, + ); } Future invoke({ @@ -125,10 +137,10 @@ abstract class CoreHandlerInterface with CoreInterface { } @override - Future validateConfig(String data) async { + Future validateConfig(String path) async { return await _invoke( method: ActionMethod.validateConfig, - data: data, + data: path, ) ?? ''; } diff --git a/lib/core/service.dart b/lib/core/service.dart index 0bf910c..7abede8 100644 --- a/lib/core/service.dart +++ b/lib/core/service.dart @@ -38,23 +38,29 @@ class CoreService extends CoreHandlerInterface { completer?.complete(data); } - void _initServer() { - runZonedGuarded( - () async { - final address = !system.isWindows - ? InternetAddress(unixSocketPath, type: InternetAddressType.unix) - : InternetAddress(localhost, type: InternetAddressType.IPv4); - await _deleteSocketFile(); - final server = await ServerSocket.bind(address, 0, shared: true); - _serverCompleter.complete(server); - await for (final socket in server) { - await _attachSocket(socket); + Future _initServer() async { + final server = await retry( + task: () async { + try { + final address = !system.isWindows + ? InternetAddress(unixSocketPath, type: InternetAddressType.unix) + : InternetAddress(localhost, type: InternetAddressType.IPv4); + await _deleteSocketFile(); + final server = await ServerSocket.bind(address, 0, shared: true); + server.listen((socket) async { + await _attachSocket(socket); + }); + return server; + } catch (_) { + return null; } }, - (error, stack) async { - commonPrint.log('Service error: $error', logLevel: LogLevel.warning); - }, + retryIf: (server) => server == null, ); + if (server == null) { + exit(0); + } + _serverCompleter.complete(server); } Future _attachSocket(Socket socket) async { diff --git a/lib/models/profile.dart b/lib/models/profile.dart index a701b48..acbde82 100644 --- a/lib/models/profile.dart +++ b/lib/models/profile.dart @@ -1,4 +1,3 @@ -import 'dart:convert'; import 'dart:io'; import 'dart:typed_data'; @@ -174,7 +173,7 @@ extension ProfileExtension on Profile { } Future saveFile(Uint8List bytes) async { - final message = await coreController.validateConfig(utf8.decode(bytes)); + final message = await coreController.validateConfigFormBytes(bytes); if (message.isNotEmpty) { throw message; } @@ -182,14 +181,4 @@ extension ProfileExtension on Profile { await file.writeAsBytes(bytes); return copyWith(lastUpdateDate: DateTime.now()); } - - Future saveFileWithString(String value) async { - final message = await coreController.validateConfig(value); - if (message.isNotEmpty) { - throw message; - } - final file = await getFile(); - await file.writeAsString(value); - return copyWith(lastUpdateDate: DateTime.now()); - } } diff --git a/lib/state.dart b/lib/state.dart index 0834cd9..53b2646 100644 --- a/lib/state.dart +++ b/lib/state.dart @@ -239,7 +239,7 @@ class GlobalState { return VpnOptions( stack: config.patchClashConfig.tun.stack.name, enable: vpnProps.enable, - systemProxy: networkProps.systemProxy, + systemProxy: vpnProps.systemProxy, port: port, ipv6: vpnProps.ipv6, dnsHijacking: vpnProps.dnsHijacking, @@ -323,6 +323,42 @@ class GlobalState { } } + Future genValidateFile(String path, String data) async { + final res = await Isolate.run(() async { + try { + final file = File(path); + if (!await file.exists()) { + await file.create(recursive: true); + } + await file.writeAsString(data); + return ''; + } catch (e) { + return e.toString(); + } + }); + if (res.isNotEmpty) { + throw res; + } + } + + Future genValidateFileFormBytes(String path, Uint8List bytes) async { + final res = await Isolate.run(() async { + try { + final file = File(path); + if (!await file.exists()) { + await file.create(recursive: true); + } + await file.writeAsBytes(bytes); + return ''; + } catch (e) { + return e.toString(); + } + }); + if (res.isNotEmpty) { + throw res; + } + } + AndroidState getAndroidState() { return AndroidState( currentProfileName: config.currentProfile?.label ?? '', diff --git a/pubspec.yaml b/pubspec.yaml index 6c63a8a..87fac8f 100755 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,7 +1,7 @@ name: fl_clash description: A multi-platform proxy client based on ClashMeta, simple and easy to use, open-source and ad-free. publish_to: 'none' -version: 0.8.88+2025092301 +version: 0.8.89+2025092701 environment: sdk: '>=3.8.0 <4.0.0' diff --git a/windows/packaging/exe/inno_setup.iss b/windows/packaging/exe/inno_setup.iss index bbd56d0..4771bfc 100644 --- a/windows/packaging/exe/inno_setup.iss +++ b/windows/packaging/exe/inno_setup.iss @@ -15,8 +15,8 @@ SolidCompression=yes SetupIconFile={{SETUP_ICON_FILE}} WizardStyle=modern PrivilegesRequired={{PRIVILEGES_REQUIRED}} -ArchitecturesAllowed={{ARCH}} -ArchitecturesInstallIn64BitMode={{ARCH}} +ArchitecturesAllowed=x64 arm64 +ArchitecturesInstallIn64BitMode=x64 arm64 [Code] procedure KillProcesses;