diff --git a/.github/update.log b/.github/update.log index 5d053497ad..e5329e6047 100644 --- a/.github/update.log +++ b/.github/update.log @@ -1176,3 +1176,4 @@ Update On Wed Nov 5 19:38:37 CET 2025 Update On Thu Nov 6 19:42:10 CET 2025 Update On Fri Nov 7 19:41:20 CET 2025 Update On Sat Nov 8 19:37:24 CET 2025 +Update On Sun Nov 9 19:36:09 CET 2025 diff --git a/clash-meta-android/README.md b/clash-meta-android/README.md index 5cc436f234..03757eca76 100644 --- a/clash-meta-android/README.md +++ b/clash-meta-android/README.md @@ -32,7 +32,15 @@ Feature of [Clash.Meta](https://github.com/MetaCubeX/Clash.Meta) sdk.dir=/path/to/android-sdk ``` -4. Create `signing.properties` in project root with +4. (Optional) Custom app package name. Add the following configuration to `local.properties`. + + ```properties + # config your ownn applicationId, or it will be 'com.github.metacubex.clash' + custom.application.id=com.my.compile.clash + # remove application id suffix, or the applicaion id will be 'com.github.metacubex.clash.alpha' + remove.suffix=true + +5. Create `signing.properties` in project root with ```properties keystore.path=/path/to/keystore/file @@ -41,7 +49,7 @@ Feature of [Clash.Meta](https://github.com/MetaCubeX/Clash.Meta) key.password= ``` -5. Build +6. Build ```bash ./gradlew app:assembleAlphaRelease diff --git a/clash-meta-android/build.gradle.kts b/clash-meta-android/build.gradle.kts index 6e1614b319..2ed94f9daf 100644 --- a/clash-meta-android/build.gradle.kts +++ b/clash-meta-android/build.gradle.kts @@ -31,11 +31,23 @@ subprojects { apply(plugin = if (isApp) "com.android.application" else "com.android.library") + fun queryConfigProperty(key: String): Any? { + val localProperties = Properties() + val localPropertiesFile = rootProject.file("local.properties") + if (localPropertiesFile.exists()) { + localProperties.load(localPropertiesFile.inputStream()) + } else { + return null + } + return localProperties.getProperty(key) + } + extensions.configure { buildFeatures.buildConfig = true defaultConfig { if (isApp) { - applicationId = "com.github.metacubex.clash" + val customApplicationId = queryConfigProperty("custom.application.id") as? String? + applicationId = customApplicationId.takeIf { it?.isNotBlank() == true } ?: "com.github.metacubex.clash" } project.name.let { name -> @@ -46,8 +58,8 @@ subprojects { minSdk = 21 targetSdk = 35 - versionName = "2.11.18" - versionCode = 211018 + versionName = "2.11.19" + versionCode = 211019 resValue("string", "release_name", "v$versionName") resValue("integer", "release_code", "$versionCode") @@ -84,17 +96,22 @@ subprojects { productFlavors { flavorDimensions("feature") + val removeSuffix = (queryConfigProperty("remove.suffix") as? String)?.toBoolean() == true + create("alpha") { isDefault = true dimension = flavorDimensionList[0] - versionNameSuffix = ".Alpha" + if (!removeSuffix) { + versionNameSuffix = ".Alpha" + } + buildConfigField("boolean", "PREMIUM", "Boolean.parseBoolean(\"false\")") resValue("string", "launch_name", "@string/launch_name_alpha") resValue("string", "application_name", "@string/application_name_alpha") - if (isApp) { + if (isApp && !removeSuffix) { applicationIdSuffix = ".alpha" } } @@ -102,14 +119,16 @@ subprojects { create("meta") { dimension = flavorDimensionList[0] - versionNameSuffix = ".Meta" + if (!removeSuffix) { + versionNameSuffix = ".Meta" + } buildConfigField("boolean", "PREMIUM", "Boolean.parseBoolean(\"false\")") resValue("string", "launch_name", "@string/launch_name_meta") resValue("string", "application_name", "@string/application_name_meta") - if (isApp) { + if (isApp && !removeSuffix) { applicationIdSuffix = ".meta" } } diff --git a/clash-meta-android/core/src/foss/golang/clash/.github/patch/go1.21.patch b/clash-meta-android/core/src/foss/golang/clash/.github/patch/go1.21.patch new file mode 100644 index 0000000000..2ada77813a --- /dev/null +++ b/clash-meta-android/core/src/foss/golang/clash/.github/patch/go1.21.patch @@ -0,0 +1,182 @@ +Subject: [PATCH] Revert "[release-branch.go1.21] crypto/rand,runtime: switch RtlGenRandom for ProcessPrng" +--- +Index: src/crypto/rand/rand.go +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +diff --git a/src/crypto/rand/rand.go b/src/crypto/rand/rand.go +--- a/src/crypto/rand/rand.go (revision 8bba868de983dd7bf55fcd121495ba8d6e2734e7) ++++ b/src/crypto/rand/rand.go (revision 7e6c963d81e14ee394402671d4044b2940c8d2c1) +@@ -15,7 +15,7 @@ + // available, /dev/urandom otherwise. + // On OpenBSD and macOS, Reader uses getentropy(2). + // On other Unix-like systems, Reader reads from /dev/urandom. +-// On Windows systems, Reader uses the ProcessPrng API. ++// On Windows systems, Reader uses the RtlGenRandom API. + // On JS/Wasm, Reader uses the Web Crypto API. + // On WASIP1/Wasm, Reader uses random_get from wasi_snapshot_preview1. + var Reader io.Reader +Index: src/crypto/rand/rand_windows.go +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +diff --git a/src/crypto/rand/rand_windows.go b/src/crypto/rand/rand_windows.go +--- a/src/crypto/rand/rand_windows.go (revision 8bba868de983dd7bf55fcd121495ba8d6e2734e7) ++++ b/src/crypto/rand/rand_windows.go (revision 7e6c963d81e14ee394402671d4044b2940c8d2c1) +@@ -15,8 +15,11 @@ + + type rngReader struct{} + +-func (r *rngReader) Read(b []byte) (int, error) { +- if err := windows.ProcessPrng(b); err != nil { ++func (r *rngReader) Read(b []byte) (n int, err error) { ++ // RtlGenRandom only returns 1<<32-1 bytes at a time. We only read at ++ // most 1<<31-1 bytes at a time so that this works the same on 32-bit ++ // and 64-bit systems. ++ if err := batched(windows.RtlGenRandom, 1<<31-1)(b); err != nil { + return 0, err + } + return len(b), nil +Index: src/internal/syscall/windows/syscall_windows.go +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +diff --git a/src/internal/syscall/windows/syscall_windows.go b/src/internal/syscall/windows/syscall_windows.go +--- a/src/internal/syscall/windows/syscall_windows.go (revision 8bba868de983dd7bf55fcd121495ba8d6e2734e7) ++++ b/src/internal/syscall/windows/syscall_windows.go (revision 7e6c963d81e14ee394402671d4044b2940c8d2c1) +@@ -384,7 +384,7 @@ + //sys DestroyEnvironmentBlock(block *uint16) (err error) = userenv.DestroyEnvironmentBlock + //sys CreateEvent(eventAttrs *SecurityAttributes, manualReset uint32, initialState uint32, name *uint16) (handle syscall.Handle, err error) = kernel32.CreateEventW + +-//sys ProcessPrng(buf []byte) (err error) = bcryptprimitives.ProcessPrng ++//sys RtlGenRandom(buf []byte) (err error) = advapi32.SystemFunction036 + + //sys RtlLookupFunctionEntry(pc uintptr, baseAddress *uintptr, table *byte) (ret uintptr) = kernel32.RtlLookupFunctionEntry + //sys RtlVirtualUnwind(handlerType uint32, baseAddress uintptr, pc uintptr, entry uintptr, ctxt uintptr, data *uintptr, frame *uintptr, ctxptrs *byte) (ret uintptr) = kernel32.RtlVirtualUnwind +Index: src/internal/syscall/windows/zsyscall_windows.go +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +diff --git a/src/internal/syscall/windows/zsyscall_windows.go b/src/internal/syscall/windows/zsyscall_windows.go +--- a/src/internal/syscall/windows/zsyscall_windows.go (revision 8bba868de983dd7bf55fcd121495ba8d6e2734e7) ++++ b/src/internal/syscall/windows/zsyscall_windows.go (revision 7e6c963d81e14ee394402671d4044b2940c8d2c1) +@@ -37,14 +37,13 @@ + } + + var ( +- modadvapi32 = syscall.NewLazyDLL(sysdll.Add("advapi32.dll")) +- modbcryptprimitives = syscall.NewLazyDLL(sysdll.Add("bcryptprimitives.dll")) +- modiphlpapi = syscall.NewLazyDLL(sysdll.Add("iphlpapi.dll")) +- modkernel32 = syscall.NewLazyDLL(sysdll.Add("kernel32.dll")) +- modnetapi32 = syscall.NewLazyDLL(sysdll.Add("netapi32.dll")) +- modpsapi = syscall.NewLazyDLL(sysdll.Add("psapi.dll")) +- moduserenv = syscall.NewLazyDLL(sysdll.Add("userenv.dll")) +- modws2_32 = syscall.NewLazyDLL(sysdll.Add("ws2_32.dll")) ++ modadvapi32 = syscall.NewLazyDLL(sysdll.Add("advapi32.dll")) ++ modiphlpapi = syscall.NewLazyDLL(sysdll.Add("iphlpapi.dll")) ++ modkernel32 = syscall.NewLazyDLL(sysdll.Add("kernel32.dll")) ++ modnetapi32 = syscall.NewLazyDLL(sysdll.Add("netapi32.dll")) ++ modpsapi = syscall.NewLazyDLL(sysdll.Add("psapi.dll")) ++ moduserenv = syscall.NewLazyDLL(sysdll.Add("userenv.dll")) ++ modws2_32 = syscall.NewLazyDLL(sysdll.Add("ws2_32.dll")) + + procAdjustTokenPrivileges = modadvapi32.NewProc("AdjustTokenPrivileges") + procDuplicateTokenEx = modadvapi32.NewProc("DuplicateTokenEx") +@@ -53,7 +52,7 @@ + procOpenThreadToken = modadvapi32.NewProc("OpenThreadToken") + procRevertToSelf = modadvapi32.NewProc("RevertToSelf") + procSetTokenInformation = modadvapi32.NewProc("SetTokenInformation") +- procProcessPrng = modbcryptprimitives.NewProc("ProcessPrng") ++ procSystemFunction036 = modadvapi32.NewProc("SystemFunction036") + procGetAdaptersAddresses = modiphlpapi.NewProc("GetAdaptersAddresses") + procCreateEventW = modkernel32.NewProc("CreateEventW") + procGetACP = modkernel32.NewProc("GetACP") +@@ -149,12 +148,12 @@ + return + } + +-func ProcessPrng(buf []byte) (err error) { ++func RtlGenRandom(buf []byte) (err error) { + var _p0 *byte + if len(buf) > 0 { + _p0 = &buf[0] + } +- r1, _, e1 := syscall.Syscall(procProcessPrng.Addr(), 2, uintptr(unsafe.Pointer(_p0)), uintptr(len(buf)), 0) ++ r1, _, e1 := syscall.Syscall(procSystemFunction036.Addr(), 2, uintptr(unsafe.Pointer(_p0)), uintptr(len(buf)), 0) + if r1 == 0 { + err = errnoErr(e1) + } +Index: src/runtime/os_windows.go +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +diff --git a/src/runtime/os_windows.go b/src/runtime/os_windows.go +--- a/src/runtime/os_windows.go (revision 8bba868de983dd7bf55fcd121495ba8d6e2734e7) ++++ b/src/runtime/os_windows.go (revision 7e6c963d81e14ee394402671d4044b2940c8d2c1) +@@ -127,8 +127,15 @@ + _AddVectoredContinueHandler, + _ stdFunction + +- // Use ProcessPrng to generate cryptographically random data. +- _ProcessPrng stdFunction ++ // Use RtlGenRandom to generate cryptographically random data. ++ // This approach has been recommended by Microsoft (see issue ++ // 15589 for details). ++ // The RtlGenRandom is not listed in advapi32.dll, instead ++ // RtlGenRandom function can be found by searching for SystemFunction036. ++ // Also some versions of Mingw cannot link to SystemFunction036 ++ // when building executable as Cgo. So load SystemFunction036 ++ // manually during runtime startup. ++ _RtlGenRandom stdFunction + + // Load ntdll.dll manually during startup, otherwise Mingw + // links wrong printf function to cgo executable (see issue +@@ -145,12 +152,12 @@ + ) + + var ( +- bcryptprimitivesdll = [...]uint16{'b', 'c', 'r', 'y', 'p', 't', 'p', 'r', 'i', 'm', 'i', 't', 'i', 'v', 'e', 's', '.', 'd', 'l', 'l', 0} +- kernel32dll = [...]uint16{'k', 'e', 'r', 'n', 'e', 'l', '3', '2', '.', 'd', 'l', 'l', 0} +- ntdlldll = [...]uint16{'n', 't', 'd', 'l', 'l', '.', 'd', 'l', 'l', 0} +- powrprofdll = [...]uint16{'p', 'o', 'w', 'r', 'p', 'r', 'o', 'f', '.', 'd', 'l', 'l', 0} +- winmmdll = [...]uint16{'w', 'i', 'n', 'm', 'm', '.', 'd', 'l', 'l', 0} +- ws2_32dll = [...]uint16{'w', 's', '2', '_', '3', '2', '.', 'd', 'l', 'l', 0} ++ advapi32dll = [...]uint16{'a', 'd', 'v', 'a', 'p', 'i', '3', '2', '.', 'd', 'l', 'l', 0} ++ kernel32dll = [...]uint16{'k', 'e', 'r', 'n', 'e', 'l', '3', '2', '.', 'd', 'l', 'l', 0} ++ ntdlldll = [...]uint16{'n', 't', 'd', 'l', 'l', '.', 'd', 'l', 'l', 0} ++ powrprofdll = [...]uint16{'p', 'o', 'w', 'r', 'p', 'r', 'o', 'f', '.', 'd', 'l', 'l', 0} ++ winmmdll = [...]uint16{'w', 'i', 'n', 'm', 'm', '.', 'd', 'l', 'l', 0} ++ ws2_32dll = [...]uint16{'w', 's', '2', '_', '3', '2', '.', 'd', 'l', 'l', 0} + ) + + // Function to be called by windows CreateThread +@@ -249,11 +256,11 @@ + } + _AddVectoredContinueHandler = windowsFindfunc(k32, []byte("AddVectoredContinueHandler\000")) + +- bcryptPrimitives := windowsLoadSystemLib(bcryptprimitivesdll[:]) +- if bcryptPrimitives == 0 { +- throw("bcryptprimitives.dll not found") ++ a32 := windowsLoadSystemLib(advapi32dll[:]) ++ if a32 == 0 { ++ throw("advapi32.dll not found") + } +- _ProcessPrng = windowsFindfunc(bcryptPrimitives, []byte("ProcessPrng\000")) ++ _RtlGenRandom = windowsFindfunc(a32, []byte("SystemFunction036\000")) + + n32 := windowsLoadSystemLib(ntdlldll[:]) + if n32 == 0 { +@@ -610,7 +617,7 @@ + //go:nosplit + func getRandomData(r []byte) { + n := 0 +- if stdcall2(_ProcessPrng, uintptr(unsafe.Pointer(&r[0])), uintptr(len(r)))&0xff != 0 { ++ if stdcall2(_RtlGenRandom, uintptr(unsafe.Pointer(&r[0])), uintptr(len(r)))&0xff != 0 { + n = len(r) + } + extendRandom(r, n) diff --git a/clash-meta-android/core/src/foss/golang/clash/.github/patch/go1.22.patch b/clash-meta-android/core/src/foss/golang/clash/.github/patch/go1.22.patch new file mode 100644 index 0000000000..3c0c66e363 --- /dev/null +++ b/clash-meta-android/core/src/foss/golang/clash/.github/patch/go1.22.patch @@ -0,0 +1,645 @@ +Subject: [PATCH] Revert "runtime: always use LoadLibraryEx to load system libraries" +Revert "syscall: remove Windows 7 console handle workaround" +Revert "net: remove sysSocket fallback for Windows 7" +Revert "crypto/rand,runtime: switch RtlGenRandom for ProcessPrng" +--- +Index: src/crypto/rand/rand.go +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +diff --git a/src/crypto/rand/rand.go b/src/crypto/rand/rand.go +--- a/src/crypto/rand/rand.go (revision cb4eee693c382bea4222f20837e26501d40ed892) ++++ b/src/crypto/rand/rand.go (revision 9779155f18b6556a034f7bb79fb7fb2aad1e26a9) +@@ -15,7 +15,7 @@ + // available, /dev/urandom otherwise. + // On OpenBSD and macOS, Reader uses getentropy(2). + // On other Unix-like systems, Reader reads from /dev/urandom. +-// On Windows systems, Reader uses the ProcessPrng API. ++// On Windows systems, Reader uses the RtlGenRandom API. + // On JS/Wasm, Reader uses the Web Crypto API. + // On WASIP1/Wasm, Reader uses random_get from wasi_snapshot_preview1. + var Reader io.Reader +Index: src/crypto/rand/rand_windows.go +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +diff --git a/src/crypto/rand/rand_windows.go b/src/crypto/rand/rand_windows.go +--- a/src/crypto/rand/rand_windows.go (revision cb4eee693c382bea4222f20837e26501d40ed892) ++++ b/src/crypto/rand/rand_windows.go (revision 9779155f18b6556a034f7bb79fb7fb2aad1e26a9) +@@ -15,8 +15,11 @@ + + type rngReader struct{} + +-func (r *rngReader) Read(b []byte) (int, error) { +- if err := windows.ProcessPrng(b); err != nil { ++func (r *rngReader) Read(b []byte) (n int, err error) { ++ // RtlGenRandom only returns 1<<32-1 bytes at a time. We only read at ++ // most 1<<31-1 bytes at a time so that this works the same on 32-bit ++ // and 64-bit systems. ++ if err := batched(windows.RtlGenRandom, 1<<31-1)(b); err != nil { + return 0, err + } + return len(b), nil +Index: src/internal/syscall/windows/syscall_windows.go +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +diff --git a/src/internal/syscall/windows/syscall_windows.go b/src/internal/syscall/windows/syscall_windows.go +--- a/src/internal/syscall/windows/syscall_windows.go (revision cb4eee693c382bea4222f20837e26501d40ed892) ++++ b/src/internal/syscall/windows/syscall_windows.go (revision 9779155f18b6556a034f7bb79fb7fb2aad1e26a9) +@@ -384,7 +384,7 @@ + //sys DestroyEnvironmentBlock(block *uint16) (err error) = userenv.DestroyEnvironmentBlock + //sys CreateEvent(eventAttrs *SecurityAttributes, manualReset uint32, initialState uint32, name *uint16) (handle syscall.Handle, err error) = kernel32.CreateEventW + +-//sys ProcessPrng(buf []byte) (err error) = bcryptprimitives.ProcessPrng ++//sys RtlGenRandom(buf []byte) (err error) = advapi32.SystemFunction036 + + type FILE_ID_BOTH_DIR_INFO struct { + NextEntryOffset uint32 +Index: src/internal/syscall/windows/zsyscall_windows.go +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +diff --git a/src/internal/syscall/windows/zsyscall_windows.go b/src/internal/syscall/windows/zsyscall_windows.go +--- a/src/internal/syscall/windows/zsyscall_windows.go (revision cb4eee693c382bea4222f20837e26501d40ed892) ++++ b/src/internal/syscall/windows/zsyscall_windows.go (revision 9779155f18b6556a034f7bb79fb7fb2aad1e26a9) +@@ -37,14 +37,13 @@ + } + + var ( +- modadvapi32 = syscall.NewLazyDLL(sysdll.Add("advapi32.dll")) +- modbcryptprimitives = syscall.NewLazyDLL(sysdll.Add("bcryptprimitives.dll")) +- modiphlpapi = syscall.NewLazyDLL(sysdll.Add("iphlpapi.dll")) +- modkernel32 = syscall.NewLazyDLL(sysdll.Add("kernel32.dll")) +- modnetapi32 = syscall.NewLazyDLL(sysdll.Add("netapi32.dll")) +- modpsapi = syscall.NewLazyDLL(sysdll.Add("psapi.dll")) +- moduserenv = syscall.NewLazyDLL(sysdll.Add("userenv.dll")) +- modws2_32 = syscall.NewLazyDLL(sysdll.Add("ws2_32.dll")) ++ modadvapi32 = syscall.NewLazyDLL(sysdll.Add("advapi32.dll")) ++ modiphlpapi = syscall.NewLazyDLL(sysdll.Add("iphlpapi.dll")) ++ modkernel32 = syscall.NewLazyDLL(sysdll.Add("kernel32.dll")) ++ modnetapi32 = syscall.NewLazyDLL(sysdll.Add("netapi32.dll")) ++ modpsapi = syscall.NewLazyDLL(sysdll.Add("psapi.dll")) ++ moduserenv = syscall.NewLazyDLL(sysdll.Add("userenv.dll")) ++ modws2_32 = syscall.NewLazyDLL(sysdll.Add("ws2_32.dll")) + + procAdjustTokenPrivileges = modadvapi32.NewProc("AdjustTokenPrivileges") + procDuplicateTokenEx = modadvapi32.NewProc("DuplicateTokenEx") +@@ -56,7 +55,7 @@ + procQueryServiceStatus = modadvapi32.NewProc("QueryServiceStatus") + procRevertToSelf = modadvapi32.NewProc("RevertToSelf") + procSetTokenInformation = modadvapi32.NewProc("SetTokenInformation") +- procProcessPrng = modbcryptprimitives.NewProc("ProcessPrng") ++ procSystemFunction036 = modadvapi32.NewProc("SystemFunction036") + procGetAdaptersAddresses = modiphlpapi.NewProc("GetAdaptersAddresses") + procCreateEventW = modkernel32.NewProc("CreateEventW") + procGetACP = modkernel32.NewProc("GetACP") +@@ -180,12 +179,12 @@ + return + } + +-func ProcessPrng(buf []byte) (err error) { ++func RtlGenRandom(buf []byte) (err error) { + var _p0 *byte + if len(buf) > 0 { + _p0 = &buf[0] + } +- r1, _, e1 := syscall.Syscall(procProcessPrng.Addr(), 2, uintptr(unsafe.Pointer(_p0)), uintptr(len(buf)), 0) ++ r1, _, e1 := syscall.Syscall(procSystemFunction036.Addr(), 2, uintptr(unsafe.Pointer(_p0)), uintptr(len(buf)), 0) + if r1 == 0 { + err = errnoErr(e1) + } +Index: src/runtime/os_windows.go +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +diff --git a/src/runtime/os_windows.go b/src/runtime/os_windows.go +--- a/src/runtime/os_windows.go (revision cb4eee693c382bea4222f20837e26501d40ed892) ++++ b/src/runtime/os_windows.go (revision 83ff9782e024cb328b690cbf0da4e7848a327f4f) +@@ -40,8 +40,8 @@ + //go:cgo_import_dynamic runtime._GetSystemInfo GetSystemInfo%1 "kernel32.dll" + //go:cgo_import_dynamic runtime._GetThreadContext GetThreadContext%2 "kernel32.dll" + //go:cgo_import_dynamic runtime._SetThreadContext SetThreadContext%2 "kernel32.dll" +-//go:cgo_import_dynamic runtime._LoadLibraryExW LoadLibraryExW%3 "kernel32.dll" + //go:cgo_import_dynamic runtime._LoadLibraryW LoadLibraryW%1 "kernel32.dll" ++//go:cgo_import_dynamic runtime._LoadLibraryA LoadLibraryA%1 "kernel32.dll" + //go:cgo_import_dynamic runtime._PostQueuedCompletionStatus PostQueuedCompletionStatus%4 "kernel32.dll" + //go:cgo_import_dynamic runtime._QueryPerformanceCounter QueryPerformanceCounter%1 "kernel32.dll" + //go:cgo_import_dynamic runtime._RaiseFailFastException RaiseFailFastException%3 "kernel32.dll" +@@ -74,7 +74,6 @@ + // Following syscalls are available on every Windows PC. + // All these variables are set by the Windows executable + // loader before the Go program starts. +- _AddVectoredContinueHandler, + _AddVectoredExceptionHandler, + _CloseHandle, + _CreateEventA, +@@ -98,8 +97,8 @@ + _GetSystemInfo, + _GetThreadContext, + _SetThreadContext, +- _LoadLibraryExW, + _LoadLibraryW, ++ _LoadLibraryA, + _PostQueuedCompletionStatus, + _QueryPerformanceCounter, + _RaiseFailFastException, +@@ -127,8 +126,23 @@ + _WriteFile, + _ stdFunction + +- // Use ProcessPrng to generate cryptographically random data. +- _ProcessPrng stdFunction ++ // Following syscalls are only available on some Windows PCs. ++ // We will load syscalls, if available, before using them. ++ _AddDllDirectory, ++ _AddVectoredContinueHandler, ++ _LoadLibraryExA, ++ _LoadLibraryExW, ++ _ stdFunction ++ ++ // Use RtlGenRandom to generate cryptographically random data. ++ // This approach has been recommended by Microsoft (see issue ++ // 15589 for details). ++ // The RtlGenRandom is not listed in advapi32.dll, instead ++ // RtlGenRandom function can be found by searching for SystemFunction036. ++ // Also some versions of Mingw cannot link to SystemFunction036 ++ // when building executable as Cgo. So load SystemFunction036 ++ // manually during runtime startup. ++ _RtlGenRandom stdFunction + + // Load ntdll.dll manually during startup, otherwise Mingw + // links wrong printf function to cgo executable (see issue +@@ -143,14 +157,6 @@ + _ stdFunction + ) + +-var ( +- bcryptprimitivesdll = [...]uint16{'b', 'c', 'r', 'y', 'p', 't', 'p', 'r', 'i', 'm', 'i', 't', 'i', 'v', 'e', 's', '.', 'd', 'l', 'l', 0} +- ntdlldll = [...]uint16{'n', 't', 'd', 'l', 'l', '.', 'd', 'l', 'l', 0} +- powrprofdll = [...]uint16{'p', 'o', 'w', 'r', 'p', 'r', 'o', 'f', '.', 'd', 'l', 'l', 0} +- winmmdll = [...]uint16{'w', 'i', 'n', 'm', 'm', '.', 'd', 'l', 'l', 0} +- ws2_32dll = [...]uint16{'w', 's', '2', '_', '3', '2', '.', 'd', 'l', 'l', 0} +-) +- + // Function to be called by windows CreateThread + // to start new os thread. + func tstart_stdcall(newm *m) +@@ -239,25 +245,51 @@ + return unsafe.String(&sysDirectory[0], sysDirectoryLen) + } + +-func windowsLoadSystemLib(name []uint16) uintptr { +- return stdcall3(_LoadLibraryExW, uintptr(unsafe.Pointer(&name[0])), 0, _LOAD_LIBRARY_SEARCH_SYSTEM32) ++//go:linkname syscall_getSystemDirectory syscall.getSystemDirectory ++func syscall_getSystemDirectory() string { ++ return unsafe.String(&sysDirectory[0], sysDirectoryLen) ++} ++ ++func windowsLoadSystemLib(name []byte) uintptr { ++ if useLoadLibraryEx { ++ return stdcall3(_LoadLibraryExA, uintptr(unsafe.Pointer(&name[0])), 0, _LOAD_LIBRARY_SEARCH_SYSTEM32) ++ } else { ++ absName := append(sysDirectory[:sysDirectoryLen], name...) ++ return stdcall1(_LoadLibraryA, uintptr(unsafe.Pointer(&absName[0]))) ++ } + } + + func loadOptionalSyscalls() { +- bcryptPrimitives := windowsLoadSystemLib(bcryptprimitivesdll[:]) +- if bcryptPrimitives == 0 { +- throw("bcryptprimitives.dll not found") ++ var kernel32dll = []byte("kernel32.dll\000") ++ k32 := stdcall1(_LoadLibraryA, uintptr(unsafe.Pointer(&kernel32dll[0]))) ++ if k32 == 0 { ++ throw("kernel32.dll not found") + } +- _ProcessPrng = windowsFindfunc(bcryptPrimitives, []byte("ProcessPrng\000")) ++ _AddDllDirectory = windowsFindfunc(k32, []byte("AddDllDirectory\000")) ++ _AddVectoredContinueHandler = windowsFindfunc(k32, []byte("AddVectoredContinueHandler\000")) ++ _LoadLibraryExA = windowsFindfunc(k32, []byte("LoadLibraryExA\000")) ++ _LoadLibraryExW = windowsFindfunc(k32, []byte("LoadLibraryExW\000")) ++ useLoadLibraryEx = (_LoadLibraryExW != nil && _LoadLibraryExA != nil && _AddDllDirectory != nil) ++ ++ initSysDirectory() + +- n32 := windowsLoadSystemLib(ntdlldll[:]) ++ var advapi32dll = []byte("advapi32.dll\000") ++ a32 := windowsLoadSystemLib(advapi32dll) ++ if a32 == 0 { ++ throw("advapi32.dll not found") ++ } ++ _RtlGenRandom = windowsFindfunc(a32, []byte("SystemFunction036\000")) ++ ++ var ntdll = []byte("ntdll.dll\000") ++ n32 := windowsLoadSystemLib(ntdll) + if n32 == 0 { + throw("ntdll.dll not found") + } + _RtlGetCurrentPeb = windowsFindfunc(n32, []byte("RtlGetCurrentPeb\000")) + _RtlGetNtVersionNumbers = windowsFindfunc(n32, []byte("RtlGetNtVersionNumbers\000")) + +- m32 := windowsLoadSystemLib(winmmdll[:]) ++ var winmmdll = []byte("winmm.dll\000") ++ m32 := windowsLoadSystemLib(winmmdll) + if m32 == 0 { + throw("winmm.dll not found") + } +@@ -267,7 +299,8 @@ + throw("timeBegin/EndPeriod not found") + } + +- ws232 := windowsLoadSystemLib(ws2_32dll[:]) ++ var ws232dll = []byte("ws2_32.dll\000") ++ ws232 := windowsLoadSystemLib(ws232dll) + if ws232 == 0 { + throw("ws2_32.dll not found") + } +@@ -286,7 +319,7 @@ + context uintptr + } + +- powrprof := windowsLoadSystemLib(powrprofdll[:]) ++ powrprof := windowsLoadSystemLib([]byte("powrprof.dll\000")) + if powrprof == 0 { + return // Running on Windows 7, where we don't need it anyway. + } +@@ -360,6 +393,22 @@ + // in sys_windows_386.s and sys_windows_amd64.s: + func getlasterror() uint32 + ++// When loading DLLs, we prefer to use LoadLibraryEx with ++// LOAD_LIBRARY_SEARCH_* flags, if available. LoadLibraryEx is not ++// available on old Windows, though, and the LOAD_LIBRARY_SEARCH_* ++// flags are not available on some versions of Windows without a ++// security patch. ++// ++// https://msdn.microsoft.com/en-us/library/ms684179(v=vs.85).aspx says: ++// "Windows 7, Windows Server 2008 R2, Windows Vista, and Windows ++// Server 2008: The LOAD_LIBRARY_SEARCH_* flags are available on ++// systems that have KB2533623 installed. To determine whether the ++// flags are available, use GetProcAddress to get the address of the ++// AddDllDirectory, RemoveDllDirectory, or SetDefaultDllDirectories ++// function. If GetProcAddress succeeds, the LOAD_LIBRARY_SEARCH_* ++// flags can be used with LoadLibraryEx." ++var useLoadLibraryEx bool ++ + var timeBeginPeriodRetValue uint32 + + // osRelaxMinNS indicates that sysmon shouldn't osRelax if the next +@@ -507,7 +556,6 @@ + initHighResTimer() + timeBeginPeriodRetValue = osRelax(false) + +- initSysDirectory() + initLongPathSupport() + + ncpu = getproccount() +@@ -524,7 +572,7 @@ + //go:nosplit + func readRandom(r []byte) int { + n := 0 +- if stdcall2(_ProcessPrng, uintptr(unsafe.Pointer(&r[0])), uintptr(len(r)))&0xff != 0 { ++ if stdcall2(_RtlGenRandom, uintptr(unsafe.Pointer(&r[0])), uintptr(len(r)))&0xff != 0 { + n = len(r) + } + return n +Index: src/net/hook_windows.go +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +diff --git a/src/net/hook_windows.go b/src/net/hook_windows.go +--- a/src/net/hook_windows.go (revision 9779155f18b6556a034f7bb79fb7fb2aad1e26a9) ++++ b/src/net/hook_windows.go (revision ef0606261340e608017860b423ffae5c1ce78239) +@@ -13,6 +13,7 @@ + hostsFilePath = windows.GetSystemDirectory() + "/Drivers/etc/hosts" + + // Placeholders for socket system calls. ++ socketFunc func(int, int, int) (syscall.Handle, error) = syscall.Socket + wsaSocketFunc func(int32, int32, int32, *syscall.WSAProtocolInfo, uint32, uint32) (syscall.Handle, error) = windows.WSASocket + connectFunc func(syscall.Handle, syscall.Sockaddr) error = syscall.Connect + listenFunc func(syscall.Handle, int) error = syscall.Listen +Index: src/net/internal/socktest/main_test.go +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +diff --git a/src/net/internal/socktest/main_test.go b/src/net/internal/socktest/main_test.go +--- a/src/net/internal/socktest/main_test.go (revision 9779155f18b6556a034f7bb79fb7fb2aad1e26a9) ++++ b/src/net/internal/socktest/main_test.go (revision ef0606261340e608017860b423ffae5c1ce78239) +@@ -2,7 +2,7 @@ + // Use of this source code is governed by a BSD-style + // license that can be found in the LICENSE file. + +-//go:build !js && !plan9 && !wasip1 && !windows ++//go:build !js && !plan9 && !wasip1 + + package socktest_test + +Index: src/net/internal/socktest/main_windows_test.go +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +diff --git a/src/net/internal/socktest/main_windows_test.go b/src/net/internal/socktest/main_windows_test.go +new file mode 100644 +--- /dev/null (revision ef0606261340e608017860b423ffae5c1ce78239) ++++ b/src/net/internal/socktest/main_windows_test.go (revision ef0606261340e608017860b423ffae5c1ce78239) +@@ -0,0 +1,22 @@ ++// Copyright 2015 The Go Authors. All rights reserved. ++// Use of this source code is governed by a BSD-style ++// license that can be found in the LICENSE file. ++ ++package socktest_test ++ ++import "syscall" ++ ++var ( ++ socketFunc func(int, int, int) (syscall.Handle, error) ++ closeFunc func(syscall.Handle) error ++) ++ ++func installTestHooks() { ++ socketFunc = sw.Socket ++ closeFunc = sw.Closesocket ++} ++ ++func uninstallTestHooks() { ++ socketFunc = syscall.Socket ++ closeFunc = syscall.Closesocket ++} +Index: src/net/internal/socktest/sys_windows.go +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +diff --git a/src/net/internal/socktest/sys_windows.go b/src/net/internal/socktest/sys_windows.go +--- a/src/net/internal/socktest/sys_windows.go (revision 9779155f18b6556a034f7bb79fb7fb2aad1e26a9) ++++ b/src/net/internal/socktest/sys_windows.go (revision ef0606261340e608017860b423ffae5c1ce78239) +@@ -9,6 +9,38 @@ + "syscall" + ) + ++// Socket wraps [syscall.Socket]. ++func (sw *Switch) Socket(family, sotype, proto int) (s syscall.Handle, err error) { ++ sw.once.Do(sw.init) ++ ++ so := &Status{Cookie: cookie(family, sotype, proto)} ++ sw.fmu.RLock() ++ f, _ := sw.fltab[FilterSocket] ++ sw.fmu.RUnlock() ++ ++ af, err := f.apply(so) ++ if err != nil { ++ return syscall.InvalidHandle, err ++ } ++ s, so.Err = syscall.Socket(family, sotype, proto) ++ if err = af.apply(so); err != nil { ++ if so.Err == nil { ++ syscall.Closesocket(s) ++ } ++ return syscall.InvalidHandle, err ++ } ++ ++ sw.smu.Lock() ++ defer sw.smu.Unlock() ++ if so.Err != nil { ++ sw.stats.getLocked(so.Cookie).OpenFailed++ ++ return syscall.InvalidHandle, so.Err ++ } ++ nso := sw.addLocked(s, family, sotype, proto) ++ sw.stats.getLocked(nso.Cookie).Opened++ ++ return s, nil ++} ++ + // WSASocket wraps [syscall.WSASocket]. + func (sw *Switch) WSASocket(family, sotype, proto int32, protinfo *syscall.WSAProtocolInfo, group uint32, flags uint32) (s syscall.Handle, err error) { + sw.once.Do(sw.init) +Index: src/net/main_windows_test.go +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +diff --git a/src/net/main_windows_test.go b/src/net/main_windows_test.go +--- a/src/net/main_windows_test.go (revision 9779155f18b6556a034f7bb79fb7fb2aad1e26a9) ++++ b/src/net/main_windows_test.go (revision ef0606261340e608017860b423ffae5c1ce78239) +@@ -8,6 +8,7 @@ + + var ( + // Placeholders for saving original socket system calls. ++ origSocket = socketFunc + origWSASocket = wsaSocketFunc + origClosesocket = poll.CloseFunc + origConnect = connectFunc +@@ -17,6 +18,7 @@ + ) + + func installTestHooks() { ++ socketFunc = sw.Socket + wsaSocketFunc = sw.WSASocket + poll.CloseFunc = sw.Closesocket + connectFunc = sw.Connect +@@ -26,6 +28,7 @@ + } + + func uninstallTestHooks() { ++ socketFunc = origSocket + wsaSocketFunc = origWSASocket + poll.CloseFunc = origClosesocket + connectFunc = origConnect +Index: src/net/sock_windows.go +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +diff --git a/src/net/sock_windows.go b/src/net/sock_windows.go +--- a/src/net/sock_windows.go (revision 9779155f18b6556a034f7bb79fb7fb2aad1e26a9) ++++ b/src/net/sock_windows.go (revision ef0606261340e608017860b423ffae5c1ce78239) +@@ -20,6 +20,21 @@ + func sysSocket(family, sotype, proto int) (syscall.Handle, error) { + s, err := wsaSocketFunc(int32(family), int32(sotype), int32(proto), + nil, 0, windows.WSA_FLAG_OVERLAPPED|windows.WSA_FLAG_NO_HANDLE_INHERIT) ++ if err == nil { ++ return s, nil ++ } ++ // WSA_FLAG_NO_HANDLE_INHERIT flag is not supported on some ++ // old versions of Windows, see ++ // https://msdn.microsoft.com/en-us/library/windows/desktop/ms742212(v=vs.85).aspx ++ // for details. Just use syscall.Socket, if windows.WSASocket failed. ++ ++ // See ../syscall/exec_unix.go for description of ForkLock. ++ syscall.ForkLock.RLock() ++ s, err = socketFunc(family, sotype, proto) ++ if err == nil { ++ syscall.CloseOnExec(s) ++ } ++ syscall.ForkLock.RUnlock() + if err != nil { + return syscall.InvalidHandle, os.NewSyscallError("socket", err) + } +Index: src/syscall/exec_windows.go +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +diff --git a/src/syscall/exec_windows.go b/src/syscall/exec_windows.go +--- a/src/syscall/exec_windows.go (revision 9779155f18b6556a034f7bb79fb7fb2aad1e26a9) ++++ b/src/syscall/exec_windows.go (revision 7f83badcb925a7e743188041cb6e561fc9b5b642) +@@ -14,7 +14,6 @@ + "unsafe" + ) + +-// ForkLock is not used on Windows. + var ForkLock sync.RWMutex + + // EscapeArg rewrites command line argument s as prescribed +@@ -317,6 +316,17 @@ + } + } + ++ var maj, min, build uint32 ++ rtlGetNtVersionNumbers(&maj, &min, &build) ++ isWin7 := maj < 6 || (maj == 6 && min <= 1) ++ // NT kernel handles are divisible by 4, with the bottom 3 bits left as ++ // a tag. The fully set tag correlates with the types of handles we're ++ // concerned about here. Except, the kernel will interpret some ++ // special handle values, like -1, -2, and so forth, so kernelbase.dll ++ // checks to see that those bottom three bits are checked, but that top ++ // bit is not checked. ++ isLegacyWin7ConsoleHandle := func(handle Handle) bool { return isWin7 && handle&0x10000003 == 3 } ++ + p, _ := GetCurrentProcess() + parentProcess := p + if sys.ParentProcess != 0 { +@@ -325,7 +335,15 @@ + fd := make([]Handle, len(attr.Files)) + for i := range attr.Files { + if attr.Files[i] > 0 { +- err := DuplicateHandle(p, Handle(attr.Files[i]), parentProcess, &fd[i], 0, true, DUPLICATE_SAME_ACCESS) ++ destinationProcessHandle := parentProcess ++ ++ // On Windows 7, console handles aren't real handles, and can only be duplicated ++ // into the current process, not a parent one, which amounts to the same thing. ++ if parentProcess != p && isLegacyWin7ConsoleHandle(Handle(attr.Files[i])) { ++ destinationProcessHandle = p ++ } ++ ++ err := DuplicateHandle(p, Handle(attr.Files[i]), destinationProcessHandle, &fd[i], 0, true, DUPLICATE_SAME_ACCESS) + if err != nil { + return 0, 0, err + } +@@ -356,6 +374,14 @@ + + fd = append(fd, sys.AdditionalInheritedHandles...) + ++ // On Windows 7, console handles aren't real handles, so don't pass them ++ // through to PROC_THREAD_ATTRIBUTE_HANDLE_LIST. ++ for i := range fd { ++ if isLegacyWin7ConsoleHandle(fd[i]) { ++ fd[i] = 0 ++ } ++ } ++ + // The presence of a NULL handle in the list is enough to cause PROC_THREAD_ATTRIBUTE_HANDLE_LIST + // to treat the entire list as empty, so remove NULL handles. + j := 0 +Index: src/runtime/syscall_windows.go +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +diff --git a/src/runtime/syscall_windows.go b/src/runtime/syscall_windows.go +--- a/src/runtime/syscall_windows.go (revision 7f83badcb925a7e743188041cb6e561fc9b5b642) ++++ b/src/runtime/syscall_windows.go (revision 83ff9782e024cb328b690cbf0da4e7848a327f4f) +@@ -413,23 +413,36 @@ + + const _LOAD_LIBRARY_SEARCH_SYSTEM32 = 0x00000800 + ++// When available, this function will use LoadLibraryEx with the filename ++// parameter and the important SEARCH_SYSTEM32 argument. But on systems that ++// do not have that option, absoluteFilepath should contain a fallback ++// to the full path inside of system32 for use with vanilla LoadLibrary. ++// + //go:linkname syscall_loadsystemlibrary syscall.loadsystemlibrary + //go:nosplit + //go:cgo_unsafe_args +-func syscall_loadsystemlibrary(filename *uint16) (handle, err uintptr) { ++func syscall_loadsystemlibrary(filename *uint16, absoluteFilepath *uint16) (handle, err uintptr) { + lockOSThread() + c := &getg().m.syscall +- c.fn = getLoadLibraryEx() +- c.n = 3 +- args := struct { +- lpFileName *uint16 +- hFile uintptr // always 0 +- flags uint32 +- }{filename, 0, _LOAD_LIBRARY_SEARCH_SYSTEM32} +- c.args = uintptr(noescape(unsafe.Pointer(&args))) ++ ++ if useLoadLibraryEx { ++ c.fn = getLoadLibraryEx() ++ c.n = 3 ++ args := struct { ++ lpFileName *uint16 ++ hFile uintptr // always 0 ++ flags uint32 ++ }{filename, 0, _LOAD_LIBRARY_SEARCH_SYSTEM32} ++ c.args = uintptr(noescape(unsafe.Pointer(&args))) ++ } else { ++ c.fn = getLoadLibrary() ++ c.n = 1 ++ c.args = uintptr(noescape(unsafe.Pointer(&absoluteFilepath))) ++ } + + cgocall(asmstdcallAddr, unsafe.Pointer(c)) + KeepAlive(filename) ++ KeepAlive(absoluteFilepath) + handle = c.r1 + if handle == 0 { + err = c.err +Index: src/syscall/dll_windows.go +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +diff --git a/src/syscall/dll_windows.go b/src/syscall/dll_windows.go +--- a/src/syscall/dll_windows.go (revision 7f83badcb925a7e743188041cb6e561fc9b5b642) ++++ b/src/syscall/dll_windows.go (revision 83ff9782e024cb328b690cbf0da4e7848a327f4f) +@@ -44,7 +44,7 @@ + + func SyscallN(trap uintptr, args ...uintptr) (r1, r2 uintptr, err Errno) + func loadlibrary(filename *uint16) (handle uintptr, err Errno) +-func loadsystemlibrary(filename *uint16) (handle uintptr, err Errno) ++func loadsystemlibrary(filename *uint16, absoluteFilepath *uint16) (handle uintptr, err Errno) + func getprocaddress(handle uintptr, procname *uint8) (proc uintptr, err Errno) + + // A DLL implements access to a single DLL. +@@ -53,6 +53,9 @@ + Handle Handle + } + ++//go:linkname getSystemDirectory ++func getSystemDirectory() string // Implemented in runtime package. ++ + // LoadDLL loads the named DLL file into memory. + // + // If name is not an absolute path and is not a known system DLL used by +@@ -69,7 +72,11 @@ + var h uintptr + var e Errno + if sysdll.IsSystemDLL[name] { +- h, e = loadsystemlibrary(namep) ++ absoluteFilepathp, err := UTF16PtrFromString(getSystemDirectory() + name) ++ if err != nil { ++ return nil, err ++ } ++ h, e = loadsystemlibrary(namep, absoluteFilepathp) + } else { + h, e = loadlibrary(namep) + } diff --git a/clash-meta-android/core/src/foss/golang/clash/.github/patch/go1.23.patch b/clash-meta-android/core/src/foss/golang/clash/.github/patch/go1.23.patch new file mode 100644 index 0000000000..e8597548f7 --- /dev/null +++ b/clash-meta-android/core/src/foss/golang/clash/.github/patch/go1.23.patch @@ -0,0 +1,643 @@ +Subject: [PATCH] Revert "runtime: always use LoadLibraryEx to load system libraries" +Revert "syscall: remove Windows 7 console handle workaround" +Revert "net: remove sysSocket fallback for Windows 7" +Revert "crypto/rand,runtime: switch RtlGenRandom for ProcessPrng" +--- +Index: src/crypto/rand/rand.go +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +diff --git a/src/crypto/rand/rand.go b/src/crypto/rand/rand.go +--- a/src/crypto/rand/rand.go (revision 6885bad7dd86880be6929c02085e5c7a67ff2887) ++++ b/src/crypto/rand/rand.go (revision 9ac42137ef6730e8b7daca016ece831297a1d75b) +@@ -16,7 +16,7 @@ + // - On macOS and iOS, Reader uses arc4random_buf(3). + // - On OpenBSD and NetBSD, Reader uses getentropy(2). + // - On other Unix-like systems, Reader reads from /dev/urandom. +-// - On Windows, Reader uses the ProcessPrng API. ++// - On Windows systems, Reader uses the RtlGenRandom API. + // - On js/wasm, Reader uses the Web Crypto API. + // - On wasip1/wasm, Reader uses random_get from wasi_snapshot_preview1. + var Reader io.Reader +Index: src/crypto/rand/rand_windows.go +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +diff --git a/src/crypto/rand/rand_windows.go b/src/crypto/rand/rand_windows.go +--- a/src/crypto/rand/rand_windows.go (revision 6885bad7dd86880be6929c02085e5c7a67ff2887) ++++ b/src/crypto/rand/rand_windows.go (revision 9ac42137ef6730e8b7daca016ece831297a1d75b) +@@ -15,8 +15,11 @@ + + type rngReader struct{} + +-func (r *rngReader) Read(b []byte) (int, error) { +- if err := windows.ProcessPrng(b); err != nil { ++func (r *rngReader) Read(b []byte) (n int, err error) { ++ // RtlGenRandom only returns 1<<32-1 bytes at a time. We only read at ++ // most 1<<31-1 bytes at a time so that this works the same on 32-bit ++ // and 64-bit systems. ++ if err := batched(windows.RtlGenRandom, 1<<31-1)(b); err != nil { + return 0, err + } + return len(b), nil +Index: src/internal/syscall/windows/syscall_windows.go +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +diff --git a/src/internal/syscall/windows/syscall_windows.go b/src/internal/syscall/windows/syscall_windows.go +--- a/src/internal/syscall/windows/syscall_windows.go (revision 6885bad7dd86880be6929c02085e5c7a67ff2887) ++++ b/src/internal/syscall/windows/syscall_windows.go (revision 9ac42137ef6730e8b7daca016ece831297a1d75b) +@@ -414,7 +414,7 @@ + //sys DestroyEnvironmentBlock(block *uint16) (err error) = userenv.DestroyEnvironmentBlock + //sys CreateEvent(eventAttrs *SecurityAttributes, manualReset uint32, initialState uint32, name *uint16) (handle syscall.Handle, err error) = kernel32.CreateEventW + +-//sys ProcessPrng(buf []byte) (err error) = bcryptprimitives.ProcessPrng ++//sys RtlGenRandom(buf []byte) (err error) = advapi32.SystemFunction036 + + type FILE_ID_BOTH_DIR_INFO struct { + NextEntryOffset uint32 +Index: src/internal/syscall/windows/zsyscall_windows.go +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +diff --git a/src/internal/syscall/windows/zsyscall_windows.go b/src/internal/syscall/windows/zsyscall_windows.go +--- a/src/internal/syscall/windows/zsyscall_windows.go (revision 6885bad7dd86880be6929c02085e5c7a67ff2887) ++++ b/src/internal/syscall/windows/zsyscall_windows.go (revision 9ac42137ef6730e8b7daca016ece831297a1d75b) +@@ -38,7 +38,6 @@ + + var ( + modadvapi32 = syscall.NewLazyDLL(sysdll.Add("advapi32.dll")) +- modbcryptprimitives = syscall.NewLazyDLL(sysdll.Add("bcryptprimitives.dll")) + modiphlpapi = syscall.NewLazyDLL(sysdll.Add("iphlpapi.dll")) + modkernel32 = syscall.NewLazyDLL(sysdll.Add("kernel32.dll")) + modnetapi32 = syscall.NewLazyDLL(sysdll.Add("netapi32.dll")) +@@ -57,7 +56,7 @@ + procQueryServiceStatus = modadvapi32.NewProc("QueryServiceStatus") + procRevertToSelf = modadvapi32.NewProc("RevertToSelf") + procSetTokenInformation = modadvapi32.NewProc("SetTokenInformation") +- procProcessPrng = modbcryptprimitives.NewProc("ProcessPrng") ++ procSystemFunction036 = modadvapi32.NewProc("SystemFunction036") + procGetAdaptersAddresses = modiphlpapi.NewProc("GetAdaptersAddresses") + procCreateEventW = modkernel32.NewProc("CreateEventW") + procGetACP = modkernel32.NewProc("GetACP") +@@ -183,12 +182,12 @@ + return + } + +-func ProcessPrng(buf []byte) (err error) { ++func RtlGenRandom(buf []byte) (err error) { + var _p0 *byte + if len(buf) > 0 { + _p0 = &buf[0] + } +- r1, _, e1 := syscall.Syscall(procProcessPrng.Addr(), 2, uintptr(unsafe.Pointer(_p0)), uintptr(len(buf)), 0) ++ r1, _, e1 := syscall.Syscall(procSystemFunction036.Addr(), 2, uintptr(unsafe.Pointer(_p0)), uintptr(len(buf)), 0) + if r1 == 0 { + err = errnoErr(e1) + } +Index: src/runtime/os_windows.go +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +diff --git a/src/runtime/os_windows.go b/src/runtime/os_windows.go +--- a/src/runtime/os_windows.go (revision 6885bad7dd86880be6929c02085e5c7a67ff2887) ++++ b/src/runtime/os_windows.go (revision 69e2eed6dd0f6d815ebf15797761c13f31213dd6) +@@ -39,8 +39,8 @@ + //go:cgo_import_dynamic runtime._GetSystemInfo GetSystemInfo%1 "kernel32.dll" + //go:cgo_import_dynamic runtime._GetThreadContext GetThreadContext%2 "kernel32.dll" + //go:cgo_import_dynamic runtime._SetThreadContext SetThreadContext%2 "kernel32.dll" +-//go:cgo_import_dynamic runtime._LoadLibraryExW LoadLibraryExW%3 "kernel32.dll" + //go:cgo_import_dynamic runtime._LoadLibraryW LoadLibraryW%1 "kernel32.dll" ++//go:cgo_import_dynamic runtime._LoadLibraryA LoadLibraryA%1 "kernel32.dll" + //go:cgo_import_dynamic runtime._PostQueuedCompletionStatus PostQueuedCompletionStatus%4 "kernel32.dll" + //go:cgo_import_dynamic runtime._QueryPerformanceCounter QueryPerformanceCounter%1 "kernel32.dll" + //go:cgo_import_dynamic runtime._QueryPerformanceFrequency QueryPerformanceFrequency%1 "kernel32.dll" +@@ -74,7 +74,6 @@ + // Following syscalls are available on every Windows PC. + // All these variables are set by the Windows executable + // loader before the Go program starts. +- _AddVectoredContinueHandler, + _AddVectoredExceptionHandler, + _CloseHandle, + _CreateEventA, +@@ -97,8 +96,8 @@ + _GetSystemInfo, + _GetThreadContext, + _SetThreadContext, +- _LoadLibraryExW, + _LoadLibraryW, ++ _LoadLibraryA, + _PostQueuedCompletionStatus, + _QueryPerformanceCounter, + _QueryPerformanceFrequency, +@@ -127,8 +126,23 @@ + _WriteFile, + _ stdFunction + +- // Use ProcessPrng to generate cryptographically random data. +- _ProcessPrng stdFunction ++ // Following syscalls are only available on some Windows PCs. ++ // We will load syscalls, if available, before using them. ++ _AddDllDirectory, ++ _AddVectoredContinueHandler, ++ _LoadLibraryExA, ++ _LoadLibraryExW, ++ _ stdFunction ++ ++ // Use RtlGenRandom to generate cryptographically random data. ++ // This approach has been recommended by Microsoft (see issue ++ // 15589 for details). ++ // The RtlGenRandom is not listed in advapi32.dll, instead ++ // RtlGenRandom function can be found by searching for SystemFunction036. ++ // Also some versions of Mingw cannot link to SystemFunction036 ++ // when building executable as Cgo. So load SystemFunction036 ++ // manually during runtime startup. ++ _RtlGenRandom stdFunction + + // Load ntdll.dll manually during startup, otherwise Mingw + // links wrong printf function to cgo executable (see issue +@@ -145,13 +159,6 @@ + _ stdFunction + ) + +-var ( +- bcryptprimitivesdll = [...]uint16{'b', 'c', 'r', 'y', 'p', 't', 'p', 'r', 'i', 'm', 'i', 't', 'i', 'v', 'e', 's', '.', 'd', 'l', 'l', 0} +- ntdlldll = [...]uint16{'n', 't', 'd', 'l', 'l', '.', 'd', 'l', 'l', 0} +- powrprofdll = [...]uint16{'p', 'o', 'w', 'r', 'p', 'r', 'o', 'f', '.', 'd', 'l', 'l', 0} +- winmmdll = [...]uint16{'w', 'i', 'n', 'm', 'm', '.', 'd', 'l', 'l', 0} +-) +- + // Function to be called by windows CreateThread + // to start new os thread. + func tstart_stdcall(newm *m) +@@ -244,8 +251,18 @@ + return unsafe.String(&sysDirectory[0], sysDirectoryLen) + } + +-func windowsLoadSystemLib(name []uint16) uintptr { +- return stdcall3(_LoadLibraryExW, uintptr(unsafe.Pointer(&name[0])), 0, _LOAD_LIBRARY_SEARCH_SYSTEM32) ++//go:linkname syscall_getSystemDirectory syscall.getSystemDirectory ++func syscall_getSystemDirectory() string { ++ return unsafe.String(&sysDirectory[0], sysDirectoryLen) ++} ++ ++func windowsLoadSystemLib(name []byte) uintptr { ++ if useLoadLibraryEx { ++ return stdcall3(_LoadLibraryExA, uintptr(unsafe.Pointer(&name[0])), 0, _LOAD_LIBRARY_SEARCH_SYSTEM32) ++ } else { ++ absName := append(sysDirectory[:sysDirectoryLen], name...) ++ return stdcall1(_LoadLibraryA, uintptr(unsafe.Pointer(&absName[0]))) ++ } + } + + //go:linkname windows_QueryPerformanceCounter internal/syscall/windows.QueryPerformanceCounter +@@ -263,13 +280,28 @@ + } + + func loadOptionalSyscalls() { +- bcryptPrimitives := windowsLoadSystemLib(bcryptprimitivesdll[:]) +- if bcryptPrimitives == 0 { +- throw("bcryptprimitives.dll not found") ++ var kernel32dll = []byte("kernel32.dll\000") ++ k32 := stdcall1(_LoadLibraryA, uintptr(unsafe.Pointer(&kernel32dll[0]))) ++ if k32 == 0 { ++ throw("kernel32.dll not found") + } +- _ProcessPrng = windowsFindfunc(bcryptPrimitives, []byte("ProcessPrng\000")) ++ _AddDllDirectory = windowsFindfunc(k32, []byte("AddDllDirectory\000")) ++ _AddVectoredContinueHandler = windowsFindfunc(k32, []byte("AddVectoredContinueHandler\000")) ++ _LoadLibraryExA = windowsFindfunc(k32, []byte("LoadLibraryExA\000")) ++ _LoadLibraryExW = windowsFindfunc(k32, []byte("LoadLibraryExW\000")) ++ useLoadLibraryEx = (_LoadLibraryExW != nil && _LoadLibraryExA != nil && _AddDllDirectory != nil) ++ ++ initSysDirectory() + +- n32 := windowsLoadSystemLib(ntdlldll[:]) ++ var advapi32dll = []byte("advapi32.dll\000") ++ a32 := windowsLoadSystemLib(advapi32dll) ++ if a32 == 0 { ++ throw("advapi32.dll not found") ++ } ++ _RtlGenRandom = windowsFindfunc(a32, []byte("SystemFunction036\000")) ++ ++ var ntdll = []byte("ntdll.dll\000") ++ n32 := windowsLoadSystemLib(ntdll) + if n32 == 0 { + throw("ntdll.dll not found") + } +@@ -298,7 +330,7 @@ + context uintptr + } + +- powrprof := windowsLoadSystemLib(powrprofdll[:]) ++ powrprof := windowsLoadSystemLib([]byte("powrprof.dll\000")) + if powrprof == 0 { + return // Running on Windows 7, where we don't need it anyway. + } +@@ -357,6 +389,22 @@ + // in sys_windows_386.s and sys_windows_amd64.s: + func getlasterror() uint32 + ++// When loading DLLs, we prefer to use LoadLibraryEx with ++// LOAD_LIBRARY_SEARCH_* flags, if available. LoadLibraryEx is not ++// available on old Windows, though, and the LOAD_LIBRARY_SEARCH_* ++// flags are not available on some versions of Windows without a ++// security patch. ++// ++// https://msdn.microsoft.com/en-us/library/ms684179(v=vs.85).aspx says: ++// "Windows 7, Windows Server 2008 R2, Windows Vista, and Windows ++// Server 2008: The LOAD_LIBRARY_SEARCH_* flags are available on ++// systems that have KB2533623 installed. To determine whether the ++// flags are available, use GetProcAddress to get the address of the ++// AddDllDirectory, RemoveDllDirectory, or SetDefaultDllDirectories ++// function. If GetProcAddress succeeds, the LOAD_LIBRARY_SEARCH_* ++// flags can be used with LoadLibraryEx." ++var useLoadLibraryEx bool ++ + var timeBeginPeriodRetValue uint32 + + // osRelaxMinNS indicates that sysmon shouldn't osRelax if the next +@@ -430,7 +478,8 @@ + // Only load winmm.dll if we need it. + // This avoids a dependency on winmm.dll for Go programs + // that run on new Windows versions. +- m32 := windowsLoadSystemLib(winmmdll[:]) ++ var winmmdll = []byte("winmm.dll\000") ++ m32 := windowsLoadSystemLib(winmmdll) + if m32 == 0 { + print("runtime: LoadLibraryExW failed; errno=", getlasterror(), "\n") + throw("winmm.dll not found") +@@ -471,6 +520,28 @@ + canUseLongPaths = true + } + ++var osVersionInfo struct { ++ majorVersion uint32 ++ minorVersion uint32 ++ buildNumber uint32 ++} ++ ++func initOsVersionInfo() { ++ info := _OSVERSIONINFOW{} ++ info.osVersionInfoSize = uint32(unsafe.Sizeof(info)) ++ stdcall1(_RtlGetVersion, uintptr(unsafe.Pointer(&info))) ++ osVersionInfo.majorVersion = info.majorVersion ++ osVersionInfo.minorVersion = info.minorVersion ++ osVersionInfo.buildNumber = info.buildNumber ++} ++ ++//go:linkname rtlGetNtVersionNumbers syscall.rtlGetNtVersionNumbers ++func rtlGetNtVersionNumbers(majorVersion *uint32, minorVersion *uint32, buildNumber *uint32) { ++ *majorVersion = osVersionInfo.majorVersion ++ *minorVersion = osVersionInfo.minorVersion ++ *buildNumber = osVersionInfo.buildNumber ++} ++ + func osinit() { + asmstdcallAddr = unsafe.Pointer(abi.FuncPCABI0(asmstdcall)) + +@@ -483,8 +554,8 @@ + initHighResTimer() + timeBeginPeriodRetValue = osRelax(false) + +- initSysDirectory() + initLongPathSupport() ++ initOsVersionInfo() + + ncpu = getproccount() + +@@ -500,7 +571,7 @@ + //go:nosplit + func readRandom(r []byte) int { + n := 0 +- if stdcall2(_ProcessPrng, uintptr(unsafe.Pointer(&r[0])), uintptr(len(r)))&0xff != 0 { ++ if stdcall2(_RtlGenRandom, uintptr(unsafe.Pointer(&r[0])), uintptr(len(r)))&0xff != 0 { + n = len(r) + } + return n +Index: src/net/hook_windows.go +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +diff --git a/src/net/hook_windows.go b/src/net/hook_windows.go +--- a/src/net/hook_windows.go (revision 9ac42137ef6730e8b7daca016ece831297a1d75b) ++++ b/src/net/hook_windows.go (revision 21290de8a4c91408de7c2b5b68757b1e90af49dd) +@@ -13,6 +13,7 @@ + hostsFilePath = windows.GetSystemDirectory() + "/Drivers/etc/hosts" + + // Placeholders for socket system calls. ++ socketFunc func(int, int, int) (syscall.Handle, error) = syscall.Socket + wsaSocketFunc func(int32, int32, int32, *syscall.WSAProtocolInfo, uint32, uint32) (syscall.Handle, error) = windows.WSASocket + connectFunc func(syscall.Handle, syscall.Sockaddr) error = syscall.Connect + listenFunc func(syscall.Handle, int) error = syscall.Listen +Index: src/net/internal/socktest/main_test.go +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +diff --git a/src/net/internal/socktest/main_test.go b/src/net/internal/socktest/main_test.go +--- a/src/net/internal/socktest/main_test.go (revision 9ac42137ef6730e8b7daca016ece831297a1d75b) ++++ b/src/net/internal/socktest/main_test.go (revision 21290de8a4c91408de7c2b5b68757b1e90af49dd) +@@ -2,7 +2,7 @@ + // Use of this source code is governed by a BSD-style + // license that can be found in the LICENSE file. + +-//go:build !js && !plan9 && !wasip1 && !windows ++//go:build !js && !plan9 && !wasip1 + + package socktest_test + +Index: src/net/internal/socktest/main_windows_test.go +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +diff --git a/src/net/internal/socktest/main_windows_test.go b/src/net/internal/socktest/main_windows_test.go +new file mode 100644 +--- /dev/null (revision 21290de8a4c91408de7c2b5b68757b1e90af49dd) ++++ b/src/net/internal/socktest/main_windows_test.go (revision 21290de8a4c91408de7c2b5b68757b1e90af49dd) +@@ -0,0 +1,22 @@ ++// Copyright 2015 The Go Authors. All rights reserved. ++// Use of this source code is governed by a BSD-style ++// license that can be found in the LICENSE file. ++ ++package socktest_test ++ ++import "syscall" ++ ++var ( ++ socketFunc func(int, int, int) (syscall.Handle, error) ++ closeFunc func(syscall.Handle) error ++) ++ ++func installTestHooks() { ++ socketFunc = sw.Socket ++ closeFunc = sw.Closesocket ++} ++ ++func uninstallTestHooks() { ++ socketFunc = syscall.Socket ++ closeFunc = syscall.Closesocket ++} +Index: src/net/internal/socktest/sys_windows.go +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +diff --git a/src/net/internal/socktest/sys_windows.go b/src/net/internal/socktest/sys_windows.go +--- a/src/net/internal/socktest/sys_windows.go (revision 9ac42137ef6730e8b7daca016ece831297a1d75b) ++++ b/src/net/internal/socktest/sys_windows.go (revision 21290de8a4c91408de7c2b5b68757b1e90af49dd) +@@ -9,6 +9,38 @@ + "syscall" + ) + ++// Socket wraps [syscall.Socket]. ++func (sw *Switch) Socket(family, sotype, proto int) (s syscall.Handle, err error) { ++ sw.once.Do(sw.init) ++ ++ so := &Status{Cookie: cookie(family, sotype, proto)} ++ sw.fmu.RLock() ++ f, _ := sw.fltab[FilterSocket] ++ sw.fmu.RUnlock() ++ ++ af, err := f.apply(so) ++ if err != nil { ++ return syscall.InvalidHandle, err ++ } ++ s, so.Err = syscall.Socket(family, sotype, proto) ++ if err = af.apply(so); err != nil { ++ if so.Err == nil { ++ syscall.Closesocket(s) ++ } ++ return syscall.InvalidHandle, err ++ } ++ ++ sw.smu.Lock() ++ defer sw.smu.Unlock() ++ if so.Err != nil { ++ sw.stats.getLocked(so.Cookie).OpenFailed++ ++ return syscall.InvalidHandle, so.Err ++ } ++ nso := sw.addLocked(s, family, sotype, proto) ++ sw.stats.getLocked(nso.Cookie).Opened++ ++ return s, nil ++} ++ + // WSASocket wraps [syscall.WSASocket]. + func (sw *Switch) WSASocket(family, sotype, proto int32, protinfo *syscall.WSAProtocolInfo, group uint32, flags uint32) (s syscall.Handle, err error) { + sw.once.Do(sw.init) +Index: src/net/main_windows_test.go +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +diff --git a/src/net/main_windows_test.go b/src/net/main_windows_test.go +--- a/src/net/main_windows_test.go (revision 9ac42137ef6730e8b7daca016ece831297a1d75b) ++++ b/src/net/main_windows_test.go (revision 21290de8a4c91408de7c2b5b68757b1e90af49dd) +@@ -8,6 +8,7 @@ + + var ( + // Placeholders for saving original socket system calls. ++ origSocket = socketFunc + origWSASocket = wsaSocketFunc + origClosesocket = poll.CloseFunc + origConnect = connectFunc +@@ -17,6 +18,7 @@ + ) + + func installTestHooks() { ++ socketFunc = sw.Socket + wsaSocketFunc = sw.WSASocket + poll.CloseFunc = sw.Closesocket + connectFunc = sw.Connect +@@ -26,6 +28,7 @@ + } + + func uninstallTestHooks() { ++ socketFunc = origSocket + wsaSocketFunc = origWSASocket + poll.CloseFunc = origClosesocket + connectFunc = origConnect +Index: src/net/sock_windows.go +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +diff --git a/src/net/sock_windows.go b/src/net/sock_windows.go +--- a/src/net/sock_windows.go (revision 9ac42137ef6730e8b7daca016ece831297a1d75b) ++++ b/src/net/sock_windows.go (revision 21290de8a4c91408de7c2b5b68757b1e90af49dd) +@@ -20,6 +20,21 @@ + func sysSocket(family, sotype, proto int) (syscall.Handle, error) { + s, err := wsaSocketFunc(int32(family), int32(sotype), int32(proto), + nil, 0, windows.WSA_FLAG_OVERLAPPED|windows.WSA_FLAG_NO_HANDLE_INHERIT) ++ if err == nil { ++ return s, nil ++ } ++ // WSA_FLAG_NO_HANDLE_INHERIT flag is not supported on some ++ // old versions of Windows, see ++ // https://msdn.microsoft.com/en-us/library/windows/desktop/ms742212(v=vs.85).aspx ++ // for details. Just use syscall.Socket, if windows.WSASocket failed. ++ ++ // See ../syscall/exec_unix.go for description of ForkLock. ++ syscall.ForkLock.RLock() ++ s, err = socketFunc(family, sotype, proto) ++ if err == nil { ++ syscall.CloseOnExec(s) ++ } ++ syscall.ForkLock.RUnlock() + if err != nil { + return syscall.InvalidHandle, os.NewSyscallError("socket", err) + } +Index: src/syscall/exec_windows.go +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +diff --git a/src/syscall/exec_windows.go b/src/syscall/exec_windows.go +--- a/src/syscall/exec_windows.go (revision 9ac42137ef6730e8b7daca016ece831297a1d75b) ++++ b/src/syscall/exec_windows.go (revision 6a31d3fa8e47ddabc10bd97bff10d9a85f4cfb76) +@@ -14,7 +14,6 @@ + "unsafe" + ) + +-// ForkLock is not used on Windows. + var ForkLock sync.RWMutex + + // EscapeArg rewrites command line argument s as prescribed +@@ -254,6 +253,9 @@ + var zeroProcAttr ProcAttr + var zeroSysProcAttr SysProcAttr + ++//go:linkname rtlGetNtVersionNumbers ++func rtlGetNtVersionNumbers(majorVersion *uint32, minorVersion *uint32, buildNumber *uint32) ++ + func StartProcess(argv0 string, argv []string, attr *ProcAttr) (pid int, handle uintptr, err error) { + if len(argv0) == 0 { + return 0, 0, EWINDOWS +@@ -317,6 +319,17 @@ + } + } + ++ var maj, min, build uint32 ++ rtlGetNtVersionNumbers(&maj, &min, &build) ++ isWin7 := maj < 6 || (maj == 6 && min <= 1) ++ // NT kernel handles are divisible by 4, with the bottom 3 bits left as ++ // a tag. The fully set tag correlates with the types of handles we're ++ // concerned about here. Except, the kernel will interpret some ++ // special handle values, like -1, -2, and so forth, so kernelbase.dll ++ // checks to see that those bottom three bits are checked, but that top ++ // bit is not checked. ++ isLegacyWin7ConsoleHandle := func(handle Handle) bool { return isWin7 && handle&0x10000003 == 3 } ++ + p, _ := GetCurrentProcess() + parentProcess := p + if sys.ParentProcess != 0 { +@@ -325,7 +338,15 @@ + fd := make([]Handle, len(attr.Files)) + for i := range attr.Files { + if attr.Files[i] > 0 { +- err := DuplicateHandle(p, Handle(attr.Files[i]), parentProcess, &fd[i], 0, true, DUPLICATE_SAME_ACCESS) ++ destinationProcessHandle := parentProcess ++ ++ // On Windows 7, console handles aren't real handles, and can only be duplicated ++ // into the current process, not a parent one, which amounts to the same thing. ++ if parentProcess != p && isLegacyWin7ConsoleHandle(Handle(attr.Files[i])) { ++ destinationProcessHandle = p ++ } ++ ++ err := DuplicateHandle(p, Handle(attr.Files[i]), destinationProcessHandle, &fd[i], 0, true, DUPLICATE_SAME_ACCESS) + if err != nil { + return 0, 0, err + } +@@ -356,6 +377,14 @@ + + fd = append(fd, sys.AdditionalInheritedHandles...) + ++ // On Windows 7, console handles aren't real handles, so don't pass them ++ // through to PROC_THREAD_ATTRIBUTE_HANDLE_LIST. ++ for i := range fd { ++ if isLegacyWin7ConsoleHandle(fd[i]) { ++ fd[i] = 0 ++ } ++ } ++ + // The presence of a NULL handle in the list is enough to cause PROC_THREAD_ATTRIBUTE_HANDLE_LIST + // to treat the entire list as empty, so remove NULL handles. + j := 0 +Index: src/runtime/syscall_windows.go +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +diff --git a/src/runtime/syscall_windows.go b/src/runtime/syscall_windows.go +--- a/src/runtime/syscall_windows.go (revision 6a31d3fa8e47ddabc10bd97bff10d9a85f4cfb76) ++++ b/src/runtime/syscall_windows.go (revision 69e2eed6dd0f6d815ebf15797761c13f31213dd6) +@@ -413,10 +413,20 @@ + + const _LOAD_LIBRARY_SEARCH_SYSTEM32 = 0x00000800 + ++// When available, this function will use LoadLibraryEx with the filename ++// parameter and the important SEARCH_SYSTEM32 argument. But on systems that ++// do not have that option, absoluteFilepath should contain a fallback ++// to the full path inside of system32 for use with vanilla LoadLibrary. ++// + //go:linkname syscall_loadsystemlibrary syscall.loadsystemlibrary +-func syscall_loadsystemlibrary(filename *uint16) (handle, err uintptr) { +- handle, _, err = syscall_SyscallN(uintptr(unsafe.Pointer(_LoadLibraryExW)), uintptr(unsafe.Pointer(filename)), 0, _LOAD_LIBRARY_SEARCH_SYSTEM32) ++func syscall_loadsystemlibrary(filename *uint16, absoluteFilepath *uint16) (handle, err uintptr) { ++ if useLoadLibraryEx { ++ handle, _, err = syscall_SyscallN(uintptr(unsafe.Pointer(_LoadLibraryExW)), uintptr(unsafe.Pointer(filename)), 0, _LOAD_LIBRARY_SEARCH_SYSTEM32) ++ } else { ++ handle, _, err = syscall_SyscallN(uintptr(unsafe.Pointer(_LoadLibraryW)), uintptr(unsafe.Pointer(absoluteFilepath))) ++ } + KeepAlive(filename) ++ KeepAlive(absoluteFilepath) + if handle != 0 { + err = 0 + } +Index: src/syscall/dll_windows.go +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +diff --git a/src/syscall/dll_windows.go b/src/syscall/dll_windows.go +--- a/src/syscall/dll_windows.go (revision 6a31d3fa8e47ddabc10bd97bff10d9a85f4cfb76) ++++ b/src/syscall/dll_windows.go (revision 69e2eed6dd0f6d815ebf15797761c13f31213dd6) +@@ -44,7 +44,7 @@ + + func SyscallN(trap uintptr, args ...uintptr) (r1, r2 uintptr, err Errno) + func loadlibrary(filename *uint16) (handle uintptr, err Errno) +-func loadsystemlibrary(filename *uint16) (handle uintptr, err Errno) ++func loadsystemlibrary(filename *uint16, absoluteFilepath *uint16) (handle uintptr, err Errno) + func getprocaddress(handle uintptr, procname *uint8) (proc uintptr, err Errno) + + // A DLL implements access to a single DLL. +@@ -53,6 +53,9 @@ + Handle Handle + } + ++//go:linkname getSystemDirectory ++func getSystemDirectory() string // Implemented in runtime package. ++ + // LoadDLL loads the named DLL file into memory. + // + // If name is not an absolute path and is not a known system DLL used by +@@ -69,7 +72,11 @@ + var h uintptr + var e Errno + if sysdll.IsSystemDLL[name] { +- h, e = loadsystemlibrary(namep) ++ absoluteFilepathp, err := UTF16PtrFromString(getSystemDirectory() + name) ++ if err != nil { ++ return nil, err ++ } ++ h, e = loadsystemlibrary(namep, absoluteFilepathp) + } else { + h, e = loadlibrary(namep) + } diff --git a/clash-meta-android/core/src/foss/golang/clash/.github/patch/go1.24.patch b/clash-meta-android/core/src/foss/golang/clash/.github/patch/go1.24.patch new file mode 100644 index 0000000000..ecfc99ff73 --- /dev/null +++ b/clash-meta-android/core/src/foss/golang/clash/.github/patch/go1.24.patch @@ -0,0 +1,657 @@ +Subject: [PATCH] Revert "runtime: always use LoadLibraryEx to load system libraries" +Revert "syscall: remove Windows 7 console handle workaround" +Revert "net: remove sysSocket fallback for Windows 7" +Revert "crypto/rand,runtime: switch RtlGenRandom for ProcessPrng" +--- +Index: src/crypto/internal/sysrand/rand_windows.go +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +diff --git a/src/crypto/internal/sysrand/rand_windows.go b/src/crypto/internal/sysrand/rand_windows.go +--- a/src/crypto/internal/sysrand/rand_windows.go (revision 3901409b5d0fb7c85a3e6730a59943cc93b2835c) ++++ b/src/crypto/internal/sysrand/rand_windows.go (revision 2a406dc9f1ea7323d6ca9fccb2fe9ddebb6b1cc8) +@@ -7,5 +7,26 @@ + import "internal/syscall/windows" + + func read(b []byte) error { +- return windows.ProcessPrng(b) ++ // RtlGenRandom only returns 1<<32-1 bytes at a time. We only read at ++ // most 1<<31-1 bytes at a time so that this works the same on 32-bit ++ // and 64-bit systems. ++ return batched(windows.RtlGenRandom, 1<<31-1)(b) ++} ++ ++// batched returns a function that calls f to populate a []byte by chunking it ++// into subslices of, at most, readMax bytes. ++func batched(f func([]byte) error, readMax int) func([]byte) error { ++ return func(out []byte) error { ++ for len(out) > 0 { ++ read := len(out) ++ if read > readMax { ++ read = readMax ++ } ++ if err := f(out[:read]); err != nil { ++ return err ++ } ++ out = out[read:] ++ } ++ return nil ++ } + } +Index: src/crypto/rand/rand.go +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +diff --git a/src/crypto/rand/rand.go b/src/crypto/rand/rand.go +--- a/src/crypto/rand/rand.go (revision 3901409b5d0fb7c85a3e6730a59943cc93b2835c) ++++ b/src/crypto/rand/rand.go (revision 2a406dc9f1ea7323d6ca9fccb2fe9ddebb6b1cc8) +@@ -22,7 +22,7 @@ + // - On legacy Linux (< 3.17), Reader opens /dev/urandom on first use. + // - On macOS, iOS, and OpenBSD Reader, uses arc4random_buf(3). + // - On NetBSD, Reader uses the kern.arandom sysctl. +-// - On Windows, Reader uses the ProcessPrng API. ++// - On Windows systems, Reader uses the RtlGenRandom API. + // - On js/wasm, Reader uses the Web Crypto API. + // - On wasip1/wasm, Reader uses random_get. + // +Index: src/internal/syscall/windows/syscall_windows.go +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +diff --git a/src/internal/syscall/windows/syscall_windows.go b/src/internal/syscall/windows/syscall_windows.go +--- a/src/internal/syscall/windows/syscall_windows.go (revision 3901409b5d0fb7c85a3e6730a59943cc93b2835c) ++++ b/src/internal/syscall/windows/syscall_windows.go (revision 2a406dc9f1ea7323d6ca9fccb2fe9ddebb6b1cc8) +@@ -416,7 +416,7 @@ + //sys DestroyEnvironmentBlock(block *uint16) (err error) = userenv.DestroyEnvironmentBlock + //sys CreateEvent(eventAttrs *SecurityAttributes, manualReset uint32, initialState uint32, name *uint16) (handle syscall.Handle, err error) = kernel32.CreateEventW + +-//sys ProcessPrng(buf []byte) (err error) = bcryptprimitives.ProcessPrng ++//sys RtlGenRandom(buf []byte) (err error) = advapi32.SystemFunction036 + + type FILE_ID_BOTH_DIR_INFO struct { + NextEntryOffset uint32 +Index: src/internal/syscall/windows/zsyscall_windows.go +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +diff --git a/src/internal/syscall/windows/zsyscall_windows.go b/src/internal/syscall/windows/zsyscall_windows.go +--- a/src/internal/syscall/windows/zsyscall_windows.go (revision 3901409b5d0fb7c85a3e6730a59943cc93b2835c) ++++ b/src/internal/syscall/windows/zsyscall_windows.go (revision 2a406dc9f1ea7323d6ca9fccb2fe9ddebb6b1cc8) +@@ -38,7 +38,6 @@ + + var ( + modadvapi32 = syscall.NewLazyDLL(sysdll.Add("advapi32.dll")) +- modbcryptprimitives = syscall.NewLazyDLL(sysdll.Add("bcryptprimitives.dll")) + modiphlpapi = syscall.NewLazyDLL(sysdll.Add("iphlpapi.dll")) + modkernel32 = syscall.NewLazyDLL(sysdll.Add("kernel32.dll")) + modnetapi32 = syscall.NewLazyDLL(sysdll.Add("netapi32.dll")) +@@ -63,7 +62,7 @@ + procQueryServiceStatus = modadvapi32.NewProc("QueryServiceStatus") + procRevertToSelf = modadvapi32.NewProc("RevertToSelf") + procSetTokenInformation = modadvapi32.NewProc("SetTokenInformation") +- procProcessPrng = modbcryptprimitives.NewProc("ProcessPrng") ++ procSystemFunction036 = modadvapi32.NewProc("SystemFunction036") + procGetAdaptersAddresses = modiphlpapi.NewProc("GetAdaptersAddresses") + procCreateEventW = modkernel32.NewProc("CreateEventW") + procGetACP = modkernel32.NewProc("GetACP") +@@ -236,12 +235,12 @@ + return + } + +-func ProcessPrng(buf []byte) (err error) { ++func RtlGenRandom(buf []byte) (err error) { + var _p0 *byte + if len(buf) > 0 { + _p0 = &buf[0] + } +- r1, _, e1 := syscall.Syscall(procProcessPrng.Addr(), 2, uintptr(unsafe.Pointer(_p0)), uintptr(len(buf)), 0) ++ r1, _, e1 := syscall.Syscall(procSystemFunction036.Addr(), 2, uintptr(unsafe.Pointer(_p0)), uintptr(len(buf)), 0) + if r1 == 0 { + err = errnoErr(e1) + } +Index: src/runtime/os_windows.go +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +diff --git a/src/runtime/os_windows.go b/src/runtime/os_windows.go +--- a/src/runtime/os_windows.go (revision 3901409b5d0fb7c85a3e6730a59943cc93b2835c) ++++ b/src/runtime/os_windows.go (revision ac3e93c061779dfefc0dd13a5b6e6f764a25621e) +@@ -40,8 +40,8 @@ + //go:cgo_import_dynamic runtime._GetSystemInfo GetSystemInfo%1 "kernel32.dll" + //go:cgo_import_dynamic runtime._GetThreadContext GetThreadContext%2 "kernel32.dll" + //go:cgo_import_dynamic runtime._SetThreadContext SetThreadContext%2 "kernel32.dll" +-//go:cgo_import_dynamic runtime._LoadLibraryExW LoadLibraryExW%3 "kernel32.dll" + //go:cgo_import_dynamic runtime._LoadLibraryW LoadLibraryW%1 "kernel32.dll" ++//go:cgo_import_dynamic runtime._LoadLibraryA LoadLibraryA%1 "kernel32.dll" + //go:cgo_import_dynamic runtime._PostQueuedCompletionStatus PostQueuedCompletionStatus%4 "kernel32.dll" + //go:cgo_import_dynamic runtime._QueryPerformanceCounter QueryPerformanceCounter%1 "kernel32.dll" + //go:cgo_import_dynamic runtime._QueryPerformanceFrequency QueryPerformanceFrequency%1 "kernel32.dll" +@@ -75,7 +75,6 @@ + // Following syscalls are available on every Windows PC. + // All these variables are set by the Windows executable + // loader before the Go program starts. +- _AddVectoredContinueHandler, + _AddVectoredExceptionHandler, + _CloseHandle, + _CreateEventA, +@@ -98,8 +97,8 @@ + _GetSystemInfo, + _GetThreadContext, + _SetThreadContext, +- _LoadLibraryExW, + _LoadLibraryW, ++ _LoadLibraryA, + _PostQueuedCompletionStatus, + _QueryPerformanceCounter, + _QueryPerformanceFrequency, +@@ -128,8 +127,23 @@ + _WriteFile, + _ stdFunction + +- // Use ProcessPrng to generate cryptographically random data. +- _ProcessPrng stdFunction ++ // Following syscalls are only available on some Windows PCs. ++ // We will load syscalls, if available, before using them. ++ _AddDllDirectory, ++ _AddVectoredContinueHandler, ++ _LoadLibraryExA, ++ _LoadLibraryExW, ++ _ stdFunction ++ ++ // Use RtlGenRandom to generate cryptographically random data. ++ // This approach has been recommended by Microsoft (see issue ++ // 15589 for details). ++ // The RtlGenRandom is not listed in advapi32.dll, instead ++ // RtlGenRandom function can be found by searching for SystemFunction036. ++ // Also some versions of Mingw cannot link to SystemFunction036 ++ // when building executable as Cgo. So load SystemFunction036 ++ // manually during runtime startup. ++ _RtlGenRandom stdFunction + + // Load ntdll.dll manually during startup, otherwise Mingw + // links wrong printf function to cgo executable (see issue +@@ -146,13 +160,6 @@ + _ stdFunction + ) + +-var ( +- bcryptprimitivesdll = [...]uint16{'b', 'c', 'r', 'y', 'p', 't', 'p', 'r', 'i', 'm', 'i', 't', 'i', 'v', 'e', 's', '.', 'd', 'l', 'l', 0} +- ntdlldll = [...]uint16{'n', 't', 'd', 'l', 'l', '.', 'd', 'l', 'l', 0} +- powrprofdll = [...]uint16{'p', 'o', 'w', 'r', 'p', 'r', 'o', 'f', '.', 'd', 'l', 'l', 0} +- winmmdll = [...]uint16{'w', 'i', 'n', 'm', 'm', '.', 'd', 'l', 'l', 0} +-) +- + // Function to be called by windows CreateThread + // to start new os thread. + func tstart_stdcall(newm *m) +@@ -245,8 +252,18 @@ + return unsafe.String(&sysDirectory[0], sysDirectoryLen) + } + +-func windowsLoadSystemLib(name []uint16) uintptr { +- return stdcall3(_LoadLibraryExW, uintptr(unsafe.Pointer(&name[0])), 0, _LOAD_LIBRARY_SEARCH_SYSTEM32) ++//go:linkname syscall_getSystemDirectory syscall.getSystemDirectory ++func syscall_getSystemDirectory() string { ++ return unsafe.String(&sysDirectory[0], sysDirectoryLen) ++} ++ ++func windowsLoadSystemLib(name []byte) uintptr { ++ if useLoadLibraryEx { ++ return stdcall3(_LoadLibraryExA, uintptr(unsafe.Pointer(&name[0])), 0, _LOAD_LIBRARY_SEARCH_SYSTEM32) ++ } else { ++ absName := append(sysDirectory[:sysDirectoryLen], name...) ++ return stdcall1(_LoadLibraryA, uintptr(unsafe.Pointer(&absName[0]))) ++ } + } + + //go:linkname windows_QueryPerformanceCounter internal/syscall/windows.QueryPerformanceCounter +@@ -264,13 +281,28 @@ + } + + func loadOptionalSyscalls() { +- bcryptPrimitives := windowsLoadSystemLib(bcryptprimitivesdll[:]) +- if bcryptPrimitives == 0 { +- throw("bcryptprimitives.dll not found") ++ var kernel32dll = []byte("kernel32.dll\000") ++ k32 := stdcall1(_LoadLibraryA, uintptr(unsafe.Pointer(&kernel32dll[0]))) ++ if k32 == 0 { ++ throw("kernel32.dll not found") + } +- _ProcessPrng = windowsFindfunc(bcryptPrimitives, []byte("ProcessPrng\000")) ++ _AddDllDirectory = windowsFindfunc(k32, []byte("AddDllDirectory\000")) ++ _AddVectoredContinueHandler = windowsFindfunc(k32, []byte("AddVectoredContinueHandler\000")) ++ _LoadLibraryExA = windowsFindfunc(k32, []byte("LoadLibraryExA\000")) ++ _LoadLibraryExW = windowsFindfunc(k32, []byte("LoadLibraryExW\000")) ++ useLoadLibraryEx = (_LoadLibraryExW != nil && _LoadLibraryExA != nil && _AddDllDirectory != nil) ++ ++ initSysDirectory() + +- n32 := windowsLoadSystemLib(ntdlldll[:]) ++ var advapi32dll = []byte("advapi32.dll\000") ++ a32 := windowsLoadSystemLib(advapi32dll) ++ if a32 == 0 { ++ throw("advapi32.dll not found") ++ } ++ _RtlGenRandom = windowsFindfunc(a32, []byte("SystemFunction036\000")) ++ ++ var ntdll = []byte("ntdll.dll\000") ++ n32 := windowsLoadSystemLib(ntdll) + if n32 == 0 { + throw("ntdll.dll not found") + } +@@ -299,7 +331,7 @@ + context uintptr + } + +- powrprof := windowsLoadSystemLib(powrprofdll[:]) ++ powrprof := windowsLoadSystemLib([]byte("powrprof.dll\000")) + if powrprof == 0 { + return // Running on Windows 7, where we don't need it anyway. + } +@@ -358,6 +390,22 @@ + // in sys_windows_386.s and sys_windows_amd64.s: + func getlasterror() uint32 + ++// When loading DLLs, we prefer to use LoadLibraryEx with ++// LOAD_LIBRARY_SEARCH_* flags, if available. LoadLibraryEx is not ++// available on old Windows, though, and the LOAD_LIBRARY_SEARCH_* ++// flags are not available on some versions of Windows without a ++// security patch. ++// ++// https://msdn.microsoft.com/en-us/library/ms684179(v=vs.85).aspx says: ++// "Windows 7, Windows Server 2008 R2, Windows Vista, and Windows ++// Server 2008: The LOAD_LIBRARY_SEARCH_* flags are available on ++// systems that have KB2533623 installed. To determine whether the ++// flags are available, use GetProcAddress to get the address of the ++// AddDllDirectory, RemoveDllDirectory, or SetDefaultDllDirectories ++// function. If GetProcAddress succeeds, the LOAD_LIBRARY_SEARCH_* ++// flags can be used with LoadLibraryEx." ++var useLoadLibraryEx bool ++ + var timeBeginPeriodRetValue uint32 + + // osRelaxMinNS indicates that sysmon shouldn't osRelax if the next +@@ -431,7 +479,8 @@ + // Only load winmm.dll if we need it. + // This avoids a dependency on winmm.dll for Go programs + // that run on new Windows versions. +- m32 := windowsLoadSystemLib(winmmdll[:]) ++ var winmmdll = []byte("winmm.dll\000") ++ m32 := windowsLoadSystemLib(winmmdll) + if m32 == 0 { + print("runtime: LoadLibraryExW failed; errno=", getlasterror(), "\n") + throw("winmm.dll not found") +@@ -472,6 +521,28 @@ + canUseLongPaths = true + } + ++var osVersionInfo struct { ++ majorVersion uint32 ++ minorVersion uint32 ++ buildNumber uint32 ++} ++ ++func initOsVersionInfo() { ++ info := _OSVERSIONINFOW{} ++ info.osVersionInfoSize = uint32(unsafe.Sizeof(info)) ++ stdcall1(_RtlGetVersion, uintptr(unsafe.Pointer(&info))) ++ osVersionInfo.majorVersion = info.majorVersion ++ osVersionInfo.minorVersion = info.minorVersion ++ osVersionInfo.buildNumber = info.buildNumber ++} ++ ++//go:linkname rtlGetNtVersionNumbers syscall.rtlGetNtVersionNumbers ++func rtlGetNtVersionNumbers(majorVersion *uint32, minorVersion *uint32, buildNumber *uint32) { ++ *majorVersion = osVersionInfo.majorVersion ++ *minorVersion = osVersionInfo.minorVersion ++ *buildNumber = osVersionInfo.buildNumber ++} ++ + func osinit() { + asmstdcallAddr = unsafe.Pointer(abi.FuncPCABI0(asmstdcall)) + +@@ -484,8 +555,8 @@ + initHighResTimer() + timeBeginPeriodRetValue = osRelax(false) + +- initSysDirectory() + initLongPathSupport() ++ initOsVersionInfo() + + ncpu = getproccount() + +@@ -501,7 +572,7 @@ + //go:nosplit + func readRandom(r []byte) int { + n := 0 +- if stdcall2(_ProcessPrng, uintptr(unsafe.Pointer(&r[0])), uintptr(len(r)))&0xff != 0 { ++ if stdcall2(_RtlGenRandom, uintptr(unsafe.Pointer(&r[0])), uintptr(len(r)))&0xff != 0 { + n = len(r) + } + return n +Index: src/net/hook_windows.go +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +diff --git a/src/net/hook_windows.go b/src/net/hook_windows.go +--- a/src/net/hook_windows.go (revision 2a406dc9f1ea7323d6ca9fccb2fe9ddebb6b1cc8) ++++ b/src/net/hook_windows.go (revision 7b1fd7d39c6be0185fbe1d929578ab372ac5c632) +@@ -13,6 +13,7 @@ + hostsFilePath = windows.GetSystemDirectory() + "/Drivers/etc/hosts" + + // Placeholders for socket system calls. ++ socketFunc func(int, int, int) (syscall.Handle, error) = syscall.Socket + wsaSocketFunc func(int32, int32, int32, *syscall.WSAProtocolInfo, uint32, uint32) (syscall.Handle, error) = windows.WSASocket + connectFunc func(syscall.Handle, syscall.Sockaddr) error = syscall.Connect + listenFunc func(syscall.Handle, int) error = syscall.Listen +Index: src/net/internal/socktest/main_test.go +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +diff --git a/src/net/internal/socktest/main_test.go b/src/net/internal/socktest/main_test.go +--- a/src/net/internal/socktest/main_test.go (revision 2a406dc9f1ea7323d6ca9fccb2fe9ddebb6b1cc8) ++++ b/src/net/internal/socktest/main_test.go (revision 7b1fd7d39c6be0185fbe1d929578ab372ac5c632) +@@ -2,7 +2,7 @@ + // Use of this source code is governed by a BSD-style + // license that can be found in the LICENSE file. + +-//go:build !js && !plan9 && !wasip1 && !windows ++//go:build !js && !plan9 && !wasip1 + + package socktest_test + +Index: src/net/internal/socktest/main_windows_test.go +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +diff --git a/src/net/internal/socktest/main_windows_test.go b/src/net/internal/socktest/main_windows_test.go +new file mode 100644 +--- /dev/null (revision 7b1fd7d39c6be0185fbe1d929578ab372ac5c632) ++++ b/src/net/internal/socktest/main_windows_test.go (revision 7b1fd7d39c6be0185fbe1d929578ab372ac5c632) +@@ -0,0 +1,22 @@ ++// Copyright 2015 The Go Authors. All rights reserved. ++// Use of this source code is governed by a BSD-style ++// license that can be found in the LICENSE file. ++ ++package socktest_test ++ ++import "syscall" ++ ++var ( ++ socketFunc func(int, int, int) (syscall.Handle, error) ++ closeFunc func(syscall.Handle) error ++) ++ ++func installTestHooks() { ++ socketFunc = sw.Socket ++ closeFunc = sw.Closesocket ++} ++ ++func uninstallTestHooks() { ++ socketFunc = syscall.Socket ++ closeFunc = syscall.Closesocket ++} +Index: src/net/internal/socktest/sys_windows.go +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +diff --git a/src/net/internal/socktest/sys_windows.go b/src/net/internal/socktest/sys_windows.go +--- a/src/net/internal/socktest/sys_windows.go (revision 2a406dc9f1ea7323d6ca9fccb2fe9ddebb6b1cc8) ++++ b/src/net/internal/socktest/sys_windows.go (revision 7b1fd7d39c6be0185fbe1d929578ab372ac5c632) +@@ -9,6 +9,38 @@ + "syscall" + ) + ++// Socket wraps [syscall.Socket]. ++func (sw *Switch) Socket(family, sotype, proto int) (s syscall.Handle, err error) { ++ sw.once.Do(sw.init) ++ ++ so := &Status{Cookie: cookie(family, sotype, proto)} ++ sw.fmu.RLock() ++ f, _ := sw.fltab[FilterSocket] ++ sw.fmu.RUnlock() ++ ++ af, err := f.apply(so) ++ if err != nil { ++ return syscall.InvalidHandle, err ++ } ++ s, so.Err = syscall.Socket(family, sotype, proto) ++ if err = af.apply(so); err != nil { ++ if so.Err == nil { ++ syscall.Closesocket(s) ++ } ++ return syscall.InvalidHandle, err ++ } ++ ++ sw.smu.Lock() ++ defer sw.smu.Unlock() ++ if so.Err != nil { ++ sw.stats.getLocked(so.Cookie).OpenFailed++ ++ return syscall.InvalidHandle, so.Err ++ } ++ nso := sw.addLocked(s, family, sotype, proto) ++ sw.stats.getLocked(nso.Cookie).Opened++ ++ return s, nil ++} ++ + // WSASocket wraps [syscall.WSASocket]. + func (sw *Switch) WSASocket(family, sotype, proto int32, protinfo *syscall.WSAProtocolInfo, group uint32, flags uint32) (s syscall.Handle, err error) { + sw.once.Do(sw.init) +Index: src/net/main_windows_test.go +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +diff --git a/src/net/main_windows_test.go b/src/net/main_windows_test.go +--- a/src/net/main_windows_test.go (revision 2a406dc9f1ea7323d6ca9fccb2fe9ddebb6b1cc8) ++++ b/src/net/main_windows_test.go (revision 7b1fd7d39c6be0185fbe1d929578ab372ac5c632) +@@ -8,6 +8,7 @@ + + var ( + // Placeholders for saving original socket system calls. ++ origSocket = socketFunc + origWSASocket = wsaSocketFunc + origClosesocket = poll.CloseFunc + origConnect = connectFunc +@@ -17,6 +18,7 @@ + ) + + func installTestHooks() { ++ socketFunc = sw.Socket + wsaSocketFunc = sw.WSASocket + poll.CloseFunc = sw.Closesocket + connectFunc = sw.Connect +@@ -26,6 +28,7 @@ + } + + func uninstallTestHooks() { ++ socketFunc = origSocket + wsaSocketFunc = origWSASocket + poll.CloseFunc = origClosesocket + connectFunc = origConnect +Index: src/net/sock_windows.go +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +diff --git a/src/net/sock_windows.go b/src/net/sock_windows.go +--- a/src/net/sock_windows.go (revision 2a406dc9f1ea7323d6ca9fccb2fe9ddebb6b1cc8) ++++ b/src/net/sock_windows.go (revision 7b1fd7d39c6be0185fbe1d929578ab372ac5c632) +@@ -20,6 +20,21 @@ + func sysSocket(family, sotype, proto int) (syscall.Handle, error) { + s, err := wsaSocketFunc(int32(family), int32(sotype), int32(proto), + nil, 0, windows.WSA_FLAG_OVERLAPPED|windows.WSA_FLAG_NO_HANDLE_INHERIT) ++ if err == nil { ++ return s, nil ++ } ++ // WSA_FLAG_NO_HANDLE_INHERIT flag is not supported on some ++ // old versions of Windows, see ++ // https://msdn.microsoft.com/en-us/library/windows/desktop/ms742212(v=vs.85).aspx ++ // for details. Just use syscall.Socket, if windows.WSASocket failed. ++ ++ // See ../syscall/exec_unix.go for description of ForkLock. ++ syscall.ForkLock.RLock() ++ s, err = socketFunc(family, sotype, proto) ++ if err == nil { ++ syscall.CloseOnExec(s) ++ } ++ syscall.ForkLock.RUnlock() + if err != nil { + return syscall.InvalidHandle, os.NewSyscallError("socket", err) + } +Index: src/syscall/exec_windows.go +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +diff --git a/src/syscall/exec_windows.go b/src/syscall/exec_windows.go +--- a/src/syscall/exec_windows.go (revision 2a406dc9f1ea7323d6ca9fccb2fe9ddebb6b1cc8) ++++ b/src/syscall/exec_windows.go (revision 979d6d8bab3823ff572ace26767fd2ce3cf351ae) +@@ -14,7 +14,6 @@ + "unsafe" + ) + +-// ForkLock is not used on Windows. + var ForkLock sync.RWMutex + + // EscapeArg rewrites command line argument s as prescribed +@@ -254,6 +253,9 @@ + var zeroProcAttr ProcAttr + var zeroSysProcAttr SysProcAttr + ++//go:linkname rtlGetNtVersionNumbers ++func rtlGetNtVersionNumbers(majorVersion *uint32, minorVersion *uint32, buildNumber *uint32) ++ + func StartProcess(argv0 string, argv []string, attr *ProcAttr) (pid int, handle uintptr, err error) { + if len(argv0) == 0 { + return 0, 0, EWINDOWS +@@ -317,6 +319,17 @@ + } + } + ++ var maj, min, build uint32 ++ rtlGetNtVersionNumbers(&maj, &min, &build) ++ isWin7 := maj < 6 || (maj == 6 && min <= 1) ++ // NT kernel handles are divisible by 4, with the bottom 3 bits left as ++ // a tag. The fully set tag correlates with the types of handles we're ++ // concerned about here. Except, the kernel will interpret some ++ // special handle values, like -1, -2, and so forth, so kernelbase.dll ++ // checks to see that those bottom three bits are checked, but that top ++ // bit is not checked. ++ isLegacyWin7ConsoleHandle := func(handle Handle) bool { return isWin7 && handle&0x10000003 == 3 } ++ + p, _ := GetCurrentProcess() + parentProcess := p + if sys.ParentProcess != 0 { +@@ -325,7 +338,15 @@ + fd := make([]Handle, len(attr.Files)) + for i := range attr.Files { + if attr.Files[i] > 0 { +- err := DuplicateHandle(p, Handle(attr.Files[i]), parentProcess, &fd[i], 0, true, DUPLICATE_SAME_ACCESS) ++ destinationProcessHandle := parentProcess ++ ++ // On Windows 7, console handles aren't real handles, and can only be duplicated ++ // into the current process, not a parent one, which amounts to the same thing. ++ if parentProcess != p && isLegacyWin7ConsoleHandle(Handle(attr.Files[i])) { ++ destinationProcessHandle = p ++ } ++ ++ err := DuplicateHandle(p, Handle(attr.Files[i]), destinationProcessHandle, &fd[i], 0, true, DUPLICATE_SAME_ACCESS) + if err != nil { + return 0, 0, err + } +@@ -356,6 +377,14 @@ + + fd = append(fd, sys.AdditionalInheritedHandles...) + ++ // On Windows 7, console handles aren't real handles, so don't pass them ++ // through to PROC_THREAD_ATTRIBUTE_HANDLE_LIST. ++ for i := range fd { ++ if isLegacyWin7ConsoleHandle(fd[i]) { ++ fd[i] = 0 ++ } ++ } ++ + // The presence of a NULL handle in the list is enough to cause PROC_THREAD_ATTRIBUTE_HANDLE_LIST + // to treat the entire list as empty, so remove NULL handles. + j := 0 +Index: src/runtime/syscall_windows.go +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +diff --git a/src/runtime/syscall_windows.go b/src/runtime/syscall_windows.go +--- a/src/runtime/syscall_windows.go (revision 979d6d8bab3823ff572ace26767fd2ce3cf351ae) ++++ b/src/runtime/syscall_windows.go (revision ac3e93c061779dfefc0dd13a5b6e6f764a25621e) +@@ -413,10 +413,20 @@ + + const _LOAD_LIBRARY_SEARCH_SYSTEM32 = 0x00000800 + ++// When available, this function will use LoadLibraryEx with the filename ++// parameter and the important SEARCH_SYSTEM32 argument. But on systems that ++// do not have that option, absoluteFilepath should contain a fallback ++// to the full path inside of system32 for use with vanilla LoadLibrary. ++// + //go:linkname syscall_loadsystemlibrary syscall.loadsystemlibrary +-func syscall_loadsystemlibrary(filename *uint16) (handle, err uintptr) { +- handle, _, err = syscall_SyscallN(uintptr(unsafe.Pointer(_LoadLibraryExW)), uintptr(unsafe.Pointer(filename)), 0, _LOAD_LIBRARY_SEARCH_SYSTEM32) ++func syscall_loadsystemlibrary(filename *uint16, absoluteFilepath *uint16) (handle, err uintptr) { ++ if useLoadLibraryEx { ++ handle, _, err = syscall_SyscallN(uintptr(unsafe.Pointer(_LoadLibraryExW)), uintptr(unsafe.Pointer(filename)), 0, _LOAD_LIBRARY_SEARCH_SYSTEM32) ++ } else { ++ handle, _, err = syscall_SyscallN(uintptr(unsafe.Pointer(_LoadLibraryW)), uintptr(unsafe.Pointer(absoluteFilepath))) ++ } + KeepAlive(filename) ++ KeepAlive(absoluteFilepath) + if handle != 0 { + err = 0 + } +Index: src/syscall/dll_windows.go +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +diff --git a/src/syscall/dll_windows.go b/src/syscall/dll_windows.go +--- a/src/syscall/dll_windows.go (revision 979d6d8bab3823ff572ace26767fd2ce3cf351ae) ++++ b/src/syscall/dll_windows.go (revision ac3e93c061779dfefc0dd13a5b6e6f764a25621e) +@@ -45,7 +45,7 @@ + //go:noescape + func SyscallN(trap uintptr, args ...uintptr) (r1, r2 uintptr, err Errno) + func loadlibrary(filename *uint16) (handle uintptr, err Errno) +-func loadsystemlibrary(filename *uint16) (handle uintptr, err Errno) ++func loadsystemlibrary(filename *uint16, absoluteFilepath *uint16) (handle uintptr, err Errno) + func getprocaddress(handle uintptr, procname *uint8) (proc uintptr, err Errno) + + // A DLL implements access to a single DLL. +@@ -54,6 +54,9 @@ + Handle Handle + } + ++//go:linkname getSystemDirectory ++func getSystemDirectory() string // Implemented in runtime package. ++ + // LoadDLL loads the named DLL file into memory. + // + // If name is not an absolute path and is not a known system DLL used by +@@ -70,7 +73,11 @@ + var h uintptr + var e Errno + if sysdll.IsSystemDLL[name] { +- h, e = loadsystemlibrary(namep) ++ absoluteFilepathp, err := UTF16PtrFromString(getSystemDirectory() + name) ++ if err != nil { ++ return nil, err ++ } ++ h, e = loadsystemlibrary(namep, absoluteFilepathp) + } else { + h, e = loadlibrary(namep) + } diff --git a/clash-meta-android/core/src/foss/golang/clash/.github/patch/go1.25.patch b/clash-meta-android/core/src/foss/golang/clash/.github/patch/go1.25.patch new file mode 100644 index 0000000000..626779dbdd --- /dev/null +++ b/clash-meta-android/core/src/foss/golang/clash/.github/patch/go1.25.patch @@ -0,0 +1,657 @@ +Subject: [PATCH] Revert "runtime: always use LoadLibraryEx to load system libraries" +Revert "syscall: remove Windows 7 console handle workaround" +Revert "net: remove sysSocket fallback for Windows 7" +Revert "crypto/rand,runtime: switch RtlGenRandom for ProcessPrng" +--- +Index: src/crypto/internal/sysrand/rand_windows.go +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +diff --git a/src/crypto/internal/sysrand/rand_windows.go b/src/crypto/internal/sysrand/rand_windows.go +--- a/src/crypto/internal/sysrand/rand_windows.go (revision 6e676ab2b809d46623acb5988248d95d1eb7939c) ++++ b/src/crypto/internal/sysrand/rand_windows.go (revision 8cb5472d94c34b88733a81091bd328e70ee565a4) +@@ -7,5 +7,26 @@ + import "internal/syscall/windows" + + func read(b []byte) error { +- return windows.ProcessPrng(b) ++ // RtlGenRandom only returns 1<<32-1 bytes at a time. We only read at ++ // most 1<<31-1 bytes at a time so that this works the same on 32-bit ++ // and 64-bit systems. ++ return batched(windows.RtlGenRandom, 1<<31-1)(b) ++} ++ ++// batched returns a function that calls f to populate a []byte by chunking it ++// into subslices of, at most, readMax bytes. ++func batched(f func([]byte) error, readMax int) func([]byte) error { ++ return func(out []byte) error { ++ for len(out) > 0 { ++ read := len(out) ++ if read > readMax { ++ read = readMax ++ } ++ if err := f(out[:read]); err != nil { ++ return err ++ } ++ out = out[read:] ++ } ++ return nil ++ } + } +Index: src/crypto/rand/rand.go +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +diff --git a/src/crypto/rand/rand.go b/src/crypto/rand/rand.go +--- a/src/crypto/rand/rand.go (revision 6e676ab2b809d46623acb5988248d95d1eb7939c) ++++ b/src/crypto/rand/rand.go (revision 8cb5472d94c34b88733a81091bd328e70ee565a4) +@@ -22,7 +22,7 @@ + // - On legacy Linux (< 3.17), Reader opens /dev/urandom on first use. + // - On macOS, iOS, and OpenBSD Reader, uses arc4random_buf(3). + // - On NetBSD, Reader uses the kern.arandom sysctl. +-// - On Windows, Reader uses the ProcessPrng API. ++// - On Windows systems, Reader uses the RtlGenRandom API. + // - On js/wasm, Reader uses the Web Crypto API. + // - On wasip1/wasm, Reader uses random_get. + // +Index: src/internal/syscall/windows/syscall_windows.go +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +diff --git a/src/internal/syscall/windows/syscall_windows.go b/src/internal/syscall/windows/syscall_windows.go +--- a/src/internal/syscall/windows/syscall_windows.go (revision 6e676ab2b809d46623acb5988248d95d1eb7939c) ++++ b/src/internal/syscall/windows/syscall_windows.go (revision 8cb5472d94c34b88733a81091bd328e70ee565a4) +@@ -419,7 +419,7 @@ + //sys DestroyEnvironmentBlock(block *uint16) (err error) = userenv.DestroyEnvironmentBlock + //sys CreateEvent(eventAttrs *SecurityAttributes, manualReset uint32, initialState uint32, name *uint16) (handle syscall.Handle, err error) = kernel32.CreateEventW + +-//sys ProcessPrng(buf []byte) (err error) = bcryptprimitives.ProcessPrng ++//sys RtlGenRandom(buf []byte) (err error) = advapi32.SystemFunction036 + + type FILE_ID_BOTH_DIR_INFO struct { + NextEntryOffset uint32 +Index: src/internal/syscall/windows/zsyscall_windows.go +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +diff --git a/src/internal/syscall/windows/zsyscall_windows.go b/src/internal/syscall/windows/zsyscall_windows.go +--- a/src/internal/syscall/windows/zsyscall_windows.go (revision 6e676ab2b809d46623acb5988248d95d1eb7939c) ++++ b/src/internal/syscall/windows/zsyscall_windows.go (revision 8cb5472d94c34b88733a81091bd328e70ee565a4) +@@ -38,7 +38,6 @@ + + var ( + modadvapi32 = syscall.NewLazyDLL(sysdll.Add("advapi32.dll")) +- modbcryptprimitives = syscall.NewLazyDLL(sysdll.Add("bcryptprimitives.dll")) + modiphlpapi = syscall.NewLazyDLL(sysdll.Add("iphlpapi.dll")) + modkernel32 = syscall.NewLazyDLL(sysdll.Add("kernel32.dll")) + modnetapi32 = syscall.NewLazyDLL(sysdll.Add("netapi32.dll")) +@@ -63,7 +62,7 @@ + procQueryServiceStatus = modadvapi32.NewProc("QueryServiceStatus") + procRevertToSelf = modadvapi32.NewProc("RevertToSelf") + procSetTokenInformation = modadvapi32.NewProc("SetTokenInformation") +- procProcessPrng = modbcryptprimitives.NewProc("ProcessPrng") ++ procSystemFunction036 = modadvapi32.NewProc("SystemFunction036") + procGetAdaptersAddresses = modiphlpapi.NewProc("GetAdaptersAddresses") + procCreateEventW = modkernel32.NewProc("CreateEventW") + procCreateIoCompletionPort = modkernel32.NewProc("CreateIoCompletionPort") +@@ -242,12 +241,12 @@ + return + } + +-func ProcessPrng(buf []byte) (err error) { ++func RtlGenRandom(buf []byte) (err error) { + var _p0 *byte + if len(buf) > 0 { + _p0 = &buf[0] + } +- r1, _, e1 := syscall.Syscall(procProcessPrng.Addr(), 2, uintptr(unsafe.Pointer(_p0)), uintptr(len(buf)), 0) ++ r1, _, e1 := syscall.Syscall(procSystemFunction036.Addr(), 2, uintptr(unsafe.Pointer(_p0)), uintptr(len(buf)), 0) + if r1 == 0 { + err = errnoErr(e1) + } +Index: src/runtime/os_windows.go +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +diff --git a/src/runtime/os_windows.go b/src/runtime/os_windows.go +--- a/src/runtime/os_windows.go (revision 6e676ab2b809d46623acb5988248d95d1eb7939c) ++++ b/src/runtime/os_windows.go (revision f56f1e23507e646c85243a71bde7b9629b2f970c) +@@ -39,8 +39,8 @@ + //go:cgo_import_dynamic runtime._GetSystemInfo GetSystemInfo%1 "kernel32.dll" + //go:cgo_import_dynamic runtime._GetThreadContext GetThreadContext%2 "kernel32.dll" + //go:cgo_import_dynamic runtime._SetThreadContext SetThreadContext%2 "kernel32.dll" +-//go:cgo_import_dynamic runtime._LoadLibraryExW LoadLibraryExW%3 "kernel32.dll" + //go:cgo_import_dynamic runtime._LoadLibraryW LoadLibraryW%1 "kernel32.dll" ++//go:cgo_import_dynamic runtime._LoadLibraryA LoadLibraryA%1 "kernel32.dll" + //go:cgo_import_dynamic runtime._PostQueuedCompletionStatus PostQueuedCompletionStatus%4 "kernel32.dll" + //go:cgo_import_dynamic runtime._QueryPerformanceCounter QueryPerformanceCounter%1 "kernel32.dll" + //go:cgo_import_dynamic runtime._QueryPerformanceFrequency QueryPerformanceFrequency%1 "kernel32.dll" +@@ -74,7 +74,6 @@ + // Following syscalls are available on every Windows PC. + // All these variables are set by the Windows executable + // loader before the Go program starts. +- _AddVectoredContinueHandler, + _AddVectoredExceptionHandler, + _CloseHandle, + _CreateEventA, +@@ -97,8 +96,8 @@ + _GetSystemInfo, + _GetThreadContext, + _SetThreadContext, +- _LoadLibraryExW, + _LoadLibraryW, ++ _LoadLibraryA, + _PostQueuedCompletionStatus, + _QueryPerformanceCounter, + _QueryPerformanceFrequency, +@@ -127,8 +126,23 @@ + _WriteFile, + _ stdFunction + +- // Use ProcessPrng to generate cryptographically random data. +- _ProcessPrng stdFunction ++ // Following syscalls are only available on some Windows PCs. ++ // We will load syscalls, if available, before using them. ++ _AddDllDirectory, ++ _AddVectoredContinueHandler, ++ _LoadLibraryExA, ++ _LoadLibraryExW, ++ _ stdFunction ++ ++ // Use RtlGenRandom to generate cryptographically random data. ++ // This approach has been recommended by Microsoft (see issue ++ // 15589 for details). ++ // The RtlGenRandom is not listed in advapi32.dll, instead ++ // RtlGenRandom function can be found by searching for SystemFunction036. ++ // Also some versions of Mingw cannot link to SystemFunction036 ++ // when building executable as Cgo. So load SystemFunction036 ++ // manually during runtime startup. ++ _RtlGenRandom stdFunction + + // Load ntdll.dll manually during startup, otherwise Mingw + // links wrong printf function to cgo executable (see issue +@@ -145,13 +159,6 @@ + _ stdFunction + ) + +-var ( +- bcryptprimitivesdll = [...]uint16{'b', 'c', 'r', 'y', 'p', 't', 'p', 'r', 'i', 'm', 'i', 't', 'i', 'v', 'e', 's', '.', 'd', 'l', 'l', 0} +- ntdlldll = [...]uint16{'n', 't', 'd', 'l', 'l', '.', 'd', 'l', 'l', 0} +- powrprofdll = [...]uint16{'p', 'o', 'w', 'r', 'p', 'r', 'o', 'f', '.', 'd', 'l', 'l', 0} +- winmmdll = [...]uint16{'w', 'i', 'n', 'm', 'm', '.', 'd', 'l', 'l', 0} +-) +- + // Function to be called by windows CreateThread + // to start new os thread. + func tstart_stdcall(newm *m) +@@ -244,8 +251,18 @@ + return unsafe.String(&sysDirectory[0], sysDirectoryLen) + } + +-func windowsLoadSystemLib(name []uint16) uintptr { +- return stdcall3(_LoadLibraryExW, uintptr(unsafe.Pointer(&name[0])), 0, _LOAD_LIBRARY_SEARCH_SYSTEM32) ++//go:linkname syscall_getSystemDirectory syscall.getSystemDirectory ++func syscall_getSystemDirectory() string { ++ return unsafe.String(&sysDirectory[0], sysDirectoryLen) ++} ++ ++func windowsLoadSystemLib(name []byte) uintptr { ++ if useLoadLibraryEx { ++ return stdcall3(_LoadLibraryExA, uintptr(unsafe.Pointer(&name[0])), 0, _LOAD_LIBRARY_SEARCH_SYSTEM32) ++ } else { ++ absName := append(sysDirectory[:sysDirectoryLen], name...) ++ return stdcall1(_LoadLibraryA, uintptr(unsafe.Pointer(&absName[0]))) ++ } + } + + //go:linkname windows_QueryPerformanceCounter internal/syscall/windows.QueryPerformanceCounter +@@ -263,13 +280,28 @@ + } + + func loadOptionalSyscalls() { +- bcryptPrimitives := windowsLoadSystemLib(bcryptprimitivesdll[:]) +- if bcryptPrimitives == 0 { +- throw("bcryptprimitives.dll not found") ++ var kernel32dll = []byte("kernel32.dll\000") ++ k32 := stdcall1(_LoadLibraryA, uintptr(unsafe.Pointer(&kernel32dll[0]))) ++ if k32 == 0 { ++ throw("kernel32.dll not found") + } +- _ProcessPrng = windowsFindfunc(bcryptPrimitives, []byte("ProcessPrng\000")) ++ _AddDllDirectory = windowsFindfunc(k32, []byte("AddDllDirectory\000")) ++ _AddVectoredContinueHandler = windowsFindfunc(k32, []byte("AddVectoredContinueHandler\000")) ++ _LoadLibraryExA = windowsFindfunc(k32, []byte("LoadLibraryExA\000")) ++ _LoadLibraryExW = windowsFindfunc(k32, []byte("LoadLibraryExW\000")) ++ useLoadLibraryEx = (_LoadLibraryExW != nil && _LoadLibraryExA != nil && _AddDllDirectory != nil) ++ ++ initSysDirectory() + +- n32 := windowsLoadSystemLib(ntdlldll[:]) ++ var advapi32dll = []byte("advapi32.dll\000") ++ a32 := windowsLoadSystemLib(advapi32dll) ++ if a32 == 0 { ++ throw("advapi32.dll not found") ++ } ++ _RtlGenRandom = windowsFindfunc(a32, []byte("SystemFunction036\000")) ++ ++ var ntdll = []byte("ntdll.dll\000") ++ n32 := windowsLoadSystemLib(ntdll) + if n32 == 0 { + throw("ntdll.dll not found") + } +@@ -298,7 +330,7 @@ + context uintptr + } + +- powrprof := windowsLoadSystemLib(powrprofdll[:]) ++ powrprof := windowsLoadSystemLib([]byte("powrprof.dll\000")) + if powrprof == 0 { + return // Running on Windows 7, where we don't need it anyway. + } +@@ -357,6 +389,22 @@ + // in sys_windows_386.s and sys_windows_amd64.s: + func getlasterror() uint32 + ++// When loading DLLs, we prefer to use LoadLibraryEx with ++// LOAD_LIBRARY_SEARCH_* flags, if available. LoadLibraryEx is not ++// available on old Windows, though, and the LOAD_LIBRARY_SEARCH_* ++// flags are not available on some versions of Windows without a ++// security patch. ++// ++// https://msdn.microsoft.com/en-us/library/ms684179(v=vs.85).aspx says: ++// "Windows 7, Windows Server 2008 R2, Windows Vista, and Windows ++// Server 2008: The LOAD_LIBRARY_SEARCH_* flags are available on ++// systems that have KB2533623 installed. To determine whether the ++// flags are available, use GetProcAddress to get the address of the ++// AddDllDirectory, RemoveDllDirectory, or SetDefaultDllDirectories ++// function. If GetProcAddress succeeds, the LOAD_LIBRARY_SEARCH_* ++// flags can be used with LoadLibraryEx." ++var useLoadLibraryEx bool ++ + var timeBeginPeriodRetValue uint32 + + // osRelaxMinNS indicates that sysmon shouldn't osRelax if the next +@@ -430,7 +478,8 @@ + // Only load winmm.dll if we need it. + // This avoids a dependency on winmm.dll for Go programs + // that run on new Windows versions. +- m32 := windowsLoadSystemLib(winmmdll[:]) ++ var winmmdll = []byte("winmm.dll\000") ++ m32 := windowsLoadSystemLib(winmmdll) + if m32 == 0 { + print("runtime: LoadLibraryExW failed; errno=", getlasterror(), "\n") + throw("winmm.dll not found") +@@ -471,6 +520,28 @@ + canUseLongPaths = true + } + ++var osVersionInfo struct { ++ majorVersion uint32 ++ minorVersion uint32 ++ buildNumber uint32 ++} ++ ++func initOsVersionInfo() { ++ info := _OSVERSIONINFOW{} ++ info.osVersionInfoSize = uint32(unsafe.Sizeof(info)) ++ stdcall1(_RtlGetVersion, uintptr(unsafe.Pointer(&info))) ++ osVersionInfo.majorVersion = info.majorVersion ++ osVersionInfo.minorVersion = info.minorVersion ++ osVersionInfo.buildNumber = info.buildNumber ++} ++ ++//go:linkname rtlGetNtVersionNumbers syscall.rtlGetNtVersionNumbers ++func rtlGetNtVersionNumbers(majorVersion *uint32, minorVersion *uint32, buildNumber *uint32) { ++ *majorVersion = osVersionInfo.majorVersion ++ *minorVersion = osVersionInfo.minorVersion ++ *buildNumber = osVersionInfo.buildNumber ++} ++ + func osinit() { + asmstdcallAddr = unsafe.Pointer(abi.FuncPCABI0(asmstdcall)) + +@@ -483,8 +554,8 @@ + initHighResTimer() + timeBeginPeriodRetValue = osRelax(false) + +- initSysDirectory() + initLongPathSupport() ++ initOsVersionInfo() + + numCPUStartup = getCPUCount() + +@@ -500,7 +571,7 @@ + //go:nosplit + func readRandom(r []byte) int { + n := 0 +- if stdcall2(_ProcessPrng, uintptr(unsafe.Pointer(&r[0])), uintptr(len(r)))&0xff != 0 { ++ if stdcall2(_RtlGenRandom, uintptr(unsafe.Pointer(&r[0])), uintptr(len(r)))&0xff != 0 { + n = len(r) + } + return n +Index: src/net/hook_windows.go +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +diff --git a/src/net/hook_windows.go b/src/net/hook_windows.go +--- a/src/net/hook_windows.go (revision 8cb5472d94c34b88733a81091bd328e70ee565a4) ++++ b/src/net/hook_windows.go (revision 6788c4c6f9fafb56729bad6b660f7ee2272d699f) +@@ -13,6 +13,7 @@ + hostsFilePath = windows.GetSystemDirectory() + "/Drivers/etc/hosts" + + // Placeholders for socket system calls. ++ socketFunc func(int, int, int) (syscall.Handle, error) = syscall.Socket + wsaSocketFunc func(int32, int32, int32, *syscall.WSAProtocolInfo, uint32, uint32) (syscall.Handle, error) = windows.WSASocket + connectFunc func(syscall.Handle, syscall.Sockaddr) error = syscall.Connect + listenFunc func(syscall.Handle, int) error = syscall.Listen +Index: src/net/internal/socktest/main_test.go +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +diff --git a/src/net/internal/socktest/main_test.go b/src/net/internal/socktest/main_test.go +--- a/src/net/internal/socktest/main_test.go (revision 8cb5472d94c34b88733a81091bd328e70ee565a4) ++++ b/src/net/internal/socktest/main_test.go (revision 6788c4c6f9fafb56729bad6b660f7ee2272d699f) +@@ -2,7 +2,7 @@ + // Use of this source code is governed by a BSD-style + // license that can be found in the LICENSE file. + +-//go:build !js && !plan9 && !wasip1 && !windows ++//go:build !js && !plan9 && !wasip1 + + package socktest_test + +Index: src/net/internal/socktest/main_windows_test.go +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +diff --git a/src/net/internal/socktest/main_windows_test.go b/src/net/internal/socktest/main_windows_test.go +new file mode 100644 +--- /dev/null (revision 6788c4c6f9fafb56729bad6b660f7ee2272d699f) ++++ b/src/net/internal/socktest/main_windows_test.go (revision 6788c4c6f9fafb56729bad6b660f7ee2272d699f) +@@ -0,0 +1,22 @@ ++// Copyright 2015 The Go Authors. All rights reserved. ++// Use of this source code is governed by a BSD-style ++// license that can be found in the LICENSE file. ++ ++package socktest_test ++ ++import "syscall" ++ ++var ( ++ socketFunc func(int, int, int) (syscall.Handle, error) ++ closeFunc func(syscall.Handle) error ++) ++ ++func installTestHooks() { ++ socketFunc = sw.Socket ++ closeFunc = sw.Closesocket ++} ++ ++func uninstallTestHooks() { ++ socketFunc = syscall.Socket ++ closeFunc = syscall.Closesocket ++} +Index: src/net/internal/socktest/sys_windows.go +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +diff --git a/src/net/internal/socktest/sys_windows.go b/src/net/internal/socktest/sys_windows.go +--- a/src/net/internal/socktest/sys_windows.go (revision 8cb5472d94c34b88733a81091bd328e70ee565a4) ++++ b/src/net/internal/socktest/sys_windows.go (revision 6788c4c6f9fafb56729bad6b660f7ee2272d699f) +@@ -9,6 +9,38 @@ + "syscall" + ) + ++// Socket wraps [syscall.Socket]. ++func (sw *Switch) Socket(family, sotype, proto int) (s syscall.Handle, err error) { ++ sw.once.Do(sw.init) ++ ++ so := &Status{Cookie: cookie(family, sotype, proto)} ++ sw.fmu.RLock() ++ f, _ := sw.fltab[FilterSocket] ++ sw.fmu.RUnlock() ++ ++ af, err := f.apply(so) ++ if err != nil { ++ return syscall.InvalidHandle, err ++ } ++ s, so.Err = syscall.Socket(family, sotype, proto) ++ if err = af.apply(so); err != nil { ++ if so.Err == nil { ++ syscall.Closesocket(s) ++ } ++ return syscall.InvalidHandle, err ++ } ++ ++ sw.smu.Lock() ++ defer sw.smu.Unlock() ++ if so.Err != nil { ++ sw.stats.getLocked(so.Cookie).OpenFailed++ ++ return syscall.InvalidHandle, so.Err ++ } ++ nso := sw.addLocked(s, family, sotype, proto) ++ sw.stats.getLocked(nso.Cookie).Opened++ ++ return s, nil ++} ++ + // WSASocket wraps [syscall.WSASocket]. + func (sw *Switch) WSASocket(family, sotype, proto int32, protinfo *syscall.WSAProtocolInfo, group uint32, flags uint32) (s syscall.Handle, err error) { + sw.once.Do(sw.init) +Index: src/net/main_windows_test.go +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +diff --git a/src/net/main_windows_test.go b/src/net/main_windows_test.go +--- a/src/net/main_windows_test.go (revision 8cb5472d94c34b88733a81091bd328e70ee565a4) ++++ b/src/net/main_windows_test.go (revision 6788c4c6f9fafb56729bad6b660f7ee2272d699f) +@@ -12,6 +12,7 @@ + + var ( + // Placeholders for saving original socket system calls. ++ origSocket = socketFunc + origWSASocket = wsaSocketFunc + origClosesocket = poll.CloseFunc + origConnect = connectFunc +@@ -21,6 +22,7 @@ + ) + + func installTestHooks() { ++ socketFunc = sw.Socket + wsaSocketFunc = sw.WSASocket + poll.CloseFunc = sw.Closesocket + connectFunc = sw.Connect +@@ -30,6 +32,7 @@ + } + + func uninstallTestHooks() { ++ socketFunc = origSocket + wsaSocketFunc = origWSASocket + poll.CloseFunc = origClosesocket + connectFunc = origConnect +Index: src/net/sock_windows.go +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +diff --git a/src/net/sock_windows.go b/src/net/sock_windows.go +--- a/src/net/sock_windows.go (revision 8cb5472d94c34b88733a81091bd328e70ee565a4) ++++ b/src/net/sock_windows.go (revision 6788c4c6f9fafb56729bad6b660f7ee2272d699f) +@@ -20,6 +20,21 @@ + func sysSocket(family, sotype, proto int) (syscall.Handle, error) { + s, err := wsaSocketFunc(int32(family), int32(sotype), int32(proto), + nil, 0, windows.WSA_FLAG_OVERLAPPED|windows.WSA_FLAG_NO_HANDLE_INHERIT) ++ if err == nil { ++ return s, nil ++ } ++ // WSA_FLAG_NO_HANDLE_INHERIT flag is not supported on some ++ // old versions of Windows, see ++ // https://msdn.microsoft.com/en-us/library/windows/desktop/ms742212(v=vs.85).aspx ++ // for details. Just use syscall.Socket, if windows.WSASocket failed. ++ ++ // See ../syscall/exec_unix.go for description of ForkLock. ++ syscall.ForkLock.RLock() ++ s, err = socketFunc(family, sotype, proto) ++ if err == nil { ++ syscall.CloseOnExec(s) ++ } ++ syscall.ForkLock.RUnlock() + if err != nil { + return syscall.InvalidHandle, os.NewSyscallError("socket", err) + } +Index: src/syscall/exec_windows.go +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +diff --git a/src/syscall/exec_windows.go b/src/syscall/exec_windows.go +--- a/src/syscall/exec_windows.go (revision 8cb5472d94c34b88733a81091bd328e70ee565a4) ++++ b/src/syscall/exec_windows.go (revision a5b2168bb836ed9d6601c626f95e56c07923f906) +@@ -14,7 +14,6 @@ + "unsafe" + ) + +-// ForkLock is not used on Windows. + var ForkLock sync.RWMutex + + // EscapeArg rewrites command line argument s as prescribed +@@ -254,6 +253,9 @@ + var zeroProcAttr ProcAttr + var zeroSysProcAttr SysProcAttr + ++//go:linkname rtlGetNtVersionNumbers ++func rtlGetNtVersionNumbers(majorVersion *uint32, minorVersion *uint32, buildNumber *uint32) ++ + func StartProcess(argv0 string, argv []string, attr *ProcAttr) (pid int, handle uintptr, err error) { + if len(argv0) == 0 { + return 0, 0, EWINDOWS +@@ -317,6 +319,17 @@ + } + } + ++ var maj, min, build uint32 ++ rtlGetNtVersionNumbers(&maj, &min, &build) ++ isWin7 := maj < 6 || (maj == 6 && min <= 1) ++ // NT kernel handles are divisible by 4, with the bottom 3 bits left as ++ // a tag. The fully set tag correlates with the types of handles we're ++ // concerned about here. Except, the kernel will interpret some ++ // special handle values, like -1, -2, and so forth, so kernelbase.dll ++ // checks to see that those bottom three bits are checked, but that top ++ // bit is not checked. ++ isLegacyWin7ConsoleHandle := func(handle Handle) bool { return isWin7 && handle&0x10000003 == 3 } ++ + p, _ := GetCurrentProcess() + parentProcess := p + if sys.ParentProcess != 0 { +@@ -325,7 +338,15 @@ + fd := make([]Handle, len(attr.Files)) + for i := range attr.Files { + if attr.Files[i] > 0 { +- err := DuplicateHandle(p, Handle(attr.Files[i]), parentProcess, &fd[i], 0, true, DUPLICATE_SAME_ACCESS) ++ destinationProcessHandle := parentProcess ++ ++ // On Windows 7, console handles aren't real handles, and can only be duplicated ++ // into the current process, not a parent one, which amounts to the same thing. ++ if parentProcess != p && isLegacyWin7ConsoleHandle(Handle(attr.Files[i])) { ++ destinationProcessHandle = p ++ } ++ ++ err := DuplicateHandle(p, Handle(attr.Files[i]), destinationProcessHandle, &fd[i], 0, true, DUPLICATE_SAME_ACCESS) + if err != nil { + return 0, 0, err + } +@@ -356,6 +377,14 @@ + + fd = append(fd, sys.AdditionalInheritedHandles...) + ++ // On Windows 7, console handles aren't real handles, so don't pass them ++ // through to PROC_THREAD_ATTRIBUTE_HANDLE_LIST. ++ for i := range fd { ++ if isLegacyWin7ConsoleHandle(fd[i]) { ++ fd[i] = 0 ++ } ++ } ++ + // The presence of a NULL handle in the list is enough to cause PROC_THREAD_ATTRIBUTE_HANDLE_LIST + // to treat the entire list as empty, so remove NULL handles. + j := 0 +Index: src/runtime/syscall_windows.go +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +diff --git a/src/runtime/syscall_windows.go b/src/runtime/syscall_windows.go +--- a/src/runtime/syscall_windows.go (revision a5b2168bb836ed9d6601c626f95e56c07923f906) ++++ b/src/runtime/syscall_windows.go (revision f56f1e23507e646c85243a71bde7b9629b2f970c) +@@ -413,10 +413,20 @@ + + const _LOAD_LIBRARY_SEARCH_SYSTEM32 = 0x00000800 + ++// When available, this function will use LoadLibraryEx with the filename ++// parameter and the important SEARCH_SYSTEM32 argument. But on systems that ++// do not have that option, absoluteFilepath should contain a fallback ++// to the full path inside of system32 for use with vanilla LoadLibrary. ++// + //go:linkname syscall_loadsystemlibrary syscall.loadsystemlibrary +-func syscall_loadsystemlibrary(filename *uint16) (handle, err uintptr) { +- handle, _, err = syscall_SyscallN(uintptr(unsafe.Pointer(_LoadLibraryExW)), uintptr(unsafe.Pointer(filename)), 0, _LOAD_LIBRARY_SEARCH_SYSTEM32) ++func syscall_loadsystemlibrary(filename *uint16, absoluteFilepath *uint16) (handle, err uintptr) { ++ if useLoadLibraryEx { ++ handle, _, err = syscall_SyscallN(uintptr(unsafe.Pointer(_LoadLibraryExW)), uintptr(unsafe.Pointer(filename)), 0, _LOAD_LIBRARY_SEARCH_SYSTEM32) ++ } else { ++ handle, _, err = syscall_SyscallN(uintptr(unsafe.Pointer(_LoadLibraryW)), uintptr(unsafe.Pointer(absoluteFilepath))) ++ } + KeepAlive(filename) ++ KeepAlive(absoluteFilepath) + if handle != 0 { + err = 0 + } +Index: src/syscall/dll_windows.go +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +diff --git a/src/syscall/dll_windows.go b/src/syscall/dll_windows.go +--- a/src/syscall/dll_windows.go (revision a5b2168bb836ed9d6601c626f95e56c07923f906) ++++ b/src/syscall/dll_windows.go (revision f56f1e23507e646c85243a71bde7b9629b2f970c) +@@ -45,7 +45,7 @@ + //go:noescape + func SyscallN(trap uintptr, args ...uintptr) (r1, r2 uintptr, err Errno) + func loadlibrary(filename *uint16) (handle uintptr, err Errno) +-func loadsystemlibrary(filename *uint16) (handle uintptr, err Errno) ++func loadsystemlibrary(filename *uint16, absoluteFilepath *uint16) (handle uintptr, err Errno) + func getprocaddress(handle uintptr, procname *uint8) (proc uintptr, err Errno) + + // A DLL implements access to a single DLL. +@@ -54,6 +54,9 @@ + Handle Handle + } + ++//go:linkname getSystemDirectory ++func getSystemDirectory() string // Implemented in runtime package. ++ + // LoadDLL loads the named DLL file into memory. + // + // If name is not an absolute path and is not a known system DLL used by +@@ -70,7 +73,11 @@ + var h uintptr + var e Errno + if sysdll.IsSystemDLL[name] { +- h, e = loadsystemlibrary(namep) ++ absoluteFilepathp, err := UTF16PtrFromString(getSystemDirectory() + name) ++ if err != nil { ++ return nil, err ++ } ++ h, e = loadsystemlibrary(namep, absoluteFilepathp) + } else { + h, e = loadlibrary(namep) + } diff --git a/clash-meta-android/core/src/foss/golang/clash/.github/workflows/build.yml b/clash-meta-android/core/src/foss/golang/clash/.github/workflows/build.yml index a9f99dc85a..9ba36ed8ae 100644 --- a/clash-meta-android/core/src/foss/golang/clash/.github/workflows/build.yml +++ b/clash-meta-android/core/src/foss/golang/clash/.github/workflows/build.yml @@ -179,12 +179,8 @@ jobs: - name: Revert Golang1.25 commit for Windows7/8 if: ${{ matrix.jobs.goos == 'windows' && matrix.jobs.goversion == '' }} run: | - alias curl='curl -H "Authorization: Bearer ${{ secrets.GITHUB_TOKEN }}"' cd $(go env GOROOT) - curl https://github.com/MetaCubeX/go/commit/8cb5472d94c34b88733a81091bd328e70ee565a4.diff | patch --verbose -p 1 - curl https://github.com/MetaCubeX/go/commit/6788c4c6f9fafb56729bad6b660f7ee2272d699f.diff | patch --verbose -p 1 - curl https://github.com/MetaCubeX/go/commit/a5b2168bb836ed9d6601c626f95e56c07923f906.diff | patch --verbose -p 1 - curl https://github.com/MetaCubeX/go/commit/f56f1e23507e646c85243a71bde7b9629b2f970c.diff | patch --verbose -p 1 + patch --verbose -p 1 < $GITHUB_WORKSPACE/.github/patch/go1.25.patch # modify from https://github.com/restic/restic/issues/4636#issuecomment-1896455557 # this patch file only works on golang1.24.x @@ -198,12 +194,8 @@ jobs: - name: Revert Golang1.24 commit for Windows7/8 if: ${{ matrix.jobs.goos == 'windows' && matrix.jobs.goversion == '1.24' }} run: | - alias curl='curl -H "Authorization: Bearer ${{ secrets.GITHUB_TOKEN }}"' cd $(go env GOROOT) - curl https://github.com/MetaCubeX/go/commit/2a406dc9f1ea7323d6ca9fccb2fe9ddebb6b1cc8.diff | patch --verbose -p 1 - curl https://github.com/MetaCubeX/go/commit/7b1fd7d39c6be0185fbe1d929578ab372ac5c632.diff | patch --verbose -p 1 - curl https://github.com/MetaCubeX/go/commit/979d6d8bab3823ff572ace26767fd2ce3cf351ae.diff | patch --verbose -p 1 - curl https://github.com/MetaCubeX/go/commit/ac3e93c061779dfefc0dd13a5b6e6f764a25621e.diff | patch --verbose -p 1 + patch --verbose -p 1 < $GITHUB_WORKSPACE/.github/patch/go1.24.patch # modify from https://github.com/restic/restic/issues/4636#issuecomment-1896455557 # this patch file only works on golang1.23.x @@ -217,12 +209,8 @@ jobs: - name: Revert Golang1.23 commit for Windows7/8 if: ${{ matrix.jobs.goos == 'windows' && matrix.jobs.goversion == '1.23' }} run: | - alias curl='curl -H "Authorization: Bearer ${{ secrets.GITHUB_TOKEN }}"' cd $(go env GOROOT) - curl https://github.com/MetaCubeX/go/commit/9ac42137ef6730e8b7daca016ece831297a1d75b.diff | patch --verbose -p 1 - curl https://github.com/MetaCubeX/go/commit/21290de8a4c91408de7c2b5b68757b1e90af49dd.diff | patch --verbose -p 1 - curl https://github.com/MetaCubeX/go/commit/6a31d3fa8e47ddabc10bd97bff10d9a85f4cfb76.diff | patch --verbose -p 1 - curl https://github.com/MetaCubeX/go/commit/69e2eed6dd0f6d815ebf15797761c13f31213dd6.diff | patch --verbose -p 1 + patch --verbose -p 1 < $GITHUB_WORKSPACE/.github/patch/go1.23.patch # modify from https://github.com/restic/restic/issues/4636#issuecomment-1896455557 # this patch file only works on golang1.22.x @@ -236,20 +224,15 @@ jobs: - name: Revert Golang1.22 commit for Windows7/8 if: ${{ matrix.jobs.goos == 'windows' && matrix.jobs.goversion == '1.22' }} run: | - alias curl='curl -H "Authorization: Bearer ${{ secrets.GITHUB_TOKEN }}"' cd $(go env GOROOT) - curl https://github.com/MetaCubeX/go/commit/9779155f18b6556a034f7bb79fb7fb2aad1e26a9.diff | patch --verbose -p 1 - curl https://github.com/MetaCubeX/go/commit/ef0606261340e608017860b423ffae5c1ce78239.diff | patch --verbose -p 1 - curl https://github.com/MetaCubeX/go/commit/7f83badcb925a7e743188041cb6e561fc9b5b642.diff | patch --verbose -p 1 - curl https://github.com/MetaCubeX/go/commit/83ff9782e024cb328b690cbf0da4e7848a327f4f.diff | patch --verbose -p 1 + patch --verbose -p 1 < $GITHUB_WORKSPACE/.github/patch/go1.22.patch # modify from https://github.com/restic/restic/issues/4636#issuecomment-1896455557 - name: Revert Golang1.21 commit for Windows7/8 if: ${{ matrix.jobs.goos == 'windows' && matrix.jobs.goversion == '1.21' }} run: | - alias curl='curl -H "Authorization: Bearer ${{ secrets.GITHUB_TOKEN }}"' cd $(go env GOROOT) - curl https://github.com/golang/go/commit/9e43850a3298a9b8b1162ba0033d4c53f8637571.diff | patch --verbose -R -p 1 + patch --verbose -p 1 < $GITHUB_WORKSPACE/.github/patch/go1.21.patch - name: Set variables run: | diff --git a/clash-meta-android/core/src/foss/golang/clash/.github/workflows/test.yml b/clash-meta-android/core/src/foss/golang/clash/.github/workflows/test.yml index 8d7a35c2a1..c6ac69cd46 100644 --- a/clash-meta-android/core/src/foss/golang/clash/.github/workflows/test.yml +++ b/clash-meta-android/core/src/foss/golang/clash/.github/workflows/test.yml @@ -48,89 +48,11 @@ jobs: with: go-version: ${{ matrix.go-version }} - # modify from https://github.com/restic/restic/issues/4636#issuecomment-1896455557 - # this patch file only works on golang1.25.x - # that means after golang1.26 release it must be changed - # see: https://github.com/MetaCubeX/go/commits/release-branch.go1.25/ - # revert: - # 693def151adff1af707d82d28f55dba81ceb08e1: "crypto/rand,runtime: switch RtlGenRandom for ProcessPrng" - # 7c1157f9544922e96945196b47b95664b1e39108: "net: remove sysSocket fallback for Windows 7" - # 48042aa09c2f878c4faa576948b07fe625c4707a: "syscall: remove Windows 7 console handle workaround" - # a17d959debdb04cd550016a3501dd09d50cd62e7: "runtime: always use LoadLibraryEx to load system libraries" - - name: Revert Golang1.25 commit for Windows7/8 - if: ${{ runner.os == 'Windows' && matrix.go-version == '1.25' }} + - name: Revert Golang commit for Windows7/8 + if: ${{ runner.os == 'Windows' && matrix.go-version != '1.20' }} run: | - alias curl='curl -H "Authorization: Bearer ${{ secrets.GITHUB_TOKEN }}"' cd $(go env GOROOT) - curl https://github.com/MetaCubeX/go/commit/8cb5472d94c34b88733a81091bd328e70ee565a4.diff | patch --verbose -p 1 - curl https://github.com/MetaCubeX/go/commit/6788c4c6f9fafb56729bad6b660f7ee2272d699f.diff | patch --verbose -p 1 - curl https://github.com/MetaCubeX/go/commit/a5b2168bb836ed9d6601c626f95e56c07923f906.diff | patch --verbose -p 1 - curl https://github.com/MetaCubeX/go/commit/f56f1e23507e646c85243a71bde7b9629b2f970c.diff | patch --verbose -p 1 - - # modify from https://github.com/restic/restic/issues/4636#issuecomment-1896455557 - # this patch file only works on golang1.24.x - # that means after golang1.25 release it must be changed - # see: https://github.com/MetaCubeX/go/commits/release-branch.go1.24/ - # revert: - # 693def151adff1af707d82d28f55dba81ceb08e1: "crypto/rand,runtime: switch RtlGenRandom for ProcessPrng" - # 7c1157f9544922e96945196b47b95664b1e39108: "net: remove sysSocket fallback for Windows 7" - # 48042aa09c2f878c4faa576948b07fe625c4707a: "syscall: remove Windows 7 console handle workaround" - # a17d959debdb04cd550016a3501dd09d50cd62e7: "runtime: always use LoadLibraryEx to load system libraries" - - name: Revert Golang1.24 commit for Windows7/8 - if: ${{ runner.os == 'Windows' && matrix.go-version == '1.24' }} - run: | - alias curl='curl -H "Authorization: Bearer ${{ secrets.GITHUB_TOKEN }}"' - cd $(go env GOROOT) - curl https://github.com/MetaCubeX/go/commit/2a406dc9f1ea7323d6ca9fccb2fe9ddebb6b1cc8.diff | patch --verbose -p 1 - curl https://github.com/MetaCubeX/go/commit/7b1fd7d39c6be0185fbe1d929578ab372ac5c632.diff | patch --verbose -p 1 - curl https://github.com/MetaCubeX/go/commit/979d6d8bab3823ff572ace26767fd2ce3cf351ae.diff | patch --verbose -p 1 - curl https://github.com/MetaCubeX/go/commit/ac3e93c061779dfefc0dd13a5b6e6f764a25621e.diff | patch --verbose -p 1 - - # modify from https://github.com/restic/restic/issues/4636#issuecomment-1896455557 - # this patch file only works on golang1.23.x - # that means after golang1.24 release it must be changed - # see: https://github.com/MetaCubeX/go/commits/release-branch.go1.23/ - # revert: - # 693def151adff1af707d82d28f55dba81ceb08e1: "crypto/rand,runtime: switch RtlGenRandom for ProcessPrng" - # 7c1157f9544922e96945196b47b95664b1e39108: "net: remove sysSocket fallback for Windows 7" - # 48042aa09c2f878c4faa576948b07fe625c4707a: "syscall: remove Windows 7 console handle workaround" - # a17d959debdb04cd550016a3501dd09d50cd62e7: "runtime: always use LoadLibraryEx to load system libraries" - - name: Revert Golang1.23 commit for Windows7/8 - if: ${{ runner.os == 'Windows' && matrix.go-version == '1.23' }} - run: | - alias curl='curl -H "Authorization: Bearer ${{ secrets.GITHUB_TOKEN }}"' - cd $(go env GOROOT) - curl https://github.com/MetaCubeX/go/commit/9ac42137ef6730e8b7daca016ece831297a1d75b.diff | patch --verbose -p 1 - curl https://github.com/MetaCubeX/go/commit/21290de8a4c91408de7c2b5b68757b1e90af49dd.diff | patch --verbose -p 1 - curl https://github.com/MetaCubeX/go/commit/6a31d3fa8e47ddabc10bd97bff10d9a85f4cfb76.diff | patch --verbose -p 1 - curl https://github.com/MetaCubeX/go/commit/69e2eed6dd0f6d815ebf15797761c13f31213dd6.diff | patch --verbose -p 1 - - # modify from https://github.com/restic/restic/issues/4636#issuecomment-1896455557 - # this patch file only works on golang1.22.x - # that means after golang1.23 release it must be changed - # see: https://github.com/MetaCubeX/go/commits/release-branch.go1.22/ - # revert: - # 693def151adff1af707d82d28f55dba81ceb08e1: "crypto/rand,runtime: switch RtlGenRandom for ProcessPrng" - # 7c1157f9544922e96945196b47b95664b1e39108: "net: remove sysSocket fallback for Windows 7" - # 48042aa09c2f878c4faa576948b07fe625c4707a: "syscall: remove Windows 7 console handle workaround" - # a17d959debdb04cd550016a3501dd09d50cd62e7: "runtime: always use LoadLibraryEx to load system libraries" - - name: Revert Golang1.22 commit for Windows7/8 - if: ${{ runner.os == 'Windows' && matrix.go-version == '1.22' }} - run: | - alias curl='curl -H "Authorization: Bearer ${{ secrets.GITHUB_TOKEN }}"' - cd $(go env GOROOT) - curl https://github.com/MetaCubeX/go/commit/9779155f18b6556a034f7bb79fb7fb2aad1e26a9.diff | patch --verbose -p 1 - curl https://github.com/MetaCubeX/go/commit/ef0606261340e608017860b423ffae5c1ce78239.diff | patch --verbose -p 1 - curl https://github.com/MetaCubeX/go/commit/7f83badcb925a7e743188041cb6e561fc9b5b642.diff | patch --verbose -p 1 - curl https://github.com/MetaCubeX/go/commit/83ff9782e024cb328b690cbf0da4e7848a327f4f.diff | patch --verbose -p 1 - - # modify from https://github.com/restic/restic/issues/4636#issuecomment-1896455557 - - name: Revert Golang1.21 commit for Windows7/8 - if: ${{ runner.os == 'Windows' && matrix.go-version == '1.21' }} - run: | - alias curl='curl -H "Authorization: Bearer ${{ secrets.GITHUB_TOKEN }}"' - cd $(go env GOROOT) - curl https://github.com/golang/go/commit/9e43850a3298a9b8b1162ba0033d4c53f8637571.diff | patch --verbose -R -p 1 + patch --verbose -p 1 < $GITHUB_WORKSPACE/.github/patch/go${{matrix.go-version}}.patch - name: Test run: go test ./... -v -count=1 diff --git a/clash-meta-android/core/src/foss/golang/clash/Dockerfile b/clash-meta-android/core/src/foss/golang/clash/Dockerfile index 67d4a6e56e..2649bf63d6 100644 --- a/clash-meta-android/core/src/foss/golang/clash/Dockerfile +++ b/clash-meta-android/core/src/foss/golang/clash/Dockerfile @@ -4,9 +4,9 @@ RUN echo "I'm building for $TARGETPLATFORM" RUN apk add --no-cache gzip && \ mkdir /mihomo-config && \ - wget -O /mihomo-config/geoip.metadb https://fastly.jsdelivr.net/gh/MetaCubeX/meta-rules-dat@release/geoip.metadb && \ - wget -O /mihomo-config/geosite.dat https://fastly.jsdelivr.net/gh/MetaCubeX/meta-rules-dat@release/geosite.dat && \ - wget -O /mihomo-config/geoip.dat https://fastly.jsdelivr.net/gh/MetaCubeX/meta-rules-dat@release/geoip.dat + wget -O /mihomo-config/geoip.metadb https://github.com/MetaCubeX/meta-rules-dat/releases/download/latest/geoip.metadb && \ + wget -O /mihomo-config/geosite.dat https://github.com/MetaCubeX/meta-rules-dat/releases/download/latest/geosite.dat && \ + wget -O /mihomo-config/geoip.dat https://github.com/MetaCubeX/meta-rules-dat/releases/download/latest/geoip.dat COPY docker/file-name.sh /mihomo/file-name.sh WORKDIR /mihomo diff --git a/clash-meta-android/core/src/foss/golang/clash/adapter/adapter.go b/clash-meta-android/core/src/foss/golang/clash/adapter/adapter.go index 4f127bcf6a..ef8d4ee347 100644 --- a/clash-meta-android/core/src/foss/golang/clash/adapter/adapter.go +++ b/clash-meta-android/core/src/foss/golang/clash/adapter/adapter.go @@ -51,26 +51,12 @@ func (p *Proxy) AliveForTestUrl(url string) bool { return p.alive.Load() } -// Dial implements C.Proxy -func (p *Proxy) Dial(metadata *C.Metadata) (C.Conn, error) { - ctx, cancel := context.WithTimeout(context.Background(), C.DefaultTCPTimeout) - defer cancel() - return p.DialContext(ctx, metadata) -} - // DialContext implements C.ProxyAdapter func (p *Proxy) DialContext(ctx context.Context, metadata *C.Metadata) (C.Conn, error) { conn, err := p.ProxyAdapter.DialContext(ctx, metadata) return conn, err } -// DialUDP implements C.ProxyAdapter -func (p *Proxy) DialUDP(metadata *C.Metadata) (C.PacketConn, error) { - ctx, cancel := context.WithTimeout(context.Background(), C.DefaultUDPTimeout) - defer cancel() - return p.ListenPacketContext(ctx, metadata) -} - // ListenPacketContext implements C.ProxyAdapter func (p *Proxy) ListenPacketContext(ctx context.Context, metadata *C.Metadata) (C.PacketConn, error) { pc, err := p.ProxyAdapter.ListenPacketContext(ctx, metadata) diff --git a/clash-meta-android/core/src/foss/golang/clash/adapter/outbound/base.go b/clash-meta-android/core/src/foss/golang/clash/adapter/outbound/base.go index 04a0fa98ae..93f6e14256 100644 --- a/clash-meta-android/core/src/foss/golang/clash/adapter/outbound/base.go +++ b/clash-meta-android/core/src/foss/golang/clash/adapter/outbound/base.go @@ -263,7 +263,9 @@ func NewConn(c net.Conn, a C.ProxyAdapter) C.Conn { if _, ok := c.(syscall.Conn); !ok { // exclusion system conn like *net.TCPConn c = N.NewDeadlineConn(c) // most conn from outbound can't handle readDeadline correctly } - return &conn{N.NewExtendedConn(c), []string{a.Name()}, a.Addr()} + cc := &conn{N.NewExtendedConn(c), nil, a.Addr()} + cc.AppendToChains(a) + return cc } type packetConn struct { @@ -320,7 +322,9 @@ func newPacketConn(pc net.PacketConn, a ProxyAdapter) C.PacketConn { if _, ok := pc.(syscall.Conn); !ok { // exclusion system conn like *net.UDPConn epc = N.NewDeadlineEnhancePacketConn(epc) // most conn from outbound can't handle readDeadline correctly } - return &packetConn{epc, []string{a.Name()}, a.Name(), utils.NewUUIDV4().String(), a.Addr(), a.ResolveUDP} + cpc := &packetConn{epc, nil, a.Name(), utils.NewUUIDV4().String(), a.Addr(), a.ResolveUDP} + cpc.AppendToChains(a) + return cpc } type AddRef interface { diff --git a/clash-meta-android/core/src/foss/golang/clash/adapter/outbound/shadowsocksr.go b/clash-meta-android/core/src/foss/golang/clash/adapter/outbound/shadowsocksr.go index a9975107da..efc368a4ad 100644 --- a/clash-meta-android/core/src/foss/golang/clash/adapter/outbound/shadowsocksr.go +++ b/clash-meta-android/core/src/foss/golang/clash/adapter/outbound/shadowsocksr.go @@ -252,13 +252,14 @@ func (spc *ssrPacketConn) WaitReadFrom() (data []byte, put func(), addr net.Addr return nil, nil, nil, errors.New("parse addr error") } - addr = _addr.UDPAddr() - if addr == nil { + udpAddr := _addr.UDPAddr() + if udpAddr == nil { if put != nil { put() } return nil, nil, nil, errors.New("parse addr error") } + addr = udpAddr data = data[len(_addr):] return diff --git a/clash-meta-android/core/src/foss/golang/clash/adapter/outboundgroup/fallback.go b/clash-meta-android/core/src/foss/golang/clash/adapter/outboundgroup/fallback.go index 8f8842a1c4..3772107bc1 100644 --- a/clash-meta-android/core/src/foss/golang/clash/adapter/outboundgroup/fallback.go +++ b/clash-meta-android/core/src/foss/golang/clash/adapter/outboundgroup/fallback.go @@ -10,7 +10,7 @@ import ( N "github.com/metacubex/mihomo/common/net" "github.com/metacubex/mihomo/common/utils" C "github.com/metacubex/mihomo/constant" - "github.com/metacubex/mihomo/constant/provider" + P "github.com/metacubex/mihomo/constant/provider" ) type Fallback struct { @@ -150,7 +150,7 @@ func (f *Fallback) ForceSet(name string) { f.selected = name } -func NewFallback(option *GroupCommonOption, providers []provider.ProxyProvider) *Fallback { +func NewFallback(option *GroupCommonOption, providers []P.ProxyProvider) *Fallback { return &Fallback{ GroupBase: NewGroupBase(GroupBaseOption{ Name: option.Name, diff --git a/clash-meta-android/core/src/foss/golang/clash/adapter/outboundgroup/groupbase.go b/clash-meta-android/core/src/foss/golang/clash/adapter/outboundgroup/groupbase.go index dc66976bba..9e705677e4 100644 --- a/clash-meta-android/core/src/foss/golang/clash/adapter/outboundgroup/groupbase.go +++ b/clash-meta-android/core/src/foss/golang/clash/adapter/outboundgroup/groupbase.go @@ -12,8 +12,7 @@ import ( "github.com/metacubex/mihomo/common/atomic" "github.com/metacubex/mihomo/common/utils" C "github.com/metacubex/mihomo/constant" - "github.com/metacubex/mihomo/constant/provider" - types "github.com/metacubex/mihomo/constant/provider" + P "github.com/metacubex/mihomo/constant/provider" "github.com/metacubex/mihomo/log" "github.com/metacubex/mihomo/tunnel" @@ -26,7 +25,7 @@ type GroupBase struct { filterRegs []*regexp2.Regexp excludeFilterRegs []*regexp2.Regexp excludeTypeArray []string - providers []provider.ProxyProvider + providers []P.ProxyProvider failedTestMux sync.Mutex failedTimes int failedTime time.Time @@ -48,7 +47,7 @@ type GroupBaseOption struct { ExcludeType string TestTimeout int MaxFailedTimes int - Providers []provider.ProxyProvider + Providers []P.ProxyProvider } func NewGroupBase(opt GroupBaseOption) *GroupBase { @@ -125,7 +124,7 @@ func (gb *GroupBase) GetProxies(touch bool) []C.Proxy { } } else { for _, pd := range gb.providers { - if pd.VehicleType() == types.Compatible { // compatible provider unneeded filter + if pd.VehicleType() == P.Compatible { // compatible provider unneeded filter proxies = append(proxies, pd.Proxies()...) continue } diff --git a/clash-meta-android/core/src/foss/golang/clash/adapter/outboundgroup/loadbalance.go b/clash-meta-android/core/src/foss/golang/clash/adapter/outboundgroup/loadbalance.go index 99e11c46fc..dff9b5ed9d 100644 --- a/clash-meta-android/core/src/foss/golang/clash/adapter/outboundgroup/loadbalance.go +++ b/clash-meta-android/core/src/foss/golang/clash/adapter/outboundgroup/loadbalance.go @@ -14,7 +14,7 @@ import ( N "github.com/metacubex/mihomo/common/net" "github.com/metacubex/mihomo/common/utils" C "github.com/metacubex/mihomo/constant" - "github.com/metacubex/mihomo/constant/provider" + P "github.com/metacubex/mihomo/constant/provider" "golang.org/x/net/publicsuffix" ) @@ -194,7 +194,7 @@ func strategyStickySessions(url string) strategyFn { key := utils.MapHash(getKeyWithSrcAndDst(metadata)) length := len(proxies) idx, has := lruCache.Get(key) - if !has { + if !has || idx >= length { idx = int(jumpHash(key+uint64(time.Now().UnixNano()), int32(length))) } @@ -239,7 +239,7 @@ func (lb *LoadBalance) MarshalJSON() ([]byte, error) { }) } -func NewLoadBalance(option *GroupCommonOption, providers []provider.ProxyProvider, strategy string) (lb *LoadBalance, err error) { +func NewLoadBalance(option *GroupCommonOption, providers []P.ProxyProvider, strategy string) (lb *LoadBalance, err error) { var strategyFn strategyFn switch strategy { case "consistent-hashing": diff --git a/clash-meta-android/core/src/foss/golang/clash/adapter/outboundgroup/parser.go b/clash-meta-android/core/src/foss/golang/clash/adapter/outboundgroup/parser.go index 9c09a0f4a2..2dcdd628b2 100644 --- a/clash-meta-android/core/src/foss/golang/clash/adapter/outboundgroup/parser.go +++ b/clash-meta-android/core/src/foss/golang/clash/adapter/outboundgroup/parser.go @@ -11,7 +11,7 @@ import ( "github.com/metacubex/mihomo/common/structure" "github.com/metacubex/mihomo/common/utils" C "github.com/metacubex/mihomo/constant" - types "github.com/metacubex/mihomo/constant/provider" + P "github.com/metacubex/mihomo/constant/provider" "github.com/metacubex/mihomo/log" ) @@ -48,7 +48,7 @@ type GroupCommonOption struct { RoutingMark int `group:"routing-mark,omitempty"` } -func ParseProxyGroup(config map[string]any, proxyMap map[string]C.Proxy, providersMap map[string]types.ProxyProvider, AllProxies []string, AllProviders []string) (C.ProxyAdapter, error) { +func ParseProxyGroup(config map[string]any, proxyMap map[string]C.Proxy, providersMap map[string]P.ProxyProvider, AllProxies []string, AllProviders []string) (C.ProxyAdapter, error) { decoder := structure.NewDecoder(structure.Option{TagName: "group", WeaklyTypedInput: true}) groupOption := &GroupCommonOption{ @@ -71,7 +71,7 @@ func ParseProxyGroup(config map[string]any, proxyMap map[string]C.Proxy, provide groupName := groupOption.Name - providers := []types.ProxyProvider{} + providers := []P.ProxyProvider{} if groupOption.IncludeAll { groupOption.IncludeAllProviders = true @@ -169,7 +169,7 @@ func ParseProxyGroup(config map[string]any, proxyMap map[string]C.Proxy, provide return nil, fmt.Errorf("%s: %w", groupName, err) } - providers = append([]types.ProxyProvider{pd}, providers...) + providers = append([]P.ProxyProvider{pd}, providers...) providersMap[groupName] = pd } @@ -206,15 +206,15 @@ func getProxies(mapping map[string]C.Proxy, list []string) ([]C.Proxy, error) { return ps, nil } -func getProviders(mapping map[string]types.ProxyProvider, list []string) ([]types.ProxyProvider, error) { - var ps []types.ProxyProvider +func getProviders(mapping map[string]P.ProxyProvider, list []string) ([]P.ProxyProvider, error) { + var ps []P.ProxyProvider for _, name := range list { p, ok := mapping[name] if !ok { return nil, fmt.Errorf("'%s' not found", name) } - if p.VehicleType() == types.Compatible { + if p.VehicleType() == P.Compatible { return nil, fmt.Errorf("proxy group %s can't contains in `use`", name) } ps = append(ps, p) @@ -222,7 +222,7 @@ func getProviders(mapping map[string]types.ProxyProvider, list []string) ([]type return ps, nil } -func addTestUrlToProviders(providers []types.ProxyProvider, url string, expectedStatus utils.IntRanges[uint16], filter string, interval uint) { +func addTestUrlToProviders(providers []P.ProxyProvider, url string, expectedStatus utils.IntRanges[uint16], filter string, interval uint) { if len(providers) == 0 || len(url) == 0 { return } diff --git a/clash-meta-android/core/src/foss/golang/clash/adapter/outboundgroup/patch_android.go b/clash-meta-android/core/src/foss/golang/clash/adapter/outboundgroup/patch_android.go index c6566814f8..016ed6067b 100644 --- a/clash-meta-android/core/src/foss/golang/clash/adapter/outboundgroup/patch_android.go +++ b/clash-meta-android/core/src/foss/golang/clash/adapter/outboundgroup/patch_android.go @@ -4,22 +4,22 @@ package outboundgroup import ( C "github.com/metacubex/mihomo/constant" - "github.com/metacubex/mihomo/constant/provider" + P "github.com/metacubex/mihomo/constant/provider" ) type ProxyGroup interface { C.ProxyAdapter - Providers() []provider.ProxyProvider + Providers() []P.ProxyProvider Proxies() []C.Proxy Now() string } -func (f *Fallback) Providers() []provider.ProxyProvider { +func (f *Fallback) Providers() []P.ProxyProvider { return f.providers } -func (lb *LoadBalance) Providers() []provider.ProxyProvider { +func (lb *LoadBalance) Providers() []P.ProxyProvider { return lb.providers } @@ -35,7 +35,7 @@ func (lb *LoadBalance) Now() string { return "" } -func (r *Relay) Providers() []provider.ProxyProvider { +func (r *Relay) Providers() []P.ProxyProvider { return r.providers } @@ -47,7 +47,7 @@ func (r *Relay) Now() string { return "" } -func (s *Selector) Providers() []provider.ProxyProvider { +func (s *Selector) Providers() []P.ProxyProvider { return s.providers } @@ -55,7 +55,7 @@ func (s *Selector) Proxies() []C.Proxy { return s.GetProxies(false) } -func (u *URLTest) Providers() []provider.ProxyProvider { +func (u *URLTest) Providers() []P.ProxyProvider { return u.providers } diff --git a/clash-meta-android/core/src/foss/golang/clash/adapter/outboundgroup/relay.go b/clash-meta-android/core/src/foss/golang/clash/adapter/outboundgroup/relay.go index 77a2f03b8e..8e93d89837 100644 --- a/clash-meta-android/core/src/foss/golang/clash/adapter/outboundgroup/relay.go +++ b/clash-meta-android/core/src/foss/golang/clash/adapter/outboundgroup/relay.go @@ -8,7 +8,7 @@ import ( "github.com/metacubex/mihomo/component/dialer" "github.com/metacubex/mihomo/component/proxydialer" C "github.com/metacubex/mihomo/constant" - "github.com/metacubex/mihomo/constant/provider" + P "github.com/metacubex/mihomo/constant/provider" "github.com/metacubex/mihomo/log" ) @@ -149,7 +149,7 @@ func (r *Relay) Addr() string { return proxies[len(proxies)-1].Addr() } -func NewRelay(option *GroupCommonOption, providers []provider.ProxyProvider) *Relay { +func NewRelay(option *GroupCommonOption, providers []P.ProxyProvider) *Relay { log.Warnln("The group [%s] with relay type is deprecated, please using dialer-proxy instead", option.Name) return &Relay{ GroupBase: NewGroupBase(GroupBaseOption{ diff --git a/clash-meta-android/core/src/foss/golang/clash/adapter/outboundgroup/selector.go b/clash-meta-android/core/src/foss/golang/clash/adapter/outboundgroup/selector.go index 03ee192c9e..f8975df744 100644 --- a/clash-meta-android/core/src/foss/golang/clash/adapter/outboundgroup/selector.go +++ b/clash-meta-android/core/src/foss/golang/clash/adapter/outboundgroup/selector.go @@ -6,7 +6,7 @@ import ( "errors" C "github.com/metacubex/mihomo/constant" - "github.com/metacubex/mihomo/constant/provider" + P "github.com/metacubex/mihomo/constant/provider" ) type Selector struct { @@ -108,7 +108,7 @@ func (s *Selector) selectedProxy(touch bool) C.Proxy { return proxies[0] } -func NewSelector(option *GroupCommonOption, providers []provider.ProxyProvider) *Selector { +func NewSelector(option *GroupCommonOption, providers []P.ProxyProvider) *Selector { return &Selector{ GroupBase: NewGroupBase(GroupBaseOption{ Name: option.Name, diff --git a/clash-meta-android/core/src/foss/golang/clash/adapter/outboundgroup/urltest.go b/clash-meta-android/core/src/foss/golang/clash/adapter/outboundgroup/urltest.go index 5dc620547e..2adb3b814e 100644 --- a/clash-meta-android/core/src/foss/golang/clash/adapter/outboundgroup/urltest.go +++ b/clash-meta-android/core/src/foss/golang/clash/adapter/outboundgroup/urltest.go @@ -11,7 +11,7 @@ import ( "github.com/metacubex/mihomo/common/singledo" "github.com/metacubex/mihomo/common/utils" C "github.com/metacubex/mihomo/constant" - "github.com/metacubex/mihomo/constant/provider" + P "github.com/metacubex/mihomo/constant/provider" ) type urlTestOption func(*URLTest) @@ -202,7 +202,7 @@ func parseURLTestOption(config map[string]any) []urlTestOption { return opts } -func NewURLTest(option *GroupCommonOption, providers []provider.ProxyProvider, options ...urlTestOption) *URLTest { +func NewURLTest(option *GroupCommonOption, providers []P.ProxyProvider, options ...urlTestOption) *URLTest { urlTest := &URLTest{ GroupBase: NewGroupBase(GroupBaseOption{ Name: option.Name, diff --git a/clash-meta-android/core/src/foss/golang/clash/adapter/parser.go b/clash-meta-android/core/src/foss/golang/clash/adapter/parser.go index 56febe2817..3052ab107f 100644 --- a/clash-meta-android/core/src/foss/golang/clash/adapter/parser.go +++ b/clash-meta-android/core/src/foss/golang/clash/adapter/parser.go @@ -49,13 +49,7 @@ func ParseProxy(mapping map[string]any) (C.Proxy, error) { } proxy, err = outbound.NewHttp(*httpOption) case "vmess": - vmessOption := &outbound.VmessOption{ - HTTPOpts: outbound.HTTPOptions{ - Method: "GET", - Path: []string{"/"}, - }, - } - + vmessOption := &outbound.VmessOption{} err = decoder.Decode(mapping, vmessOption) if err != nil { break diff --git a/clash-meta-android/core/src/foss/golang/clash/adapter/provider/parser.go b/clash-meta-android/core/src/foss/golang/clash/adapter/provider/parser.go index 57dc6e24f6..d6297b5662 100644 --- a/clash-meta-android/core/src/foss/golang/clash/adapter/provider/parser.go +++ b/clash-meta-android/core/src/foss/golang/clash/adapter/provider/parser.go @@ -10,7 +10,7 @@ import ( "github.com/metacubex/mihomo/common/utils" "github.com/metacubex/mihomo/component/resource" C "github.com/metacubex/mihomo/constant" - types "github.com/metacubex/mihomo/constant/provider" + P "github.com/metacubex/mihomo/constant/provider" "github.com/dlclark/regexp2" ) @@ -73,7 +73,7 @@ type proxyProviderSchema struct { Header map[string][]string `provider:"header,omitempty"` } -func ParseProxyProvider(name string, mapping map[string]any) (types.ProxyProvider, error) { +func ParseProxyProvider(name string, mapping map[string]any) (P.ProxyProvider, error) { decoder := structure.NewDecoder(structure.Option{TagName: "provider", WeaklyTypedInput: true}) schema := &proxyProviderSchema{ @@ -104,7 +104,7 @@ func ParseProxyProvider(name string, mapping map[string]any) (types.ProxyProvide return nil, err } - var vehicle types.Vehicle + var vehicle P.Vehicle switch schema.Type { case "file": path := C.Path.Resolve(schema.Path) diff --git a/clash-meta-android/core/src/foss/golang/clash/adapter/provider/provider.go b/clash-meta-android/core/src/foss/golang/clash/adapter/provider/provider.go index 2f71b41bb1..e5d3b8acd5 100644 --- a/clash-meta-android/core/src/foss/golang/clash/adapter/provider/provider.go +++ b/clash-meta-android/core/src/foss/golang/clash/adapter/provider/provider.go @@ -16,7 +16,7 @@ import ( "github.com/metacubex/mihomo/component/profile/cachefile" "github.com/metacubex/mihomo/component/resource" C "github.com/metacubex/mihomo/constant" - types "github.com/metacubex/mihomo/constant/provider" + P "github.com/metacubex/mihomo/constant/provider" "github.com/metacubex/mihomo/tunnel/statistic" "github.com/dlclark/regexp2" @@ -68,8 +68,8 @@ func (bp *baseProvider) HealthCheck() { bp.healthCheck.check() } -func (bp *baseProvider) Type() types.ProviderType { - return types.Proxy +func (bp *baseProvider) Type() P.ProviderType { + return P.Proxy } func (bp *baseProvider) Proxies() []C.Proxy { @@ -171,7 +171,7 @@ func (pp *proxySetProvider) Close() error { return pp.Fetcher.Close() } -func NewProxySetProvider(name string, interval time.Duration, payload []map[string]any, parser resource.Parser[[]C.Proxy], vehicle types.Vehicle, hc *HealthCheck) (*ProxySetProvider, error) { +func NewProxySetProvider(name string, interval time.Duration, payload []map[string]any, parser resource.Parser[[]C.Proxy], vehicle P.Vehicle, hc *HealthCheck) (*ProxySetProvider, error) { pd := &proxySetProvider{ baseProvider: baseProvider{ name: name, @@ -238,8 +238,8 @@ func (ip *inlineProvider) MarshalJSON() ([]byte, error) { }) } -func (ip *inlineProvider) VehicleType() types.VehicleType { - return types.Inline +func (ip *inlineProvider) VehicleType() P.VehicleType { + return P.Inline } func (ip *inlineProvider) Update() error { @@ -303,8 +303,8 @@ func (cp *compatibleProvider) Update() error { return nil } -func (cp *compatibleProvider) VehicleType() types.VehicleType { - return types.Compatible +func (cp *compatibleProvider) VehicleType() P.VehicleType { + return P.Compatible } func NewCompatibleProvider(name string, proxies []C.Proxy, hc *HealthCheck) (*CompatibleProvider, error) { diff --git a/clash-meta-android/core/src/foss/golang/clash/common/maphash/comparable_go120.go b/clash-meta-android/core/src/foss/golang/clash/common/maphash/comparable_go120.go index 05256d67dd..b4ddad84c6 100644 --- a/clash-meta-android/core/src/foss/golang/clash/common/maphash/comparable_go120.go +++ b/clash-meta-android/core/src/foss/golang/clash/common/maphash/comparable_go120.go @@ -138,3 +138,5 @@ func escape[T any](x T) T { // ptrSize is the size of a pointer in bytes - unsafe.Sizeof(uintptr(0)) but as an ideal constant. // It is also the size of the machine's native word size (that is, 4 on 32-bit systems, 8 on 64-bit). const ptrSize = 4 << (^uintptr(0) >> 63) + +const testComparableAllocations = false diff --git a/clash-meta-android/core/src/foss/golang/clash/common/maphash/comparable_go124.go b/clash-meta-android/core/src/foss/golang/clash/common/maphash/comparable_go124.go index 3a96edb661..4e5fcc33d0 100644 --- a/clash-meta-android/core/src/foss/golang/clash/common/maphash/comparable_go124.go +++ b/clash-meta-android/core/src/foss/golang/clash/common/maphash/comparable_go124.go @@ -11,3 +11,5 @@ func Comparable[T comparable](seed Seed, v T) uint64 { func WriteComparable[T comparable](h *Hash, x T) { maphash.WriteComparable(h, x) } + +const testComparableAllocations = true diff --git a/clash-meta-android/core/src/foss/golang/clash/common/maphash/maphash_test.go b/clash-meta-android/core/src/foss/golang/clash/common/maphash/maphash_test.go index 73887f2715..6cafe9cbee 100644 --- a/clash-meta-android/core/src/foss/golang/clash/common/maphash/maphash_test.go +++ b/clash-meta-android/core/src/foss/golang/clash/common/maphash/maphash_test.go @@ -423,7 +423,9 @@ func TestWriteComparableNoncommute(t *testing.T) { } func TestComparableAllocations(t *testing.T) { - t.Skip("test broken in old golang version") + if !testComparableAllocations { + t.Skip("test broken in old golang version") + } seed := MakeSeed() x := heapStr(t) allocs := testing.AllocsPerRun(10, func() { diff --git a/clash-meta-android/core/src/foss/golang/clash/common/net/sing.go b/clash-meta-android/core/src/foss/golang/clash/common/net/sing.go index 72bfd97253..df07bf98df 100644 --- a/clash-meta-android/core/src/foss/golang/clash/common/net/sing.go +++ b/clash-meta-android/core/src/foss/golang/clash/common/net/sing.go @@ -24,6 +24,8 @@ var WriteBuffer = bufio.WriteBuffer type ReadWaitOptions = network.ReadWaitOptions var NewReadWaitOptions = network.NewReadWaitOptions +var CalculateFrontHeadroom = network.CalculateFrontHeadroom +var CalculateRearHeadroom = network.CalculateRearHeadroom type ReaderWithUpstream = network.ReaderWithUpstream type WithUpstreamReader = network.WithUpstreamReader diff --git a/clash-meta-android/core/src/foss/golang/clash/common/structure/structure.go b/clash-meta-android/core/src/foss/golang/clash/common/structure/structure.go index 5bafc178e0..bf79f7dd27 100644 --- a/clash-meta-android/core/src/foss/golang/clash/common/structure/structure.go +++ b/clash-meta-android/core/src/foss/golang/clash/common/structure/structure.go @@ -53,6 +53,12 @@ func (d *Decoder) Decode(src map[string]any, dst any) error { key, omitKey, found := strings.Cut(tag, ",") omitempty := found && omitKey == "omitempty" + // As a special case, if the field tag is "-", the field is always omitted. + // Note that a field with name "-" can still be generated using the tag "-,". + if key == "-" { + continue + } + value, ok := src[key] if !ok { if d.option.KeyReplacer != nil { diff --git a/clash-meta-android/core/src/foss/golang/clash/common/structure/structure_test.go b/clash-meta-android/core/src/foss/golang/clash/common/structure/structure_test.go index fcdd853a63..06dffd0f32 100644 --- a/clash-meta-android/core/src/foss/golang/clash/common/structure/structure_test.go +++ b/clash-meta-android/core/src/foss/golang/clash/common/structure/structure_test.go @@ -288,3 +288,23 @@ func TestStructure_Null(t *testing.T) { assert.Nil(t, err) assert.Equal(t, s.Opt.Bar, "") } + +func TestStructure_Ignore(t *testing.T) { + rawMap := map[string]any{ + "-": "newData", + } + + s := struct { + MustIgnore string `test:"-"` + }{MustIgnore: "oldData"} + + err := decoder.Decode(rawMap, &s) + assert.Nil(t, err) + assert.Equal(t, s.MustIgnore, "oldData") + + // test omitempty + delete(rawMap, "-") + err = decoder.Decode(rawMap, &s) + assert.Nil(t, err) + assert.Equal(t, s.MustIgnore, "oldData") +} diff --git a/clash-meta-android/core/src/foss/golang/clash/component/fakeip/cachefile.go b/clash-meta-android/core/src/foss/golang/clash/component/fakeip/cachefile.go index 92d09721d8..2ebb0d58e4 100644 --- a/clash-meta-android/core/src/foss/golang/clash/component/fakeip/cachefile.go +++ b/clash-meta-android/core/src/foss/golang/clash/component/fakeip/cachefile.go @@ -50,6 +50,10 @@ func (c *cachefileStore) FlushFakeIP() error { return c.cache.FlushFakeIP() } -func newCachefileStore(cache *cachefile.CacheFile) *cachefileStore { - return &cachefileStore{cache.FakeIpStore()} +func newCachefileStore(cache *cachefile.CacheFile, prefix netip.Prefix) *cachefileStore { + if prefix.Addr().Is6() { + return &cachefileStore{cache.FakeIpStore6()} + } else { + return &cachefileStore{cache.FakeIpStore()} + } } diff --git a/clash-meta-android/core/src/foss/golang/clash/component/fakeip/pool.go b/clash-meta-android/core/src/foss/golang/clash/component/fakeip/pool.go index 895fb6587d..0417e20c52 100644 --- a/clash-meta-android/core/src/foss/golang/clash/component/fakeip/pool.go +++ b/clash-meta-android/core/src/foss/golang/clash/component/fakeip/pool.go @@ -7,7 +7,6 @@ import ( "sync" "github.com/metacubex/mihomo/component/profile/cachefile" - C "github.com/metacubex/mihomo/constant" "go4.org/netipx" ) @@ -36,8 +35,6 @@ type Pool struct { offset netip.Addr cycle bool mux sync.Mutex - host []C.DomainMatcher - mode C.FilterMode ipnet netip.Prefix store store } @@ -66,24 +63,6 @@ func (p *Pool) LookBack(ip netip.Addr) (string, bool) { return p.store.GetByIP(ip) } -// ShouldSkipped return if domain should be skipped -func (p *Pool) ShouldSkipped(domain string) bool { - should := p.shouldSkipped(domain) - if p.mode == C.FilterWhiteList { - return !should - } - return should -} - -func (p *Pool) shouldSkipped(domain string) bool { - for _, matcher := range p.host { - if matcher.MatchDomain(domain) { - return true - } - } - return false -} - // Exist returns if given ip exists in fake-ip pool func (p *Pool) Exist(ip netip.Addr) bool { p.mux.Lock() @@ -166,8 +145,6 @@ func (p *Pool) restoreState() { type Options struct { IPNet netip.Prefix - Host []C.DomainMatcher - Mode C.FilterMode // Size sets the maximum number of entries in memory // and does not work if Persistence is true @@ -197,12 +174,10 @@ func New(options Options) (*Pool, error) { last: last, offset: first.Prev(), cycle: false, - host: options.Host, - mode: options.Mode, ipnet: options.IPNet, } if options.Persistence { - pool.store = newCachefileStore(cachefile.Cache()) + pool.store = newCachefileStore(cachefile.Cache(), options.IPNet) } else { pool.store = newMemoryStore(options.Size) } diff --git a/clash-meta-android/core/src/foss/golang/clash/component/fakeip/pool_test.go b/clash-meta-android/core/src/foss/golang/clash/component/fakeip/pool_test.go index be78b87c71..0952bc3b07 100644 --- a/clash-meta-android/core/src/foss/golang/clash/component/fakeip/pool_test.go +++ b/clash-meta-android/core/src/foss/golang/clash/component/fakeip/pool_test.go @@ -8,8 +8,6 @@ import ( "time" "github.com/metacubex/mihomo/component/profile/cachefile" - "github.com/metacubex/mihomo/component/trie" - C "github.com/metacubex/mihomo/constant" "github.com/metacubex/bbolt" "github.com/stretchr/testify/assert" @@ -43,7 +41,7 @@ func createCachefileStore(options Options) (*Pool, string, error) { return nil, "", err } - pool.store = newCachefileStore(&cachefile.CacheFile{DB: db}) + pool.store = newCachefileStore(&cachefile.CacheFile{DB: db}, options.IPNet) return pool, f.Name(), nil } @@ -146,47 +144,6 @@ func TestPool_CycleUsed(t *testing.T) { } } -func TestPool_Skip(t *testing.T) { - ipnet := netip.MustParsePrefix("192.168.0.1/29") - tree := trie.New[struct{}]() - assert.NoError(t, tree.Insert("example.com", struct{}{})) - assert.False(t, tree.IsEmpty()) - pools, tempfile, err := createPools(Options{ - IPNet: ipnet, - Size: 10, - Host: []C.DomainMatcher{tree.NewDomainSet()}, - }) - assert.Nil(t, err) - defer os.Remove(tempfile) - - for _, pool := range pools { - assert.True(t, pool.ShouldSkipped("example.com")) - assert.False(t, pool.ShouldSkipped("foo.com")) - assert.False(t, pool.shouldSkipped("baz.com")) - } -} - -func TestPool_SkipWhiteList(t *testing.T) { - ipnet := netip.MustParsePrefix("192.168.0.1/29") - tree := trie.New[struct{}]() - assert.NoError(t, tree.Insert("example.com", struct{}{})) - assert.False(t, tree.IsEmpty()) - pools, tempfile, err := createPools(Options{ - IPNet: ipnet, - Size: 10, - Host: []C.DomainMatcher{tree.NewDomainSet()}, - Mode: C.FilterWhiteList, - }) - assert.Nil(t, err) - defer os.Remove(tempfile) - - for _, pool := range pools { - assert.False(t, pool.ShouldSkipped("example.com")) - assert.True(t, pool.ShouldSkipped("foo.com")) - assert.True(t, pool.ShouldSkipped("baz.com")) - } -} - func TestPool_MaxCacheSize(t *testing.T) { ipnet := netip.MustParsePrefix("192.168.0.1/24") pool, _ := New(Options{ diff --git a/clash-meta-android/core/src/foss/golang/clash/component/fakeip/skipper.go b/clash-meta-android/core/src/foss/golang/clash/component/fakeip/skipper.go new file mode 100644 index 0000000000..2df4094a0b --- /dev/null +++ b/clash-meta-android/core/src/foss/golang/clash/component/fakeip/skipper.go @@ -0,0 +1,28 @@ +package fakeip + +import ( + C "github.com/metacubex/mihomo/constant" +) + +type Skipper struct { + Host []C.DomainMatcher + Mode C.FilterMode +} + +// ShouldSkipped return if domain should be skipped +func (p *Skipper) ShouldSkipped(domain string) bool { + should := p.shouldSkipped(domain) + if p.Mode == C.FilterWhiteList { + return !should + } + return should +} + +func (p *Skipper) shouldSkipped(domain string) bool { + for _, matcher := range p.Host { + if matcher.MatchDomain(domain) { + return true + } + } + return false +} diff --git a/clash-meta-android/core/src/foss/golang/clash/component/fakeip/skipper_test.go b/clash-meta-android/core/src/foss/golang/clash/component/fakeip/skipper_test.go new file mode 100644 index 0000000000..3ffffee930 --- /dev/null +++ b/clash-meta-android/core/src/foss/golang/clash/component/fakeip/skipper_test.go @@ -0,0 +1,35 @@ +package fakeip + +import ( + "testing" + + "github.com/metacubex/mihomo/component/trie" + C "github.com/metacubex/mihomo/constant" + + "github.com/stretchr/testify/assert" +) + +func TestSkipper_BlackList(t *testing.T) { + tree := trie.New[struct{}]() + assert.NoError(t, tree.Insert("example.com", struct{}{})) + assert.False(t, tree.IsEmpty()) + skipper := &Skipper{ + Host: []C.DomainMatcher{tree.NewDomainSet()}, + } + assert.True(t, skipper.ShouldSkipped("example.com")) + assert.False(t, skipper.ShouldSkipped("foo.com")) + assert.False(t, skipper.shouldSkipped("baz.com")) +} + +func TestSkipper_WhiteList(t *testing.T) { + tree := trie.New[struct{}]() + assert.NoError(t, tree.Insert("example.com", struct{}{})) + assert.False(t, tree.IsEmpty()) + skipper := &Skipper{ + Host: []C.DomainMatcher{tree.NewDomainSet()}, + Mode: C.FilterWhiteList, + } + assert.False(t, skipper.ShouldSkipped("example.com")) + assert.True(t, skipper.ShouldSkipped("foo.com")) + assert.True(t, skipper.ShouldSkipped("baz.com")) +} diff --git a/clash-meta-android/core/src/foss/golang/clash/component/profile/cachefile/cache.go b/clash-meta-android/core/src/foss/golang/clash/component/profile/cachefile/cache.go index 7b4cdfc2a6..3c46d7338b 100644 --- a/clash-meta-android/core/src/foss/golang/clash/component/profile/cachefile/cache.go +++ b/clash-meta-android/core/src/foss/golang/clash/component/profile/cachefile/cache.go @@ -19,6 +19,7 @@ var ( bucketSelected = []byte("selected") bucketFakeip = []byte("fakeip") + bucketFakeip6 = []byte("fakeip6") bucketETag = []byte("etag") bucketSubscriptionInfo = []byte("subscriptioninfo") ) diff --git a/clash-meta-android/core/src/foss/golang/clash/component/profile/cachefile/fakeip.go b/clash-meta-android/core/src/foss/golang/clash/component/profile/cachefile/fakeip.go index 20a09f9c95..5278132820 100644 --- a/clash-meta-android/core/src/foss/golang/clash/component/profile/cachefile/fakeip.go +++ b/clash-meta-android/core/src/foss/golang/clash/component/profile/cachefile/fakeip.go @@ -10,10 +10,15 @@ import ( type FakeIpStore struct { *CacheFile + bucketName []byte } func (c *CacheFile) FakeIpStore() *FakeIpStore { - return &FakeIpStore{c} + return &FakeIpStore{c, bucketFakeip} +} + +func (c *CacheFile) FakeIpStore6() *FakeIpStore { + return &FakeIpStore{c, bucketFakeip6} } func (c *FakeIpStore) GetByHost(host string) (ip netip.Addr, exist bool) { @@ -21,7 +26,7 @@ func (c *FakeIpStore) GetByHost(host string) (ip netip.Addr, exist bool) { return } c.DB.View(func(t *bbolt.Tx) error { - if bucket := t.Bucket(bucketFakeip); bucket != nil { + if bucket := t.Bucket(c.bucketName); bucket != nil { if v := bucket.Get([]byte(host)); v != nil { ip, exist = netip.AddrFromSlice(v) } @@ -36,7 +41,7 @@ func (c *FakeIpStore) PutByHost(host string, ip netip.Addr) { return } err := c.DB.Batch(func(t *bbolt.Tx) error { - bucket, err := t.CreateBucketIfNotExists(bucketFakeip) + bucket, err := t.CreateBucketIfNotExists(c.bucketName) if err != nil { return err } @@ -52,7 +57,7 @@ func (c *FakeIpStore) GetByIP(ip netip.Addr) (host string, exist bool) { return } c.DB.View(func(t *bbolt.Tx) error { - if bucket := t.Bucket(bucketFakeip); bucket != nil { + if bucket := t.Bucket(c.bucketName); bucket != nil { if v := bucket.Get(ip.AsSlice()); v != nil { host, exist = string(v), true } @@ -67,7 +72,7 @@ func (c *FakeIpStore) PutByIP(ip netip.Addr, host string) { return } err := c.DB.Batch(func(t *bbolt.Tx) error { - bucket, err := t.CreateBucketIfNotExists(bucketFakeip) + bucket, err := t.CreateBucketIfNotExists(c.bucketName) if err != nil { return err } @@ -85,7 +90,7 @@ func (c *FakeIpStore) DelByIP(ip netip.Addr) { addr := ip.AsSlice() err := c.DB.Batch(func(t *bbolt.Tx) error { - bucket, err := t.CreateBucketIfNotExists(bucketFakeip) + bucket, err := t.CreateBucketIfNotExists(c.bucketName) if err != nil { return err } @@ -105,11 +110,11 @@ func (c *FakeIpStore) DelByIP(ip netip.Addr) { func (c *FakeIpStore) FlushFakeIP() error { err := c.DB.Batch(func(t *bbolt.Tx) error { - bucket := t.Bucket(bucketFakeip) + bucket := t.Bucket(c.bucketName) if bucket == nil { return nil } - return t.DeleteBucket(bucketFakeip) + return t.DeleteBucket(c.bucketName) }) return err } diff --git a/clash-meta-android/core/src/foss/golang/clash/component/resource/fetcher.go b/clash-meta-android/core/src/foss/golang/clash/component/resource/fetcher.go index 24f24d47b9..a48e7bc82f 100644 --- a/clash-meta-android/core/src/foss/golang/clash/component/resource/fetcher.go +++ b/clash-meta-android/core/src/foss/golang/clash/component/resource/fetcher.go @@ -8,7 +8,7 @@ import ( "github.com/metacubex/mihomo/common/utils" "github.com/metacubex/mihomo/component/slowdown" - types "github.com/metacubex/mihomo/constant/provider" + P "github.com/metacubex/mihomo/constant/provider" "github.com/metacubex/mihomo/log" "github.com/metacubex/fswatch" @@ -22,7 +22,7 @@ type Fetcher[V any] struct { ctxCancel context.CancelFunc resourceType string name string - vehicle types.Vehicle + vehicle P.Vehicle updatedAt time.Time hash utils.HashType parser Parser[V] @@ -37,11 +37,11 @@ func (f *Fetcher[V]) Name() string { return f.name } -func (f *Fetcher[V]) Vehicle() types.Vehicle { +func (f *Fetcher[V]) Vehicle() P.Vehicle { return f.vehicle } -func (f *Fetcher[V]) VehicleType() types.VehicleType { +func (f *Fetcher[V]) VehicleType() P.VehicleType { return f.vehicle.Type() } @@ -88,7 +88,7 @@ func (f *Fetcher[V]) Update() (V, bool, error) { f.backoff.AddAttempt() // add a failed attempt to backoff return lo.Empty[V](), false, err } - return f.loadBuf(buf, hash, f.vehicle.Type() != types.File) + return f.loadBuf(buf, hash, f.vehicle.Type() != P.File) } func (f *Fetcher[V]) SideUpdate(buf []byte) (V, bool, error) { @@ -180,7 +180,7 @@ func (f *Fetcher[V]) pullLoop(forceUpdate bool) { func (f *Fetcher[V]) startPullLoop(forceUpdate bool) (err error) { // pull contents automatically - if f.vehicle.Type() == types.File { + if f.vehicle.Type() == P.File { f.watcher, err = fswatch.NewWatcher(fswatch.Options{ Path: []string{f.vehicle.Path()}, Callback: f.updateCallback, @@ -218,7 +218,7 @@ func (f *Fetcher[V]) updateWithLog() { return } -func NewFetcher[V any](name string, interval time.Duration, vehicle types.Vehicle, parser Parser[V], onUpdate func(V)) *Fetcher[V] { +func NewFetcher[V any](name string, interval time.Duration, vehicle P.Vehicle, parser Parser[V], onUpdate func(V)) *Fetcher[V] { ctx, cancel := context.WithCancel(context.Background()) minBackoff := 10 * time.Second if interval < minBackoff { diff --git a/clash-meta-android/core/src/foss/golang/clash/component/resource/vehicle.go b/clash-meta-android/core/src/foss/golang/clash/component/resource/vehicle.go index 67ab19b723..a34417aab2 100644 --- a/clash-meta-android/core/src/foss/golang/clash/component/resource/vehicle.go +++ b/clash-meta-android/core/src/foss/golang/clash/component/resource/vehicle.go @@ -12,7 +12,7 @@ import ( "github.com/metacubex/mihomo/common/utils" mihomoHttp "github.com/metacubex/mihomo/component/http" "github.com/metacubex/mihomo/component/profile/cachefile" - types "github.com/metacubex/mihomo/constant/provider" + P "github.com/metacubex/mihomo/constant/provider" ) const ( @@ -50,8 +50,8 @@ type FileVehicle struct { path string } -func (f *FileVehicle) Type() types.VehicleType { - return types.File +func (f *FileVehicle) Type() P.VehicleType { + return P.File } func (f *FileVehicle) Path() string { @@ -91,15 +91,15 @@ type HTTPVehicle struct { timeout time.Duration sizeLimit int64 inRead func(response *http.Response) - provider types.ProxyProvider + provider P.ProxyProvider } func (h *HTTPVehicle) Url() string { return h.url } -func (h *HTTPVehicle) Type() types.VehicleType { - return types.HTTP +func (h *HTTPVehicle) Type() P.VehicleType { + return P.HTTP } func (h *HTTPVehicle) Path() string { diff --git a/clash-meta-android/core/src/foss/golang/clash/config/config.go b/clash-meta-android/core/src/foss/golang/clash/config/config.go index dec0955b2d..efc8903248 100644 --- a/clash-meta-android/core/src/foss/golang/clash/config/config.go +++ b/clash-meta-android/core/src/foss/golang/clash/config/config.go @@ -20,15 +20,15 @@ import ( "github.com/metacubex/mihomo/component/cidr" "github.com/metacubex/mihomo/component/fakeip" "github.com/metacubex/mihomo/component/geodata" - P "github.com/metacubex/mihomo/component/process" + "github.com/metacubex/mihomo/component/process" "github.com/metacubex/mihomo/component/resolver" "github.com/metacubex/mihomo/component/sniffer" "github.com/metacubex/mihomo/component/trie" C "github.com/metacubex/mihomo/constant" - providerTypes "github.com/metacubex/mihomo/constant/provider" + P "github.com/metacubex/mihomo/constant/provider" snifferTypes "github.com/metacubex/mihomo/constant/sniffer" "github.com/metacubex/mihomo/dns" - L "github.com/metacubex/mihomo/listener" + "github.com/metacubex/mihomo/listener" LC "github.com/metacubex/mihomo/listener/config" "github.com/metacubex/mihomo/log" R "github.com/metacubex/mihomo/rules" @@ -44,27 +44,27 @@ import ( // General config type General struct { Inbound - Mode T.TunnelMode `json:"mode"` - UnifiedDelay bool `json:"unified-delay"` - LogLevel log.LogLevel `json:"log-level"` - IPv6 bool `json:"ipv6"` - Interface string `json:"interface-name"` - RoutingMark int `json:"routing-mark"` - GeoXUrl GeoXUrl `json:"geox-url"` - GeoAutoUpdate bool `json:"geo-auto-update"` - GeoUpdateInterval int `json:"geo-update-interval"` - GeodataMode bool `json:"geodata-mode"` - GeodataLoader string `json:"geodata-loader"` - GeositeMatcher string `json:"geosite-matcher"` - TCPConcurrent bool `json:"tcp-concurrent"` - FindProcessMode P.FindProcessMode `json:"find-process-mode"` - Sniffing bool `json:"sniffing"` - GlobalClientFingerprint string `json:"global-client-fingerprint"` - GlobalUA string `json:"global-ua"` - ETagSupport bool `json:"etag-support"` - KeepAliveIdle int `json:"keep-alive-idle"` - KeepAliveInterval int `json:"keep-alive-interval"` - DisableKeepAlive bool `json:"disable-keep-alive"` + Mode T.TunnelMode `json:"mode"` + UnifiedDelay bool `json:"unified-delay"` + LogLevel log.LogLevel `json:"log-level"` + IPv6 bool `json:"ipv6"` + Interface string `json:"interface-name"` + RoutingMark int `json:"routing-mark"` + GeoXUrl GeoXUrl `json:"geox-url"` + GeoAutoUpdate bool `json:"geo-auto-update"` + GeoUpdateInterval int `json:"geo-update-interval"` + GeodataMode bool `json:"geodata-mode"` + GeodataLoader string `json:"geodata-loader"` + GeositeMatcher string `json:"geosite-matcher"` + TCPConcurrent bool `json:"tcp-concurrent"` + FindProcessMode process.FindProcessMode `json:"find-process-mode"` + Sniffing bool `json:"sniffing"` + GlobalClientFingerprint string `json:"global-client-fingerprint"` + GlobalUA string `json:"global-ua"` + ETagSupport bool `json:"etag-support"` + KeepAliveIdle int `json:"keep-alive-idle"` + KeepAliveInterval int `json:"keep-alive-interval"` + DisableKeepAlive bool `json:"disable-keep-alive"` } // Inbound config @@ -157,7 +157,11 @@ type DNS struct { DefaultNameserver []dns.NameServer CacheAlgorithm string CacheMaxSize int - FakeIPRange *fakeip.Pool + FakeIPRange netip.Prefix + FakeIPPool *fakeip.Pool + FakeIPRange6 netip.Prefix + FakeIPPool6 *fakeip.Pool + FakeIPSkipper *fakeip.Skipper NameServerPolicy []dns.Policy ProxyServerNameserver []dns.NameServer DirectNameServer []dns.NameServer @@ -195,8 +199,8 @@ type Config struct { Users []auth.AuthUser Proxies map[string]C.Proxy Listeners map[string]C.InboundListener - Providers map[string]providerTypes.ProxyProvider - RuleProviders map[string]providerTypes.RuleProvider + Providers map[string]P.ProxyProvider + RuleProviders map[string]P.RuleProvider Tunnels []LC.Tunnel Sniffer *sniffer.Config TLS *TLS @@ -221,6 +225,7 @@ type RawDNS struct { Listen string `yaml:"listen" json:"listen"` EnhancedMode C.DNSMode `yaml:"enhanced-mode" json:"enhanced-mode"` FakeIPRange string `yaml:"fake-ip-range" json:"fake-ip-range"` + FakeIPRange6 string `yaml:"fake-ip-range6" json:"fake-ip-range6"` FakeIPFilter []string `yaml:"fake-ip-filter" json:"fake-ip-filter"` FakeIPFilterMode C.FilterMode `yaml:"fake-ip-filter-mode" json:"fake-ip-filter-mode"` DefaultNameserver []string `yaml:"default-nameserver" json:"default-nameserver"` @@ -377,51 +382,51 @@ type RawTLS struct { } type RawConfig struct { - Port int `yaml:"port" json:"port"` - SocksPort int `yaml:"socks-port" json:"socks-port"` - RedirPort int `yaml:"redir-port" json:"redir-port"` - TProxyPort int `yaml:"tproxy-port" json:"tproxy-port"` - MixedPort int `yaml:"mixed-port" json:"mixed-port"` - ShadowSocksConfig string `yaml:"ss-config" json:"ss-config"` - VmessConfig string `yaml:"vmess-config" json:"vmess-config"` - InboundTfo bool `yaml:"inbound-tfo" json:"inbound-tfo"` - InboundMPTCP bool `yaml:"inbound-mptcp" json:"inbound-mptcp"` - Authentication []string `yaml:"authentication" json:"authentication"` - SkipAuthPrefixes []netip.Prefix `yaml:"skip-auth-prefixes" json:"skip-auth-prefixes"` - LanAllowedIPs []netip.Prefix `yaml:"lan-allowed-ips" json:"lan-allowed-ips"` - LanDisAllowedIPs []netip.Prefix `yaml:"lan-disallowed-ips" json:"lan-disallowed-ips"` - AllowLan bool `yaml:"allow-lan" json:"allow-lan"` - BindAddress string `yaml:"bind-address" json:"bind-address"` - Mode T.TunnelMode `yaml:"mode" json:"mode"` - UnifiedDelay bool `yaml:"unified-delay" json:"unified-delay"` - LogLevel log.LogLevel `yaml:"log-level" json:"log-level"` - IPv6 bool `yaml:"ipv6" json:"ipv6"` - ExternalController string `yaml:"external-controller" json:"external-controller"` - ExternalControllerPipe string `yaml:"external-controller-pipe" json:"external-controller-pipe"` - ExternalControllerUnix string `yaml:"external-controller-unix" json:"external-controller-unix"` - ExternalControllerTLS string `yaml:"external-controller-tls" json:"external-controller-tls"` - ExternalControllerCors RawCors `yaml:"external-controller-cors" json:"external-controller-cors"` - ExternalUI string `yaml:"external-ui" json:"external-ui"` - ExternalUIURL string `yaml:"external-ui-url" json:"external-ui-url"` - ExternalUIName string `yaml:"external-ui-name" json:"external-ui-name"` - ExternalDohServer string `yaml:"external-doh-server" json:"external-doh-server"` - Secret string `yaml:"secret" json:"secret"` - Interface string `yaml:"interface-name" json:"interface-name"` - RoutingMark int `yaml:"routing-mark" json:"routing-mark"` - Tunnels []LC.Tunnel `yaml:"tunnels" json:"tunnels"` - GeoAutoUpdate bool `yaml:"geo-auto-update" json:"geo-auto-update"` - GeoUpdateInterval int `yaml:"geo-update-interval" json:"geo-update-interval"` - GeodataMode bool `yaml:"geodata-mode" json:"geodata-mode"` - GeodataLoader string `yaml:"geodata-loader" json:"geodata-loader"` - GeositeMatcher string `yaml:"geosite-matcher" json:"geosite-matcher"` - TCPConcurrent bool `yaml:"tcp-concurrent" json:"tcp-concurrent"` - FindProcessMode P.FindProcessMode `yaml:"find-process-mode" json:"find-process-mode"` - GlobalClientFingerprint string `yaml:"global-client-fingerprint" json:"global-client-fingerprint"` - GlobalUA string `yaml:"global-ua" json:"global-ua"` - ETagSupport bool `yaml:"etag-support" json:"etag-support"` - KeepAliveIdle int `yaml:"keep-alive-idle" json:"keep-alive-idle"` - KeepAliveInterval int `yaml:"keep-alive-interval" json:"keep-alive-interval"` - DisableKeepAlive bool `yaml:"disable-keep-alive" json:"disable-keep-alive"` + Port int `yaml:"port" json:"port"` + SocksPort int `yaml:"socks-port" json:"socks-port"` + RedirPort int `yaml:"redir-port" json:"redir-port"` + TProxyPort int `yaml:"tproxy-port" json:"tproxy-port"` + MixedPort int `yaml:"mixed-port" json:"mixed-port"` + ShadowSocksConfig string `yaml:"ss-config" json:"ss-config"` + VmessConfig string `yaml:"vmess-config" json:"vmess-config"` + InboundTfo bool `yaml:"inbound-tfo" json:"inbound-tfo"` + InboundMPTCP bool `yaml:"inbound-mptcp" json:"inbound-mptcp"` + Authentication []string `yaml:"authentication" json:"authentication"` + SkipAuthPrefixes []netip.Prefix `yaml:"skip-auth-prefixes" json:"skip-auth-prefixes"` + LanAllowedIPs []netip.Prefix `yaml:"lan-allowed-ips" json:"lan-allowed-ips"` + LanDisAllowedIPs []netip.Prefix `yaml:"lan-disallowed-ips" json:"lan-disallowed-ips"` + AllowLan bool `yaml:"allow-lan" json:"allow-lan"` + BindAddress string `yaml:"bind-address" json:"bind-address"` + Mode T.TunnelMode `yaml:"mode" json:"mode"` + UnifiedDelay bool `yaml:"unified-delay" json:"unified-delay"` + LogLevel log.LogLevel `yaml:"log-level" json:"log-level"` + IPv6 bool `yaml:"ipv6" json:"ipv6"` + ExternalController string `yaml:"external-controller" json:"external-controller"` + ExternalControllerPipe string `yaml:"external-controller-pipe" json:"external-controller-pipe"` + ExternalControllerUnix string `yaml:"external-controller-unix" json:"external-controller-unix"` + ExternalControllerTLS string `yaml:"external-controller-tls" json:"external-controller-tls"` + ExternalControllerCors RawCors `yaml:"external-controller-cors" json:"external-controller-cors"` + ExternalUI string `yaml:"external-ui" json:"external-ui"` + ExternalUIURL string `yaml:"external-ui-url" json:"external-ui-url"` + ExternalUIName string `yaml:"external-ui-name" json:"external-ui-name"` + ExternalDohServer string `yaml:"external-doh-server" json:"external-doh-server"` + Secret string `yaml:"secret" json:"secret"` + Interface string `yaml:"interface-name" json:"interface-name"` + RoutingMark int `yaml:"routing-mark" json:"routing-mark"` + Tunnels []LC.Tunnel `yaml:"tunnels" json:"tunnels"` + GeoAutoUpdate bool `yaml:"geo-auto-update" json:"geo-auto-update"` + GeoUpdateInterval int `yaml:"geo-update-interval" json:"geo-update-interval"` + GeodataMode bool `yaml:"geodata-mode" json:"geodata-mode"` + GeodataLoader string `yaml:"geodata-loader" json:"geodata-loader"` + GeositeMatcher string `yaml:"geosite-matcher" json:"geosite-matcher"` + TCPConcurrent bool `yaml:"tcp-concurrent" json:"tcp-concurrent"` + FindProcessMode process.FindProcessMode `yaml:"find-process-mode" json:"find-process-mode"` + GlobalClientFingerprint string `yaml:"global-client-fingerprint" json:"global-client-fingerprint"` + GlobalUA string `yaml:"global-ua" json:"global-ua"` + ETagSupport bool `yaml:"etag-support" json:"etag-support"` + KeepAliveIdle int `yaml:"keep-alive-idle" json:"keep-alive-idle"` + KeepAliveInterval int `yaml:"keep-alive-interval" json:"keep-alive-interval"` + DisableKeepAlive bool `yaml:"disable-keep-alive" json:"disable-keep-alive"` ProxyProvider map[string]map[string]any `yaml:"proxy-providers" json:"proxy-providers"` RuleProvider map[string]map[string]any `yaml:"rule-providers" json:"rule-providers"` @@ -474,7 +479,7 @@ func DefaultRawConfig() *RawConfig { Proxy: []map[string]any{}, ProxyGroup: []map[string]any{}, TCPConcurrent: false, - FindProcessMode: P.FindProcessStrict, + FindProcessMode: process.FindProcessStrict, GlobalUA: "clash.meta/" + C.Version, ETagSupport: true, DNS: RawDNS{ @@ -648,11 +653,11 @@ func ParseRawConfig(rawCfg *RawConfig) (*Config, error) { config.Proxies = proxies config.Providers = providers - listener, err := parseListeners(rawCfg) + listeners, err := parseListeners(rawCfg) if err != nil { return nil, err } - config.Listeners = listener + config.Listeners = listeners log.Infoln("Geodata Loader mode: %s", geodata.LoaderName()) log.Infoln("Geosite Matcher implementation: %s", geodata.SiteMatcherName()) @@ -680,13 +685,15 @@ func ParseRawConfig(rawCfg *RawConfig) (*Config, error) { } config.Hosts = hosts + parseIPV6(rawCfg) // must before DNS and Tun + dnsCfg, err := parseDNS(rawCfg, ruleProviders) if err != nil { return nil, err } config.DNS = dnsCfg - err = parseTun(rawCfg.Tun, config.General) + err = parseTun(rawCfg.Tun, dnsCfg, config.General) if err != nil { return nil, err } @@ -838,9 +845,9 @@ func parseTLS(cfg *RawConfig) (*TLS, error) { }, nil } -func parseProxies(cfg *RawConfig) (proxies map[string]C.Proxy, providersMap map[string]providerTypes.ProxyProvider, err error) { +func parseProxies(cfg *RawConfig) (proxies map[string]C.Proxy, providersMap map[string]P.ProxyProvider, err error) { proxies = make(map[string]C.Proxy) - providersMap = make(map[string]providerTypes.ProxyProvider) + providersMap = make(map[string]P.ProxyProvider) proxiesConfig := cfg.Proxy groupsConfig := cfg.ProxyGroup providersConfig := cfg.ProxyProvider @@ -940,7 +947,7 @@ func parseProxies(cfg *RawConfig) (proxies map[string]C.Proxy, providersMap map[ &outboundgroup.GroupCommonOption{ Name: "GLOBAL", }, - []providerTypes.ProxyProvider{pd}, + []P.ProxyProvider{pd}, ) proxies["GLOBAL"] = adapter.NewProxy(global) } @@ -950,24 +957,25 @@ func parseProxies(cfg *RawConfig) (proxies map[string]C.Proxy, providersMap map[ func parseListeners(cfg *RawConfig) (listeners map[string]C.InboundListener, err error) { listeners = make(map[string]C.InboundListener) for index, mapping := range cfg.Listeners { - listener, err := L.ParseListener(mapping) + inboundListener, err := listener.ParseListener(mapping) if err != nil { return nil, fmt.Errorf("proxy %d: %w", index, err) } - if _, exist := mapping[listener.Name()]; exist { - return nil, fmt.Errorf("listener %s is the duplicate name", listener.Name()) + name := inboundListener.Name() + if _, exist := mapping[name]; exist { + return nil, fmt.Errorf("listener %s is the duplicate name", name) } - listeners[listener.Name()] = listener + listeners[name] = inboundListener } return } -func parseRuleProviders(cfg *RawConfig) (ruleProviders map[string]providerTypes.RuleProvider, err error) { +func parseRuleProviders(cfg *RawConfig) (ruleProviders map[string]P.RuleProvider, err error) { RP.SetTunnel(T.Tunnel) - ruleProviders = map[string]providerTypes.RuleProvider{} + ruleProviders = map[string]P.RuleProvider{} // parse rule provider for name, mapping := range cfg.RuleProvider { rp, err := RP.ParseRuleProvider(name, mapping, R.ParseRule) @@ -980,7 +988,7 @@ func parseRuleProviders(cfg *RawConfig) (ruleProviders map[string]providerTypes. return } -func parseSubRules(cfg *RawConfig, proxies map[string]C.Proxy, ruleProviders map[string]providerTypes.RuleProvider) (subRules map[string][]C.Rule, err error) { +func parseSubRules(cfg *RawConfig, proxies map[string]C.Proxy, ruleProviders map[string]P.RuleProvider) (subRules map[string][]C.Rule, err error) { subRules = map[string][]C.Rule{} for name := range cfg.SubRules { subRules[name] = make([]C.Rule, 0) @@ -1043,7 +1051,7 @@ func verifySubRuleCircularReferences(n string, subRules map[string][]C.Rule, arr return nil } -func parseRules(rulesConfig []string, proxies map[string]C.Proxy, ruleProviders map[string]providerTypes.RuleProvider, subRules map[string][]C.Rule, format string) ([]C.Rule, error) { +func parseRules(rulesConfig []string, proxies map[string]C.Proxy, ruleProviders map[string]P.RuleProvider, subRules map[string][]C.Rule, format string) ([]C.Rule, error) { var rules []C.Rule // parse rules @@ -1266,7 +1274,7 @@ func parsePureDNSServer(server string) string { } } -func parseNameServerPolicy(nsPolicy *orderedmap.OrderedMap[string, any], ruleProviders map[string]providerTypes.RuleProvider, respectRules bool, preferH3 bool) ([]dns.Policy, error) { +func parseNameServerPolicy(nsPolicy *orderedmap.OrderedMap[string, any], ruleProviders map[string]P.RuleProvider, respectRules bool, preferH3 bool) ([]dns.Policy, error) { var policy []dns.Policy for pair := nsPolicy.Oldest(); pair != nil; pair = pair.Next() { @@ -1341,7 +1349,7 @@ func parseNameServerPolicy(nsPolicy *orderedmap.OrderedMap[string, any], rulePro return policy, nil } -func parseDNS(rawCfg *RawConfig, ruleProviders map[string]providerTypes.RuleProvider) (*DNS, error) { +func parseDNS(rawCfg *RawConfig, ruleProviders map[string]P.RuleProvider) (*DNS, error) { cfg := rawCfg.DNS if cfg.Enable && len(cfg.NameServer) == 0 { return nil, fmt.Errorf("if DNS configuration is turned on, NameServer cannot be empty") @@ -1407,13 +1415,27 @@ func parseDNS(rawCfg *RawConfig, ruleProviders map[string]providerTypes.RuleProv } } - fakeIPRange, err := netip.ParsePrefix(cfg.FakeIPRange) - T.SetFakeIPRange(fakeIPRange) - if cfg.EnhancedMode == C.DNSFakeIP { + if cfg.FakeIPRange != "" { + dnsCfg.FakeIPRange, err = netip.ParsePrefix(cfg.FakeIPRange) if err != nil { return nil, err } + if !dnsCfg.FakeIPRange.Addr().Is4() { + return nil, errors.New("dns.fake-ip-range must be a IPv4 prefix") + } + } + if cfg.FakeIPRange6 != "" { + dnsCfg.FakeIPRange6, err = netip.ParsePrefix(cfg.FakeIPRange6) + if err != nil { + return nil, err + } + if !dnsCfg.FakeIPRange6.Addr().Is6() { + return nil, errors.New("dns.fake-ip-range6 must be a IPv6 prefix") + } + } + + if cfg.EnhancedMode == C.DNSFakeIP { var fakeIPTrie *trie.DomainTrie[struct{}] if len(dnsCfg.Fallback) != 0 { fakeIPTrie = trie.New[struct{}]() @@ -1431,18 +1453,39 @@ func parseDNS(rawCfg *RawConfig, ruleProviders map[string]providerTypes.RuleProv return nil, err } - pool, err := fakeip.New(fakeip.Options{ - IPNet: fakeIPRange, - Size: 1000, - Host: host, - Mode: cfg.FakeIPFilterMode, - Persistence: rawCfg.Profile.StoreFakeIP, - }) - if err != nil { - return nil, err + skipper := &fakeip.Skipper{ + Host: host, + Mode: cfg.FakeIPFilterMode, + } + dnsCfg.FakeIPSkipper = skipper + + if dnsCfg.FakeIPRange.IsValid() { + pool, err := fakeip.New(fakeip.Options{ + IPNet: dnsCfg.FakeIPRange, + Size: 1000, + Persistence: rawCfg.Profile.StoreFakeIP, + }) + if err != nil { + return nil, err + } + dnsCfg.FakeIPPool = pool } - dnsCfg.FakeIPRange = pool + if dnsCfg.FakeIPRange6.IsValid() { + pool6, err := fakeip.New(fakeip.Options{ + IPNet: dnsCfg.FakeIPRange6, + Size: 1000, + Persistence: rawCfg.Profile.StoreFakeIP, + }) + if err != nil { + return nil, err + } + dnsCfg.FakeIPPool6 = pool6 + } + + if dnsCfg.FakeIPPool == nil && dnsCfg.FakeIPPool6 == nil { + return nil, errors.New("disallow `fake-ip-range` and `fake-ip-range6` both empty with fake-ip mode") + } } if len(cfg.Fallback) != 0 { @@ -1504,17 +1547,20 @@ func parseAuthentication(rawRecords []string) []auth.AuthUser { return users } -func parseTun(rawTun RawTun, general *General) error { - tunAddressPrefix := T.FakeIPRange() +func parseIPV6(rawCfg *RawConfig) { + if !rawCfg.IPv6 || !verifyIP6() { + rawCfg.DNS.FakeIPRange6 = "" + rawCfg.Tun.Inet6Address = nil + } +} + +func parseTun(rawTun RawTun, dns *DNS, general *General) error { + tunAddressPrefix := dns.FakeIPRange if !tunAddressPrefix.IsValid() { tunAddressPrefix = netip.MustParsePrefix("198.18.0.1/16") } tunAddressPrefix = netip.PrefixFrom(tunAddressPrefix.Addr(), 30) - if !general.IPv6 || !verifyIP6() { - rawTun.Inet6Address = nil - } - general.Tun = LC.Tun{ Enable: rawTun.Enable, Device: rawTun.Device, @@ -1587,7 +1633,7 @@ func parseTuicServer(rawTuic RawTuicServer, general *General) error { return nil } -func parseSniffer(snifferRaw RawSniffer, ruleProviders map[string]providerTypes.RuleProvider) (*sniffer.Config, error) { +func parseSniffer(snifferRaw RawSniffer, ruleProviders map[string]P.RuleProvider) (*sniffer.Config, error) { snifferConfig := &sniffer.Config{ Enable: snifferRaw.Enable, ForceDnsMapping: snifferRaw.ForceDnsMapping, @@ -1677,7 +1723,7 @@ func parseSniffer(snifferRaw RawSniffer, ruleProviders map[string]providerTypes. return snifferConfig, nil } -func parseIPCIDR(addresses []string, cidrSet *cidr.IpCidrSet, adapterName string, ruleProviders map[string]providerTypes.RuleProvider) (matchers []C.IpMatcher, err error) { +func parseIPCIDR(addresses []string, cidrSet *cidr.IpCidrSet, adapterName string, ruleProviders map[string]P.RuleProvider) (matchers []C.IpMatcher, err error) { var matcher C.IpMatcher for _, ipcidr := range addresses { ipcidrLower := strings.ToLower(ipcidr) @@ -1724,7 +1770,7 @@ func parseIPCIDR(addresses []string, cidrSet *cidr.IpCidrSet, adapterName string return } -func parseDomain(domains []string, domainTrie *trie.DomainTrie[struct{}], adapterName string, ruleProviders map[string]providerTypes.RuleProvider) (matchers []C.DomainMatcher, err error) { +func parseDomain(domains []string, domainTrie *trie.DomainTrie[struct{}], adapterName string, ruleProviders map[string]P.RuleProvider) (matchers []C.DomainMatcher, err error) { var matcher C.DomainMatcher for _, domain := range domains { domainLower := strings.ToLower(domain) @@ -1767,14 +1813,14 @@ func parseDomain(domains []string, domainTrie *trie.DomainTrie[struct{}], adapte return } -func parseIPRuleSet(domainSetName string, adapterName string, ruleProviders map[string]providerTypes.RuleProvider) (C.IpMatcher, error) { +func parseIPRuleSet(domainSetName string, adapterName string, ruleProviders map[string]P.RuleProvider) (C.IpMatcher, error) { if rp, ok := ruleProviders[domainSetName]; !ok { return nil, fmt.Errorf("not found rule-set: %s", domainSetName) } else { switch rp.Behavior() { - case providerTypes.Domain: + case P.Domain: return nil, fmt.Errorf("rule provider type error, except ipcidr,actual %s", rp.Behavior()) - case providerTypes.Classical: + case P.Classical: log.Warnln("%s provider is %s, only matching it contain ip rule", rp.Name(), rp.Behavior()) default: } @@ -1782,14 +1828,14 @@ func parseIPRuleSet(domainSetName string, adapterName string, ruleProviders map[ return RP.NewRuleSet(domainSetName, adapterName, false, true) } -func parseDomainRuleSet(domainSetName string, adapterName string, ruleProviders map[string]providerTypes.RuleProvider) (C.DomainMatcher, error) { +func parseDomainRuleSet(domainSetName string, adapterName string, ruleProviders map[string]P.RuleProvider) (C.DomainMatcher, error) { if rp, ok := ruleProviders[domainSetName]; !ok { return nil, fmt.Errorf("not found rule-set: %s", domainSetName) } else { switch rp.Behavior() { - case providerTypes.IPCIDR: + case P.IPCIDR: return nil, fmt.Errorf("rule provider type error, except domain,actual %s", rp.Behavior()) - case providerTypes.Classical: + case P.Classical: log.Warnln("%s provider is %s, only matching it contain domain rule", rp.Name(), rp.Behavior()) default: } diff --git a/clash-meta-android/core/src/foss/golang/clash/config/utils.go b/clash-meta-android/core/src/foss/golang/clash/config/utils.go index c72c120df7..3e7f32528a 100644 --- a/clash-meta-android/core/src/foss/golang/clash/config/utils.go +++ b/clash-meta-android/core/src/foss/golang/clash/config/utils.go @@ -155,6 +155,10 @@ func verifyIP6() bool { } } } + } else { + // eg: Calling net.InterfaceAddrs() fails on Android SDK 30 + // https://github.com/golang/go/issues/40569 + return true // just ignore } return false } diff --git a/clash-meta-android/core/src/foss/golang/clash/constant/adapters.go b/clash-meta-android/core/src/foss/golang/clash/constant/adapters.go index ab48c47d23..97e9235b5c 100644 --- a/clash-meta-android/core/src/foss/golang/clash/constant/adapters.go +++ b/clash-meta-android/core/src/foss/golang/clash/constant/adapters.go @@ -139,8 +139,11 @@ type ProxyAdapter interface { // SupportUOT return UDP over TCP support SupportUOT() bool + // SupportWithDialer only for deprecated relay group, the new protocol does not need to be implemented. SupportWithDialer() NetWork + // DialContextWithDialer only for deprecated relay group, the new protocol does not need to be implemented. DialContextWithDialer(ctx context.Context, dialer Dialer, metadata *Metadata) (Conn, error) + // ListenPacketWithDialer only for deprecated relay group, the new protocol does not need to be implemented. ListenPacketWithDialer(ctx context.Context, dialer Dialer, metadata *Metadata) (PacketConn, error) // IsL3Protocol return ProxyAdapter working in L3 (tell dns module not pass the domain to avoid loopback) @@ -178,12 +181,6 @@ type Proxy interface { ExtraDelayHistories() map[string]ProxyState LastDelayForTestUrl(url string) uint16 URLTest(ctx context.Context, url string, expectedStatus utils.IntRanges[uint16]) (uint16, error) - - // Deprecated: use DialContext instead. - Dial(metadata *Metadata) (Conn, error) - - // Deprecated: use DialPacketConn instead. - DialUDP(metadata *Metadata) (PacketConn, error) } // AdapterType is enum of adapter type diff --git a/clash-meta-android/core/src/foss/golang/clash/constant/metadata.go b/clash-meta-android/core/src/foss/golang/clash/constant/metadata.go index 72b9995b1b..23cdcd8616 100644 --- a/clash-meta-android/core/src/foss/golang/clash/constant/metadata.go +++ b/clash-meta-android/core/src/foss/golang/clash/constant/metadata.go @@ -38,6 +38,7 @@ const ( TUIC HYSTERIA2 ANYTLS + MIERU INNER ) @@ -109,6 +110,8 @@ func (t Type) String() string { return "Hysteria2" case ANYTLS: return "AnyTLS" + case MIERU: + return "Mieru" case INNER: return "Inner" default: @@ -149,6 +152,8 @@ func ParseType(t string) (*Type, error) { res = HYSTERIA2 case "ANYTLS": res = ANYTLS + case "MIERU": + res = MIERU case "INNER": res = INNER default: diff --git a/clash-meta-android/core/src/foss/golang/clash/dns/enhancer.go b/clash-meta-android/core/src/foss/golang/clash/dns/enhancer.go index 36923ca624..c84f8c32fe 100644 --- a/clash-meta-android/core/src/foss/golang/clash/dns/enhancer.go +++ b/clash-meta-android/core/src/foss/golang/clash/dns/enhancer.go @@ -9,10 +9,12 @@ import ( ) type ResolverEnhancer struct { - mode C.DNSMode - fakePool *fakeip.Pool - mapping *lru.LruCache[netip.Addr, string] - useHosts bool + mode C.DNSMode + fakeIPPool *fakeip.Pool + fakeIPPool6 *fakeip.Pool + fakeIPSkipper *fakeip.Skipper + mapping *lru.LruCache[netip.Addr, string] + useHosts bool } func (h *ResolverEnhancer) FakeIPEnabled() bool { @@ -28,10 +30,14 @@ func (h *ResolverEnhancer) IsExistFakeIP(ip netip.Addr) bool { return false } - if pool := h.fakePool; pool != nil { + if pool := h.fakeIPPool; pool != nil { return pool.Exist(ip) } + if pool6 := h.fakeIPPool6; pool6 != nil { + return pool6.Exist(ip) + } + return false } @@ -40,10 +46,14 @@ func (h *ResolverEnhancer) IsFakeIP(ip netip.Addr) bool { return false } - if pool := h.fakePool; pool != nil { + if pool := h.fakeIPPool; pool != nil { return pool.IPNet().Contains(ip) && ip != pool.Gateway() && ip != pool.Broadcast() } + if pool6 := h.fakeIPPool6; pool6 != nil { + return pool6.IPNet().Contains(ip) && ip != pool6.Gateway() && ip != pool6.Broadcast() + } + return false } @@ -52,20 +62,30 @@ func (h *ResolverEnhancer) IsFakeBroadcastIP(ip netip.Addr) bool { return false } - if pool := h.fakePool; pool != nil { + if pool := h.fakeIPPool; pool != nil { return pool.Broadcast() == ip } + if pool6 := h.fakeIPPool6; pool6 != nil { + return pool6.Broadcast() == ip + } + return false } func (h *ResolverEnhancer) FindHostByIP(ip netip.Addr) (string, bool) { - if pool := h.fakePool; pool != nil { + if pool := h.fakeIPPool; pool != nil { if host, existed := pool.LookBack(ip); existed { return host, true } } + if pool6 := h.fakeIPPool6; pool6 != nil { + if host, existed := pool6.LookBack(ip); existed { + return host, true + } + } + if mapping := h.mapping; mapping != nil { if host, existed := h.mapping.Get(ip); existed { return host, true @@ -82,9 +102,12 @@ func (h *ResolverEnhancer) InsertHostByIP(ip netip.Addr, host string) { } func (h *ResolverEnhancer) FlushFakeIP() error { - if pool := h.fakePool; pool != nil { + if pool := h.fakeIPPool; pool != nil { return pool.FlushFakeIP() } + if pool6 := h.fakeIPPool6; pool6 != nil { + return pool6.FlushFakeIP() + } return nil } @@ -93,36 +116,48 @@ func (h *ResolverEnhancer) PatchFrom(o *ResolverEnhancer) { o.mapping.CloneTo(h.mapping) } - if h.fakePool != nil && o.fakePool != nil { - h.fakePool.CloneFrom(o.fakePool) + if h.fakeIPPool != nil && o.fakeIPPool != nil { + h.fakeIPPool.CloneFrom(o.fakeIPPool) + } + + if h.fakeIPPool6 != nil && o.fakeIPPool6 != nil { + h.fakeIPPool6.CloneFrom(o.fakeIPPool6) } } func (h *ResolverEnhancer) StoreFakePoolState() { - if h.fakePool != nil { - h.fakePool.StoreState() + if h.fakeIPPool != nil { + h.fakeIPPool.StoreState() + } + + if h.fakeIPPool6 != nil { + h.fakeIPPool6.StoreState() } } type EnhancerConfig struct { - EnhancedMode C.DNSMode - Pool *fakeip.Pool - UseHosts bool + IPv6 bool + EnhancedMode C.DNSMode + FakeIPPool *fakeip.Pool + FakeIPPool6 *fakeip.Pool + FakeIPSkipper *fakeip.Skipper + UseHosts bool } func NewEnhancer(cfg EnhancerConfig) *ResolverEnhancer { - var fakePool *fakeip.Pool - var mapping *lru.LruCache[netip.Addr, string] - - if cfg.EnhancedMode != C.DNSNormal { - fakePool = cfg.Pool - mapping = lru.New(lru.WithSize[netip.Addr, string](4096)) - } - - return &ResolverEnhancer{ + e := &ResolverEnhancer{ mode: cfg.EnhancedMode, - fakePool: fakePool, - mapping: mapping, useHosts: cfg.UseHosts, } + + if cfg.EnhancedMode != C.DNSNormal { + e.fakeIPPool = cfg.FakeIPPool + if cfg.IPv6 { + e.fakeIPPool6 = cfg.FakeIPPool6 + } + e.fakeIPSkipper = cfg.FakeIPSkipper + e.mapping = lru.New(lru.WithSize[netip.Addr, string](4096)) + } + + return e } diff --git a/clash-meta-android/core/src/foss/golang/clash/dns/middleware.go b/clash-meta-android/core/src/foss/golang/clash/dns/middleware.go index 502a37e5e5..8472eb94e2 100644 --- a/clash-meta-android/core/src/foss/golang/clash/dns/middleware.go +++ b/clash-meta-android/core/src/foss/golang/clash/dns/middleware.go @@ -67,8 +67,7 @@ func withHosts(mapping *lru.LruCache[netip.Addr, string]) middleware { } else if q.Qtype == D.TypeAAAA { rr := &D.AAAA{} rr.Hdr = D.RR_Header{Name: q.Name, Rrtype: D.TypeAAAA, Class: D.ClassINET, Ttl: 10} - ip := ipAddr.As16() - rr.AAAA = ip[:] + rr.AAAA = ipAddr.AsSlice() msg.Answer = append(msg.Answer, rr) if mapping != nil { mapping.SetWithExpire(ipAddr, host, time.Now().Add(time.Second*10)) @@ -147,29 +146,42 @@ func withMapping(mapping *lru.LruCache[netip.Addr, string]) middleware { } } -func withFakeIP(fakePool *fakeip.Pool) middleware { +func withFakeIP(skipper *fakeip.Skipper, fakePool *fakeip.Pool, fakePool6 *fakeip.Pool) middleware { return func(next handler) handler { return func(ctx *icontext.DNSContext, r *D.Msg) (*D.Msg, error) { q := r.Question[0] host := strings.TrimRight(q.Name, ".") - if fakePool.ShouldSkipped(host) { + if skipper.ShouldSkipped(host) { return next(ctx, r) } + var rr D.RR switch q.Qtype { - case D.TypeAAAA, D.TypeSVCB, D.TypeHTTPS: + case D.TypeA: + if fakePool == nil { + return handleMsgWithEmptyAnswer(r), nil + } + ip := fakePool.Lookup(host) + rr = &D.A{ + Hdr: D.RR_Header{Name: q.Name, Rrtype: D.TypeA, Class: D.ClassINET, Ttl: dnsDefaultTTL}, + A: ip.AsSlice(), + } + case D.TypeAAAA: + if fakePool6 == nil { + return handleMsgWithEmptyAnswer(r), nil + } + ip := fakePool6.Lookup(host) + rr = &D.AAAA{ + Hdr: D.RR_Header{Name: q.Name, Rrtype: D.TypeAAAA, Class: D.ClassINET, Ttl: dnsDefaultTTL}, + AAAA: ip.AsSlice(), + } + case D.TypeSVCB, D.TypeHTTPS: return handleMsgWithEmptyAnswer(r), nil - } - - if q.Qtype != D.TypeA { + default: return next(ctx, r) } - rr := &D.A{} - rr.Hdr = D.RR_Header{Name: q.Name, Rrtype: D.TypeA, Class: D.ClassINET, Ttl: dnsDefaultTTL} - ip := fakePool.Lookup(host) - rr.A = ip.AsSlice() msg := r.Copy() msg.Answer = []D.RR{rr} @@ -226,7 +238,7 @@ func newHandler(resolver *Resolver, mapper *ResolverEnhancer) handler { } if mapper.mode == C.DNSFakeIP { - middlewares = append(middlewares, withFakeIP(mapper.fakePool)) + middlewares = append(middlewares, withFakeIP(mapper.fakeIPSkipper, mapper.fakeIPPool, mapper.fakeIPPool6)) } if mapper.mode != C.DNSNormal { diff --git a/clash-meta-android/core/src/foss/golang/clash/docs/config.yaml b/clash-meta-android/core/src/foss/golang/clash/docs/config.yaml index 0650bc5364..e71b06f482 100644 --- a/clash-meta-android/core/src/foss/golang/clash/docs/config.yaml +++ b/clash-meta-android/core/src/foss/golang/clash/docs/config.yaml @@ -261,6 +261,7 @@ dns: enhanced-mode: fake-ip # or redir-host fake-ip-range: 198.18.0.1/16 # fake-ip 池设置 + # fake-ip-range6: fdfe:dcba:9876::1/64 # fake-ip6 池设置 # 配置不使用 fake-ip 的域名 fake-ip-filter: @@ -1555,6 +1556,15 @@ listeners: # -----END ECH KEYS----- # padding-scheme: "" # https://github.com/anytls/anytls-go/blob/main/docs/protocol.md#cmdupdatepaddingscheme + - name: mieru-in-1 + type: mieru + port: 10818 # 支持使用ports格式,例如200,302 or 200,204,401-429,501-503 + listen: 0.0.0.0 + transport: TCP # 支持 TCP 或者 UDP + users: + username1: password1 + username2: password2 + - name: trojan-in-1 type: trojan port: 10819 # 支持使用ports格式,例如200,302 or 200,204,401-429,501-503 diff --git a/clash-meta-android/core/src/foss/golang/clash/go.mod b/clash-meta-android/core/src/foss/golang/clash/go.mod index 957dfa7f70..17f18b2deb 100644 --- a/clash-meta-android/core/src/foss/golang/clash/go.mod +++ b/clash-meta-android/core/src/foss/golang/clash/go.mod @@ -6,25 +6,25 @@ require ( github.com/bahlo/generic-list-go v0.2.0 github.com/coreos/go-iptables v0.8.0 github.com/dlclark/regexp2 v1.11.5 - github.com/ebitengine/purego v0.9.0 - github.com/enfein/mieru/v3 v3.20.0 + github.com/ebitengine/purego v0.9.1 + github.com/enfein/mieru/v3 v3.22.1 github.com/go-chi/chi/v5 v5.2.3 github.com/go-chi/render v1.0.3 github.com/gobwas/ws v1.4.0 - github.com/gofrs/uuid/v5 v5.3.2 + github.com/gofrs/uuid/v5 v5.4.0 github.com/golang/snappy v1.0.0 github.com/insomniacslk/dhcp v0.0.0-20250109001534-8abf58130905 github.com/klauspost/compress v1.17.9 // lastest version compatible with golang1.20 github.com/mdlayher/netlink v1.7.2 - github.com/metacubex/amneziawg-go v0.0.0-20250902133113-a7f637c14281 - github.com/metacubex/bart v0.24.0 + github.com/metacubex/amneziawg-go v0.0.0-20251104174305-5a0e9f7e361d + github.com/metacubex/bart v0.26.0 github.com/metacubex/bbolt v0.0.0-20250725135710-010dbbbb7a5b github.com/metacubex/blake3 v0.1.0 github.com/metacubex/chacha v0.1.5 github.com/metacubex/fswatch v0.1.1 github.com/metacubex/gopacket v1.1.20-0.20230608035415-7e2f98a3e759 - github.com/metacubex/kcp-go v0.0.0-20251007183319-0df1aec1639a - github.com/metacubex/quic-go v0.55.1-0.20251004050223-450bd9e32033 + github.com/metacubex/kcp-go v0.0.0-20251105084629-8c93f4bf37be + github.com/metacubex/quic-go v0.55.1-0.20251024060151-bd465f127128 github.com/metacubex/randv2 v0.2.0 github.com/metacubex/restls-client-go v0.1.7 github.com/metacubex/sing v0.5.6 @@ -33,12 +33,12 @@ require ( github.com/metacubex/sing-shadowsocks v0.2.12 github.com/metacubex/sing-shadowsocks2 v0.2.7 github.com/metacubex/sing-shadowtls v0.0.0-20250503063515-5d9f966d17a2 - github.com/metacubex/sing-tun v0.4.8 + github.com/metacubex/sing-tun v0.4.9 github.com/metacubex/sing-vmess v0.2.4 github.com/metacubex/sing-wireguard v0.0.0-20250503063753-2dc62acc626f github.com/metacubex/smux v0.0.0-20250922175018-15c9a6a78719 - github.com/metacubex/tfo-go v0.0.0-20250921095601-b102db4216c0 - github.com/metacubex/utls v1.8.2 + github.com/metacubex/tfo-go v0.0.0-20251024101424-368b42b59148 + github.com/metacubex/utls v1.8.3 github.com/metacubex/wireguard-go v0.0.0-20250820062549-a6cecdd7f57f github.com/miekg/dns v1.1.63 // lastest version compatible with golang1.20 github.com/mroth/weightedrand/v2 v2.1.0 @@ -46,7 +46,7 @@ require ( github.com/oschwald/maxminddb-golang v1.12.0 // lastest version compatible with golang1.20 github.com/sagernet/cors v1.2.1 github.com/sagernet/netlink v0.0.0-20240612041022-b9a21c07ac6a - github.com/samber/lo v1.51.0 + github.com/samber/lo v1.52.0 github.com/sirupsen/logrus v1.9.3 github.com/stretchr/testify v1.11.1 github.com/vmihailenco/msgpack/v5 v5.4.1 diff --git a/clash-meta-android/core/src/foss/golang/clash/go.sum b/clash-meta-android/core/src/foss/golang/clash/go.sum index e5ac16e39e..d8e51c5abc 100644 --- a/clash-meta-android/core/src/foss/golang/clash/go.sum +++ b/clash-meta-android/core/src/foss/golang/clash/go.sum @@ -23,10 +23,10 @@ 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.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/ebitengine/purego v0.9.1 h1:a/k2f2HQU3Pi399RPW1MOaZyhKJL9w/xFpKAg4q1s0A= +github.com/ebitengine/purego v0.9.1/go.mod h1:iIjxzd6CiRiOG0UyXP+V1+jWqUXVjPKLAI0mRfJZTmQ= +github.com/enfein/mieru/v3 v3.22.1 h1:/XGYYXpEhEJlxosmtbpEJkhtRLHB8IToG7LB8kU2ZDY= +github.com/enfein/mieru/v3 v3.22.1/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= @@ -55,8 +55,8 @@ github.com/gobwas/pool v0.2.1 h1:xfeeEhW7pwmX8nuLVlqbzVc7udMDrwetjEv+TZIz1og= github.com/gobwas/pool v0.2.1/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw= github.com/gobwas/ws v1.4.0 h1:CTaoG1tojrh4ucGPcoJFiAQUAsEWekEWvLy7GsVNqGs= github.com/gobwas/ws v1.4.0/go.mod h1:G3gNqMNtPppf5XUz7O4shetPpcZ1VJ7zt18dlUeakrc= -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/gofrs/uuid/v5 v5.4.0 h1:EfbpCTjqMuGyq5ZJwxqzn3Cbr2d0rUZU7v5ycAk/e/0= +github.com/gofrs/uuid/v5 v5.4.0/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/snappy v1.0.0 h1:Oy607GVXHs7RtbggtPBnr2RmDArIsAefDwvrdWvRhGs= @@ -90,12 +90,12 @@ github.com/mdlayher/netlink v1.7.2 h1:/UtM3ofJap7Vl4QWCPDGXY8d3GIY2UGSDbK+QWmY8/ 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-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/amneziawg-go v0.0.0-20251104174305-5a0e9f7e361d h1:vAJ0ZT4aO803F1uw2roIA9yH7Sxzox34tVVyye1bz6c= +github.com/metacubex/amneziawg-go v0.0.0-20251104174305-5a0e9f7e361d/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.24.0 h1:EyNiPeVOlg0joSHTzi5oentI0j5M89utUq/5dd76pWM= -github.com/metacubex/bart v0.24.0/go.mod h1:DCcyfP4MC+Zy7sLK7XeGuMw+P5K9mIRsYOBgiE8icsI= +github.com/metacubex/bart v0.26.0 h1:d/bBTvVatfVWGfQbiDpYKI1bXUJgjaabB2KpK1Tnk6w= +github.com/metacubex/bart v0.26.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= @@ -108,12 +108,12 @@ github.com/metacubex/gopacket v1.1.20-0.20230608035415-7e2f98a3e759 h1:cjd4biTvO github.com/metacubex/gopacket v1.1.20-0.20230608035415-7e2f98a3e759/go.mod h1:UHOv2xu+RIgLwpXca7TLrXleEd4oR3sPatW6IF8wU88= 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-20251007183319-0df1aec1639a h1:5vdk2pI71itLBT2mpyNExM1UKZ+2mG7MVC+ZARpRXmg= -github.com/metacubex/kcp-go v0.0.0-20251007183319-0df1aec1639a/go.mod h1:HIJZW4QMhbBqXuqC1ly6Hn0TEYT2SzRw58ns1yGhXTs= +github.com/metacubex/kcp-go v0.0.0-20251105084629-8c93f4bf37be h1:Y7SigZIqfv/+RIA/D7R6EbB9p+brPRoGOM6zobSmRIM= +github.com/metacubex/kcp-go v0.0.0-20251105084629-8c93f4bf37be/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.55.1-0.20251004050223-450bd9e32033 h1:LEzvR5AmHEatqE6IWgMBUJHnaiz9VJfZeDGOiHFuWZU= -github.com/metacubex/quic-go v0.55.1-0.20251004050223-450bd9e32033/go.mod h1:1lktQFtCD17FZliVypbrDHwbsFSsmz2xz2TRXydvB5c= +github.com/metacubex/quic-go v0.55.1-0.20251024060151-bd465f127128 h1:I1uvJl206/HbkzEAZpLgGkZgUveOZb+P+6oTUj7dN+o= +github.com/metacubex/quic-go v0.55.1-0.20251024060151-bd465f127128/go.mod h1:1lktQFtCD17FZliVypbrDHwbsFSsmz2xz2TRXydvB5c= github.com/metacubex/randv2 v0.2.0 h1:uP38uBvV2SxYfLj53kuvAjbND4RUDfFJjwr4UigMiLs= github.com/metacubex/randv2 v0.2.0/go.mod h1:kFi2SzrQ5WuneuoLLCMkABtiBu6VRrMrWFqSPyj2cxY= github.com/metacubex/restls-client-go v0.1.7 h1:eCwiXCTQb5WJu9IlgYvDBA1OgrINv58dEe7hcN5H15k= @@ -131,18 +131,18 @@ github.com/metacubex/sing-shadowsocks2 v0.2.7 h1:hSuuc0YpsfiqYqt1o+fP4m34BQz4e6w 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.8 h1:3PyiUKWXYi37yHptXskzL1723O3OUdyt0Aej4XHVikM= -github.com/metacubex/sing-tun v0.4.8/go.mod h1:L/TjQY5JEGy8nvsuYmy/XgMFMCPiF0+AWSFCYfS6r9w= +github.com/metacubex/sing-tun v0.4.9 h1:jY0Yyt8nnN3yQRN/jTxgqNCmGi1dsFdxdIi7pQUlVVU= +github.com/metacubex/sing-tun v0.4.9/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-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.2 h1:d7KalMZ5hnOJ6lThMz8Ykd+5dvmXH3Eoeyfv2jUuG3w= -github.com/metacubex/utls v1.8.2/go.mod h1:kncGGVhFaoGn5M3pFe3SXhZCzsbCJayNOH4UEqTKTko= +github.com/metacubex/tfo-go v0.0.0-20251024101424-368b42b59148 h1:Zd0QqciLIhv9MKbGKTPEgN8WUFsgQGA1WJBy6spEnVU= +github.com/metacubex/tfo-go v0.0.0-20251024101424-368b42b59148/go.mod h1:l9oLnLoEXyGZ5RVLsh7QCC5XsouTUyKk4F2nLm2DHLw= +github.com/metacubex/utls v1.8.3 h1:0m/yCxm3SK6kWve2lKiFb1pue1wHitJ8sQQD4Ikqde4= +github.com/metacubex/utls v1.8.3/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= @@ -175,8 +175,8 @@ github.com/sagernet/cors v1.2.1 h1:Cv5Z8y9YSD6Gm+qSpNrL3LO4lD3eQVvbFYJSG7JCMHQ= github.com/sagernet/cors v1.2.1/go.mod h1:O64VyOjjhrkLmQIjF4KGRrJO/5dVXFdpEmCW/eISRAI= github.com/sagernet/netlink v0.0.0-20240612041022-b9a21c07ac6a h1:ObwtHN2VpqE0ZNjr6sGeT00J8uU7JF4cNUdb44/Duis= 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/samber/lo v1.52.0 h1:Rvi+3BFHES3A8meP33VPAxiBZX/Aws5RxrschYGjomw= +github.com/samber/lo v1.52.0/go.mod h1:4+MXEGsJzbKGaUEQFKBq2xtfuznW9oz/WrgyzMzRoM0= 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= diff --git a/clash-meta-android/core/src/foss/golang/clash/hub/executor/executor.go b/clash-meta-android/core/src/foss/golang/clash/hub/executor/executor.go index 041e6fc36b..e92a8de448 100644 --- a/clash-meta-android/core/src/foss/golang/clash/hub/executor/executor.go +++ b/clash-meta-android/core/src/foss/golang/clash/hub/executor/executor.go @@ -31,7 +31,7 @@ import ( "github.com/metacubex/mihomo/component/updater" "github.com/metacubex/mihomo/config" C "github.com/metacubex/mihomo/constant" - "github.com/metacubex/mihomo/constant/provider" + P "github.com/metacubex/mihomo/constant/provider" "github.com/metacubex/mihomo/dns" "github.com/metacubex/mihomo/listener" authStore "github.com/metacubex/mihomo/listener/auth" @@ -39,7 +39,7 @@ import ( "github.com/metacubex/mihomo/listener/inner" "github.com/metacubex/mihomo/listener/tproxy" "github.com/metacubex/mihomo/log" - "github.com/metacubex/mihomo/ntp" + "github.com/metacubex/mihomo/ntp/ntp" "github.com/metacubex/mihomo/tunnel" ) @@ -247,10 +247,11 @@ func updateDNS(c *config.DNS, generalIPv6 bool) { return } + ipv6 := c.IPv6 && generalIPv6 r := dns.NewResolver(dns.Config{ Main: c.NameServer, Fallback: c.Fallback, - IPv6: c.IPv6 && generalIPv6, + IPv6: ipv6, IPv6Timeout: c.IPv6Timeout, FallbackIPFilter: c.FallbackIPFilter, FallbackDomainFilter: c.FallbackDomainFilter, @@ -263,9 +264,12 @@ func updateDNS(c *config.DNS, generalIPv6 bool) { CacheMaxSize: c.CacheMaxSize, }) m := dns.NewEnhancer(dns.EnhancerConfig{ - EnhancedMode: c.EnhancedMode, - Pool: c.FakeIPRange, - UseHosts: c.UseHosts, + IPv6: ipv6, + EnhancedMode: c.EnhancedMode, + FakeIPPool: c.FakeIPPool, + FakeIPPool6: c.FakeIPPool6, + FakeIPSkipper: c.FakeIPSkipper, + UseHosts: c.UseHosts, }) // reuse cache of old host mapper @@ -299,18 +303,18 @@ func updateHosts(tree *trie.DomainTrie[resolver.HostValue]) { resolver.DefaultHosts = resolver.NewHosts(tree) } -func updateProxies(proxies map[string]C.Proxy, providers map[string]provider.ProxyProvider) { +func updateProxies(proxies map[string]C.Proxy, providers map[string]P.ProxyProvider) { tunnel.UpdateProxies(proxies, providers) } -func updateRules(rules []C.Rule, subRules map[string][]C.Rule, ruleProviders map[string]provider.RuleProvider) { +func updateRules(rules []C.Rule, subRules map[string][]C.Rule, ruleProviders map[string]P.RuleProvider) { tunnel.UpdateRules(rules, subRules, ruleProviders) } -func loadProvider[P provider.Provider](providers map[string]P) { - load := func(pv P) { +func loadProvider[T P.Provider](providers map[string]T) { + load := func(pv T) { name := pv.Name() - if pv.VehicleType() == provider.Compatible { + if pv.VehicleType() == P.Compatible { log.Infoln("Start initial compatible provider %s", name) } else { log.Infoln("Start initial provider %s", name) @@ -318,11 +322,11 @@ func loadProvider[P provider.Provider](providers map[string]P) { if err := pv.Initial(); err != nil { switch pv.Type() { - case provider.Proxy: + case P.Proxy: { log.Errorln("initial proxy provider %s error: %v", name, err) } - case provider.Rule: + case P.Rule: { log.Errorln("initial rule provider %s error: %v", name, err) } diff --git a/clash-meta-android/core/src/foss/golang/clash/hub/route/configs.go b/clash-meta-android/core/src/foss/golang/clash/hub/route/configs.go index 92253c3f72..141a6c1559 100644 --- a/clash-meta-android/core/src/foss/golang/clash/hub/route/configs.go +++ b/clash-meta-android/core/src/foss/golang/clash/hub/route/configs.go @@ -13,7 +13,7 @@ import ( "github.com/metacubex/mihomo/config" C "github.com/metacubex/mihomo/constant" "github.com/metacubex/mihomo/hub/executor" - P "github.com/metacubex/mihomo/listener" + "github.com/metacubex/mihomo/listener" LC "github.com/metacubex/mihomo/listener/config" "github.com/metacubex/mihomo/log" "github.com/metacubex/mihomo/tunnel" @@ -306,7 +306,7 @@ func patchConfigs(w http.ResponseWriter, r *http.Request) { } if general.AllowLan != nil { - P.SetAllowLan(*general.AllowLan) + listener.SetAllowLan(*general.AllowLan) } if general.SkipAuthPrefixes != nil { @@ -322,7 +322,7 @@ func patchConfigs(w http.ResponseWriter, r *http.Request) { } if general.BindAddress != nil { - P.SetBindAddress(*general.BindAddress) + listener.SetBindAddress(*general.BindAddress) } if general.Sniffing != nil { @@ -337,17 +337,17 @@ func patchConfigs(w http.ResponseWriter, r *http.Request) { dialer.DefaultInterface.Store(*general.InterfaceName) } - ports := P.GetPorts() + ports := listener.GetPorts() - P.ReCreateHTTP(pointerOrDefault(general.Port, ports.Port), tunnel.Tunnel) - P.ReCreateSocks(pointerOrDefault(general.SocksPort, ports.SocksPort), tunnel.Tunnel) - P.ReCreateRedir(pointerOrDefault(general.RedirPort, ports.RedirPort), tunnel.Tunnel) - P.ReCreateTProxy(pointerOrDefault(general.TProxyPort, ports.TProxyPort), tunnel.Tunnel) - P.ReCreateMixed(pointerOrDefault(general.MixedPort, ports.MixedPort), tunnel.Tunnel) - P.ReCreateTun(pointerOrDefaultTun(general.Tun, P.LastTunConf), tunnel.Tunnel) - P.ReCreateShadowSocks(pointerOrDefault(general.ShadowSocksConfig, ports.ShadowSocksConfig), tunnel.Tunnel) - P.ReCreateVmess(pointerOrDefault(general.VmessConfig, ports.VmessConfig), tunnel.Tunnel) - P.ReCreateTuic(pointerOrDefaultTuicServer(general.TuicServer, P.LastTuicConf), tunnel.Tunnel) + listener.ReCreateHTTP(pointerOrDefault(general.Port, ports.Port), tunnel.Tunnel) + listener.ReCreateSocks(pointerOrDefault(general.SocksPort, ports.SocksPort), tunnel.Tunnel) + listener.ReCreateRedir(pointerOrDefault(general.RedirPort, ports.RedirPort), tunnel.Tunnel) + listener.ReCreateTProxy(pointerOrDefault(general.TProxyPort, ports.TProxyPort), tunnel.Tunnel) + listener.ReCreateMixed(pointerOrDefault(general.MixedPort, ports.MixedPort), tunnel.Tunnel) + listener.ReCreateTun(pointerOrDefaultTun(general.Tun, listener.LastTunConf), tunnel.Tunnel) + listener.ReCreateShadowSocks(pointerOrDefault(general.ShadowSocksConfig, ports.ShadowSocksConfig), tunnel.Tunnel) + listener.ReCreateVmess(pointerOrDefault(general.VmessConfig, ports.VmessConfig), tunnel.Tunnel) + listener.ReCreateTuic(pointerOrDefaultTuicServer(general.TuicServer, listener.LastTuicConf), tunnel.Tunnel) if general.Mode != nil { tunnel.SetMode(*general.Mode) diff --git a/clash-meta-android/core/src/foss/golang/clash/hub/route/provider.go b/clash-meta-android/core/src/foss/golang/clash/hub/route/provider.go index a8611a7948..24b1989ed1 100644 --- a/clash-meta-android/core/src/foss/golang/clash/hub/route/provider.go +++ b/clash-meta-android/core/src/foss/golang/clash/hub/route/provider.go @@ -5,7 +5,7 @@ import ( "net/http" C "github.com/metacubex/mihomo/constant" - "github.com/metacubex/mihomo/constant/provider" + P "github.com/metacubex/mihomo/constant/provider" "github.com/metacubex/mihomo/tunnel" "github.com/go-chi/chi/v5" @@ -45,12 +45,12 @@ func getProviders(w http.ResponseWriter, r *http.Request) { } func getProvider(w http.ResponseWriter, r *http.Request) { - provider := r.Context().Value(CtxKeyProvider).(provider.ProxyProvider) + provider := r.Context().Value(CtxKeyProvider).(P.ProxyProvider) render.JSON(w, r, provider) } func updateProvider(w http.ResponseWriter, r *http.Request) { - provider := r.Context().Value(CtxKeyProvider).(provider.ProxyProvider) + provider := r.Context().Value(CtxKeyProvider).(P.ProxyProvider) if err := provider.Update(); err != nil { render.Status(r, http.StatusServiceUnavailable) render.JSON(w, r, newError(err.Error())) @@ -60,7 +60,7 @@ func updateProvider(w http.ResponseWriter, r *http.Request) { } func healthCheckProvider(w http.ResponseWriter, r *http.Request) { - provider := r.Context().Value(CtxKeyProvider).(provider.ProxyProvider) + provider := r.Context().Value(CtxKeyProvider).(P.ProxyProvider) provider.HealthCheck() render.NoContent(w, r) } @@ -93,7 +93,7 @@ func findProviderProxyByName(next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { var ( name = r.Context().Value(CtxKeyProxyName).(string) - pd = r.Context().Value(CtxKeyProvider).(provider.ProxyProvider) + pd = r.Context().Value(CtxKeyProvider).(P.ProxyProvider) ) proxy, exist := lo.Find(pd.Proxies(), func(proxy C.Proxy) bool { return proxy.Name() == name @@ -128,7 +128,7 @@ func getRuleProviders(w http.ResponseWriter, r *http.Request) { } func updateRuleProvider(w http.ResponseWriter, r *http.Request) { - provider := r.Context().Value(CtxKeyProvider).(provider.RuleProvider) + provider := r.Context().Value(CtxKeyProvider).(P.RuleProvider) if err := provider.Update(); err != nil { render.Status(r, http.StatusServiceUnavailable) render.JSON(w, r, newError(err.Error())) diff --git a/clash-meta-android/core/src/foss/golang/clash/listener/inbound/mieru.go b/clash-meta-android/core/src/foss/golang/clash/listener/inbound/mieru.go new file mode 100644 index 0000000000..cf8cc403bc --- /dev/null +++ b/clash-meta-android/core/src/foss/golang/clash/listener/inbound/mieru.go @@ -0,0 +1,181 @@ +package inbound + +import ( + "context" + "fmt" + "net" + "sync" + + "github.com/metacubex/mihomo/adapter/inbound" + "github.com/metacubex/mihomo/common/utils" + C "github.com/metacubex/mihomo/constant" + "github.com/metacubex/mihomo/listener/mieru" + "github.com/metacubex/mihomo/log" + "google.golang.org/protobuf/proto" + + mieruserver "github.com/enfein/mieru/v3/apis/server" + mierupb "github.com/enfein/mieru/v3/pkg/appctl/appctlpb" +) + +type Mieru struct { + *Base + option *MieruOption + server mieruserver.Server + mu sync.Mutex +} + +type MieruOption struct { + BaseOption + Transport string `inbound:"transport"` + Users map[string]string `inbound:"users"` +} + +type mieruListenerFactory struct{} + +func (mieruListenerFactory) Listen(ctx context.Context, network, address string) (net.Listener, error) { + return inbound.ListenContext(ctx, network, address) +} + +func (mieruListenerFactory) ListenPacket(ctx context.Context, network, address string) (net.PacketConn, error) { + return inbound.ListenPacketContext(ctx, network, address) +} + +func NewMieru(option *MieruOption) (*Mieru, error) { + base, err := NewBase(&option.BaseOption) + if err != nil { + return nil, err + } + + config, err := buildMieruServerConfig(option, base.ports) + if err != nil { + return nil, fmt.Errorf("failed to build mieru server config: %w", err) + } + s := mieruserver.NewServer() + if err := s.Store(config); err != nil { + return nil, fmt.Errorf("failed to store mieru server config: %w", err) + } + // Server is started lazily when Listen() is called for the first time. + return &Mieru{ + Base: base, + option: option, + server: s, + }, nil +} + +func (m *Mieru) Config() C.InboundConfig { + return m.option +} + +func (m *Mieru) Listen(tunnel C.Tunnel) error { + m.mu.Lock() + defer m.mu.Unlock() + + if !m.server.IsRunning() { + if err := m.server.Start(); err != nil { + return fmt.Errorf("failed to start mieru server: %w", err) + } + } + + additions := m.config.Additions() + if len(additions) == 0 { + additions = []inbound.Addition{ + inbound.WithInName("DEFAULT-MIERU"), + inbound.WithSpecialRules(""), + } + } + + go func() { + for { + c, req, err := m.server.Accept() + if err != nil { + if !m.server.IsRunning() { + break + } + } + go mieru.Handle(c, tunnel, req, additions...) + } + }() + log.Infoln("Mieru[%s] proxy listening at: %s", m.Name(), m.Address()) + return nil +} + +func (m *Mieru) Close() error { + m.mu.Lock() + defer m.mu.Unlock() + + if m.server.IsRunning() { + return m.server.Stop() + } + + return nil +} + +var _ C.InboundListener = (*Mieru)(nil) + +func (o MieruOption) Equal(config C.InboundConfig) bool { + return optionToString(o) == optionToString(config) +} + +func buildMieruServerConfig(option *MieruOption, ports utils.IntRanges[uint16]) (*mieruserver.ServerConfig, error) { + if err := validateMieruOption(option); err != nil { + return nil, fmt.Errorf("failed to validate mieru option: %w", err) + } + if len(ports) == 0 { + return nil, fmt.Errorf("port is not set") + } + + var transportProtocol *mierupb.TransportProtocol + switch option.Transport { + case "TCP": + transportProtocol = mierupb.TransportProtocol_TCP.Enum() + case "UDP": + transportProtocol = mierupb.TransportProtocol_UDP.Enum() + } + var portBindings []*mierupb.PortBinding + for _, portRange := range ports { + if portRange.Start() == portRange.End() { + portBindings = append(portBindings, &mierupb.PortBinding{ + Port: proto.Int32(int32(portRange.Start())), + Protocol: transportProtocol, + }) + } else { + portBindings = append(portBindings, &mierupb.PortBinding{ + PortRange: proto.String(fmt.Sprintf("%d-%d", portRange.Start(), portRange.End())), + Protocol: transportProtocol, + }) + } + } + var users []*mierupb.User + for username, password := range option.Users { + users = append(users, &mierupb.User{ + Name: proto.String(username), + Password: proto.String(password), + }) + } + return &mieruserver.ServerConfig{ + Config: &mierupb.ServerConfig{ + PortBindings: portBindings, + Users: users, + }, + StreamListenerFactory: mieruListenerFactory{}, + PacketListenerFactory: mieruListenerFactory{}, + }, nil +} + +func validateMieruOption(option *MieruOption) error { + if option.Transport != "TCP" && option.Transport != "UDP" { + return fmt.Errorf("transport must be TCP or UDP") + } + if len(option.Users) == 0 { + return fmt.Errorf("users is empty") + } + for username, password := range option.Users { + if username == "" { + return fmt.Errorf("username is empty") + } + if password == "" { + return fmt.Errorf("password is empty") + } + } + return nil +} diff --git a/clash-meta-android/core/src/foss/golang/clash/listener/inbound/mieru_test.go b/clash-meta-android/core/src/foss/golang/clash/listener/inbound/mieru_test.go new file mode 100644 index 0000000000..d163b49dcc --- /dev/null +++ b/clash-meta-android/core/src/foss/golang/clash/listener/inbound/mieru_test.go @@ -0,0 +1,212 @@ +package inbound_test + +import ( + "net" + "net/netip" + "strconv" + "testing" + + "github.com/metacubex/mihomo/adapter/outbound" + "github.com/metacubex/mihomo/listener/inbound" + "github.com/stretchr/testify/assert" +) + +func TestNewMieru(t *testing.T) { + type args struct { + option *inbound.MieruOption + } + tests := []struct { + name string + args args + wantErr bool + }{ + { + name: "valid with port", + args: args{ + option: &inbound.MieruOption{ + BaseOption: inbound.BaseOption{ + Port: "8080", + }, + Transport: "TCP", + Users: map[string]string{"user": "pass"}, + }, + }, + wantErr: false, + }, + { + name: "valid with port range", + args: args{ + option: &inbound.MieruOption{ + BaseOption: inbound.BaseOption{ + Port: "8090-8099", + }, + Transport: "UDP", + Users: map[string]string{"user": "pass"}, + }, + }, + wantErr: false, + }, + { + name: "valid mix of port and port-range", + args: args{ + option: &inbound.MieruOption{ + BaseOption: inbound.BaseOption{ + Port: "8080,8090-8099", + }, + Transport: "TCP", + Users: map[string]string{"user": "pass"}, + }, + }, + wantErr: false, + }, + { + name: "invalid - no port", + args: args{ + option: &inbound.MieruOption{ + Transport: "TCP", + Users: map[string]string{"user": "pass"}, + }, + }, + wantErr: true, + }, + { + name: "invalid - transport", + args: args{ + option: &inbound.MieruOption{ + BaseOption: inbound.BaseOption{ + Port: "8080", + }, + Transport: "INVALID", + Users: map[string]string{"user": "pass"}, + }, + }, + wantErr: true, + }, + { + name: "invalid - no transport", + args: args{ + option: &inbound.MieruOption{ + BaseOption: inbound.BaseOption{ + Port: "8080", + }, + Users: map[string]string{"user": "pass"}, + }, + }, + wantErr: true, + }, + { + name: "invalid - no users", + args: args{ + option: &inbound.MieruOption{ + BaseOption: inbound.BaseOption{ + Port: "8080", + }, + Transport: "TCP", + Users: map[string]string{}, + }, + }, + wantErr: true, + }, + { + name: "invalid - empty username", + args: args{ + option: &inbound.MieruOption{ + BaseOption: inbound.BaseOption{ + Port: "8080", + }, + Transport: "TCP", + Users: map[string]string{"": "pass"}, + }, + }, + wantErr: true, + }, + { + name: "invalid - empty password", + args: args{ + option: &inbound.MieruOption{ + BaseOption: inbound.BaseOption{ + Port: "8080", + }, + Transport: "TCP", + Users: map[string]string{"user": ""}, + }, + }, + wantErr: true, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got, err := inbound.NewMieru(tt.args.option) + if (err != nil) != tt.wantErr { + t.Errorf("NewMieru() error = %v, wantErr %v", err, tt.wantErr) + return + } + if err == nil { + got.Close() + } + }) + } +} + +func TestInboundMieru(t *testing.T) { + t.Run("HANDSHAKE_STANDARD", func(t *testing.T) { + testInboundMieruTCP(t, "HANDSHAKE_STANDARD") + }) + t.Run("HANDSHAKE_NO_WAIT", func(t *testing.T) { + testInboundMieruTCP(t, "HANDSHAKE_NO_WAIT") + }) +} + +func testInboundMieruTCP(t *testing.T, handshakeMode string) { + t.Parallel() + l, err := net.Listen("tcp", "127.0.0.1:0") + if !assert.NoError(t, err) { + return + } + port := l.Addr().(*net.TCPAddr).Port + l.Close() + + inboundOptions := inbound.MieruOption{ + BaseOption: inbound.BaseOption{ + NameStr: "mieru_inbound", + Listen: "127.0.0.1", + Port: strconv.Itoa(port), + }, + Transport: "TCP", + Users: map[string]string{"test": "password"}, + } + in, err := inbound.NewMieru(&inboundOptions) + if !assert.NoError(t, err) { + return + } + + tunnel := NewHttpTestTunnel() + defer tunnel.Close() + + err = in.Listen(tunnel) + if !assert.NoError(t, err) { + return + } + defer in.Close() + + addrPort, err := netip.ParseAddrPort(in.Address()) + if !assert.NoError(t, err) { + return + } + outboundOptions := outbound.MieruOption{ + Name: "mieru_outbound", + Server: addrPort.Addr().String(), + Port: int(addrPort.Port()), + Transport: "TCP", + UserName: "test", + Password: "password", + HandshakeMode: handshakeMode, + } + out, err := outbound.NewMieru(outboundOptions) + if !assert.NoError(t, err) { + return + } + defer out.Close() + + tunnel.DoTest(t, out) +} diff --git a/clash-meta-android/core/src/foss/golang/clash/listener/mieru/server.go b/clash-meta-android/core/src/foss/golang/clash/listener/mieru/server.go new file mode 100644 index 0000000000..9b1e2e6f8f --- /dev/null +++ b/clash-meta-android/core/src/foss/golang/clash/listener/mieru/server.go @@ -0,0 +1,124 @@ +package mieru + +import ( + "errors" + "io" + "net" + "net/netip" + + "github.com/metacubex/mihomo/adapter/inbound" + N "github.com/metacubex/mihomo/common/net" + C "github.com/metacubex/mihomo/constant" + "github.com/metacubex/mihomo/transport/socks5" + + mierucommon "github.com/enfein/mieru/v3/apis/common" + mieruconstant "github.com/enfein/mieru/v3/apis/constant" + mierumodel "github.com/enfein/mieru/v3/apis/model" +) + +func Handle(conn net.Conn, tunnel C.Tunnel, request *mierumodel.Request, additions ...inbound.Addition) { + // Return a fake response to the client. + resp := &mierumodel.Response{ + Reply: mieruconstant.Socks5ReplySuccess, + BindAddr: mierumodel.AddrSpec{ + IP: net.IPv4zero, + Port: 0, + }, + } + if err := resp.WriteToSocks5(conn); err != nil { + conn.Close() + return + } + + // Handle the connection with tunnel. + metadata := mieruRequestToMetadata(request) + inbound.ApplyAdditions(&metadata, additions...) + switch metadata.NetWork { + case C.TCP: + tunnel.HandleTCPConn(conn, &metadata) + case C.UDP: + pc := mierucommon.NewPacketOverStreamTunnel(conn) + ep := N.NewEnhancePacketConn(pc) + for { + data, put, addr, err := ep.WaitReadFrom() + if err != nil { + if put != nil { + // Unresolved UDP packet, return buffer to the pool. + put() + } + // mieru returns EOF or ErrUnexpectedEOF when a session is closed. + if errors.Is(err, io.EOF) || errors.Is(err, io.ErrUnexpectedEOF) || errors.Is(err, io.ErrClosedPipe) { + break + } + continue + } + target, payload, err := socks5.DecodeUDPPacket(data) + if err != nil { + return + } + packet := &packet{ + pc: ep, + addr: addr, + payload: payload, + put: put, + } + tunnel.HandleUDPPacket(inbound.NewPacket(target, packet, C.MIERU, additions...)) + } + } +} + +func mieruRequestToMetadata(request *mierumodel.Request) C.Metadata { + m := C.Metadata{ + DstPort: uint16(request.DstAddr.Port), + } + switch request.Command { + case mieruconstant.Socks5ConnectCmd: + m.NetWork = C.TCP + case mieruconstant.Socks5UDPAssociateCmd: + m.NetWork = C.UDP + } + if request.DstAddr.FQDN != "" { + m.Host = request.DstAddr.FQDN + } else if request.DstAddr.IP != nil { + m.DstIP, _ = netip.AddrFromSlice(request.DstAddr.IP) + } + return m +} + +type packet struct { + pc net.PacketConn + addr net.Addr // source (i.e. remote) IP & Port of the packet + payload []byte + put func() +} + +var _ C.UDPPacket = (*packet)(nil) +var _ C.UDPPacketInAddr = (*packet)(nil) + +func (c *packet) Data() []byte { + return c.payload +} + +func (c *packet) WriteBack(b []byte, addr net.Addr) (n int, err error) { + packet, err := socks5.EncodeUDPPacket(socks5.ParseAddrToSocksAddr(addr), b) + if err != nil { + return + } + return c.pc.WriteTo(packet, c.addr) +} + +func (c *packet) Drop() { + if c.put != nil { + c.put() + c.put = nil + } + c.payload = nil +} + +func (c *packet) LocalAddr() net.Addr { + return c.addr +} + +func (c *packet) InAddr() net.Addr { + return c.pc.LocalAddr() +} diff --git a/clash-meta-android/core/src/foss/golang/clash/listener/parse.go b/clash-meta-android/core/src/foss/golang/clash/listener/parse.go index 8aec050ece..4e893bf1d0 100644 --- a/clash-meta-android/core/src/foss/golang/clash/listener/parse.go +++ b/clash-meta-android/core/src/foss/golang/clash/listener/parse.go @@ -127,6 +127,13 @@ func ParseListener(mapping map[string]any) (C.InboundListener, error) { return nil, err } listener, err = IN.NewAnyTLS(anytlsOption) + case "mieru": + mieruOption := &IN.MieruOption{} + err = decoder.Decode(mapping, mieruOption) + if err != nil { + return nil, err + } + listener, err = IN.NewMieru(mieruOption) default: return nil, fmt.Errorf("unsupport proxy type: %s", proxyType) } diff --git a/clash-meta-android/core/src/foss/golang/clash/listener/sing_tun/server.go b/clash-meta-android/core/src/foss/golang/clash/listener/sing_tun/server.go index ccd12f42db..87f413d431 100644 --- a/clash-meta-android/core/src/foss/golang/clash/listener/sing_tun/server.go +++ b/clash-meta-android/core/src/foss/golang/clash/listener/sing_tun/server.go @@ -18,7 +18,7 @@ import ( "github.com/metacubex/mihomo/component/iface" "github.com/metacubex/mihomo/component/resolver" C "github.com/metacubex/mihomo/constant" - "github.com/metacubex/mihomo/constant/provider" + P "github.com/metacubex/mihomo/constant/provider" LC "github.com/metacubex/mihomo/listener/config" "github.com/metacubex/mihomo/listener/sing" "github.com/metacubex/mihomo/log" @@ -133,7 +133,7 @@ func New(options LC.Tun, tunnel C.Tunnel, additions ...inbound.Addition) (l *Lis } } ctx := context.TODO() - rpTunnel := tunnel.(provider.Tunnel) + rpTunnel := tunnel.(P.Tunnel) if options.GSOMaxSize == 0 { options.GSOMaxSize = 65536 } @@ -504,7 +504,7 @@ func New(options LC.Tun, tunnel C.Tunnel, additions ...inbound.Addition) (l *Lis return } -func (l *Listener) ruleUpdateCallback(ruleProvider provider.RuleProvider) { +func (l *Listener) ruleUpdateCallback(ruleProvider P.RuleProvider) { name := ruleProvider.Name() if slices.Contains(l.options.RouteAddressSet, name) { l.updateRule(ruleProvider, false, true) @@ -520,7 +520,7 @@ type toIpCidr interface { ToIpCidr() *netipx.IPSet } -func (l *Listener) updateRule(ruleProvider provider.RuleProvider, exclude bool, update bool) { +func (l *Listener) updateRule(ruleProvider P.RuleProvider, exclude bool, update bool) { l.ruleUpdateMutex.Lock() defer l.ruleUpdateMutex.Unlock() name := ruleProvider.Name() diff --git a/clash-meta-android/core/src/foss/golang/clash/ntp/service.go b/clash-meta-android/core/src/foss/golang/clash/ntp/ntp/service.go similarity index 80% rename from clash-meta-android/core/src/foss/golang/clash/ntp/service.go rename to clash-meta-android/core/src/foss/golang/clash/ntp/ntp/service.go index 8473df6a8f..8f27d0aac1 100644 --- a/clash-meta-android/core/src/foss/golang/clash/ntp/service.go +++ b/clash-meta-android/core/src/foss/golang/clash/ntp/ntp/service.go @@ -3,18 +3,18 @@ package ntp import ( "context" "sync" - "sync/atomic" "time" "github.com/metacubex/mihomo/component/dialer" "github.com/metacubex/mihomo/component/proxydialer" "github.com/metacubex/mihomo/log" + mihomoNtp "github.com/metacubex/mihomo/ntp" M "github.com/metacubex/sing/common/metadata" "github.com/metacubex/sing/common/ntp" ) -var globalSrv atomic.Pointer[Service] +var globalSrv *Service var globalMu sync.Mutex type Service struct { @@ -23,21 +23,20 @@ type Service struct { ticker *time.Ticker ctx context.Context cancel context.CancelFunc - offset atomic.Int64 // [time.Duration] syncSystemTime bool } func ReCreateNTPService(server string, interval time.Duration, dialerProxy string, syncSystemTime bool) { globalMu.Lock() defer globalMu.Unlock() - if service := globalSrv.Swap(nil); service != nil { - service.Stop() + if globalSrv != nil { + globalSrv.Stop() } if server == "" || interval <= 0 { return } ctx, cancel := context.WithCancel(context.Background()) - service := &Service{ + globalSrv = &Service{ server: M.ParseSocksaddr(server), dialer: proxydialer.NewByNameSingDialer(dialerProxy, dialer.NewDialer()), ticker: time.NewTicker(interval * time.Minute), @@ -45,8 +44,7 @@ func ReCreateNTPService(server string, interval time.Duration, dialerProxy strin cancel: cancel, syncSystemTime: syncSystemTime, } - service.Start() - globalSrv.Store(service) + globalSrv.Start() } func (srv *Service) Start() { @@ -59,10 +57,6 @@ func (srv *Service) Stop() { srv.cancel() } -func (srv *Service) Offset() time.Duration { - return time.Duration(srv.offset.Load()) -} - func (srv *Service) update() error { var response *ntp.Response var err error @@ -80,7 +74,7 @@ func (srv *Service) update() error { } else if offset < time.Duration(0) { log.Infoln("System clock is behind NTP time by %s", -offset) } - srv.offset.Store(int64(offset)) + mihomoNtp.SetOffset(offset) if srv.syncSystemTime { timeNow := response.Time syncErr := setSystemTime(timeNow) @@ -97,7 +91,7 @@ func (srv *Service) update() error { } func (srv *Service) loopUpdate() { - defer srv.offset.Store(0) + defer mihomoNtp.SetOffset(0) defer srv.ticker.Stop() for { err := srv.update() @@ -111,13 +105,3 @@ func (srv *Service) loopUpdate() { } } } - -func Now() time.Time { - now := time.Now() - if service := globalSrv.Load(); service != nil { - if offset := service.Offset(); offset.Abs() > 0 { - now = now.Add(offset) - } - } - return now -} diff --git a/clash-meta-android/core/src/foss/golang/clash/ntp/time_stub.go b/clash-meta-android/core/src/foss/golang/clash/ntp/ntp/time_stub.go similarity index 100% rename from clash-meta-android/core/src/foss/golang/clash/ntp/time_stub.go rename to clash-meta-android/core/src/foss/golang/clash/ntp/ntp/time_stub.go diff --git a/clash-meta-android/core/src/foss/golang/clash/ntp/time_unix.go b/clash-meta-android/core/src/foss/golang/clash/ntp/ntp/time_unix.go similarity index 100% rename from clash-meta-android/core/src/foss/golang/clash/ntp/time_unix.go rename to clash-meta-android/core/src/foss/golang/clash/ntp/ntp/time_unix.go diff --git a/clash-meta-android/core/src/foss/golang/clash/ntp/time_windows.go b/clash-meta-android/core/src/foss/golang/clash/ntp/ntp/time_windows.go similarity index 100% rename from clash-meta-android/core/src/foss/golang/clash/ntp/time_windows.go rename to clash-meta-android/core/src/foss/golang/clash/ntp/ntp/time_windows.go diff --git a/clash-meta-android/core/src/foss/golang/clash/ntp/time.go b/clash-meta-android/core/src/foss/golang/clash/ntp/time.go new file mode 100644 index 0000000000..e69be02564 --- /dev/null +++ b/clash-meta-android/core/src/foss/golang/clash/ntp/time.go @@ -0,0 +1,28 @@ +// Package ntp provide time.Now +// +// DON'T import other package in mihomo to keep minimal internal dependencies +package ntp + +import ( + "time" + + "sync/atomic" +) + +var _offset atomic.Int64 // [time.Duration] + +func SetOffset(offset time.Duration) { + _offset.Store(int64(offset)) +} + +func GetOffset() time.Duration { + return time.Duration(_offset.Load()) +} + +func Now() time.Time { + now := time.Now() + if offset := GetOffset(); offset != 0 { + now = now.Add(offset) + } + return now +} diff --git a/clash-meta-android/core/src/foss/golang/clash/rules/provider/mrs_converter.go b/clash-meta-android/core/src/foss/golang/clash/rules/provider/mrs_converter.go index dbbe51cb29..edc24e7eea 100644 --- a/clash-meta-android/core/src/foss/golang/clash/rules/provider/mrs_converter.go +++ b/clash-meta-android/core/src/foss/golang/clash/rules/provider/mrs_converter.go @@ -34,7 +34,7 @@ func ConvertToMrs(buf []byte, behavior P.RuleBehavior, format P.RuleFormat, w io } var encoder *zstd.Encoder - encoder, err = zstd.NewWriter(w, zstd.WithEncoderLevel(zstd.SpeedBestCompression)) + encoder, err = zstd.NewWriter(w) if err != nil { return err } diff --git a/clash-meta-android/core/src/foss/golang/clash/transport/trojan/trojan.go b/clash-meta-android/core/src/foss/golang/clash/transport/trojan/trojan.go index 93819130fd..73b09dbc1a 100644 --- a/clash-meta-android/core/src/foss/golang/clash/transport/trojan/trojan.go +++ b/clash-meta-android/core/src/foss/golang/clash/transport/trojan/trojan.go @@ -183,7 +183,11 @@ func (pc *PacketConn) WaitReadFrom() (data []byte, put func(), addr net.Addr, er if err != nil { return nil, nil, nil, err } - addr = destination.UDPAddr() + udpAddr := destination.UDPAddr() + if udpAddr == nil { + return nil, nil, nil, errors.New("parse addr error") + } + addr = udpAddr data = pool.Get(pool.UDPBufferSize) put = func() { diff --git a/clash-meta-android/core/src/foss/golang/clash/transport/tuic/common/congestion.go b/clash-meta-android/core/src/foss/golang/clash/transport/tuic/common/congestion.go index afcf7a7851..fb0956bcd8 100644 --- a/clash-meta-android/core/src/foss/golang/clash/transport/tuic/common/congestion.go +++ b/clash-meta-android/core/src/foss/golang/clash/transport/tuic/common/congestion.go @@ -21,7 +21,6 @@ func SetCongestionController(quicConn *quic.Conn, cc string, cwnd int) { case "cubic": quicConn.SetCongestionControl( congestion.NewCubicSender( - congestion.DefaultClock{}, congestion.GetInitialPacketSize(quicConn), false, ), @@ -29,7 +28,6 @@ func SetCongestionController(quicConn *quic.Conn, cc string, cwnd int) { case "new_reno": quicConn.SetCongestionControl( congestion.NewCubicSender( - congestion.DefaultClock{}, congestion.GetInitialPacketSize(quicConn), true, ), @@ -37,7 +35,6 @@ func SetCongestionController(quicConn *quic.Conn, cc string, cwnd int) { case "bbr_meta_v1": quicConn.SetCongestionControl( congestion.NewBBRSender( - congestion.DefaultClock{}, congestion.GetInitialPacketSize(quicConn), c.ByteCount(cwnd)*congestion.InitialMaxDatagramSize, congestion.DefaultBBRMaxCongestionWindow*congestion.InitialMaxDatagramSize, @@ -48,7 +45,6 @@ func SetCongestionController(quicConn *quic.Conn, cc string, cwnd int) { case "bbr": quicConn.SetCongestionControl( congestionv2.NewBbrSender( - congestionv2.DefaultClock{}, congestionv2.GetInitialPacketSize(quicConn), c.ByteCount(cwnd), ), diff --git a/clash-meta-android/core/src/foss/golang/clash/transport/tuic/congestion/bbr_sender.go b/clash-meta-android/core/src/foss/golang/clash/transport/tuic/congestion/bbr_sender.go index 7f41d5be7e..7a75349107 100644 --- a/clash-meta-android/core/src/foss/golang/clash/transport/tuic/congestion/bbr_sender.go +++ b/clash-meta-android/core/src/foss/golang/clash/transport/tuic/congestion/bbr_sender.go @@ -101,7 +101,6 @@ const ( type bbrSender struct { mode bbrMode - clock Clock rttStats congestion.RTTStatsProvider bytesInFlight congestion.ByteCount // return total bytes of unacked packets. @@ -232,14 +231,12 @@ type bbrSender struct { } func NewBBRSender( - clock Clock, initialMaxDatagramSize, initialCongestionWindow, initialMaxCongestionWindow congestion.ByteCount, ) *bbrSender { b := &bbrSender{ mode: STARTUP, - clock: clock, sampler: NewBandwidthSampler(), maxBandwidth: NewWindowedFilter(int64(BandwidthWindowSize), MaxFilter), maxAckHeight: NewWindowedFilter(int64(BandwidthWindowSize), MaxFilter), diff --git a/clash-meta-android/core/src/foss/golang/clash/transport/tuic/congestion/clock.go b/clash-meta-android/core/src/foss/golang/clash/transport/tuic/congestion/clock.go deleted file mode 100644 index 405fae70f9..0000000000 --- a/clash-meta-android/core/src/foss/golang/clash/transport/tuic/congestion/clock.go +++ /dev/null @@ -1,18 +0,0 @@ -package congestion - -import "time" - -// A Clock returns the current time -type Clock interface { - Now() time.Time -} - -// DefaultClock implements the Clock interface using the Go stdlib clock. -type DefaultClock struct{} - -var _ Clock = DefaultClock{} - -// Now gets the current time -func (DefaultClock) Now() time.Time { - return time.Now() -} diff --git a/clash-meta-android/core/src/foss/golang/clash/transport/tuic/congestion/cubic.go b/clash-meta-android/core/src/foss/golang/clash/transport/tuic/congestion/cubic.go index 35c3f0cba1..b92c5b6f68 100644 --- a/clash-meta-android/core/src/foss/golang/clash/transport/tuic/congestion/cubic.go +++ b/clash-meta-android/core/src/foss/golang/clash/transport/tuic/congestion/cubic.go @@ -37,8 +37,6 @@ const betaLastMax float32 = 0.85 // Cubic implements the cubic algorithm from TCP type Cubic struct { - clock Clock - // Number of connections to simulate. numConnections int @@ -67,9 +65,8 @@ type Cubic struct { } // NewCubic returns a new Cubic instance -func NewCubic(clock Clock) *Cubic { +func NewCubic() *Cubic { c := &Cubic{ - clock: clock, numConnections: defaultNumConnections, } c.Reset() diff --git a/clash-meta-android/core/src/foss/golang/clash/transport/tuic/congestion/cubic_sender.go b/clash-meta-android/core/src/foss/golang/clash/transport/tuic/congestion/cubic_sender.go index dcf63a0a8d..54fb203e9a 100644 --- a/clash-meta-android/core/src/foss/golang/clash/transport/tuic/congestion/cubic_sender.go +++ b/clash-meta-android/core/src/foss/golang/clash/transport/tuic/congestion/cubic_sender.go @@ -23,7 +23,6 @@ type cubicSender struct { rttStats congestion.RTTStatsProvider cubic *Cubic pacer *pacer - clock Clock reno bool @@ -61,12 +60,10 @@ var ( // NewCubicSender makes a new cubic sender func NewCubicSender( - clock Clock, initialMaxDatagramSize congestion.ByteCount, reno bool, ) *cubicSender { return newCubicSender( - clock, reno, initialMaxDatagramSize, initialCongestionWindow*initialMaxDatagramSize, @@ -75,7 +72,6 @@ func NewCubicSender( } func newCubicSender( - clock Clock, reno bool, initialMaxDatagramSize, initialCongestionWindow, @@ -89,8 +85,7 @@ func newCubicSender( initialMaxCongestionWindow: initialMaxCongestionWindow, congestionWindow: initialCongestionWindow, slowStartThreshold: MaxByteCount, - cubic: NewCubic(clock), - clock: clock, + cubic: NewCubic(), reno: reno, maxDatagramSize: initialMaxDatagramSize, } diff --git a/clash-meta-android/core/src/foss/golang/clash/transport/tuic/congestion_v2/bbr_sender.go b/clash-meta-android/core/src/foss/golang/clash/transport/tuic/congestion_v2/bbr_sender.go index 6020ab391f..ac17c35506 100644 --- a/clash-meta-android/core/src/foss/golang/clash/transport/tuic/congestion_v2/bbr_sender.go +++ b/clash-meta-android/core/src/foss/golang/clash/transport/tuic/congestion_v2/bbr_sender.go @@ -96,7 +96,6 @@ const ( type bbrSender struct { rttStats congestion.RTTStatsProvider - clock Clock pacer *Pacer mode bbrMode @@ -244,12 +243,10 @@ type bbrSender struct { var _ congestion.CongestionControl = &bbrSender{} func NewBbrSender( - clock Clock, initialMaxDatagramSize congestion.ByteCount, initialCongestionWindowPackets congestion.ByteCount, ) *bbrSender { return newBbrSender( - clock, initialMaxDatagramSize, initialCongestionWindowPackets*initialMaxDatagramSize, congestion.MaxCongestionWindowPackets*initialMaxDatagramSize, @@ -257,13 +254,11 @@ func NewBbrSender( } func newBbrSender( - clock Clock, initialMaxDatagramSize, initialCongestionWindow, initialMaxCongestionWindow congestion.ByteCount, ) *bbrSender { b := &bbrSender{ - clock: clock, mode: bbrModeStartup, sampler: newBandwidthSampler(roundTripCount(bandwidthWindowSize)), lastSentPacket: invalidPacketNumber, @@ -297,7 +292,7 @@ func newBbrSender( } */ - b.enterStartupMode(b.clock.Now()) + b.enterStartupMode() b.setHighCwndGain(derivedHighCWNDGain) return b @@ -605,7 +600,7 @@ func (b *bbrSender) maybeUpdateMinRtt(now monotime.Time, sampleMinRtt time.Durat } // Enters the STARTUP mode. -func (b *bbrSender) enterStartupMode(now monotime.Time) { +func (b *bbrSender) enterStartupMode() { b.mode = bbrModeStartup // b.maybeTraceStateChange(logging.CongestionStateStartup) b.pacingGain = b.highGain @@ -757,7 +752,7 @@ func (b *bbrSender) maybeEnterOrExitProbeRtt(now monotime.Time, isRoundStart, mi if now.Sub(b.exitProbeRttAt) >= 0 && b.probeRttRoundPassed { b.minRttTimestamp = now if !b.isAtFullBandwidth { - b.enterStartupMode(now) + b.enterStartupMode() } else { b.enterProbeBandwidthMode(now) } diff --git a/clash-meta-android/core/src/foss/golang/clash/transport/tuic/congestion_v2/clock.go b/clash-meta-android/core/src/foss/golang/clash/transport/tuic/congestion_v2/clock.go deleted file mode 100644 index e6ea35dbd4..0000000000 --- a/clash-meta-android/core/src/foss/golang/clash/transport/tuic/congestion_v2/clock.go +++ /dev/null @@ -1,20 +0,0 @@ -package congestion - -import ( - "github.com/metacubex/quic-go/monotime" -) - -// A Clock returns the current time -type Clock interface { - Now() monotime.Time -} - -// DefaultClock implements the Clock interface using the Go stdlib clock. -type DefaultClock struct{} - -var _ Clock = DefaultClock{} - -// Now gets the current time -func (DefaultClock) Now() monotime.Time { - return monotime.Now() -} diff --git a/clash-meta-android/core/src/foss/golang/clash/transport/vless/vision/conn.go b/clash-meta-android/core/src/foss/golang/clash/transport/vless/vision/conn.go index 4e62b1536c..a4d236c1d6 100644 --- a/clash-meta-android/core/src/foss/golang/clash/transport/vless/vision/conn.go +++ b/clash-meta-android/core/src/foss/golang/clash/transport/vless/vision/conn.go @@ -242,14 +242,26 @@ func (vc *Conn) WriteBuffer(buffer *buf.Buffer) (err error) { } func (vc *Conn) FrontHeadroom() int { + fontHeadroom := PaddingHeaderLen - uuid.Size if vc.readFilterUUID || vc.writeOnceUserUUID != nil { - return PaddingHeaderLen + fontHeadroom = PaddingHeaderLen } - return PaddingHeaderLen - uuid.Size + if vc.writeFilterApplicationData { // The writer may be replaced, add the required value for vc.netConn + if abs := N.CalculateFrontHeadroom(vc.netConn) - N.CalculateFrontHeadroom(vc.Conn); abs > 0 { + fontHeadroom += abs + } + } + return fontHeadroom } func (vc *Conn) RearHeadroom() int { - return 500 + 900 + rearHeadroom := 500 + 900 + if vc.writeFilterApplicationData { // The writer may be replaced, add the required value for vc.netConn + if abs := N.CalculateRearHeadroom(vc.netConn) - N.CalculateRearHeadroom(vc.Conn); abs > 0 { + rearHeadroom += abs + } + } + return rearHeadroom } func (vc *Conn) NeedHandshake() bool { diff --git a/clash-meta-android/core/src/foss/golang/clash/transport/vmess/http.go b/clash-meta-android/core/src/foss/golang/clash/transport/vmess/http.go index 3c66fe6b24..94f1fbd351 100644 --- a/clash-meta-android/core/src/foss/golang/clash/transport/vmess/http.go +++ b/clash-meta-android/core/src/foss/golang/clash/transport/vmess/http.go @@ -3,7 +3,6 @@ package vmess import ( "bufio" "bytes" - "errors" "fmt" "net" "net/http" @@ -55,11 +54,11 @@ func (hc *httpConn) Write(b []byte) (int, error) { return hc.Conn.Write(b) } - if len(hc.cfg.Path) == 0 { - return -1, errors.New("path is empty") + path := "/" + if len(hc.cfg.Path) > 0 { + path = hc.cfg.Path[randv2.IntN(len(hc.cfg.Path))] } - path := hc.cfg.Path[randv2.IntN(len(hc.cfg.Path))] host := hc.cfg.Host if header := hc.cfg.Headers["Host"]; len(header) != 0 { host = header[randv2.IntN(len(header))] diff --git a/clash-meta-android/core/src/foss/golang/clash/tunnel/tunnel.go b/clash-meta-android/core/src/foss/golang/clash/tunnel/tunnel.go index 17d1f28200..fc901eb354 100644 --- a/clash-meta-android/core/src/foss/golang/clash/tunnel/tunnel.go +++ b/clash-meta-android/core/src/foss/golang/clash/tunnel/tunnel.go @@ -17,13 +17,13 @@ import ( "github.com/metacubex/mihomo/common/utils" "github.com/metacubex/mihomo/component/loopback" "github.com/metacubex/mihomo/component/nat" - P "github.com/metacubex/mihomo/component/process" + "github.com/metacubex/mihomo/component/process" "github.com/metacubex/mihomo/component/resolver" "github.com/metacubex/mihomo/component/slowdown" "github.com/metacubex/mihomo/component/sniffer" C "github.com/metacubex/mihomo/constant" "github.com/metacubex/mihomo/constant/features" - "github.com/metacubex/mihomo/constant/provider" + P "github.com/metacubex/mihomo/constant/provider" icontext "github.com/metacubex/mihomo/context" "github.com/metacubex/mihomo/log" "github.com/metacubex/mihomo/tunnel/statistic" @@ -43,8 +43,8 @@ var ( listeners = make(map[string]C.InboundListener) subRules map[string][]C.Rule proxies = make(map[string]C.Proxy) - providers map[string]provider.ProxyProvider - ruleProviders map[string]provider.RuleProvider + providers map[string]P.ProxyProvider + ruleProviders map[string]P.RuleProvider configMux sync.RWMutex // for compatibility, lazy init @@ -59,21 +59,19 @@ var ( // default timeout for UDP session udpTimeout = 60 * time.Second - findProcessMode = atomic.NewInt32Enum(P.FindProcessStrict) - - fakeIPRange netip.Prefix + findProcessMode = atomic.NewInt32Enum(process.FindProcessStrict) snifferDispatcher *sniffer.Dispatcher sniffingEnable = false - ruleUpdateCallback = utils.NewCallback[provider.RuleProvider]() + ruleUpdateCallback = utils.NewCallback[P.RuleProvider]() ) type tunnel struct{} var Tunnel = tunnel{} var _ C.Tunnel = Tunnel -var _ provider.Tunnel = Tunnel +var _ P.Tunnel = Tunnel func (t tunnel) HandleTCPConn(conn net.Conn, metadata *C.Metadata) { connCtx := icontext.NewConnContext(conn, metadata) @@ -114,15 +112,15 @@ func (t tunnel) NatTable() C.NatTable { return natTable } -func (t tunnel) Providers() map[string]provider.ProxyProvider { +func (t tunnel) Providers() map[string]P.ProxyProvider { return providers } -func (t tunnel) RuleProviders() map[string]provider.RuleProvider { +func (t tunnel) RuleProviders() map[string]P.RuleProvider { return ruleProviders } -func (t tunnel) RuleUpdateCallback() *utils.Callback[provider.RuleProvider] { +func (t tunnel) RuleUpdateCallback() *utils.Callback[P.RuleProvider] { return ruleUpdateCallback } @@ -142,14 +140,6 @@ func Status() TunnelStatus { return status.Load() } -func SetFakeIPRange(p netip.Prefix) { - fakeIPRange = p -} - -func FakeIPRange() netip.Prefix { - return fakeIPRange -} - func SetSniffing(b bool) { if snifferDispatcher.Enable() { configMux.Lock() @@ -205,7 +195,7 @@ func Listeners() map[string]C.InboundListener { } // UpdateRules handle update rules -func UpdateRules(newRules []C.Rule, newSubRule map[string][]C.Rule, rp map[string]provider.RuleProvider) { +func UpdateRules(newRules []C.Rule, newSubRule map[string][]C.Rule, rp map[string]P.RuleProvider) { configMux.Lock() rules = newRules ruleProviders = rp @@ -233,17 +223,17 @@ func ProxiesWithProviders() map[string]C.Proxy { } // Providers return all compatible providers -func Providers() map[string]provider.ProxyProvider { +func Providers() map[string]P.ProxyProvider { return providers } // RuleProviders return all loaded rule providers -func RuleProviders() map[string]provider.RuleProvider { +func RuleProviders() map[string]P.RuleProvider { return ruleProviders } // UpdateProxies handle update proxies -func UpdateProxies(newProxies map[string]C.Proxy, newProviders map[string]provider.ProxyProvider) { +func UpdateProxies(newProxies map[string]C.Proxy, newProviders map[string]P.ProxyProvider) { configMux.Lock() proxies = newProxies providers = newProviders @@ -273,13 +263,13 @@ func SetMode(m TunnelMode) { mode = m } -func FindProcessMode() P.FindProcessMode { +func FindProcessMode() process.FindProcessMode { return findProcessMode.Load() } // SetFindProcessMode replace SetAlwaysFindProcess // always find process info if legacyAlways = true or mode.Always() = true, may be increase many memory -func SetFindProcessMode(mode P.FindProcessMode) { +func SetFindProcessMode(mode process.FindProcessMode) { findProcessMode.Store(mode) } @@ -368,7 +358,7 @@ func resolveMetadata(metadata *C.Metadata) (proxy C.Proxy, rule C.Rule, err erro attemptProcessLookup = false if !features.CMFA { // normal check for process - uid, path, err := P.FindProcessName(metadata.NetWork.String(), metadata.SrcIP, int(metadata.SrcPort)) + uid, path, err := process.FindProcessName(metadata.NetWork.String(), metadata.SrcIP, int(metadata.SrcPort)) if err != nil { log.Debugln("[Process] find process error for %s: %v", metadata.String(), err) } else { @@ -376,13 +366,13 @@ func resolveMetadata(metadata *C.Metadata) (proxy C.Proxy, rule C.Rule, err erro metadata.ProcessPath = path metadata.Uid = uid - if pkg, err := P.FindPackageName(metadata); err == nil { // for android (not CMFA) package names + if pkg, err := process.FindPackageName(metadata); err == nil { // for android (not CMFA) package names metadata.Process = pkg } } } else { // check package names - pkg, err := P.FindPackageName(metadata) + pkg, err := process.FindPackageName(metadata) if err != nil { log.Debugln("[Process] find process error for %s: %v", metadata.String(), err) } else { @@ -394,10 +384,10 @@ func resolveMetadata(metadata *C.Metadata) (proxy C.Proxy, rule C.Rule, err erro } switch FindProcessMode() { - case P.FindProcessAlways: + case process.FindProcessAlways: helper.FindProcess() helper.FindProcess = nil - case P.FindProcessOff: + case process.FindProcessOff: helper.FindProcess = nil } @@ -563,7 +553,7 @@ func handleTCPConn(connCtx C.ConnContext) { dialMetadata := metadata if len(metadata.Host) > 0 { if node, ok := resolver.DefaultHosts.Search(metadata.Host, false); ok { - if dstIp, _ := node.RandIP(); !FakeIPRange().Contains(dstIp) { + if dstIp, _ := node.RandIP(); !resolver.IsFakeIP(dstIp) { dialMetadata.DstIP = dstIp dialMetadata.DNSMode = C.DNSHosts dialMetadata = dialMetadata.Pure() diff --git a/clash-meta-android/core/src/foss/golang/go.mod b/clash-meta-android/core/src/foss/golang/go.mod index 92b8794bb1..b78c904307 100644 --- a/clash-meta-android/core/src/foss/golang/go.mod +++ b/clash-meta-android/core/src/foss/golang/go.mod @@ -13,8 +13,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.9.0 // indirect - github.com/enfein/mieru/v3 v3.20.0 // indirect + github.com/ebitengine/purego v0.9.1 // indirect + github.com/enfein/mieru/v3 v3.22.1 // 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 @@ -28,7 +28,7 @@ require ( github.com/gobwas/httphead v0.1.0 // indirect 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/gofrs/uuid/v5 v5.4.0 // 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 @@ -41,19 +41,19 @@ require ( 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-20250902133113-a7f637c14281 // indirect + github.com/metacubex/amneziawg-go v0.0.0-20251104174305-5a0e9f7e361d // indirect github.com/metacubex/ascon v0.1.0 // indirect - github.com/metacubex/bart v0.24.0 // indirect + github.com/metacubex/bart v0.26.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-20250919004547-6122b699a301 // indirect - github.com/metacubex/kcp-go v0.0.0-20251007183319-0df1aec1639a // indirect + github.com/metacubex/kcp-go v0.0.0-20251105084629-8c93f4bf37be // indirect github.com/metacubex/mihomo v1.7.0 // indirect github.com/metacubex/nftables v0.0.0-20250503052935-30a69ab87793 // indirect - github.com/metacubex/quic-go v0.55.1-0.20251004050223-450bd9e32033 // indirect + github.com/metacubex/quic-go v0.55.1-0.20251024060151-bd465f127128 // 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.6 // indirect @@ -62,12 +62,12 @@ require ( github.com/metacubex/sing-shadowsocks v0.2.12 // 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.8 // indirect + github.com/metacubex/sing-tun v0.4.9 // 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-20250922175018-15c9a6a78719 // indirect - github.com/metacubex/tfo-go v0.0.0-20250921095601-b102db4216c0 // indirect - github.com/metacubex/utls v1.8.2 // indirect + github.com/metacubex/tfo-go v0.0.0-20251024101424-368b42b59148 // indirect + github.com/metacubex/utls v1.8.3 // 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 @@ -80,7 +80,7 @@ require ( 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/samber/lo v1.52.0 // 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 diff --git a/clash-meta-android/core/src/foss/golang/go.sum b/clash-meta-android/core/src/foss/golang/go.sum index 8534ebaa31..95f5119c9f 100644 --- a/clash-meta-android/core/src/foss/golang/go.sum +++ b/clash-meta-android/core/src/foss/golang/go.sum @@ -22,10 +22,10 @@ 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.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/ebitengine/purego v0.9.1 h1:a/k2f2HQU3Pi399RPW1MOaZyhKJL9w/xFpKAg4q1s0A= +github.com/ebitengine/purego v0.9.1/go.mod h1:iIjxzd6CiRiOG0UyXP+V1+jWqUXVjPKLAI0mRfJZTmQ= +github.com/enfein/mieru/v3 v3.22.1 h1:/XGYYXpEhEJlxosmtbpEJkhtRLHB8IToG7LB8kU2ZDY= +github.com/enfein/mieru/v3 v3.22.1/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= @@ -54,8 +54,8 @@ github.com/gobwas/pool v0.2.1 h1:xfeeEhW7pwmX8nuLVlqbzVc7udMDrwetjEv+TZIz1og= github.com/gobwas/pool v0.2.1/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw= github.com/gobwas/ws v1.4.0 h1:CTaoG1tojrh4ucGPcoJFiAQUAsEWekEWvLy7GsVNqGs= github.com/gobwas/ws v1.4.0/go.mod h1:G3gNqMNtPppf5XUz7O4shetPpcZ1VJ7zt18dlUeakrc= -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/gofrs/uuid/v5 v5.4.0 h1:EfbpCTjqMuGyq5ZJwxqzn3Cbr2d0rUZU7v5ycAk/e/0= +github.com/gofrs/uuid/v5 v5.4.0/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.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= github.com/golang/snappy v1.0.0 h1:Oy607GVXHs7RtbggtPBnr2RmDArIsAefDwvrdWvRhGs= @@ -86,12 +86,12 @@ github.com/mdlayher/netlink v1.7.2 h1:/UtM3ofJap7Vl4QWCPDGXY8d3GIY2UGSDbK+QWmY8/ 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-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/amneziawg-go v0.0.0-20251104174305-5a0e9f7e361d h1:vAJ0ZT4aO803F1uw2roIA9yH7Sxzox34tVVyye1bz6c= +github.com/metacubex/amneziawg-go v0.0.0-20251104174305-5a0e9f7e361d/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.24.0 h1:EyNiPeVOlg0joSHTzi5oentI0j5M89utUq/5dd76pWM= -github.com/metacubex/bart v0.24.0/go.mod h1:DCcyfP4MC+Zy7sLK7XeGuMw+P5K9mIRsYOBgiE8icsI= +github.com/metacubex/bart v0.26.0 h1:d/bBTvVatfVWGfQbiDpYKI1bXUJgjaabB2KpK1Tnk6w= +github.com/metacubex/bart v0.26.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= @@ -104,12 +104,12 @@ github.com/metacubex/gopacket v1.1.20-0.20230608035415-7e2f98a3e759 h1:cjd4biTvO github.com/metacubex/gopacket v1.1.20-0.20230608035415-7e2f98a3e759/go.mod h1:UHOv2xu+RIgLwpXca7TLrXleEd4oR3sPatW6IF8wU88= 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-20251007183319-0df1aec1639a h1:5vdk2pI71itLBT2mpyNExM1UKZ+2mG7MVC+ZARpRXmg= -github.com/metacubex/kcp-go v0.0.0-20251007183319-0df1aec1639a/go.mod h1:HIJZW4QMhbBqXuqC1ly6Hn0TEYT2SzRw58ns1yGhXTs= +github.com/metacubex/kcp-go v0.0.0-20251105084629-8c93f4bf37be h1:Y7SigZIqfv/+RIA/D7R6EbB9p+brPRoGOM6zobSmRIM= +github.com/metacubex/kcp-go v0.0.0-20251105084629-8c93f4bf37be/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.55.1-0.20251004050223-450bd9e32033 h1:LEzvR5AmHEatqE6IWgMBUJHnaiz9VJfZeDGOiHFuWZU= -github.com/metacubex/quic-go v0.55.1-0.20251004050223-450bd9e32033/go.mod h1:1lktQFtCD17FZliVypbrDHwbsFSsmz2xz2TRXydvB5c= +github.com/metacubex/quic-go v0.55.1-0.20251024060151-bd465f127128 h1:I1uvJl206/HbkzEAZpLgGkZgUveOZb+P+6oTUj7dN+o= +github.com/metacubex/quic-go v0.55.1-0.20251024060151-bd465f127128/go.mod h1:1lktQFtCD17FZliVypbrDHwbsFSsmz2xz2TRXydvB5c= github.com/metacubex/randv2 v0.2.0 h1:uP38uBvV2SxYfLj53kuvAjbND4RUDfFJjwr4UigMiLs= github.com/metacubex/randv2 v0.2.0/go.mod h1:kFi2SzrQ5WuneuoLLCMkABtiBu6VRrMrWFqSPyj2cxY= github.com/metacubex/restls-client-go v0.1.7 h1:eCwiXCTQb5WJu9IlgYvDBA1OgrINv58dEe7hcN5H15k= @@ -127,18 +127,18 @@ github.com/metacubex/sing-shadowsocks2 v0.2.7 h1:hSuuc0YpsfiqYqt1o+fP4m34BQz4e6w 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.8 h1:3PyiUKWXYi37yHptXskzL1723O3OUdyt0Aej4XHVikM= -github.com/metacubex/sing-tun v0.4.8/go.mod h1:L/TjQY5JEGy8nvsuYmy/XgMFMCPiF0+AWSFCYfS6r9w= +github.com/metacubex/sing-tun v0.4.9 h1:jY0Yyt8nnN3yQRN/jTxgqNCmGi1dsFdxdIi7pQUlVVU= +github.com/metacubex/sing-tun v0.4.9/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-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.2 h1:d7KalMZ5hnOJ6lThMz8Ykd+5dvmXH3Eoeyfv2jUuG3w= -github.com/metacubex/utls v1.8.2/go.mod h1:kncGGVhFaoGn5M3pFe3SXhZCzsbCJayNOH4UEqTKTko= +github.com/metacubex/tfo-go v0.0.0-20251024101424-368b42b59148 h1:Zd0QqciLIhv9MKbGKTPEgN8WUFsgQGA1WJBy6spEnVU= +github.com/metacubex/tfo-go v0.0.0-20251024101424-368b42b59148/go.mod h1:l9oLnLoEXyGZ5RVLsh7QCC5XsouTUyKk4F2nLm2DHLw= +github.com/metacubex/utls v1.8.3 h1:0m/yCxm3SK6kWve2lKiFb1pue1wHitJ8sQQD4Ikqde4= +github.com/metacubex/utls v1.8.3/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= @@ -170,8 +170,8 @@ github.com/sagernet/cors v1.2.1 h1:Cv5Z8y9YSD6Gm+qSpNrL3LO4lD3eQVvbFYJSG7JCMHQ= github.com/sagernet/cors v1.2.1/go.mod h1:O64VyOjjhrkLmQIjF4KGRrJO/5dVXFdpEmCW/eISRAI= github.com/sagernet/netlink v0.0.0-20240612041022-b9a21c07ac6a h1:ObwtHN2VpqE0ZNjr6sGeT00J8uU7JF4cNUdb44/Duis= 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/samber/lo v1.52.0 h1:Rvi+3BFHES3A8meP33VPAxiBZX/Aws5RxrschYGjomw= +github.com/samber/lo v1.52.0/go.mod h1:4+MXEGsJzbKGaUEQFKBq2xtfuznW9oz/WrgyzMzRoM0= 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= diff --git a/clash-meta-android/core/src/main/golang/go.mod b/clash-meta-android/core/src/main/golang/go.mod index c4bcc5363d..786f105806 100644 --- a/clash-meta-android/core/src/main/golang/go.mod +++ b/clash-meta-android/core/src/main/golang/go.mod @@ -19,8 +19,8 @@ require ( github.com/bahlo/generic-list-go v0.2.0 // indirect github.com/buger/jsonparser v1.1.1 // indirect github.com/coreos/go-iptables v0.8.0 // indirect - github.com/ebitengine/purego v0.9.0 // indirect - github.com/enfein/mieru/v3 v3.20.0 // indirect + github.com/ebitengine/purego v0.9.1 // indirect + github.com/enfein/mieru/v3 v3.22.1 // 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,7 +34,7 @@ require ( github.com/gobwas/httphead v0.1.0 // indirect 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/gofrs/uuid/v5 v5.4.0 // indirect github.com/golang/protobuf v1.5.4 // indirect github.com/golang/snappy v1.0.0 // indirect github.com/google/btree v1.1.3 // indirect @@ -48,18 +48,18 @@ require ( 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-20250902133113-a7f637c14281 // indirect + github.com/metacubex/amneziawg-go v0.0.0-20251104174305-5a0e9f7e361d // indirect github.com/metacubex/ascon v0.1.0 // indirect - github.com/metacubex/bart v0.24.0 // indirect + github.com/metacubex/bart v0.26.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-20250919004547-6122b699a301 // indirect - github.com/metacubex/kcp-go v0.0.0-20251007183319-0df1aec1639a // indirect + github.com/metacubex/kcp-go v0.0.0-20251105084629-8c93f4bf37be // indirect github.com/metacubex/nftables v0.0.0-20250503052935-30a69ab87793 // indirect - github.com/metacubex/quic-go v0.55.1-0.20251004050223-450bd9e32033 // indirect + github.com/metacubex/quic-go v0.55.1-0.20251024060151-bd465f127128 // 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.6 // indirect @@ -68,12 +68,12 @@ require ( github.com/metacubex/sing-shadowsocks v0.2.12 // 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.8 // indirect + github.com/metacubex/sing-tun v0.4.9 // 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-20250922175018-15c9a6a78719 // indirect - github.com/metacubex/tfo-go v0.0.0-20250921095601-b102db4216c0 // indirect - github.com/metacubex/utls v1.8.2 // indirect + github.com/metacubex/tfo-go v0.0.0-20251024101424-368b42b59148 // indirect + github.com/metacubex/utls v1.8.3 // 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 @@ -86,7 +86,7 @@ require ( 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/samber/lo v1.52.0 // 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 diff --git a/clash-meta-android/core/src/main/golang/go.sum b/clash-meta-android/core/src/main/golang/go.sum index d6e0c6eee4..4592afba78 100644 --- a/clash-meta-android/core/src/main/golang/go.sum +++ b/clash-meta-android/core/src/main/golang/go.sum @@ -22,10 +22,10 @@ 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.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/ebitengine/purego v0.9.1 h1:a/k2f2HQU3Pi399RPW1MOaZyhKJL9w/xFpKAg4q1s0A= +github.com/ebitengine/purego v0.9.1/go.mod h1:iIjxzd6CiRiOG0UyXP+V1+jWqUXVjPKLAI0mRfJZTmQ= +github.com/enfein/mieru/v3 v3.22.1 h1:/XGYYXpEhEJlxosmtbpEJkhtRLHB8IToG7LB8kU2ZDY= +github.com/enfein/mieru/v3 v3.22.1/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= @@ -54,8 +54,8 @@ github.com/gobwas/pool v0.2.1 h1:xfeeEhW7pwmX8nuLVlqbzVc7udMDrwetjEv+TZIz1og= github.com/gobwas/pool v0.2.1/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw= github.com/gobwas/ws v1.4.0 h1:CTaoG1tojrh4ucGPcoJFiAQUAsEWekEWvLy7GsVNqGs= github.com/gobwas/ws v1.4.0/go.mod h1:G3gNqMNtPppf5XUz7O4shetPpcZ1VJ7zt18dlUeakrc= -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/gofrs/uuid/v5 v5.4.0 h1:EfbpCTjqMuGyq5ZJwxqzn3Cbr2d0rUZU7v5ycAk/e/0= +github.com/gofrs/uuid/v5 v5.4.0/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.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= @@ -87,12 +87,12 @@ github.com/mdlayher/netlink v1.7.2 h1:/UtM3ofJap7Vl4QWCPDGXY8d3GIY2UGSDbK+QWmY8/ 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-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/amneziawg-go v0.0.0-20251104174305-5a0e9f7e361d h1:vAJ0ZT4aO803F1uw2roIA9yH7Sxzox34tVVyye1bz6c= +github.com/metacubex/amneziawg-go v0.0.0-20251104174305-5a0e9f7e361d/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.24.0 h1:EyNiPeVOlg0joSHTzi5oentI0j5M89utUq/5dd76pWM= -github.com/metacubex/bart v0.24.0/go.mod h1:DCcyfP4MC+Zy7sLK7XeGuMw+P5K9mIRsYOBgiE8icsI= +github.com/metacubex/bart v0.26.0 h1:d/bBTvVatfVWGfQbiDpYKI1bXUJgjaabB2KpK1Tnk6w= +github.com/metacubex/bart v0.26.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= @@ -105,12 +105,12 @@ github.com/metacubex/gopacket v1.1.20-0.20230608035415-7e2f98a3e759 h1:cjd4biTvO github.com/metacubex/gopacket v1.1.20-0.20230608035415-7e2f98a3e759/go.mod h1:UHOv2xu+RIgLwpXca7TLrXleEd4oR3sPatW6IF8wU88= 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-20251007183319-0df1aec1639a h1:5vdk2pI71itLBT2mpyNExM1UKZ+2mG7MVC+ZARpRXmg= -github.com/metacubex/kcp-go v0.0.0-20251007183319-0df1aec1639a/go.mod h1:HIJZW4QMhbBqXuqC1ly6Hn0TEYT2SzRw58ns1yGhXTs= +github.com/metacubex/kcp-go v0.0.0-20251105084629-8c93f4bf37be h1:Y7SigZIqfv/+RIA/D7R6EbB9p+brPRoGOM6zobSmRIM= +github.com/metacubex/kcp-go v0.0.0-20251105084629-8c93f4bf37be/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.55.1-0.20251004050223-450bd9e32033 h1:LEzvR5AmHEatqE6IWgMBUJHnaiz9VJfZeDGOiHFuWZU= -github.com/metacubex/quic-go v0.55.1-0.20251004050223-450bd9e32033/go.mod h1:1lktQFtCD17FZliVypbrDHwbsFSsmz2xz2TRXydvB5c= +github.com/metacubex/quic-go v0.55.1-0.20251024060151-bd465f127128 h1:I1uvJl206/HbkzEAZpLgGkZgUveOZb+P+6oTUj7dN+o= +github.com/metacubex/quic-go v0.55.1-0.20251024060151-bd465f127128/go.mod h1:1lktQFtCD17FZliVypbrDHwbsFSsmz2xz2TRXydvB5c= github.com/metacubex/randv2 v0.2.0 h1:uP38uBvV2SxYfLj53kuvAjbND4RUDfFJjwr4UigMiLs= github.com/metacubex/randv2 v0.2.0/go.mod h1:kFi2SzrQ5WuneuoLLCMkABtiBu6VRrMrWFqSPyj2cxY= github.com/metacubex/restls-client-go v0.1.7 h1:eCwiXCTQb5WJu9IlgYvDBA1OgrINv58dEe7hcN5H15k= @@ -128,18 +128,18 @@ github.com/metacubex/sing-shadowsocks2 v0.2.7 h1:hSuuc0YpsfiqYqt1o+fP4m34BQz4e6w 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.8 h1:3PyiUKWXYi37yHptXskzL1723O3OUdyt0Aej4XHVikM= -github.com/metacubex/sing-tun v0.4.8/go.mod h1:L/TjQY5JEGy8nvsuYmy/XgMFMCPiF0+AWSFCYfS6r9w= +github.com/metacubex/sing-tun v0.4.9 h1:jY0Yyt8nnN3yQRN/jTxgqNCmGi1dsFdxdIi7pQUlVVU= +github.com/metacubex/sing-tun v0.4.9/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-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.2 h1:d7KalMZ5hnOJ6lThMz8Ykd+5dvmXH3Eoeyfv2jUuG3w= -github.com/metacubex/utls v1.8.2/go.mod h1:kncGGVhFaoGn5M3pFe3SXhZCzsbCJayNOH4UEqTKTko= +github.com/metacubex/tfo-go v0.0.0-20251024101424-368b42b59148 h1:Zd0QqciLIhv9MKbGKTPEgN8WUFsgQGA1WJBy6spEnVU= +github.com/metacubex/tfo-go v0.0.0-20251024101424-368b42b59148/go.mod h1:l9oLnLoEXyGZ5RVLsh7QCC5XsouTUyKk4F2nLm2DHLw= +github.com/metacubex/utls v1.8.3 h1:0m/yCxm3SK6kWve2lKiFb1pue1wHitJ8sQQD4Ikqde4= +github.com/metacubex/utls v1.8.3/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= @@ -171,8 +171,8 @@ github.com/sagernet/cors v1.2.1 h1:Cv5Z8y9YSD6Gm+qSpNrL3LO4lD3eQVvbFYJSG7JCMHQ= github.com/sagernet/cors v1.2.1/go.mod h1:O64VyOjjhrkLmQIjF4KGRrJO/5dVXFdpEmCW/eISRAI= github.com/sagernet/netlink v0.0.0-20240612041022-b9a21c07ac6a h1:ObwtHN2VpqE0ZNjr6sGeT00J8uU7JF4cNUdb44/Duis= 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/samber/lo v1.52.0 h1:Rvi+3BFHES3A8meP33VPAxiBZX/Aws5RxrschYGjomw= +github.com/samber/lo v1.52.0/go.mod h1:4+MXEGsJzbKGaUEQFKBq2xtfuznW9oz/WrgyzMzRoM0= 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= diff --git a/clash-meta/component/memory/memory_darwin.go b/clash-meta/component/memory/memory_darwin.go index 1dd33af32a..63356fe539 100644 --- a/clash-meta/component/memory/memory_darwin.go +++ b/clash-meta/component/memory/memory_darwin.go @@ -1,9 +1,9 @@ package memory import ( + "syscall" "unsafe" - - "github.com/ebitengine/purego" + _ "unsafe" ) const PROC_PIDTASKINFO = 4 @@ -29,24 +29,12 @@ type ProcTaskInfo struct { Priority int32 } -const System = "/usr/lib/libSystem.B.dylib" - -type ProcPidInfoFunc func(pid, flavor int32, arg uint64, buffer uintptr, bufferSize int32) int32 - -const ProcPidInfoSym = "proc_pidinfo" - func GetMemoryInfo(pid int32) (*MemoryInfoStat, error) { - lib, err := purego.Dlopen(System, purego.RTLD_LAZY|purego.RTLD_GLOBAL) - if err != nil { - return nil, err - } - defer purego.Dlclose(lib) - - var procPidInfo ProcPidInfoFunc - purego.RegisterLibFunc(&procPidInfo, lib, ProcPidInfoSym) - var ti ProcTaskInfo - procPidInfo(pid, PROC_PIDTASKINFO, 0, uintptr(unsafe.Pointer(&ti)), int32(unsafe.Sizeof(ti))) + _, _, errno := syscall_syscall6(proc_pidinfo_trampoline_addr, uintptr(pid), PROC_PIDTASKINFO, 0, uintptr(unsafe.Pointer(&ti)), unsafe.Sizeof(ti), 0) + if errno != 0 { + return nil, errno + } ret := &MemoryInfoStat{ RSS: uint64(ti.Resident_size), @@ -54,3 +42,26 @@ func GetMemoryInfo(pid int32) (*MemoryInfoStat, error) { } return ret, nil } + +var proc_pidinfo_trampoline_addr uintptr + +//go:cgo_import_dynamic proc_pidinfo proc_pidinfo "/usr/lib/libSystem.B.dylib" + +// from golang.org/x/sys@v0.30.0/unix/syscall_darwin_libSystem.go + +// Implemented in the runtime package (runtime/sys_darwin.go) +func syscall_syscall(fn, a1, a2, a3 uintptr) (r1, r2 uintptr, err syscall.Errno) +func syscall_syscall6(fn, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err syscall.Errno) +func syscall_syscall6X(fn, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err syscall.Errno) +func syscall_syscall9(fn, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2 uintptr, err syscall.Errno) // 32-bit only +func syscall_rawSyscall(fn, a1, a2, a3 uintptr) (r1, r2 uintptr, err syscall.Errno) +func syscall_rawSyscall6(fn, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err syscall.Errno) +func syscall_syscallPtr(fn, a1, a2, a3 uintptr) (r1, r2 uintptr, err syscall.Errno) + +//go:linkname syscall_syscall syscall.syscall +//go:linkname syscall_syscall6 syscall.syscall6 +//go:linkname syscall_syscall6X syscall.syscall6X +//go:linkname syscall_syscall9 syscall.syscall9 +//go:linkname syscall_rawSyscall syscall.rawSyscall +//go:linkname syscall_rawSyscall6 syscall.rawSyscall6 +//go:linkname syscall_syscallPtr syscall.syscallPtr diff --git a/clash-meta/component/memory/memory_darwin_amd64.s b/clash-meta/component/memory/memory_darwin_amd64.s new file mode 100644 index 0000000000..4c17419a57 --- /dev/null +++ b/clash-meta/component/memory/memory_darwin_amd64.s @@ -0,0 +1,9 @@ +// go run mkasm.go darwin amd64 +// Code generated by the command above; DO NOT EDIT. + +#include "textflag.h" + +TEXT proc_pidinfo_trampoline<>(SB),NOSPLIT,$0-0 + JMP proc_pidinfo(SB) +GLOBL ·proc_pidinfo_trampoline_addr(SB), RODATA, $8 +DATA ·proc_pidinfo_trampoline_addr(SB)/8, $proc_pidinfo_trampoline<>(SB) diff --git a/clash-meta/component/memory/memory_darwin_arm64.s b/clash-meta/component/memory/memory_darwin_arm64.s new file mode 100644 index 0000000000..645bc68042 --- /dev/null +++ b/clash-meta/component/memory/memory_darwin_arm64.s @@ -0,0 +1,9 @@ +// go run mkasm.go darwin arm64 +// Code generated by the command above; DO NOT EDIT. + +#include "textflag.h" + +TEXT proc_pidinfo_trampoline<>(SB),NOSPLIT,$0-0 + JMP proc_pidinfo(SB) +GLOBL ·proc_pidinfo_trampoline_addr(SB), RODATA, $8 +DATA ·proc_pidinfo_trampoline_addr(SB)/8, $proc_pidinfo_trampoline<>(SB) diff --git a/clash-meta/constant/metadata.go b/clash-meta/constant/metadata.go index 72b9995b1b..23cdcd8616 100644 --- a/clash-meta/constant/metadata.go +++ b/clash-meta/constant/metadata.go @@ -38,6 +38,7 @@ const ( TUIC HYSTERIA2 ANYTLS + MIERU INNER ) @@ -109,6 +110,8 @@ func (t Type) String() string { return "Hysteria2" case ANYTLS: return "AnyTLS" + case MIERU: + return "Mieru" case INNER: return "Inner" default: @@ -149,6 +152,8 @@ func ParseType(t string) (*Type, error) { res = HYSTERIA2 case "ANYTLS": res = ANYTLS + case "MIERU": + res = MIERU case "INNER": res = INNER default: diff --git a/clash-meta/dns/enhancer.go b/clash-meta/dns/enhancer.go index c84f8c32fe..7e34977258 100644 --- a/clash-meta/dns/enhancer.go +++ b/clash-meta/dns/enhancer.go @@ -1,6 +1,7 @@ package dns import ( + "errors" "net/netip" "github.com/metacubex/mihomo/common/lru" @@ -31,11 +32,15 @@ func (h *ResolverEnhancer) IsExistFakeIP(ip netip.Addr) bool { } if pool := h.fakeIPPool; pool != nil { - return pool.Exist(ip) + if pool.Exist(ip) { + return true + } } if pool6 := h.fakeIPPool6; pool6 != nil { - return pool6.Exist(ip) + if pool6.Exist(ip) { + return true + } } return false @@ -47,11 +52,15 @@ func (h *ResolverEnhancer) IsFakeIP(ip netip.Addr) bool { } if pool := h.fakeIPPool; pool != nil { - return pool.IPNet().Contains(ip) && ip != pool.Gateway() && ip != pool.Broadcast() + if pool.IPNet().Contains(ip) && ip != pool.Gateway() && ip != pool.Broadcast() { + return true + } } if pool6 := h.fakeIPPool6; pool6 != nil { - return pool6.IPNet().Contains(ip) && ip != pool6.Gateway() && ip != pool6.Broadcast() + if pool6.IPNet().Contains(ip) && ip != pool6.Gateway() && ip != pool6.Broadcast() { + return true + } } return false @@ -63,11 +72,15 @@ func (h *ResolverEnhancer) IsFakeBroadcastIP(ip netip.Addr) bool { } if pool := h.fakeIPPool; pool != nil { - return pool.Broadcast() == ip + if pool.Broadcast() == ip { + return true + } } if pool6 := h.fakeIPPool6; pool6 != nil { - return pool6.Broadcast() == ip + if pool6.Broadcast() == ip { + return true + } } return false @@ -102,11 +115,19 @@ func (h *ResolverEnhancer) InsertHostByIP(ip netip.Addr, host string) { } func (h *ResolverEnhancer) FlushFakeIP() error { + var errs []error if pool := h.fakeIPPool; pool != nil { - return pool.FlushFakeIP() + if err := pool.FlushFakeIP(); err != nil { + errs = append(errs, err) + } } if pool6 := h.fakeIPPool6; pool6 != nil { - return pool6.FlushFakeIP() + if err := pool6.FlushFakeIP(); err != nil { + errs = append(errs, err) + } + } + if len(errs) > 0 { + return errors.Join(errs...) } return nil } diff --git a/clash-meta/docs/config.yaml b/clash-meta/docs/config.yaml index 57a1adcf91..e71b06f482 100644 --- a/clash-meta/docs/config.yaml +++ b/clash-meta/docs/config.yaml @@ -1556,6 +1556,15 @@ listeners: # -----END ECH KEYS----- # padding-scheme: "" # https://github.com/anytls/anytls-go/blob/main/docs/protocol.md#cmdupdatepaddingscheme + - name: mieru-in-1 + type: mieru + port: 10818 # 支持使用ports格式,例如200,302 or 200,204,401-429,501-503 + listen: 0.0.0.0 + transport: TCP # 支持 TCP 或者 UDP + users: + username1: password1 + username2: password2 + - name: trojan-in-1 type: trojan port: 10819 # 支持使用ports格式,例如200,302 or 200,204,401-429,501-503 diff --git a/clash-meta/go.mod b/clash-meta/go.mod index ea42bce7d6..d203eb6407 100644 --- a/clash-meta/go.mod +++ b/clash-meta/go.mod @@ -6,8 +6,7 @@ require ( github.com/bahlo/generic-list-go v0.2.0 github.com/coreos/go-iptables v0.8.0 github.com/dlclark/regexp2 v1.11.5 - github.com/ebitengine/purego v0.9.0 - github.com/enfein/mieru/v3 v3.20.0 + github.com/enfein/mieru/v3 v3.22.1 github.com/go-chi/chi/v5 v5.2.3 github.com/go-chi/render v1.0.3 github.com/gobwas/ws v1.4.0 @@ -33,7 +32,7 @@ require ( github.com/metacubex/sing-shadowsocks v0.2.12 github.com/metacubex/sing-shadowsocks2 v0.2.7 github.com/metacubex/sing-shadowtls v0.0.0-20250503063515-5d9f966d17a2 - github.com/metacubex/sing-tun v0.4.8 + github.com/metacubex/sing-tun v0.4.9 github.com/metacubex/sing-vmess v0.2.4 github.com/metacubex/sing-wireguard v0.0.0-20250503063753-2dc62acc626f github.com/metacubex/smux v0.0.0-20250922175018-15c9a6a78719 diff --git a/clash-meta/go.sum b/clash-meta/go.sum index bfc1a8f524..4670178e98 100644 --- a/clash-meta/go.sum +++ b/clash-meta/go.sum @@ -23,10 +23,8 @@ 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.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/enfein/mieru/v3 v3.22.1 h1:/XGYYXpEhEJlxosmtbpEJkhtRLHB8IToG7LB8kU2ZDY= +github.com/enfein/mieru/v3 v3.22.1/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= @@ -131,8 +129,8 @@ github.com/metacubex/sing-shadowsocks2 v0.2.7 h1:hSuuc0YpsfiqYqt1o+fP4m34BQz4e6w 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.8 h1:3PyiUKWXYi37yHptXskzL1723O3OUdyt0Aej4XHVikM= -github.com/metacubex/sing-tun v0.4.8/go.mod h1:L/TjQY5JEGy8nvsuYmy/XgMFMCPiF0+AWSFCYfS6r9w= +github.com/metacubex/sing-tun v0.4.9 h1:jY0Yyt8nnN3yQRN/jTxgqNCmGi1dsFdxdIi7pQUlVVU= +github.com/metacubex/sing-tun v0.4.9/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= diff --git a/clash-meta/listener/inbound/mieru.go b/clash-meta/listener/inbound/mieru.go new file mode 100644 index 0000000000..cf8cc403bc --- /dev/null +++ b/clash-meta/listener/inbound/mieru.go @@ -0,0 +1,181 @@ +package inbound + +import ( + "context" + "fmt" + "net" + "sync" + + "github.com/metacubex/mihomo/adapter/inbound" + "github.com/metacubex/mihomo/common/utils" + C "github.com/metacubex/mihomo/constant" + "github.com/metacubex/mihomo/listener/mieru" + "github.com/metacubex/mihomo/log" + "google.golang.org/protobuf/proto" + + mieruserver "github.com/enfein/mieru/v3/apis/server" + mierupb "github.com/enfein/mieru/v3/pkg/appctl/appctlpb" +) + +type Mieru struct { + *Base + option *MieruOption + server mieruserver.Server + mu sync.Mutex +} + +type MieruOption struct { + BaseOption + Transport string `inbound:"transport"` + Users map[string]string `inbound:"users"` +} + +type mieruListenerFactory struct{} + +func (mieruListenerFactory) Listen(ctx context.Context, network, address string) (net.Listener, error) { + return inbound.ListenContext(ctx, network, address) +} + +func (mieruListenerFactory) ListenPacket(ctx context.Context, network, address string) (net.PacketConn, error) { + return inbound.ListenPacketContext(ctx, network, address) +} + +func NewMieru(option *MieruOption) (*Mieru, error) { + base, err := NewBase(&option.BaseOption) + if err != nil { + return nil, err + } + + config, err := buildMieruServerConfig(option, base.ports) + if err != nil { + return nil, fmt.Errorf("failed to build mieru server config: %w", err) + } + s := mieruserver.NewServer() + if err := s.Store(config); err != nil { + return nil, fmt.Errorf("failed to store mieru server config: %w", err) + } + // Server is started lazily when Listen() is called for the first time. + return &Mieru{ + Base: base, + option: option, + server: s, + }, nil +} + +func (m *Mieru) Config() C.InboundConfig { + return m.option +} + +func (m *Mieru) Listen(tunnel C.Tunnel) error { + m.mu.Lock() + defer m.mu.Unlock() + + if !m.server.IsRunning() { + if err := m.server.Start(); err != nil { + return fmt.Errorf("failed to start mieru server: %w", err) + } + } + + additions := m.config.Additions() + if len(additions) == 0 { + additions = []inbound.Addition{ + inbound.WithInName("DEFAULT-MIERU"), + inbound.WithSpecialRules(""), + } + } + + go func() { + for { + c, req, err := m.server.Accept() + if err != nil { + if !m.server.IsRunning() { + break + } + } + go mieru.Handle(c, tunnel, req, additions...) + } + }() + log.Infoln("Mieru[%s] proxy listening at: %s", m.Name(), m.Address()) + return nil +} + +func (m *Mieru) Close() error { + m.mu.Lock() + defer m.mu.Unlock() + + if m.server.IsRunning() { + return m.server.Stop() + } + + return nil +} + +var _ C.InboundListener = (*Mieru)(nil) + +func (o MieruOption) Equal(config C.InboundConfig) bool { + return optionToString(o) == optionToString(config) +} + +func buildMieruServerConfig(option *MieruOption, ports utils.IntRanges[uint16]) (*mieruserver.ServerConfig, error) { + if err := validateMieruOption(option); err != nil { + return nil, fmt.Errorf("failed to validate mieru option: %w", err) + } + if len(ports) == 0 { + return nil, fmt.Errorf("port is not set") + } + + var transportProtocol *mierupb.TransportProtocol + switch option.Transport { + case "TCP": + transportProtocol = mierupb.TransportProtocol_TCP.Enum() + case "UDP": + transportProtocol = mierupb.TransportProtocol_UDP.Enum() + } + var portBindings []*mierupb.PortBinding + for _, portRange := range ports { + if portRange.Start() == portRange.End() { + portBindings = append(portBindings, &mierupb.PortBinding{ + Port: proto.Int32(int32(portRange.Start())), + Protocol: transportProtocol, + }) + } else { + portBindings = append(portBindings, &mierupb.PortBinding{ + PortRange: proto.String(fmt.Sprintf("%d-%d", portRange.Start(), portRange.End())), + Protocol: transportProtocol, + }) + } + } + var users []*mierupb.User + for username, password := range option.Users { + users = append(users, &mierupb.User{ + Name: proto.String(username), + Password: proto.String(password), + }) + } + return &mieruserver.ServerConfig{ + Config: &mierupb.ServerConfig{ + PortBindings: portBindings, + Users: users, + }, + StreamListenerFactory: mieruListenerFactory{}, + PacketListenerFactory: mieruListenerFactory{}, + }, nil +} + +func validateMieruOption(option *MieruOption) error { + if option.Transport != "TCP" && option.Transport != "UDP" { + return fmt.Errorf("transport must be TCP or UDP") + } + if len(option.Users) == 0 { + return fmt.Errorf("users is empty") + } + for username, password := range option.Users { + if username == "" { + return fmt.Errorf("username is empty") + } + if password == "" { + return fmt.Errorf("password is empty") + } + } + return nil +} diff --git a/clash-meta/listener/inbound/mieru_test.go b/clash-meta/listener/inbound/mieru_test.go new file mode 100644 index 0000000000..d163b49dcc --- /dev/null +++ b/clash-meta/listener/inbound/mieru_test.go @@ -0,0 +1,212 @@ +package inbound_test + +import ( + "net" + "net/netip" + "strconv" + "testing" + + "github.com/metacubex/mihomo/adapter/outbound" + "github.com/metacubex/mihomo/listener/inbound" + "github.com/stretchr/testify/assert" +) + +func TestNewMieru(t *testing.T) { + type args struct { + option *inbound.MieruOption + } + tests := []struct { + name string + args args + wantErr bool + }{ + { + name: "valid with port", + args: args{ + option: &inbound.MieruOption{ + BaseOption: inbound.BaseOption{ + Port: "8080", + }, + Transport: "TCP", + Users: map[string]string{"user": "pass"}, + }, + }, + wantErr: false, + }, + { + name: "valid with port range", + args: args{ + option: &inbound.MieruOption{ + BaseOption: inbound.BaseOption{ + Port: "8090-8099", + }, + Transport: "UDP", + Users: map[string]string{"user": "pass"}, + }, + }, + wantErr: false, + }, + { + name: "valid mix of port and port-range", + args: args{ + option: &inbound.MieruOption{ + BaseOption: inbound.BaseOption{ + Port: "8080,8090-8099", + }, + Transport: "TCP", + Users: map[string]string{"user": "pass"}, + }, + }, + wantErr: false, + }, + { + name: "invalid - no port", + args: args{ + option: &inbound.MieruOption{ + Transport: "TCP", + Users: map[string]string{"user": "pass"}, + }, + }, + wantErr: true, + }, + { + name: "invalid - transport", + args: args{ + option: &inbound.MieruOption{ + BaseOption: inbound.BaseOption{ + Port: "8080", + }, + Transport: "INVALID", + Users: map[string]string{"user": "pass"}, + }, + }, + wantErr: true, + }, + { + name: "invalid - no transport", + args: args{ + option: &inbound.MieruOption{ + BaseOption: inbound.BaseOption{ + Port: "8080", + }, + Users: map[string]string{"user": "pass"}, + }, + }, + wantErr: true, + }, + { + name: "invalid - no users", + args: args{ + option: &inbound.MieruOption{ + BaseOption: inbound.BaseOption{ + Port: "8080", + }, + Transport: "TCP", + Users: map[string]string{}, + }, + }, + wantErr: true, + }, + { + name: "invalid - empty username", + args: args{ + option: &inbound.MieruOption{ + BaseOption: inbound.BaseOption{ + Port: "8080", + }, + Transport: "TCP", + Users: map[string]string{"": "pass"}, + }, + }, + wantErr: true, + }, + { + name: "invalid - empty password", + args: args{ + option: &inbound.MieruOption{ + BaseOption: inbound.BaseOption{ + Port: "8080", + }, + Transport: "TCP", + Users: map[string]string{"user": ""}, + }, + }, + wantErr: true, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got, err := inbound.NewMieru(tt.args.option) + if (err != nil) != tt.wantErr { + t.Errorf("NewMieru() error = %v, wantErr %v", err, tt.wantErr) + return + } + if err == nil { + got.Close() + } + }) + } +} + +func TestInboundMieru(t *testing.T) { + t.Run("HANDSHAKE_STANDARD", func(t *testing.T) { + testInboundMieruTCP(t, "HANDSHAKE_STANDARD") + }) + t.Run("HANDSHAKE_NO_WAIT", func(t *testing.T) { + testInboundMieruTCP(t, "HANDSHAKE_NO_WAIT") + }) +} + +func testInboundMieruTCP(t *testing.T, handshakeMode string) { + t.Parallel() + l, err := net.Listen("tcp", "127.0.0.1:0") + if !assert.NoError(t, err) { + return + } + port := l.Addr().(*net.TCPAddr).Port + l.Close() + + inboundOptions := inbound.MieruOption{ + BaseOption: inbound.BaseOption{ + NameStr: "mieru_inbound", + Listen: "127.0.0.1", + Port: strconv.Itoa(port), + }, + Transport: "TCP", + Users: map[string]string{"test": "password"}, + } + in, err := inbound.NewMieru(&inboundOptions) + if !assert.NoError(t, err) { + return + } + + tunnel := NewHttpTestTunnel() + defer tunnel.Close() + + err = in.Listen(tunnel) + if !assert.NoError(t, err) { + return + } + defer in.Close() + + addrPort, err := netip.ParseAddrPort(in.Address()) + if !assert.NoError(t, err) { + return + } + outboundOptions := outbound.MieruOption{ + Name: "mieru_outbound", + Server: addrPort.Addr().String(), + Port: int(addrPort.Port()), + Transport: "TCP", + UserName: "test", + Password: "password", + HandshakeMode: handshakeMode, + } + out, err := outbound.NewMieru(outboundOptions) + if !assert.NoError(t, err) { + return + } + defer out.Close() + + tunnel.DoTest(t, out) +} diff --git a/clash-meta/listener/mieru/server.go b/clash-meta/listener/mieru/server.go new file mode 100644 index 0000000000..3428c40a3c --- /dev/null +++ b/clash-meta/listener/mieru/server.go @@ -0,0 +1,117 @@ +package mieru + +import ( + "errors" + "io" + "net" + "net/netip" + + "github.com/metacubex/mihomo/adapter/inbound" + N "github.com/metacubex/mihomo/common/net" + C "github.com/metacubex/mihomo/constant" + "github.com/metacubex/mihomo/transport/socks5" + + mierucommon "github.com/enfein/mieru/v3/apis/common" + mieruconstant "github.com/enfein/mieru/v3/apis/constant" + mierumodel "github.com/enfein/mieru/v3/apis/model" +) + +func Handle(conn net.Conn, tunnel C.Tunnel, request *mierumodel.Request, additions ...inbound.Addition) { + // Return a fake response to the client. + resp := &mierumodel.Response{ + Reply: mieruconstant.Socks5ReplySuccess, + BindAddr: mierumodel.AddrSpec{ + IP: net.IPv4zero, + Port: 0, + }, + } + if err := resp.WriteToSocks5(conn); err != nil { + conn.Close() + return + } + + // Handle the connection with tunnel. + switch request.Command { + case mieruconstant.Socks5ConnectCmd: // TCP + metadata := &C.Metadata{ + NetWork: C.TCP, + Type: C.MIERU, + DstPort: uint16(request.DstAddr.Port), + } + if request.DstAddr.FQDN != "" { + metadata.Host = request.DstAddr.FQDN + } else if request.DstAddr.IP != nil { + metadata.DstIP, _ = netip.AddrFromSlice(request.DstAddr.IP) + metadata.DstIP = metadata.DstIP.Unmap() + } + inbound.ApplyAdditions(metadata, inbound.WithSrcAddr(conn.RemoteAddr()), inbound.WithInAddr(conn.LocalAddr())) + inbound.ApplyAdditions(metadata, additions...) + tunnel.HandleTCPConn(conn, metadata) + case mieruconstant.Socks5UDPAssociateCmd: // UDP + pc := mierucommon.NewPacketOverStreamTunnel(conn) + ep := N.NewEnhancePacketConn(pc) + for { + data, put, addr, err := ep.WaitReadFrom() + if err != nil { + if put != nil { + // Unresolved UDP packet, return buffer to the pool. + put() + } + // mieru returns EOF or ErrUnexpectedEOF when a session is closed. + if errors.Is(err, io.EOF) || errors.Is(err, io.ErrUnexpectedEOF) || errors.Is(err, io.ErrClosedPipe) { + break + } + continue + } + target, payload, err := socks5.DecodeUDPPacket(data) + if err != nil { + return + } + packet := &packet{ + pc: ep, + addr: addr, + payload: payload, + put: put, + } + tunnel.HandleUDPPacket(inbound.NewPacket(target, packet, C.MIERU, additions...)) + } + } +} + +type packet struct { + pc net.PacketConn + addr net.Addr // source (i.e. remote) IP & Port of the packet + payload []byte + put func() +} + +var _ C.UDPPacket = (*packet)(nil) +var _ C.UDPPacketInAddr = (*packet)(nil) + +func (c *packet) Data() []byte { + return c.payload +} + +func (c *packet) WriteBack(b []byte, addr net.Addr) (n int, err error) { + packet, err := socks5.EncodeUDPPacket(socks5.ParseAddrToSocksAddr(addr), b) + if err != nil { + return + } + return c.pc.WriteTo(packet, c.addr) +} + +func (c *packet) Drop() { + if c.put != nil { + c.put() + c.put = nil + } + c.payload = nil +} + +func (c *packet) LocalAddr() net.Addr { + return c.addr +} + +func (c *packet) InAddr() net.Addr { + return c.pc.LocalAddr() +} diff --git a/clash-meta/listener/parse.go b/clash-meta/listener/parse.go index 8aec050ece..4e893bf1d0 100644 --- a/clash-meta/listener/parse.go +++ b/clash-meta/listener/parse.go @@ -127,6 +127,13 @@ func ParseListener(mapping map[string]any) (C.InboundListener, error) { return nil, err } listener, err = IN.NewAnyTLS(anytlsOption) + case "mieru": + mieruOption := &IN.MieruOption{} + err = decoder.Decode(mapping, mieruOption) + if err != nil { + return nil, err + } + listener, err = IN.NewMieru(mieruOption) default: return nil, fmt.Errorf("unsupport proxy type: %s", proxyType) } diff --git a/lede/include/trusted-firmware-a.mk b/lede/include/trusted-firmware-a.mk index 15bbb1d690..d86fb1aa12 100644 --- a/lede/include/trusted-firmware-a.mk +++ b/lede/include/trusted-firmware-a.mk @@ -81,7 +81,6 @@ define Build/Compile/Trusted-Firmware-A $(if $(DTC),DTC="$(DTC)") \ PLAT=$(PLAT) \ BUILD_STRING="OpenWrt v$(PKG_VERSION)-$(PKG_RELEASE) ($(VARIANT))" \ - $(if $(CONFIG_BINUTILS_VERSION_2_37)$(CONFIG_BINUTILS_VERSION_2_38),,LDFLAGS="-no-warn-rwx-segments") \ $(TFA_MAKE_FLAGS) endef diff --git a/lede/package/boot/arm-trusted-firmware-mvebu/Makefile b/lede/package/boot/arm-trusted-firmware-mvebu/Makefile index e66b9d40b2..d8f0714f68 100644 --- a/lede/package/boot/arm-trusted-firmware-mvebu/Makefile +++ b/lede/package/boot/arm-trusted-firmware-mvebu/Makefile @@ -108,6 +108,7 @@ TFA_TARGETS:= \ udpu TFA_MAKE_FLAGS += \ + $(if $(CONFIG_BINUTILS_VERSION_2_37)$(CONFIG_BINUTILS_VERSION_2_38),,LDFLAGS="-no-warn-rwx-segments") \ CROSS_CM3=$(STAGING_DIR_IMAGE)/$(LINARO_NAME)-$(LINARO_RELEASE).$(LINARO_VERSION)/bin/arm-linux-gnueabi- \ BL33=$(STAGING_DIR_IMAGE)/$(UBOOT)-u-boot.bin \ MV_DDR_PATH=$(STAGING_DIR_IMAGE)/$(MV_DDR_NAME) \ diff --git a/lede/package/boot/arm-trusted-firmware-sunxi/Makefile b/lede/package/boot/arm-trusted-firmware-sunxi/Makefile index 4b007f8b03..4903c98cde 100644 --- a/lede/package/boot/arm-trusted-firmware-sunxi/Makefile +++ b/lede/package/boot/arm-trusted-firmware-sunxi/Makefile @@ -46,6 +46,9 @@ TFA_TARGETS:= \ sunxi-h6 \ sunxi-h616 +TFA_MAKE_FLAGS+= \ + $(if $(CONFIG_BINUTILS_VERSION_2_37)$(CONFIG_BINUTILS_VERSION_2_38),,LDFLAGS="-no-warn-rwx-segments") + define Package/trusted-firmware-a/install $(INSTALL_DIR) $(STAGING_DIR_IMAGE) $(INSTALL_DATA) $(PKG_BUILD_DIR)/build/$(PLAT)/release/bl31.bin $(STAGING_DIR_IMAGE)/bl31_$(BUILD_VARIANT).bin diff --git a/mieru/Makefile b/mieru/Makefile index 718163f80c..11b2ea2e75 100644 --- a/mieru/Makefile +++ b/mieru/Makefile @@ -32,7 +32,7 @@ PROJECT_NAME=$(shell basename "${ROOT}") # - pkg/version/current.go # # Use `tools/bump_version.sh` script to change all those files at one shot. -VERSION="3.22.0" +VERSION="3.22.1" # With .ONESHELL, each recipe is executed in a single shell instance. # This allows `cd` to affect subsequent commands in the same recipe. diff --git a/mieru/build/package/mieru/amd64/debian/DEBIAN/control b/mieru/build/package/mieru/amd64/debian/DEBIAN/control index fe1d0cef6b..102fc2a1c7 100755 --- a/mieru/build/package/mieru/amd64/debian/DEBIAN/control +++ b/mieru/build/package/mieru/amd64/debian/DEBIAN/control @@ -1,5 +1,5 @@ Package: mieru -Version: 3.22.0 +Version: 3.22.1 Section: net Priority: optional Architecture: amd64 diff --git a/mieru/build/package/mieru/amd64/rpm/mieru.spec b/mieru/build/package/mieru/amd64/rpm/mieru.spec index 07bd0fa408..24931a539a 100644 --- a/mieru/build/package/mieru/amd64/rpm/mieru.spec +++ b/mieru/build/package/mieru/amd64/rpm/mieru.spec @@ -1,5 +1,5 @@ Name: mieru -Version: 3.22.0 +Version: 3.22.1 Release: 1%{?dist} Summary: Mieru proxy client License: GPLv3+ diff --git a/mieru/build/package/mieru/arm64/debian/DEBIAN/control b/mieru/build/package/mieru/arm64/debian/DEBIAN/control index b5c1a100bc..d4429c384c 100755 --- a/mieru/build/package/mieru/arm64/debian/DEBIAN/control +++ b/mieru/build/package/mieru/arm64/debian/DEBIAN/control @@ -1,5 +1,5 @@ Package: mieru -Version: 3.22.0 +Version: 3.22.1 Section: net Priority: optional Architecture: arm64 diff --git a/mieru/build/package/mieru/arm64/rpm/mieru.spec b/mieru/build/package/mieru/arm64/rpm/mieru.spec index 07bd0fa408..24931a539a 100644 --- a/mieru/build/package/mieru/arm64/rpm/mieru.spec +++ b/mieru/build/package/mieru/arm64/rpm/mieru.spec @@ -1,5 +1,5 @@ Name: mieru -Version: 3.22.0 +Version: 3.22.1 Release: 1%{?dist} Summary: Mieru proxy client License: GPLv3+ diff --git a/mieru/build/package/mita/amd64/debian/DEBIAN/control b/mieru/build/package/mita/amd64/debian/DEBIAN/control index 1be4b58b36..13365f83d9 100755 --- a/mieru/build/package/mita/amd64/debian/DEBIAN/control +++ b/mieru/build/package/mita/amd64/debian/DEBIAN/control @@ -1,5 +1,5 @@ Package: mita -Version: 3.22.0 +Version: 3.22.1 Section: net Priority: optional Architecture: amd64 diff --git a/mieru/build/package/mita/amd64/rpm/mita.spec b/mieru/build/package/mita/amd64/rpm/mita.spec index 2c91fbd8c8..b392fbe939 100644 --- a/mieru/build/package/mita/amd64/rpm/mita.spec +++ b/mieru/build/package/mita/amd64/rpm/mita.spec @@ -1,5 +1,5 @@ Name: mita -Version: 3.22.0 +Version: 3.22.1 Release: 1%{?dist} Summary: Mieru proxy server License: GPLv3+ diff --git a/mieru/build/package/mita/arm64/debian/DEBIAN/control b/mieru/build/package/mita/arm64/debian/DEBIAN/control index 6fb906e9f1..47b639d69a 100755 --- a/mieru/build/package/mita/arm64/debian/DEBIAN/control +++ b/mieru/build/package/mita/arm64/debian/DEBIAN/control @@ -1,5 +1,5 @@ Package: mita -Version: 3.22.0 +Version: 3.22.1 Section: net Priority: optional Architecture: arm64 diff --git a/mieru/build/package/mita/arm64/rpm/mita.spec b/mieru/build/package/mita/arm64/rpm/mita.spec index 0b06087a12..319eb3e38e 100644 --- a/mieru/build/package/mita/arm64/rpm/mita.spec +++ b/mieru/build/package/mita/arm64/rpm/mita.spec @@ -1,5 +1,5 @@ Name: mita -Version: 3.22.0 +Version: 3.22.1 Release: 1%{?dist} Summary: Mieru proxy server License: GPLv3+ diff --git a/mieru/docs/server-install.md b/mieru/docs/server-install.md index 79504d4e69..86e69989e6 100644 --- a/mieru/docs/server-install.md +++ b/mieru/docs/server-install.md @@ -18,32 +18,32 @@ Or you can manually install and configure proxy server using the steps below. ```sh # Debian / Ubuntu - X86_64 -curl -LSO https://github.com/enfein/mieru/releases/download/v3.22.0/mita_3.22.0_amd64.deb +curl -LSO https://github.com/enfein/mieru/releases/download/v3.22.1/mita_3.22.1_amd64.deb # Debian / Ubuntu - ARM 64 -curl -LSO https://github.com/enfein/mieru/releases/download/v3.22.0/mita_3.22.0_arm64.deb +curl -LSO https://github.com/enfein/mieru/releases/download/v3.22.1/mita_3.22.1_arm64.deb # RedHat / CentOS / Rocky Linux - X86_64 -curl -LSO https://github.com/enfein/mieru/releases/download/v3.22.0/mita-3.22.0-1.x86_64.rpm +curl -LSO https://github.com/enfein/mieru/releases/download/v3.22.1/mita-3.22.1-1.x86_64.rpm # RedHat / CentOS / Rocky Linux - ARM 64 -curl -LSO https://github.com/enfein/mieru/releases/download/v3.22.0/mita-3.22.0-1.aarch64.rpm +curl -LSO https://github.com/enfein/mieru/releases/download/v3.22.1/mita-3.22.1-1.aarch64.rpm ``` ## Install mita package ```sh # Debian / Ubuntu - X86_64 -sudo dpkg -i mita_3.22.0_amd64.deb +sudo dpkg -i mita_3.22.1_amd64.deb # Debian / Ubuntu - ARM 64 -sudo dpkg -i mita_3.22.0_arm64.deb +sudo dpkg -i mita_3.22.1_arm64.deb # RedHat / CentOS / Rocky Linux - X86_64 -sudo rpm -Uvh --force mita-3.22.0-1.x86_64.rpm +sudo rpm -Uvh --force mita-3.22.1-1.x86_64.rpm # RedHat / CentOS / Rocky Linux - ARM 64 -sudo rpm -Uvh --force mita-3.22.0-1.aarch64.rpm +sudo rpm -Uvh --force mita-3.22.1-1.aarch64.rpm ``` Those instructions can also be used to upgrade the version of mita software package. diff --git a/mieru/docs/server-install.zh_CN.md b/mieru/docs/server-install.zh_CN.md index a541ee9600..aedaffc684 100644 --- a/mieru/docs/server-install.zh_CN.md +++ b/mieru/docs/server-install.zh_CN.md @@ -18,32 +18,32 @@ sudo python3 setup.py --lang=zh ```sh # Debian / Ubuntu - X86_64 -curl -LSO https://github.com/enfein/mieru/releases/download/v3.22.0/mita_3.22.0_amd64.deb +curl -LSO https://github.com/enfein/mieru/releases/download/v3.22.1/mita_3.22.1_amd64.deb # Debian / Ubuntu - ARM 64 -curl -LSO https://github.com/enfein/mieru/releases/download/v3.22.0/mita_3.22.0_arm64.deb +curl -LSO https://github.com/enfein/mieru/releases/download/v3.22.1/mita_3.22.1_arm64.deb # RedHat / CentOS / Rocky Linux - X86_64 -curl -LSO https://github.com/enfein/mieru/releases/download/v3.22.0/mita-3.22.0-1.x86_64.rpm +curl -LSO https://github.com/enfein/mieru/releases/download/v3.22.1/mita-3.22.1-1.x86_64.rpm # RedHat / CentOS / Rocky Linux - ARM 64 -curl -LSO https://github.com/enfein/mieru/releases/download/v3.22.0/mita-3.22.0-1.aarch64.rpm +curl -LSO https://github.com/enfein/mieru/releases/download/v3.22.1/mita-3.22.1-1.aarch64.rpm ``` ## 安装 mita 软件包 ```sh # Debian / Ubuntu - X86_64 -sudo dpkg -i mita_3.22.0_amd64.deb +sudo dpkg -i mita_3.22.1_amd64.deb # Debian / Ubuntu - ARM 64 -sudo dpkg -i mita_3.22.0_arm64.deb +sudo dpkg -i mita_3.22.1_arm64.deb # RedHat / CentOS / Rocky Linux - X86_64 -sudo rpm -Uvh --force mita-3.22.0-1.x86_64.rpm +sudo rpm -Uvh --force mita-3.22.1-1.x86_64.rpm # RedHat / CentOS / Rocky Linux - ARM 64 -sudo rpm -Uvh --force mita-3.22.0-1.aarch64.rpm +sudo rpm -Uvh --force mita-3.22.1-1.aarch64.rpm ``` 上述指令也可以用来升级 mita 软件包的版本。 diff --git a/mieru/pkg/protocol/mux.go b/mieru/pkg/protocol/mux.go index a0d7e876d6..e8934dc5f8 100644 --- a/mieru/pkg/protocol/mux.go +++ b/mieru/pkg/protocol/mux.go @@ -128,9 +128,12 @@ func (m *Mux) SetEndpoints(endpoints []UnderlayProperties) *Mux { case <-m.done: log.Infof("Unable to add new endpoint after multiplexer is closed") default: + var wg sync.WaitGroup for _, p := range new { - go m.acceptUnderlayLoop(m.ctx, p) + wg.Add(1) + go m.acceptUnderlayLoop(m.ctx, p, &wg) } + wg.Wait() m.endpoints = endpoints } } else { @@ -289,9 +292,12 @@ func (m *Mux) Start() error { m.mu.Lock() defer m.mu.Unlock() m.used = true + var wg sync.WaitGroup for _, p := range m.endpoints { - go m.acceptUnderlayLoop(m.ctx, p) + wg.Add(1) + go m.acceptUnderlayLoop(m.ctx, p, &wg) } + wg.Wait() return nil } @@ -379,13 +385,14 @@ func (m *Mux) newEndpoints(old, new []UnderlayProperties) []UnderlayProperties { return newEndpoints } -func (m *Mux) acceptUnderlayLoop(ctx context.Context, properties UnderlayProperties) { +func (m *Mux) acceptUnderlayLoop(ctx context.Context, properties UnderlayProperties, wg *sync.WaitGroup) { laddr := properties.LocalAddr().String() if laddr == "" { log.Errorf("Underlay local address is empty") if m.acceptHasErr.CompareAndSwap(false, true) { close(m.acceptErr) } + wg.Done() return } @@ -398,6 +405,7 @@ func (m *Mux) acceptUnderlayLoop(ctx context.Context, properties UnderlayPropert if m.acceptHasErr.CompareAndSwap(false, true) { close(m.acceptErr) } + wg.Done() return } rawListener, err := m.streamListenerFactory.Listen(ctx, tcpAddr.Network(), tcpAddr.String()) @@ -406,8 +414,10 @@ func (m *Mux) acceptUnderlayLoop(ctx context.Context, properties UnderlayPropert if m.acceptHasErr.CompareAndSwap(false, true) { close(m.acceptErr) } + wg.Done() return } + wg.Done() log.Infof("Mux is listening to endpoint %s %s", network, laddr) // Close the rawListener if the master context is canceled. @@ -471,6 +481,7 @@ func (m *Mux) acceptUnderlayLoop(ctx context.Context, properties UnderlayPropert if m.acceptHasErr.CompareAndSwap(false, true) { close(m.acceptErr) } + wg.Done() return } conn, err := m.packetListenerFactory.ListenPacket(ctx, udpAddr.Network(), udpAddr.String()) @@ -479,9 +490,12 @@ func (m *Mux) acceptUnderlayLoop(ctx context.Context, properties UnderlayPropert if m.acceptHasErr.CompareAndSwap(false, true) { close(m.acceptErr) } + wg.Done() return } + wg.Done() log.Infof("Mux is listening to endpoint %s %s", network, laddr) + underlay := &PacketUnderlay{ baseUnderlay: *newBaseUnderlay(false, properties.MTU()), conn: conn, @@ -531,6 +545,7 @@ func (m *Mux) acceptUnderlayLoop(ctx context.Context, properties UnderlayPropert if m.acceptHasErr.CompareAndSwap(false, true) { close(m.acceptErr) } + wg.Done() } } diff --git a/mieru/pkg/version/current.go b/mieru/pkg/version/current.go index bfb327e7f5..c159b4402a 100644 --- a/mieru/pkg/version/current.go +++ b/mieru/pkg/version/current.go @@ -16,5 +16,5 @@ package version const ( - AppVersion = "3.22.0" + AppVersion = "3.22.1" ) diff --git a/mieru/test/deploy/mihomo/test.sh b/mieru/test/deploy/mihomo/test.sh index bf6f1b959a..07a67865e2 100755 --- a/mieru/test/deploy/mihomo/test.sh +++ b/mieru/test/deploy/mihomo/test.sh @@ -36,9 +36,9 @@ sleep 1 sleep 1 # Run server test. -# echo "========== BEGIN OF SERVER TEST ==========" -# ./test_server.sh -# echo "========== END OF SERVER TEST ==========" +echo "========== BEGIN OF SERVER TEST ==========" +./test_server.sh +echo "========== END OF SERVER TEST ==========" # Run client TCP test. echo "========== BEGIN OF CLIENT TCP TEST ==========" diff --git a/mihomo/component/memory/memory_darwin.go b/mihomo/component/memory/memory_darwin.go index 1dd33af32a..63356fe539 100644 --- a/mihomo/component/memory/memory_darwin.go +++ b/mihomo/component/memory/memory_darwin.go @@ -1,9 +1,9 @@ package memory import ( + "syscall" "unsafe" - - "github.com/ebitengine/purego" + _ "unsafe" ) const PROC_PIDTASKINFO = 4 @@ -29,24 +29,12 @@ type ProcTaskInfo struct { Priority int32 } -const System = "/usr/lib/libSystem.B.dylib" - -type ProcPidInfoFunc func(pid, flavor int32, arg uint64, buffer uintptr, bufferSize int32) int32 - -const ProcPidInfoSym = "proc_pidinfo" - func GetMemoryInfo(pid int32) (*MemoryInfoStat, error) { - lib, err := purego.Dlopen(System, purego.RTLD_LAZY|purego.RTLD_GLOBAL) - if err != nil { - return nil, err - } - defer purego.Dlclose(lib) - - var procPidInfo ProcPidInfoFunc - purego.RegisterLibFunc(&procPidInfo, lib, ProcPidInfoSym) - var ti ProcTaskInfo - procPidInfo(pid, PROC_PIDTASKINFO, 0, uintptr(unsafe.Pointer(&ti)), int32(unsafe.Sizeof(ti))) + _, _, errno := syscall_syscall6(proc_pidinfo_trampoline_addr, uintptr(pid), PROC_PIDTASKINFO, 0, uintptr(unsafe.Pointer(&ti)), unsafe.Sizeof(ti), 0) + if errno != 0 { + return nil, errno + } ret := &MemoryInfoStat{ RSS: uint64(ti.Resident_size), @@ -54,3 +42,26 @@ func GetMemoryInfo(pid int32) (*MemoryInfoStat, error) { } return ret, nil } + +var proc_pidinfo_trampoline_addr uintptr + +//go:cgo_import_dynamic proc_pidinfo proc_pidinfo "/usr/lib/libSystem.B.dylib" + +// from golang.org/x/sys@v0.30.0/unix/syscall_darwin_libSystem.go + +// Implemented in the runtime package (runtime/sys_darwin.go) +func syscall_syscall(fn, a1, a2, a3 uintptr) (r1, r2 uintptr, err syscall.Errno) +func syscall_syscall6(fn, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err syscall.Errno) +func syscall_syscall6X(fn, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err syscall.Errno) +func syscall_syscall9(fn, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2 uintptr, err syscall.Errno) // 32-bit only +func syscall_rawSyscall(fn, a1, a2, a3 uintptr) (r1, r2 uintptr, err syscall.Errno) +func syscall_rawSyscall6(fn, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err syscall.Errno) +func syscall_syscallPtr(fn, a1, a2, a3 uintptr) (r1, r2 uintptr, err syscall.Errno) + +//go:linkname syscall_syscall syscall.syscall +//go:linkname syscall_syscall6 syscall.syscall6 +//go:linkname syscall_syscall6X syscall.syscall6X +//go:linkname syscall_syscall9 syscall.syscall9 +//go:linkname syscall_rawSyscall syscall.rawSyscall +//go:linkname syscall_rawSyscall6 syscall.rawSyscall6 +//go:linkname syscall_syscallPtr syscall.syscallPtr diff --git a/mihomo/component/memory/memory_darwin_amd64.s b/mihomo/component/memory/memory_darwin_amd64.s new file mode 100644 index 0000000000..4c17419a57 --- /dev/null +++ b/mihomo/component/memory/memory_darwin_amd64.s @@ -0,0 +1,9 @@ +// go run mkasm.go darwin amd64 +// Code generated by the command above; DO NOT EDIT. + +#include "textflag.h" + +TEXT proc_pidinfo_trampoline<>(SB),NOSPLIT,$0-0 + JMP proc_pidinfo(SB) +GLOBL ·proc_pidinfo_trampoline_addr(SB), RODATA, $8 +DATA ·proc_pidinfo_trampoline_addr(SB)/8, $proc_pidinfo_trampoline<>(SB) diff --git a/mihomo/component/memory/memory_darwin_arm64.s b/mihomo/component/memory/memory_darwin_arm64.s new file mode 100644 index 0000000000..645bc68042 --- /dev/null +++ b/mihomo/component/memory/memory_darwin_arm64.s @@ -0,0 +1,9 @@ +// go run mkasm.go darwin arm64 +// Code generated by the command above; DO NOT EDIT. + +#include "textflag.h" + +TEXT proc_pidinfo_trampoline<>(SB),NOSPLIT,$0-0 + JMP proc_pidinfo(SB) +GLOBL ·proc_pidinfo_trampoline_addr(SB), RODATA, $8 +DATA ·proc_pidinfo_trampoline_addr(SB)/8, $proc_pidinfo_trampoline<>(SB) diff --git a/mihomo/constant/metadata.go b/mihomo/constant/metadata.go index 72b9995b1b..23cdcd8616 100644 --- a/mihomo/constant/metadata.go +++ b/mihomo/constant/metadata.go @@ -38,6 +38,7 @@ const ( TUIC HYSTERIA2 ANYTLS + MIERU INNER ) @@ -109,6 +110,8 @@ func (t Type) String() string { return "Hysteria2" case ANYTLS: return "AnyTLS" + case MIERU: + return "Mieru" case INNER: return "Inner" default: @@ -149,6 +152,8 @@ func ParseType(t string) (*Type, error) { res = HYSTERIA2 case "ANYTLS": res = ANYTLS + case "MIERU": + res = MIERU case "INNER": res = INNER default: diff --git a/mihomo/dns/enhancer.go b/mihomo/dns/enhancer.go index c84f8c32fe..7e34977258 100644 --- a/mihomo/dns/enhancer.go +++ b/mihomo/dns/enhancer.go @@ -1,6 +1,7 @@ package dns import ( + "errors" "net/netip" "github.com/metacubex/mihomo/common/lru" @@ -31,11 +32,15 @@ func (h *ResolverEnhancer) IsExistFakeIP(ip netip.Addr) bool { } if pool := h.fakeIPPool; pool != nil { - return pool.Exist(ip) + if pool.Exist(ip) { + return true + } } if pool6 := h.fakeIPPool6; pool6 != nil { - return pool6.Exist(ip) + if pool6.Exist(ip) { + return true + } } return false @@ -47,11 +52,15 @@ func (h *ResolverEnhancer) IsFakeIP(ip netip.Addr) bool { } if pool := h.fakeIPPool; pool != nil { - return pool.IPNet().Contains(ip) && ip != pool.Gateway() && ip != pool.Broadcast() + if pool.IPNet().Contains(ip) && ip != pool.Gateway() && ip != pool.Broadcast() { + return true + } } if pool6 := h.fakeIPPool6; pool6 != nil { - return pool6.IPNet().Contains(ip) && ip != pool6.Gateway() && ip != pool6.Broadcast() + if pool6.IPNet().Contains(ip) && ip != pool6.Gateway() && ip != pool6.Broadcast() { + return true + } } return false @@ -63,11 +72,15 @@ func (h *ResolverEnhancer) IsFakeBroadcastIP(ip netip.Addr) bool { } if pool := h.fakeIPPool; pool != nil { - return pool.Broadcast() == ip + if pool.Broadcast() == ip { + return true + } } if pool6 := h.fakeIPPool6; pool6 != nil { - return pool6.Broadcast() == ip + if pool6.Broadcast() == ip { + return true + } } return false @@ -102,11 +115,19 @@ func (h *ResolverEnhancer) InsertHostByIP(ip netip.Addr, host string) { } func (h *ResolverEnhancer) FlushFakeIP() error { + var errs []error if pool := h.fakeIPPool; pool != nil { - return pool.FlushFakeIP() + if err := pool.FlushFakeIP(); err != nil { + errs = append(errs, err) + } } if pool6 := h.fakeIPPool6; pool6 != nil { - return pool6.FlushFakeIP() + if err := pool6.FlushFakeIP(); err != nil { + errs = append(errs, err) + } + } + if len(errs) > 0 { + return errors.Join(errs...) } return nil } diff --git a/mihomo/docs/config.yaml b/mihomo/docs/config.yaml index 57a1adcf91..e71b06f482 100644 --- a/mihomo/docs/config.yaml +++ b/mihomo/docs/config.yaml @@ -1556,6 +1556,15 @@ listeners: # -----END ECH KEYS----- # padding-scheme: "" # https://github.com/anytls/anytls-go/blob/main/docs/protocol.md#cmdupdatepaddingscheme + - name: mieru-in-1 + type: mieru + port: 10818 # 支持使用ports格式,例如200,302 or 200,204,401-429,501-503 + listen: 0.0.0.0 + transport: TCP # 支持 TCP 或者 UDP + users: + username1: password1 + username2: password2 + - name: trojan-in-1 type: trojan port: 10819 # 支持使用ports格式,例如200,302 or 200,204,401-429,501-503 diff --git a/mihomo/go.mod b/mihomo/go.mod index ea42bce7d6..d203eb6407 100644 --- a/mihomo/go.mod +++ b/mihomo/go.mod @@ -6,8 +6,7 @@ require ( github.com/bahlo/generic-list-go v0.2.0 github.com/coreos/go-iptables v0.8.0 github.com/dlclark/regexp2 v1.11.5 - github.com/ebitengine/purego v0.9.0 - github.com/enfein/mieru/v3 v3.20.0 + github.com/enfein/mieru/v3 v3.22.1 github.com/go-chi/chi/v5 v5.2.3 github.com/go-chi/render v1.0.3 github.com/gobwas/ws v1.4.0 @@ -33,7 +32,7 @@ require ( github.com/metacubex/sing-shadowsocks v0.2.12 github.com/metacubex/sing-shadowsocks2 v0.2.7 github.com/metacubex/sing-shadowtls v0.0.0-20250503063515-5d9f966d17a2 - github.com/metacubex/sing-tun v0.4.8 + github.com/metacubex/sing-tun v0.4.9 github.com/metacubex/sing-vmess v0.2.4 github.com/metacubex/sing-wireguard v0.0.0-20250503063753-2dc62acc626f github.com/metacubex/smux v0.0.0-20250922175018-15c9a6a78719 diff --git a/mihomo/go.sum b/mihomo/go.sum index bfc1a8f524..4670178e98 100644 --- a/mihomo/go.sum +++ b/mihomo/go.sum @@ -23,10 +23,8 @@ 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.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/enfein/mieru/v3 v3.22.1 h1:/XGYYXpEhEJlxosmtbpEJkhtRLHB8IToG7LB8kU2ZDY= +github.com/enfein/mieru/v3 v3.22.1/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= @@ -131,8 +129,8 @@ github.com/metacubex/sing-shadowsocks2 v0.2.7 h1:hSuuc0YpsfiqYqt1o+fP4m34BQz4e6w 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.8 h1:3PyiUKWXYi37yHptXskzL1723O3OUdyt0Aej4XHVikM= -github.com/metacubex/sing-tun v0.4.8/go.mod h1:L/TjQY5JEGy8nvsuYmy/XgMFMCPiF0+AWSFCYfS6r9w= +github.com/metacubex/sing-tun v0.4.9 h1:jY0Yyt8nnN3yQRN/jTxgqNCmGi1dsFdxdIi7pQUlVVU= +github.com/metacubex/sing-tun v0.4.9/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= diff --git a/mihomo/listener/inbound/mieru.go b/mihomo/listener/inbound/mieru.go new file mode 100644 index 0000000000..cf8cc403bc --- /dev/null +++ b/mihomo/listener/inbound/mieru.go @@ -0,0 +1,181 @@ +package inbound + +import ( + "context" + "fmt" + "net" + "sync" + + "github.com/metacubex/mihomo/adapter/inbound" + "github.com/metacubex/mihomo/common/utils" + C "github.com/metacubex/mihomo/constant" + "github.com/metacubex/mihomo/listener/mieru" + "github.com/metacubex/mihomo/log" + "google.golang.org/protobuf/proto" + + mieruserver "github.com/enfein/mieru/v3/apis/server" + mierupb "github.com/enfein/mieru/v3/pkg/appctl/appctlpb" +) + +type Mieru struct { + *Base + option *MieruOption + server mieruserver.Server + mu sync.Mutex +} + +type MieruOption struct { + BaseOption + Transport string `inbound:"transport"` + Users map[string]string `inbound:"users"` +} + +type mieruListenerFactory struct{} + +func (mieruListenerFactory) Listen(ctx context.Context, network, address string) (net.Listener, error) { + return inbound.ListenContext(ctx, network, address) +} + +func (mieruListenerFactory) ListenPacket(ctx context.Context, network, address string) (net.PacketConn, error) { + return inbound.ListenPacketContext(ctx, network, address) +} + +func NewMieru(option *MieruOption) (*Mieru, error) { + base, err := NewBase(&option.BaseOption) + if err != nil { + return nil, err + } + + config, err := buildMieruServerConfig(option, base.ports) + if err != nil { + return nil, fmt.Errorf("failed to build mieru server config: %w", err) + } + s := mieruserver.NewServer() + if err := s.Store(config); err != nil { + return nil, fmt.Errorf("failed to store mieru server config: %w", err) + } + // Server is started lazily when Listen() is called for the first time. + return &Mieru{ + Base: base, + option: option, + server: s, + }, nil +} + +func (m *Mieru) Config() C.InboundConfig { + return m.option +} + +func (m *Mieru) Listen(tunnel C.Tunnel) error { + m.mu.Lock() + defer m.mu.Unlock() + + if !m.server.IsRunning() { + if err := m.server.Start(); err != nil { + return fmt.Errorf("failed to start mieru server: %w", err) + } + } + + additions := m.config.Additions() + if len(additions) == 0 { + additions = []inbound.Addition{ + inbound.WithInName("DEFAULT-MIERU"), + inbound.WithSpecialRules(""), + } + } + + go func() { + for { + c, req, err := m.server.Accept() + if err != nil { + if !m.server.IsRunning() { + break + } + } + go mieru.Handle(c, tunnel, req, additions...) + } + }() + log.Infoln("Mieru[%s] proxy listening at: %s", m.Name(), m.Address()) + return nil +} + +func (m *Mieru) Close() error { + m.mu.Lock() + defer m.mu.Unlock() + + if m.server.IsRunning() { + return m.server.Stop() + } + + return nil +} + +var _ C.InboundListener = (*Mieru)(nil) + +func (o MieruOption) Equal(config C.InboundConfig) bool { + return optionToString(o) == optionToString(config) +} + +func buildMieruServerConfig(option *MieruOption, ports utils.IntRanges[uint16]) (*mieruserver.ServerConfig, error) { + if err := validateMieruOption(option); err != nil { + return nil, fmt.Errorf("failed to validate mieru option: %w", err) + } + if len(ports) == 0 { + return nil, fmt.Errorf("port is not set") + } + + var transportProtocol *mierupb.TransportProtocol + switch option.Transport { + case "TCP": + transportProtocol = mierupb.TransportProtocol_TCP.Enum() + case "UDP": + transportProtocol = mierupb.TransportProtocol_UDP.Enum() + } + var portBindings []*mierupb.PortBinding + for _, portRange := range ports { + if portRange.Start() == portRange.End() { + portBindings = append(portBindings, &mierupb.PortBinding{ + Port: proto.Int32(int32(portRange.Start())), + Protocol: transportProtocol, + }) + } else { + portBindings = append(portBindings, &mierupb.PortBinding{ + PortRange: proto.String(fmt.Sprintf("%d-%d", portRange.Start(), portRange.End())), + Protocol: transportProtocol, + }) + } + } + var users []*mierupb.User + for username, password := range option.Users { + users = append(users, &mierupb.User{ + Name: proto.String(username), + Password: proto.String(password), + }) + } + return &mieruserver.ServerConfig{ + Config: &mierupb.ServerConfig{ + PortBindings: portBindings, + Users: users, + }, + StreamListenerFactory: mieruListenerFactory{}, + PacketListenerFactory: mieruListenerFactory{}, + }, nil +} + +func validateMieruOption(option *MieruOption) error { + if option.Transport != "TCP" && option.Transport != "UDP" { + return fmt.Errorf("transport must be TCP or UDP") + } + if len(option.Users) == 0 { + return fmt.Errorf("users is empty") + } + for username, password := range option.Users { + if username == "" { + return fmt.Errorf("username is empty") + } + if password == "" { + return fmt.Errorf("password is empty") + } + } + return nil +} diff --git a/mihomo/listener/inbound/mieru_test.go b/mihomo/listener/inbound/mieru_test.go new file mode 100644 index 0000000000..d163b49dcc --- /dev/null +++ b/mihomo/listener/inbound/mieru_test.go @@ -0,0 +1,212 @@ +package inbound_test + +import ( + "net" + "net/netip" + "strconv" + "testing" + + "github.com/metacubex/mihomo/adapter/outbound" + "github.com/metacubex/mihomo/listener/inbound" + "github.com/stretchr/testify/assert" +) + +func TestNewMieru(t *testing.T) { + type args struct { + option *inbound.MieruOption + } + tests := []struct { + name string + args args + wantErr bool + }{ + { + name: "valid with port", + args: args{ + option: &inbound.MieruOption{ + BaseOption: inbound.BaseOption{ + Port: "8080", + }, + Transport: "TCP", + Users: map[string]string{"user": "pass"}, + }, + }, + wantErr: false, + }, + { + name: "valid with port range", + args: args{ + option: &inbound.MieruOption{ + BaseOption: inbound.BaseOption{ + Port: "8090-8099", + }, + Transport: "UDP", + Users: map[string]string{"user": "pass"}, + }, + }, + wantErr: false, + }, + { + name: "valid mix of port and port-range", + args: args{ + option: &inbound.MieruOption{ + BaseOption: inbound.BaseOption{ + Port: "8080,8090-8099", + }, + Transport: "TCP", + Users: map[string]string{"user": "pass"}, + }, + }, + wantErr: false, + }, + { + name: "invalid - no port", + args: args{ + option: &inbound.MieruOption{ + Transport: "TCP", + Users: map[string]string{"user": "pass"}, + }, + }, + wantErr: true, + }, + { + name: "invalid - transport", + args: args{ + option: &inbound.MieruOption{ + BaseOption: inbound.BaseOption{ + Port: "8080", + }, + Transport: "INVALID", + Users: map[string]string{"user": "pass"}, + }, + }, + wantErr: true, + }, + { + name: "invalid - no transport", + args: args{ + option: &inbound.MieruOption{ + BaseOption: inbound.BaseOption{ + Port: "8080", + }, + Users: map[string]string{"user": "pass"}, + }, + }, + wantErr: true, + }, + { + name: "invalid - no users", + args: args{ + option: &inbound.MieruOption{ + BaseOption: inbound.BaseOption{ + Port: "8080", + }, + Transport: "TCP", + Users: map[string]string{}, + }, + }, + wantErr: true, + }, + { + name: "invalid - empty username", + args: args{ + option: &inbound.MieruOption{ + BaseOption: inbound.BaseOption{ + Port: "8080", + }, + Transport: "TCP", + Users: map[string]string{"": "pass"}, + }, + }, + wantErr: true, + }, + { + name: "invalid - empty password", + args: args{ + option: &inbound.MieruOption{ + BaseOption: inbound.BaseOption{ + Port: "8080", + }, + Transport: "TCP", + Users: map[string]string{"user": ""}, + }, + }, + wantErr: true, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got, err := inbound.NewMieru(tt.args.option) + if (err != nil) != tt.wantErr { + t.Errorf("NewMieru() error = %v, wantErr %v", err, tt.wantErr) + return + } + if err == nil { + got.Close() + } + }) + } +} + +func TestInboundMieru(t *testing.T) { + t.Run("HANDSHAKE_STANDARD", func(t *testing.T) { + testInboundMieruTCP(t, "HANDSHAKE_STANDARD") + }) + t.Run("HANDSHAKE_NO_WAIT", func(t *testing.T) { + testInboundMieruTCP(t, "HANDSHAKE_NO_WAIT") + }) +} + +func testInboundMieruTCP(t *testing.T, handshakeMode string) { + t.Parallel() + l, err := net.Listen("tcp", "127.0.0.1:0") + if !assert.NoError(t, err) { + return + } + port := l.Addr().(*net.TCPAddr).Port + l.Close() + + inboundOptions := inbound.MieruOption{ + BaseOption: inbound.BaseOption{ + NameStr: "mieru_inbound", + Listen: "127.0.0.1", + Port: strconv.Itoa(port), + }, + Transport: "TCP", + Users: map[string]string{"test": "password"}, + } + in, err := inbound.NewMieru(&inboundOptions) + if !assert.NoError(t, err) { + return + } + + tunnel := NewHttpTestTunnel() + defer tunnel.Close() + + err = in.Listen(tunnel) + if !assert.NoError(t, err) { + return + } + defer in.Close() + + addrPort, err := netip.ParseAddrPort(in.Address()) + if !assert.NoError(t, err) { + return + } + outboundOptions := outbound.MieruOption{ + Name: "mieru_outbound", + Server: addrPort.Addr().String(), + Port: int(addrPort.Port()), + Transport: "TCP", + UserName: "test", + Password: "password", + HandshakeMode: handshakeMode, + } + out, err := outbound.NewMieru(outboundOptions) + if !assert.NoError(t, err) { + return + } + defer out.Close() + + tunnel.DoTest(t, out) +} diff --git a/mihomo/listener/mieru/server.go b/mihomo/listener/mieru/server.go new file mode 100644 index 0000000000..3428c40a3c --- /dev/null +++ b/mihomo/listener/mieru/server.go @@ -0,0 +1,117 @@ +package mieru + +import ( + "errors" + "io" + "net" + "net/netip" + + "github.com/metacubex/mihomo/adapter/inbound" + N "github.com/metacubex/mihomo/common/net" + C "github.com/metacubex/mihomo/constant" + "github.com/metacubex/mihomo/transport/socks5" + + mierucommon "github.com/enfein/mieru/v3/apis/common" + mieruconstant "github.com/enfein/mieru/v3/apis/constant" + mierumodel "github.com/enfein/mieru/v3/apis/model" +) + +func Handle(conn net.Conn, tunnel C.Tunnel, request *mierumodel.Request, additions ...inbound.Addition) { + // Return a fake response to the client. + resp := &mierumodel.Response{ + Reply: mieruconstant.Socks5ReplySuccess, + BindAddr: mierumodel.AddrSpec{ + IP: net.IPv4zero, + Port: 0, + }, + } + if err := resp.WriteToSocks5(conn); err != nil { + conn.Close() + return + } + + // Handle the connection with tunnel. + switch request.Command { + case mieruconstant.Socks5ConnectCmd: // TCP + metadata := &C.Metadata{ + NetWork: C.TCP, + Type: C.MIERU, + DstPort: uint16(request.DstAddr.Port), + } + if request.DstAddr.FQDN != "" { + metadata.Host = request.DstAddr.FQDN + } else if request.DstAddr.IP != nil { + metadata.DstIP, _ = netip.AddrFromSlice(request.DstAddr.IP) + metadata.DstIP = metadata.DstIP.Unmap() + } + inbound.ApplyAdditions(metadata, inbound.WithSrcAddr(conn.RemoteAddr()), inbound.WithInAddr(conn.LocalAddr())) + inbound.ApplyAdditions(metadata, additions...) + tunnel.HandleTCPConn(conn, metadata) + case mieruconstant.Socks5UDPAssociateCmd: // UDP + pc := mierucommon.NewPacketOverStreamTunnel(conn) + ep := N.NewEnhancePacketConn(pc) + for { + data, put, addr, err := ep.WaitReadFrom() + if err != nil { + if put != nil { + // Unresolved UDP packet, return buffer to the pool. + put() + } + // mieru returns EOF or ErrUnexpectedEOF when a session is closed. + if errors.Is(err, io.EOF) || errors.Is(err, io.ErrUnexpectedEOF) || errors.Is(err, io.ErrClosedPipe) { + break + } + continue + } + target, payload, err := socks5.DecodeUDPPacket(data) + if err != nil { + return + } + packet := &packet{ + pc: ep, + addr: addr, + payload: payload, + put: put, + } + tunnel.HandleUDPPacket(inbound.NewPacket(target, packet, C.MIERU, additions...)) + } + } +} + +type packet struct { + pc net.PacketConn + addr net.Addr // source (i.e. remote) IP & Port of the packet + payload []byte + put func() +} + +var _ C.UDPPacket = (*packet)(nil) +var _ C.UDPPacketInAddr = (*packet)(nil) + +func (c *packet) Data() []byte { + return c.payload +} + +func (c *packet) WriteBack(b []byte, addr net.Addr) (n int, err error) { + packet, err := socks5.EncodeUDPPacket(socks5.ParseAddrToSocksAddr(addr), b) + if err != nil { + return + } + return c.pc.WriteTo(packet, c.addr) +} + +func (c *packet) Drop() { + if c.put != nil { + c.put() + c.put = nil + } + c.payload = nil +} + +func (c *packet) LocalAddr() net.Addr { + return c.addr +} + +func (c *packet) InAddr() net.Addr { + return c.pc.LocalAddr() +} diff --git a/mihomo/listener/parse.go b/mihomo/listener/parse.go index 8aec050ece..4e893bf1d0 100644 --- a/mihomo/listener/parse.go +++ b/mihomo/listener/parse.go @@ -127,6 +127,13 @@ func ParseListener(mapping map[string]any) (C.InboundListener, error) { return nil, err } listener, err = IN.NewAnyTLS(anytlsOption) + case "mieru": + mieruOption := &IN.MieruOption{} + err = decoder.Decode(mapping, mieruOption) + if err != nil { + return nil, err + } + listener, err = IN.NewMieru(mieruOption) default: return nil, fmt.Errorf("unsupport proxy type: %s", proxyType) } diff --git a/openwrt-packages/smartdns/Makefile b/openwrt-packages/smartdns/Makefile index ad6a258e7f..649e500b71 100644 --- a/openwrt-packages/smartdns/Makefile +++ b/openwrt-packages/smartdns/Makefile @@ -5,12 +5,12 @@ include $(TOPDIR)/rules.mk PKG_NAME:=smartdns -PKG_VERSION:=47 -PKG_RELEASE:=3 +PKG_VERSION:=47.1 +PKG_RELEASE:=1 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz PKG_SOURCE_URL:=https://codeload.github.com/pymumu/smartdns/tar.gz/Release$(PKG_VERSION)? -PKG_HASH:=90414fc46de16bdec69a8511d78616287db17c5cc20034c210978896dfa7530a +PKG_HASH:=0a143ee81ccb7a31b7b7b0c29d6a6ee41a54331da75477719925592af124ec97 PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-Release$(PKG_VERSION) PKG_MAINTAINER:=Nick Peng diff --git a/openwrt-passwall/luci-app-passwall/luasrc/passwall/util_xray.lua b/openwrt-passwall/luci-app-passwall/luasrc/passwall/util_xray.lua index 7399c38ed2..22b18b1d74 100644 --- a/openwrt-passwall/luci-app-passwall/luasrc/passwall/util_xray.lua +++ b/openwrt-passwall/luci-app-passwall/luasrc/passwall/util_xray.lua @@ -1301,6 +1301,7 @@ function gen_config(var) end end + local dns_rule_position = 1 if dns_listen_port then table.insert(inbounds, { listen = "127.0.0.1", @@ -1334,16 +1335,18 @@ function gen_config(var) }, outboundTag = "dns-out" }) + dns_rule_position = dns_rule_position + 1 end if COMMON.default_outbound_tag == "direct" then if direct_dns_udp_server or direct_dns_tcp_server then - table.insert(routing.rules, { + table.insert(routing.rules, dns_rule_position, { inboundTag = { "dns-global-direct" }, outboundTag = "direct" }) + dns_rule_position = dns_rule_position + 1 end end @@ -1376,11 +1379,12 @@ function gen_config(var) balancerTag = nil end table.insert(dns.servers, dns_server) - table.insert(routing.rules, { + table.insert(routing.rules, dns_rule_position, { inboundTag = { dns_server.tag }, outboundTag = outboundTag, balancerTag = balancerTag }) + dns_rule_position = dns_rule_position + 1 end end end @@ -1394,11 +1398,12 @@ function gen_config(var) _outboundTag = "direct" _balancerTag = nil end - table.insert(routing.rules, { + table.insert(routing.rules, dns_rule_position, { inboundTag = { "dns-global" }, balancerTag = _balancerTag, outboundTag = _outboundTag }) + dns_rule_position = dns_rule_position + 1 local default_rule_index = nil for index, value in ipairs(routing.rules) do diff --git a/openwrt-passwall/luci-app-passwall/root/usr/share/passwall/iptables.sh b/openwrt-passwall/luci-app-passwall/root/usr/share/passwall/iptables.sh index 526ddafd94..d1f4fbc8fd 100755 --- a/openwrt-passwall/luci-app-passwall/root/usr/share/passwall/iptables.sh +++ b/openwrt-passwall/luci-app-passwall/root/usr/share/passwall/iptables.sh @@ -980,17 +980,20 @@ add_firewall_rule() { $ipt_n -I PREROUTING 1 -j PSW_DNS fi + $ipt_m -N PSW_DIVERT + $ipt_m -A PSW_DIVERT -j MARK --set-mark 1 + $ipt_m -A PSW_DIVERT -j ACCEPT + $ipt_m -N PSW_RULE $ipt_m -A PSW_RULE -j CONNMARK --restore-mark $ipt_m -A PSW_RULE -m mark --mark 1 -j RETURN - $ipt_m -A PSW_RULE -p tcp -m tcp --syn -j MARK --set-xmark 1 - $ipt_m -A PSW_RULE -p udp -m conntrack --ctstate NEW,RELATED -j MARK --set-xmark 1 + $ipt_m -A PSW_RULE -p tcp -m tcp --tcp-flags FIN,SYN,RST,ACK SYN -j MARK --set-xmark 1 + $ipt_m -A PSW_RULE -p udp -m conntrack --ctstate NEW -j MARK --set-xmark 1 $ipt_m -A PSW_RULE -j CONNMARK --save-mark $ipt_m -N PSW $ipt_m -A PSW $(dst $IPSET_LAN) -j RETURN $ipt_m -A PSW $(dst $IPSET_VPS) -j RETURN - $ipt_m -A PSW -m conntrack --ctdir REPLY -j RETURN [ ! -z "${WAN_IP}" ] && { $ipt_m -A PSW $(comment "WAN_IP_RETURN") -d "${WAN_IP}" -j RETURN @@ -999,11 +1002,11 @@ add_firewall_rule() { unset WAN_IP insert_rule_before "$ipt_m" "PREROUTING" "mwan3" "-j PSW" + insert_rule_before "$ipt_m" "PREROUTING" "PSW" "-p tcp -m socket -j PSW_DIVERT" $ipt_m -N PSW_OUTPUT $ipt_m -A PSW_OUTPUT $(dst $IPSET_LAN) -j RETURN $ipt_m -A PSW_OUTPUT $(dst $IPSET_VPS) -j RETURN - $ipt_m -A PSW_OUTPUT -m conntrack --ctdir REPLY -j RETURN [ -n "$IPT_APPEND_DNS" ] && { local local_dns dns_address dns_port @@ -1050,29 +1053,32 @@ add_firewall_rule() { $ip6t_n -I PREROUTING 1 -j PSW_DNS fi + $ip6t_m -N PSW_DIVERT + $ip6t_m -A PSW_DIVERT -j MARK --set-mark 1 + $ip6t_m -A PSW_DIVERT -j ACCEPT + $ip6t_m -N PSW_RULE $ip6t_m -A PSW_RULE -j CONNMARK --restore-mark $ip6t_m -A PSW_RULE -m mark --mark 1 -j RETURN - $ip6t_m -A PSW_RULE -p tcp -m tcp --syn -j MARK --set-xmark 1 - $ip6t_m -A PSW_RULE -p udp -m conntrack --ctstate NEW,RELATED -j MARK --set-xmark 1 + $ip6t_m -A PSW_RULE -p tcp -m tcp --tcp-flags FIN,SYN,RST,ACK SYN -j MARK --set-xmark 1 + $ip6t_m -A PSW_RULE -p udp -m conntrack --ctstate NEW -j MARK --set-xmark 1 $ip6t_m -A PSW_RULE -j CONNMARK --save-mark $ip6t_m -N PSW $ip6t_m -A PSW $(dst $IPSET_LAN6) -j RETURN $ip6t_m -A PSW $(dst $IPSET_VPS6) -j RETURN - $ip6t_m -A PSW -m conntrack --ctdir REPLY -j RETURN WAN6_IP=$(get_wan6_ip) [ ! -z "${WAN6_IP}" ] && $ip6t_m -A PSW $(comment "WAN6_IP_RETURN") -d ${WAN6_IP} -j RETURN unset WAN6_IP insert_rule_before "$ip6t_m" "PREROUTING" "mwan3" "-j PSW" + insert_rule_before "$ip6t_m" "PREROUTING" "PSW" "-p tcp -m socket -j PSW_DIVERT" $ip6t_m -N PSW_OUTPUT $ip6t_m -A PSW_OUTPUT -m mark --mark 0xff -j RETURN $ip6t_m -A PSW_OUTPUT $(dst $IPSET_LAN6) -j RETURN $ip6t_m -A PSW_OUTPUT $(dst $IPSET_VPS6) -j RETURN - $ip6t_m -A PSW_OUTPUT -m conntrack --ctdir REPLY -j RETURN [ "${USE_BLOCK_LIST}" = "1" ] && $ip6t_m -A PSW_OUTPUT $(dst $IPSET_BLOCK6) -j DROP [ "${USE_DIRECT_LIST}" = "1" ] && $ip6t_m -A PSW_OUTPUT $(dst $IPSET_WHITE6) -j RETURN @@ -1309,7 +1315,7 @@ del_firewall_rule() { $ipt -D $chain $index 2>/dev/null done done - for chain in "PSW" "PSW_OUTPUT" "PSW_DNS" "PSW_RULE"; do + for chain in "PSW" "PSW_OUTPUT" "PSW_DIVERT" "PSW_DNS" "PSW_RULE"; do $ipt -F $chain 2>/dev/null $ipt -X $chain 2>/dev/null done @@ -1363,7 +1369,7 @@ gen_include() { [ -z "${_ipt}" ] && return echo "*$2" - ${_ipt}-save -t $2 | grep "PSW" | grep -v "\-j PSW$" | sed -e "s/^-A \(OUTPUT\|PREROUTING\)/-I \1 1/" + ${_ipt}-save -t $2 | grep "PSW" | grep -v "\-j PSW$" | grep -v "mangle\-OUTPUT\-PSW" | grep -v "socket \-j PSW_DIVERT$" | sed -e "s/^-A \(OUTPUT\|PREROUTING\)/-I \1 1/" echo 'COMMIT' } local __ipt="" @@ -1384,6 +1390,7 @@ gen_include() { [ -z "${is_tproxy}" ] && \$(${MY_PATH} insert_rule_after "$ipt_n" "PREROUTING" "prerouting_rule" "-p tcp -j PSW") \$(${MY_PATH} insert_rule_before "$ipt_m" "PREROUTING" "mwan3" "-j PSW") + \$(${MY_PATH} insert_rule_before "$ipt_m" "PREROUTING" "PSW" "-p tcp -m socket -j PSW_DIVERT") WAN_IP=\$(${MY_PATH} get_wan_ip) @@ -1416,6 +1423,7 @@ gen_include() { [ "$accept_icmpv6" = "1" ] && $ip6t_n -A PREROUTING -p ipv6-icmp -j PSW \$(${MY_PATH} insert_rule_before "$ip6t_m" "PREROUTING" "mwan3" "-j PSW") + \$(${MY_PATH} insert_rule_before "$ip6t_m" "PREROUTING" "PSW" "-p tcp -m socket -j PSW_DIVERT") PR_INDEX=\$(${MY_PATH} RULE_LAST_INDEX "$ip6t_m" PSW WAN6_IP_RETURN -1) if [ \$PR_INDEX -ge 0 ]; then diff --git a/openwrt-passwall/luci-app-passwall/root/usr/share/passwall/nftables.sh b/openwrt-passwall/luci-app-passwall/root/usr/share/passwall/nftables.sh index e2db320719..e2934432af 100755 --- a/openwrt-passwall/luci-app-passwall/root/usr/share/passwall/nftables.sh +++ b/openwrt-passwall/luci-app-passwall/root/usr/share/passwall/nftables.sh @@ -986,6 +986,10 @@ add_firewall_rule() { nft_output_chain="PSW_OUTPUT_MANGLE" fi + nft "add chain $NFTABLE_NAME PSW_DIVERT" + nft "flush chain $NFTABLE_NAME PSW_DIVERT" + nft "add rule $NFTABLE_NAME PSW_DIVERT meta l4proto tcp socket transparent 1 mark set 1 counter accept" + nft "add chain $NFTABLE_NAME PSW_DNS" nft "flush chain $NFTABLE_NAME PSW_DNS" if [ $(config_t_get global dns_redirect "1") = "0" ]; then @@ -1001,8 +1005,8 @@ add_firewall_rule() { nft "flush chain $NFTABLE_NAME PSW_RULE" nft "add rule $NFTABLE_NAME PSW_RULE meta mark set ct mark counter" nft "add rule $NFTABLE_NAME PSW_RULE meta mark 1 counter return" - nft "add rule $NFTABLE_NAME PSW_RULE tcp flags syn meta mark set mark and 0x0 xor 0x1 counter" - nft "add rule $NFTABLE_NAME PSW_RULE meta l4proto udp ct state new,related meta mark set mark and 0x0 xor 0x1 counter" + nft "add rule $NFTABLE_NAME PSW_RULE tcp flags &(fin|syn|rst|ack) == syn meta mark set mark and 0x0 xor 0x1 counter" + nft "add rule $NFTABLE_NAME PSW_RULE meta l4proto udp ct state new meta mark set mark and 0x0 xor 0x1 counter" nft "add rule $NFTABLE_NAME PSW_RULE ct mark set mark counter" #ipv4 tproxy mode and udp @@ -1010,13 +1014,11 @@ add_firewall_rule() { nft "flush chain $NFTABLE_NAME PSW_MANGLE" nft "add rule $NFTABLE_NAME PSW_MANGLE ip daddr @$NFTSET_LAN counter return" nft "add rule $NFTABLE_NAME PSW_MANGLE ip daddr @$NFTSET_VPS counter return" - nft "add rule $NFTABLE_NAME PSW_MANGLE ct direction reply counter return" nft "add chain $NFTABLE_NAME PSW_OUTPUT_MANGLE" nft "flush chain $NFTABLE_NAME PSW_OUTPUT_MANGLE" nft "add rule $NFTABLE_NAME PSW_OUTPUT_MANGLE ip daddr @$NFTSET_LAN counter return" nft "add rule $NFTABLE_NAME PSW_OUTPUT_MANGLE ip daddr @$NFTSET_VPS counter return" - nft "add rule $NFTABLE_NAME PSW_OUTPUT_MANGLE ct direction reply counter return" [ "${USE_BLOCK_LIST}" = "1" ] && nft "add rule $NFTABLE_NAME PSW_OUTPUT_MANGLE ip daddr @$NFTSET_BLOCK counter drop" [ "${USE_DIRECT_LIST}" = "1" ] && nft "add rule $NFTABLE_NAME PSW_OUTPUT_MANGLE ip daddr @$NFTSET_WHITE counter return" @@ -1025,6 +1027,7 @@ add_firewall_rule() { # jump chains nft "add rule $NFTABLE_NAME mangle_prerouting ip protocol udp counter jump PSW_MANGLE" [ -n "${is_tproxy}" ] && nft "add rule $NFTABLE_NAME mangle_prerouting ip protocol tcp counter jump PSW_MANGLE" + insert_rule_before "$NFTABLE_NAME" "mangle_prerouting" "PSW_MANGLE" "counter jump PSW_DIVERT" #ipv4 tcp redirect mode [ -z "${is_tproxy}" ] && { @@ -1075,13 +1078,11 @@ add_firewall_rule() { nft "flush chain $NFTABLE_NAME PSW_MANGLE_V6" nft "add rule $NFTABLE_NAME PSW_MANGLE_V6 ip6 daddr @$NFTSET_LAN6 counter return" nft "add rule $NFTABLE_NAME PSW_MANGLE_V6 ip6 daddr @$NFTSET_VPS6 counter return" - nft "add rule $NFTABLE_NAME PSW_MANGLE_V6 ct direction reply counter return" nft "add chain $NFTABLE_NAME PSW_OUTPUT_MANGLE_V6" nft "flush chain $NFTABLE_NAME PSW_OUTPUT_MANGLE_V6" nft "add rule $NFTABLE_NAME PSW_OUTPUT_MANGLE_V6 ip6 daddr @$NFTSET_LAN6 counter return" nft "add rule $NFTABLE_NAME PSW_OUTPUT_MANGLE_V6 ip6 daddr @$NFTSET_VPS6 counter return" - nft "add rule $NFTABLE_NAME PSW_OUTPUT_MANGLE_V6 ct direction reply counter return" [ "${USE_BLOCK_LIST}" = "1" ] && nft "add rule $NFTABLE_NAME PSW_OUTPUT_MANGLE_V6 ip6 daddr @$NFTSET_BLOCK6 counter drop" [ "${USE_DIRECT_LIST}" = "1" ] && nft "add rule $NFTABLE_NAME PSW_OUTPUT_MANGLE_V6 ip6 daddr @$NFTSET_WHITE6 counter return" nft "add rule $NFTABLE_NAME PSW_OUTPUT_MANGLE_V6 meta mark 0xff counter return" @@ -1397,7 +1398,7 @@ gen_include() { local __nft=" " __nft=$(cat <<- EOF - [ -z "\$(nft list chain $NFTABLE_NAME mangle_prerouting | grep PSW)" ] && nft -f ${nft_chain_file} + [ -z "\$(nft list chain $NFTABLE_NAME mangle_prerouting | grep PSW_DIVERT)" ] && nft -f ${nft_chain_file} [ -z "${is_tproxy}" ] && { PR_INDEX=\$(sh ${MY_PATH} RULE_LAST_INDEX "$NFTABLE_NAME" PSW_NAT WAN_IP_RETURN -1) if [ \$PR_INDEX -ge 0 ]; then diff --git a/small/gn/Makefile b/small/gn/Makefile index aabc09600a..d908747c00 100644 --- a/small/gn/Makefile +++ b/small/gn/Makefile @@ -9,9 +9,9 @@ PKG_RELEASE:=1 PKG_SOURCE_PROTO:=git PKG_SOURCE_URL:=https://gn.googlesource.com/gn.git -PKG_SOURCE_DATE:=2025-10-26 -PKG_SOURCE_VERSION:=092f4f0d612e5982728c8b872c2e69cf3d04b21f -PKG_MIRROR_HASH:=e7d1de40a1e729645686c5a1fc74d7e457b2016b82b68633d3e01194b3b61786 +PKG_SOURCE_DATE:=2025-11-09 +PKG_SOURCE_VERSION:=e7f3202128bdb2429872fdb138626a010b2bff7f +PKG_MIRROR_HASH:=841a6ec3b1a5a500319914e1a1e05f2163a4efcbe4a7f281e778a51918bf52b4 PKG_LICENSE:=BSD 3-Clause PKG_LICENSE_FILES:=LICENSE diff --git a/small/gn/src/out/last_commit_position.h b/small/gn/src/out/last_commit_position.h index 8d87e733ac..92713e0f05 100644 --- a/small/gn/src/out/last_commit_position.h +++ b/small/gn/src/out/last_commit_position.h @@ -3,7 +3,7 @@ #ifndef OUT_LAST_COMMIT_POSITION_H_ #define OUT_LAST_COMMIT_POSITION_H_ -#define LAST_COMMIT_POSITION_NUM 2289 -#define LAST_COMMIT_POSITION "2289 (092f4f0d612e)" +#define LAST_COMMIT_POSITION_NUM 2292 +#define LAST_COMMIT_POSITION "2292 (e7f3202128bd)" #endif // OUT_LAST_COMMIT_POSITION_H_ diff --git a/small/luci-app-homeproxy/htdocs/luci-static/resources/view/homeproxy/client.js b/small/luci-app-homeproxy/htdocs/luci-static/resources/view/homeproxy/client.js index dcbb05c539..38ec4c74ac 100644 --- a/small/luci-app-homeproxy/htdocs/luci-static/resources/view/homeproxy/client.js +++ b/small/luci-app-homeproxy/htdocs/luci-static/resources/view/homeproxy/client.js @@ -949,7 +949,7 @@ return view.extend({ so.value('tcp', _('TCP')); so.value('tls', _('TLS')); so.value('https', _('HTTPS')); - so.value('http3', _('HTTP3')); + so.value('h3', _('HTTP/3')); so.value('quic', _('QUIC')); so.default = 'udp'; so.rmempty = false; @@ -961,6 +961,7 @@ return view.extend({ so = ss.option(form.Value, 'server_port', _('Port'), _('The port of the DNS server.')); + so.placeholder = 'auto'; so.datatype = 'port'; so = ss.option(form.Value, 'path', _('Path'), diff --git a/small/luci-app-homeproxy/po/templates/homeproxy.pot b/small/luci-app-homeproxy/po/templates/homeproxy.pot index 3dc8846af6..0fa7165548 100644 --- a/small/luci-app-homeproxy/po/templates/homeproxy.pot +++ b/small/luci-app-homeproxy/po/templates/homeproxy.pot @@ -18,7 +18,7 @@ msgid "4 or 6. Not limited if empty." msgstr "" #: htdocs/luci-static/resources/view/homeproxy/client.js:775 -#: htdocs/luci-static/resources/view/homeproxy/client.js:1209 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1210 msgid "" "%s will be temporarily overwritten to %s after 50 " "triggers in 30s if not enabled." @@ -39,11 +39,11 @@ msgstr "" msgid "Accept any if empty." msgstr "" -#: htdocs/luci-static/resources/view/homeproxy/client.js:1137 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1138 msgid "Accept empty query response" msgstr "" -#: htdocs/luci-static/resources/view/homeproxy/client.js:1398 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1399 msgid "Access Control" msgstr "" @@ -56,11 +56,11 @@ msgid "Access key secret" msgstr "" #: htdocs/luci-static/resources/view/homeproxy/client.js:669 -#: htdocs/luci-static/resources/view/homeproxy/client.js:1145 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1146 msgid "Action" msgstr "" -#: htdocs/luci-static/resources/view/homeproxy/client.js:1055 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1056 msgid "Add a DNS rule" msgstr "" @@ -80,7 +80,7 @@ msgstr "" msgid "Add a routing rule" msgstr "" -#: htdocs/luci-static/resources/view/homeproxy/client.js:1319 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1320 msgid "Add a rule set" msgstr "" @@ -88,7 +88,7 @@ msgstr "" msgid "Add a server" msgstr "" -#: htdocs/luci-static/resources/view/homeproxy/client.js:974 +#: htdocs/luci-static/resources/view/homeproxy/client.js:975 msgid "Additional headers to be sent to the DNS server." msgstr "" @@ -97,11 +97,11 @@ msgstr "" msgid "Address" msgstr "" -#: htdocs/luci-static/resources/view/homeproxy/client.js:987 +#: htdocs/luci-static/resources/view/homeproxy/client.js:988 msgid "Address resolver" msgstr "" -#: htdocs/luci-static/resources/view/homeproxy/client.js:1019 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1020 msgid "Address strategy" msgstr "" @@ -165,7 +165,7 @@ msgstr "" msgid "An error occurred during updating subscriptions: %s" msgstr "" -#: htdocs/luci-static/resources/view/homeproxy/client.js:1226 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1227 msgid "Answer" msgstr "" @@ -180,7 +180,7 @@ msgstr "" #: htdocs/luci-static/resources/view/homeproxy/client.js:799 #: htdocs/luci-static/resources/view/homeproxy/client.js:909 -#: htdocs/luci-static/resources/view/homeproxy/client.js:1194 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1195 msgid "" "Append a edns0-subnet OPT extra record with the specified IP " "prefix to every query by default.
If value is an IP address instead of " @@ -247,23 +247,23 @@ msgstr "" msgid "Based on google/gvisor." msgstr "" -#: htdocs/luci-static/resources/view/homeproxy/client.js:1340 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1341 msgid "Binary file" msgstr "" #: htdocs/luci-static/resources/view/homeproxy/client.js:453 -#: htdocs/luci-static/resources/view/homeproxy/client.js:1411 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1412 #: htdocs/luci-static/resources/view/homeproxy/server.js:874 msgid "Bind interface" msgstr "" -#: htdocs/luci-static/resources/view/homeproxy/client.js:1412 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1413 msgid "" "Bind outbound traffic to specific interface. Leave empty to auto detect." msgstr "" #: htdocs/luci-static/resources/view/homeproxy/client.js:617 -#: htdocs/luci-static/resources/view/homeproxy/client.js:1105 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1106 msgid "BitTorrent" msgstr "" @@ -277,8 +277,8 @@ msgstr "" #: htdocs/luci-static/resources/view/homeproxy/client.js:612 #: htdocs/luci-static/resources/view/homeproxy/client.js:640 -#: htdocs/luci-static/resources/view/homeproxy/client.js:1091 -#: htdocs/luci-static/resources/view/homeproxy/client.js:1101 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1092 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1102 #: htdocs/luci-static/resources/view/homeproxy/server.js:869 msgid "Both" msgstr "" @@ -404,7 +404,7 @@ msgstr "" msgid "DNS" msgstr "" -#: htdocs/luci-static/resources/view/homeproxy/client.js:1046 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1047 msgid "DNS Rules" msgstr "" @@ -420,7 +420,7 @@ msgstr "" msgid "DNS provider" msgstr "" -#: htdocs/luci-static/resources/view/homeproxy/client.js:1055 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1056 msgid "DNS rule" msgstr "" @@ -435,7 +435,7 @@ msgid "DNS01 challenge" msgstr "" #: htdocs/luci-static/resources/view/homeproxy/client.js:619 -#: htdocs/luci-static/resources/view/homeproxy/client.js:1106 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1107 msgid "DTLS" msgstr "" @@ -447,8 +447,8 @@ msgstr "" #: htdocs/luci-static/resources/view/homeproxy/client.js:433 #: htdocs/luci-static/resources/view/homeproxy/client.js:603 #: htdocs/luci-static/resources/view/homeproxy/client.js:755 -#: htdocs/luci-static/resources/view/homeproxy/client.js:1082 -#: htdocs/luci-static/resources/view/homeproxy/client.js:1380 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1083 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1381 #: htdocs/luci-static/resources/view/homeproxy/node.js:710 msgid "Default" msgstr "" @@ -457,8 +457,8 @@ msgstr "" #: htdocs/luci-static/resources/view/homeproxy/client.js:434 #: htdocs/luci-static/resources/view/homeproxy/client.js:756 #: htdocs/luci-static/resources/view/homeproxy/client.js:887 -#: htdocs/luci-static/resources/view/homeproxy/client.js:994 -#: htdocs/luci-static/resources/view/homeproxy/client.js:1160 +#: htdocs/luci-static/resources/view/homeproxy/client.js:995 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1161 msgid "Default DNS (issued by WAN)" msgstr "" @@ -497,33 +497,33 @@ msgstr "" #: htdocs/luci-static/resources/view/homeproxy/client.js:364 #: htdocs/luci-static/resources/view/homeproxy/client.js:466 #: htdocs/luci-static/resources/view/homeproxy/client.js:684 -#: htdocs/luci-static/resources/view/homeproxy/client.js:1032 -#: htdocs/luci-static/resources/view/homeproxy/client.js:1381 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1033 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1382 #: htdocs/luci-static/resources/view/homeproxy/node.js:428 msgid "Direct" msgstr "" -#: htdocs/luci-static/resources/view/homeproxy/client.js:1513 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1514 msgid "Direct Domain List" msgstr "" -#: htdocs/luci-static/resources/view/homeproxy/client.js:1427 -#: htdocs/luci-static/resources/view/homeproxy/client.js:1472 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1428 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1473 msgid "Direct IPv4 IP-s" msgstr "" -#: htdocs/luci-static/resources/view/homeproxy/client.js:1430 -#: htdocs/luci-static/resources/view/homeproxy/client.js:1475 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1431 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1476 msgid "Direct IPv6 IP-s" msgstr "" -#: htdocs/luci-static/resources/view/homeproxy/client.js:1433 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1434 msgid "Direct MAC-s" msgstr "" #: htdocs/luci-static/resources/view/homeproxy/client.js:123 #: htdocs/luci-static/resources/view/homeproxy/client.js:151 -#: htdocs/luci-static/resources/view/homeproxy/client.js:1421 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1422 #: htdocs/luci-static/resources/view/homeproxy/node.js:499 #: htdocs/luci-static/resources/view/homeproxy/node.js:555 #: htdocs/luci-static/resources/view/homeproxy/node.js:568 @@ -564,7 +564,7 @@ msgstr "" msgid "Disable UDP domain unmapping" msgstr "" -#: htdocs/luci-static/resources/view/homeproxy/client.js:1181 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1182 msgid "Disable cache and save cache in this query." msgstr "" @@ -572,7 +572,7 @@ msgstr "" msgid "Disable cache expire" msgstr "" -#: htdocs/luci-static/resources/view/homeproxy/client.js:1180 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1181 msgid "Disable dns cache" msgstr "" @@ -584,17 +584,17 @@ msgid "" msgstr "" #: htdocs/luci-static/resources/view/homeproxy/client.js:814 -#: htdocs/luci-static/resources/view/homeproxy/client.js:1250 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1251 msgid "Domain keyword" msgstr "" #: htdocs/luci-static/resources/view/homeproxy/client.js:805 -#: htdocs/luci-static/resources/view/homeproxy/client.js:1241 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1242 msgid "Domain name" msgstr "" #: htdocs/luci-static/resources/view/homeproxy/client.js:818 -#: htdocs/luci-static/resources/view/homeproxy/client.js:1254 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1255 msgid "Domain regex" msgstr "" @@ -604,7 +604,7 @@ msgstr "" #: htdocs/luci-static/resources/view/homeproxy/client.js:347 #: htdocs/luci-static/resources/view/homeproxy/client.js:446 -#: htdocs/luci-static/resources/view/homeproxy/client.js:1173 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1174 msgid "Domain strategy" msgstr "" @@ -613,7 +613,7 @@ msgid "Domain strategy for resolving the domain names." msgstr "" #: htdocs/luci-static/resources/view/homeproxy/client.js:810 -#: htdocs/luci-static/resources/view/homeproxy/client.js:1246 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1247 msgid "Domain suffix" msgstr "" @@ -625,7 +625,7 @@ msgstr "" msgid "Don't drop packets" msgstr "" -#: htdocs/luci-static/resources/view/homeproxy/client.js:1208 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1209 msgid "Don't drop requests" msgstr "" @@ -644,8 +644,8 @@ msgstr "" msgid "Drop packets" msgstr "" -#: htdocs/luci-static/resources/view/homeproxy/client.js:1203 -#: htdocs/luci-static/resources/view/homeproxy/client.js:1210 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1204 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1211 msgid "Drop requests" msgstr "" @@ -689,7 +689,7 @@ msgstr "" #: htdocs/luci-static/resources/view/homeproxy/client.js:798 #: htdocs/luci-static/resources/view/homeproxy/client.js:908 -#: htdocs/luci-static/resources/view/homeproxy/client.js:1193 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1194 msgid "EDNS Client subnet" msgstr "" @@ -718,8 +718,8 @@ msgstr "" #: htdocs/luci-static/resources/view/homeproxy/client.js:414 #: htdocs/luci-static/resources/view/homeproxy/client.js:590 #: htdocs/luci-static/resources/view/homeproxy/client.js:942 -#: htdocs/luci-static/resources/view/homeproxy/client.js:1069 -#: htdocs/luci-static/resources/view/homeproxy/client.js:1328 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1070 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1329 #: htdocs/luci-static/resources/view/homeproxy/server.js:148 #: htdocs/luci-static/resources/view/homeproxy/server.js:166 msgid "Enable" @@ -807,11 +807,11 @@ msgstr "" #: htdocs/luci-static/resources/view/homeproxy/client.js:504 #: htdocs/luci-static/resources/view/homeproxy/client.js:518 #: htdocs/luci-static/resources/view/homeproxy/client.js:521 -#: htdocs/luci-static/resources/view/homeproxy/client.js:1356 -#: htdocs/luci-static/resources/view/homeproxy/client.js:1361 -#: htdocs/luci-static/resources/view/homeproxy/client.js:1364 -#: htdocs/luci-static/resources/view/homeproxy/client.js:1506 -#: htdocs/luci-static/resources/view/homeproxy/client.js:1538 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1357 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1362 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1365 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1507 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1539 #: htdocs/luci-static/resources/view/homeproxy/node.js:488 #: htdocs/luci-static/resources/view/homeproxy/node.js:1131 #: htdocs/luci-static/resources/view/homeproxy/node.js:1302 @@ -835,7 +835,7 @@ msgstr "" msgid "External account key ID" msgstr "" -#: htdocs/luci-static/resources/view/homeproxy/client.js:1236 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1237 msgid "Extra records" msgstr "" @@ -876,7 +876,7 @@ msgstr "" msgid "For resolving domain name in the server address." msgstr "" -#: htdocs/luci-static/resources/view/homeproxy/client.js:1339 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1340 msgid "Format" msgstr "" @@ -905,15 +905,15 @@ msgstr "" msgid "GFWList" msgstr "" -#: htdocs/luci-static/resources/view/homeproxy/client.js:1445 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1446 msgid "Gaming mode IPv4 IP-s" msgstr "" -#: htdocs/luci-static/resources/view/homeproxy/client.js:1447 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1448 msgid "Gaming mode IPv6 IP-s" msgstr "" -#: htdocs/luci-static/resources/view/homeproxy/client.js:1450 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1451 msgid "Gaming mode MAC-s" msgstr "" @@ -935,15 +935,15 @@ msgstr "" msgid "Global padding" msgstr "" -#: htdocs/luci-static/resources/view/homeproxy/client.js:1452 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1453 msgid "Global proxy IPv4 IP-s" msgstr "" -#: htdocs/luci-static/resources/view/homeproxy/client.js:1455 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1456 msgid "Global proxy IPv6 IP-s" msgstr "" -#: htdocs/luci-static/resources/view/homeproxy/client.js:1458 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1459 msgid "Global proxy MAC-s" msgstr "" @@ -964,7 +964,7 @@ msgid "Grant access to homeproxy configuration" msgstr "" #: htdocs/luci-static/resources/view/homeproxy/client.js:620 -#: htdocs/luci-static/resources/view/homeproxy/client.js:1107 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1108 #: htdocs/luci-static/resources/view/homeproxy/node.js:430 #: htdocs/luci-static/resources/view/homeproxy/node.js:777 #: htdocs/luci-static/resources/view/homeproxy/server.js:177 @@ -973,7 +973,7 @@ msgid "HTTP" msgstr "" #: htdocs/luci-static/resources/view/homeproxy/client.js:952 -msgid "HTTP3" +msgid "HTTP/3" msgstr "" #: htdocs/luci-static/resources/view/homeproxy/server.js:332 @@ -999,7 +999,7 @@ msgstr "" msgid "Handshake server port" msgstr "" -#: htdocs/luci-static/resources/view/homeproxy/client.js:973 +#: htdocs/luci-static/resources/view/homeproxy/client.js:974 msgid "Headers" msgstr "" @@ -1048,7 +1048,7 @@ msgid "Host key algorithms" msgstr "" #: htdocs/luci-static/resources/view/homeproxy/client.js:581 -#: htdocs/luci-static/resources/view/homeproxy/client.js:1060 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1061 msgid "Host/IP fields" msgstr "" @@ -1069,17 +1069,17 @@ msgid "Hysteria2" msgstr "" #: htdocs/luci-static/resources/view/homeproxy/client.js:830 -#: htdocs/luci-static/resources/view/homeproxy/client.js:1266 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1267 msgid "IP CIDR" msgstr "" #: htdocs/luci-static/resources/view/homeproxy/client.js:608 -#: htdocs/luci-static/resources/view/homeproxy/client.js:1088 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1089 msgid "IP version" msgstr "" #: htdocs/luci-static/resources/view/homeproxy/client.js:610 -#: htdocs/luci-static/resources/view/homeproxy/client.js:1089 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1090 msgid "IPv4" msgstr "" @@ -1088,7 +1088,7 @@ msgid "IPv4 only" msgstr "" #: htdocs/luci-static/resources/view/homeproxy/client.js:611 -#: htdocs/luci-static/resources/view/homeproxy/client.js:1090 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1091 msgid "IPv6" msgstr "" @@ -1192,7 +1192,7 @@ msgstr "" msgid "Info" msgstr "" -#: htdocs/luci-static/resources/view/homeproxy/client.js:1404 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1405 msgid "Interface Control" msgstr "" @@ -1216,12 +1216,12 @@ msgid "" msgstr "" #: htdocs/luci-static/resources/view/homeproxy/client.js:665 -#: htdocs/luci-static/resources/view/homeproxy/client.js:1141 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1142 msgid "Invert" msgstr "" #: htdocs/luci-static/resources/view/homeproxy/client.js:666 -#: htdocs/luci-static/resources/view/homeproxy/client.js:1142 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1143 msgid "Invert match result." msgstr "" @@ -1229,15 +1229,15 @@ msgstr "" msgid "Key path" msgstr "" -#: htdocs/luci-static/resources/view/homeproxy/client.js:1418 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1419 msgid "LAN IP Policy" msgstr "" #: htdocs/luci-static/resources/view/homeproxy/client.js:409 #: htdocs/luci-static/resources/view/homeproxy/client.js:585 #: htdocs/luci-static/resources/view/homeproxy/client.js:937 -#: htdocs/luci-static/resources/view/homeproxy/client.js:1064 -#: htdocs/luci-static/resources/view/homeproxy/client.js:1323 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1065 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1324 #: htdocs/luci-static/resources/view/homeproxy/node.js:422 #: htdocs/luci-static/resources/view/homeproxy/server.js:160 msgid "Label" @@ -1274,15 +1274,15 @@ msgstr "" msgid "List of supported application level protocols, in order of preference." msgstr "" -#: htdocs/luci-static/resources/view/homeproxy/client.js:1227 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1228 msgid "List of text DNS record to respond as answers." msgstr "" -#: htdocs/luci-static/resources/view/homeproxy/client.js:1237 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1238 msgid "List of text DNS record to respond as extra records." msgstr "" -#: htdocs/luci-static/resources/view/homeproxy/client.js:1232 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1233 msgid "List of text DNS record to respond as name servers." msgstr "" @@ -1290,7 +1290,7 @@ msgstr "" msgid "Listen address" msgstr "" -#: htdocs/luci-static/resources/view/homeproxy/client.js:1406 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1407 msgid "Listen interfaces" msgstr "" @@ -1302,7 +1302,7 @@ msgstr "" msgid "Loading" msgstr "" -#: htdocs/luci-static/resources/view/homeproxy/client.js:1334 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1335 msgid "Local" msgstr "" @@ -1334,11 +1334,11 @@ msgstr "" msgid "Make IP CIDR in rule set used to match the source IP." msgstr "" -#: htdocs/luci-static/resources/view/homeproxy/client.js:1134 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1135 msgid "Make IP CIDR in rule sets match the source IP." msgstr "" -#: htdocs/luci-static/resources/view/homeproxy/client.js:1138 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1139 msgid "Make IP CIDR in rule-sets accept empty query response." msgstr "" @@ -1352,7 +1352,7 @@ msgstr "" msgid "Masquerade" msgstr "" -#: htdocs/luci-static/resources/view/homeproxy/client.js:1267 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1268 msgid "" "Match IP CIDR with query response. Current rule will be skipped if not match." msgstr "" @@ -1362,90 +1362,90 @@ msgid "Match IP CIDR." msgstr "" #: htdocs/luci-static/resources/view/homeproxy/client.js:811 -#: htdocs/luci-static/resources/view/homeproxy/client.js:1247 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1248 msgid "Match domain suffix." msgstr "" #: htdocs/luci-static/resources/view/homeproxy/client.js:815 -#: htdocs/luci-static/resources/view/homeproxy/client.js:1251 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1252 msgid "Match domain using keyword." msgstr "" #: htdocs/luci-static/resources/view/homeproxy/client.js:819 -#: htdocs/luci-static/resources/view/homeproxy/client.js:1255 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1256 msgid "Match domain using regular expression." msgstr "" #: htdocs/luci-static/resources/view/homeproxy/client.js:806 -#: htdocs/luci-static/resources/view/homeproxy/client.js:1242 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1243 msgid "Match full domain." msgstr "" #: htdocs/luci-static/resources/view/homeproxy/client.js:854 -#: htdocs/luci-static/resources/view/homeproxy/client.js:1291 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1292 msgid "Match port range. Format as START:/:END/START:END." msgstr "" #: htdocs/luci-static/resources/view/homeproxy/client.js:849 -#: htdocs/luci-static/resources/view/homeproxy/client.js:1286 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1287 msgid "Match port." msgstr "" #: htdocs/luci-static/resources/view/homeproxy/client.js:835 -#: htdocs/luci-static/resources/view/homeproxy/client.js:1271 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1272 msgid "Match private IP" msgstr "" -#: htdocs/luci-static/resources/view/homeproxy/client.js:1272 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1273 msgid "Match private IP with query response." msgstr "" #: htdocs/luci-static/resources/view/homeproxy/client.js:827 -#: htdocs/luci-static/resources/view/homeproxy/client.js:1263 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1264 msgid "Match private source IP" msgstr "" #: htdocs/luci-static/resources/view/homeproxy/client.js:859 -#: htdocs/luci-static/resources/view/homeproxy/client.js:1296 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1297 msgid "Match process name." msgstr "" #: htdocs/luci-static/resources/view/homeproxy/client.js:867 -#: htdocs/luci-static/resources/view/homeproxy/client.js:1304 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1305 msgid "Match process path using regular expression." msgstr "" #: htdocs/luci-static/resources/view/homeproxy/client.js:863 -#: htdocs/luci-static/resources/view/homeproxy/client.js:1300 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1301 msgid "Match process path." msgstr "" -#: htdocs/luci-static/resources/view/homeproxy/client.js:1095 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1096 msgid "Match query type." msgstr "" #: htdocs/luci-static/resources/view/homeproxy/client.js:647 -#: htdocs/luci-static/resources/view/homeproxy/client.js:1119 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1120 msgid "Match rule set." msgstr "" #: htdocs/luci-static/resources/view/homeproxy/client.js:823 -#: htdocs/luci-static/resources/view/homeproxy/client.js:1259 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1260 msgid "Match source IP CIDR." msgstr "" #: htdocs/luci-static/resources/view/homeproxy/client.js:844 -#: htdocs/luci-static/resources/view/homeproxy/client.js:1281 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1282 msgid "Match source port range. Format as START:/:END/START:END." msgstr "" #: htdocs/luci-static/resources/view/homeproxy/client.js:839 -#: htdocs/luci-static/resources/view/homeproxy/client.js:1276 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1277 msgid "Match source port." msgstr "" #: htdocs/luci-static/resources/view/homeproxy/client.js:643 -#: htdocs/luci-static/resources/view/homeproxy/client.js:1115 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1116 msgid "Match user name." msgstr "" @@ -1495,8 +1495,8 @@ msgstr "" #: htdocs/luci-static/resources/view/homeproxy/client.js:768 #: htdocs/luci-static/resources/view/homeproxy/client.js:776 -#: htdocs/luci-static/resources/view/homeproxy/client.js:1201 -#: htdocs/luci-static/resources/view/homeproxy/client.js:1210 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1202 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1211 #: htdocs/luci-static/resources/view/homeproxy/node.js:841 #: htdocs/luci-static/resources/view/homeproxy/server.js:452 msgid "Method" @@ -1531,7 +1531,7 @@ msgid "Mixed system TCP stack and gVisor UDP stack." msgstr "" #: htdocs/luci-static/resources/view/homeproxy/client.js:595 -#: htdocs/luci-static/resources/view/homeproxy/client.js:1074 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1075 msgid "Mode" msgstr "" @@ -1558,7 +1558,7 @@ msgstr "" msgid "NOTE: Save current settings before updating subscriptions." msgstr "" -#: htdocs/luci-static/resources/view/homeproxy/client.js:1231 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1232 msgid "NS" msgstr "" @@ -1571,7 +1571,7 @@ msgid "NaïveProxy" msgstr "" #: htdocs/luci-static/resources/view/homeproxy/client.js:637 -#: htdocs/luci-static/resources/view/homeproxy/client.js:1098 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1099 #: htdocs/luci-static/resources/view/homeproxy/server.js:866 msgid "Network" msgstr "" @@ -1617,7 +1617,7 @@ msgstr "" msgid "Nodes" msgstr "" -#: htdocs/luci-static/resources/view/homeproxy/client.js:993 +#: htdocs/luci-static/resources/view/homeproxy/client.js:994 #: htdocs/luci-static/resources/view/homeproxy/node.js:737 #: htdocs/luci-static/resources/view/homeproxy/node.js:775 #: htdocs/luci-static/resources/view/homeproxy/server.js:386 @@ -1635,7 +1635,7 @@ msgstr "" msgid "Obfuscate type" msgstr "" -#: htdocs/luci-static/resources/view/homeproxy/client.js:1407 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1408 msgid "Only process traffic from specific interfaces. Leave empty for all." msgstr "" @@ -1644,14 +1644,14 @@ msgid "Only proxy mainland China" msgstr "" #: htdocs/luci-static/resources/view/homeproxy/client.js:580 -#: htdocs/luci-static/resources/view/homeproxy/client.js:1059 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1060 msgid "Other fields" msgstr "" #: htdocs/luci-static/resources/view/homeproxy/client.js:460 #: htdocs/luci-static/resources/view/homeproxy/client.js:678 -#: htdocs/luci-static/resources/view/homeproxy/client.js:1026 -#: htdocs/luci-static/resources/view/homeproxy/client.js:1374 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1027 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1375 msgid "Outbound" msgstr "" @@ -1704,8 +1704,8 @@ msgstr "" msgid "Password" msgstr "" -#: htdocs/luci-static/resources/view/homeproxy/client.js:966 -#: htdocs/luci-static/resources/view/homeproxy/client.js:1345 +#: htdocs/luci-static/resources/view/homeproxy/client.js:967 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1346 #: htdocs/luci-static/resources/view/homeproxy/node.js:836 #: htdocs/luci-static/resources/view/homeproxy/node.js:869 #: htdocs/luci-static/resources/view/homeproxy/server.js:447 @@ -1742,7 +1742,7 @@ msgstr "" #: htdocs/luci-static/resources/view/homeproxy/client.js:848 #: htdocs/luci-static/resources/view/homeproxy/client.js:962 -#: htdocs/luci-static/resources/view/homeproxy/client.js:1285 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1286 #: htdocs/luci-static/resources/view/homeproxy/node.js:453 msgid "Port" msgstr "" @@ -1752,7 +1752,7 @@ msgid "Port %s alrealy exists!" msgstr "" #: htdocs/luci-static/resources/view/homeproxy/client.js:582 -#: htdocs/luci-static/resources/view/homeproxy/client.js:1061 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1062 msgid "Port fields" msgstr "" @@ -1761,7 +1761,7 @@ msgid "Port hopping interval in seconds." msgstr "" #: htdocs/luci-static/resources/view/homeproxy/client.js:853 -#: htdocs/luci-static/resources/view/homeproxy/client.js:1290 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1291 msgid "Port range" msgstr "" @@ -1769,7 +1769,7 @@ msgstr "" msgid "Pre-shared key" msgstr "" -#: htdocs/luci-static/resources/view/homeproxy/client.js:1149 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1150 msgid "Predefined" msgstr "" @@ -1791,27 +1791,27 @@ msgid "Private key passphrase" msgstr "" #: htdocs/luci-static/resources/view/homeproxy/client.js:583 -#: htdocs/luci-static/resources/view/homeproxy/client.js:1062 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1063 msgid "Process fields" msgstr "" #: htdocs/luci-static/resources/view/homeproxy/client.js:858 -#: htdocs/luci-static/resources/view/homeproxy/client.js:1295 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1296 msgid "Process name" msgstr "" #: htdocs/luci-static/resources/view/homeproxy/client.js:862 -#: htdocs/luci-static/resources/view/homeproxy/client.js:1299 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1300 msgid "Process path" msgstr "" #: htdocs/luci-static/resources/view/homeproxy/client.js:866 -#: htdocs/luci-static/resources/view/homeproxy/client.js:1303 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1304 msgid "Process path (regex)" msgstr "" #: htdocs/luci-static/resources/view/homeproxy/client.js:615 -#: htdocs/luci-static/resources/view/homeproxy/client.js:1103 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1104 #: htdocs/luci-static/resources/view/homeproxy/node.js:543 #: htdocs/luci-static/resources/view/homeproxy/node.js:951 #: htdocs/luci-static/resources/view/homeproxy/server.js:250 @@ -1828,33 +1828,33 @@ msgid "" "default in v2ray and cannot be disabled)." msgstr "" -#: htdocs/luci-static/resources/view/homeproxy/client.js:1481 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1482 msgid "Proxy Domain List" msgstr "" -#: htdocs/luci-static/resources/view/homeproxy/client.js:1436 -#: htdocs/luci-static/resources/view/homeproxy/client.js:1465 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1437 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1466 msgid "Proxy IPv4 IP-s" msgstr "" -#: htdocs/luci-static/resources/view/homeproxy/client.js:1439 -#: htdocs/luci-static/resources/view/homeproxy/client.js:1468 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1440 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1469 msgid "Proxy IPv6 IP-s" msgstr "" -#: htdocs/luci-static/resources/view/homeproxy/client.js:1442 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1443 msgid "Proxy MAC-s" msgstr "" -#: htdocs/luci-static/resources/view/homeproxy/client.js:1423 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1424 msgid "Proxy all except listed" msgstr "" -#: htdocs/luci-static/resources/view/homeproxy/client.js:1420 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1421 msgid "Proxy filter mode" msgstr "" -#: htdocs/luci-static/resources/view/homeproxy/client.js:1422 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1423 msgid "Proxy listed only" msgstr "" @@ -1868,7 +1868,7 @@ msgstr "" #: htdocs/luci-static/resources/view/homeproxy/client.js:621 #: htdocs/luci-static/resources/view/homeproxy/client.js:953 -#: htdocs/luci-static/resources/view/homeproxy/client.js:1108 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1109 #: htdocs/luci-static/resources/view/homeproxy/node.js:712 #: htdocs/luci-static/resources/view/homeproxy/node.js:779 #: htdocs/luci-static/resources/view/homeproxy/server.js:405 @@ -1894,16 +1894,16 @@ msgstr "" msgid "QUIC stream receive window" msgstr "" -#: htdocs/luci-static/resources/view/homeproxy/client.js:1094 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1095 msgid "Query type" msgstr "" -#: htdocs/luci-static/resources/view/homeproxy/client.js:1214 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1215 msgid "RCode" msgstr "" #: htdocs/luci-static/resources/view/homeproxy/client.js:622 -#: htdocs/luci-static/resources/view/homeproxy/client.js:1109 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1110 msgid "RDP" msgstr "" @@ -1943,7 +1943,7 @@ msgstr "" msgid "Recursive outbound detected!" msgstr "" -#: htdocs/luci-static/resources/view/homeproxy/client.js:1012 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1013 msgid "Recursive resolver detected!" msgstr "" @@ -1968,11 +1968,11 @@ msgid "Region ID" msgstr "" #: htdocs/luci-static/resources/view/homeproxy/client.js:672 -#: htdocs/luci-static/resources/view/homeproxy/client.js:1148 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1149 msgid "Reject" msgstr "" -#: htdocs/luci-static/resources/view/homeproxy/client.js:1335 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1336 msgid "Remote" msgstr "" @@ -1984,7 +1984,7 @@ msgstr "" msgid "Remove all nodes from subscriptions" msgstr "" -#: htdocs/luci-static/resources/view/homeproxy/client.js:1202 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1203 msgid "Reply with REFUSED" msgstr "" @@ -2017,22 +2017,22 @@ msgid "Reuse listener address." msgstr "" #: htdocs/luci-static/resources/view/homeproxy/client.js:792 -#: htdocs/luci-static/resources/view/homeproxy/client.js:1186 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1187 msgid "Rewrite TTL" msgstr "" #: htdocs/luci-static/resources/view/homeproxy/client.js:793 -#: htdocs/luci-static/resources/view/homeproxy/client.js:1187 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1188 msgid "Rewrite TTL in DNS responses." msgstr "" #: htdocs/luci-static/resources/view/homeproxy/client.js:670 -#: htdocs/luci-static/resources/view/homeproxy/client.js:1146 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1147 msgid "Route" msgstr "" #: htdocs/luci-static/resources/view/homeproxy/client.js:671 -#: htdocs/luci-static/resources/view/homeproxy/client.js:1147 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1148 msgid "Route options" msgstr "" @@ -2064,33 +2064,33 @@ msgstr "" msgid "Routing rule" msgstr "" -#: htdocs/luci-static/resources/view/homeproxy/client.js:1310 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1311 msgid "Rule Set" msgstr "" #: htdocs/luci-static/resources/view/homeproxy/client.js:646 -#: htdocs/luci-static/resources/view/homeproxy/client.js:1118 -#: htdocs/luci-static/resources/view/homeproxy/client.js:1319 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1119 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1320 msgid "Rule set" msgstr "" #: htdocs/luci-static/resources/view/homeproxy/client.js:661 -#: htdocs/luci-static/resources/view/homeproxy/client.js:1133 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1134 msgid "Rule set IP CIDR as source IP" msgstr "" -#: htdocs/luci-static/resources/view/homeproxy/client.js:1352 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1353 msgid "Rule set URL" msgstr "" #: htdocs/luci-static/resources/view/homeproxy/client.js:623 -#: htdocs/luci-static/resources/view/homeproxy/client.js:1110 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1111 #: htdocs/luci-static/resources/view/homeproxy/node.js:438 msgid "SSH" msgstr "" #: htdocs/luci-static/resources/view/homeproxy/client.js:624 -#: htdocs/luci-static/resources/view/homeproxy/client.js:1111 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1112 msgid "STUN" msgstr "" @@ -2124,7 +2124,7 @@ msgstr "" msgid "Save subscriptions settings" msgstr "" -#: htdocs/luci-static/resources/view/homeproxy/client.js:1154 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1155 #: htdocs/luci-static/resources/view/homeproxy/server.js:156 msgid "Server" msgstr "" @@ -2147,7 +2147,7 @@ msgstr "" msgid "Service Status" msgstr "" -#: htdocs/luci-static/resources/view/homeproxy/client.js:1174 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1175 msgid "Set domain strategy for this query." msgstr "" @@ -2169,7 +2169,7 @@ msgid "Sniffed client type (QUIC client type or SSH client name)." msgstr "" #: htdocs/luci-static/resources/view/homeproxy/client.js:616 -#: htdocs/luci-static/resources/view/homeproxy/client.js:1104 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1105 msgid "" "Sniffed protocol, see Sniff for details." @@ -2197,21 +2197,21 @@ msgid "Socks5" msgstr "" #: htdocs/luci-static/resources/view/homeproxy/client.js:822 -#: htdocs/luci-static/resources/view/homeproxy/client.js:1258 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1259 msgid "Source IP CIDR" msgstr "" -#: htdocs/luci-static/resources/view/homeproxy/client.js:1341 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1342 msgid "Source file" msgstr "" #: htdocs/luci-static/resources/view/homeproxy/client.js:838 -#: htdocs/luci-static/resources/view/homeproxy/client.js:1275 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1276 msgid "Source port" msgstr "" #: htdocs/luci-static/resources/view/homeproxy/client.js:843 -#: htdocs/luci-static/resources/view/homeproxy/client.js:1280 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1281 msgid "Source port range" msgstr "" @@ -2307,14 +2307,14 @@ msgstr "" #: htdocs/luci-static/resources/view/homeproxy/client.js:435 #: htdocs/luci-static/resources/view/homeproxy/client.js:757 #: htdocs/luci-static/resources/view/homeproxy/client.js:888 -#: htdocs/luci-static/resources/view/homeproxy/client.js:995 -#: htdocs/luci-static/resources/view/homeproxy/client.js:1161 +#: htdocs/luci-static/resources/view/homeproxy/client.js:996 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1162 msgid "System DNS" msgstr "" #: htdocs/luci-static/resources/view/homeproxy/client.js:638 #: htdocs/luci-static/resources/view/homeproxy/client.js:949 -#: htdocs/luci-static/resources/view/homeproxy/client.js:1099 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1100 #: htdocs/luci-static/resources/view/homeproxy/server.js:867 msgid "TCP" msgstr "" @@ -2334,7 +2334,7 @@ msgstr "" #: htdocs/luci-static/resources/view/homeproxy/client.js:625 #: htdocs/luci-static/resources/view/homeproxy/client.js:950 -#: htdocs/luci-static/resources/view/homeproxy/client.js:1112 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1113 #: htdocs/luci-static/resources/view/homeproxy/node.js:1003 #: htdocs/luci-static/resources/view/homeproxy/server.js:532 msgid "TLS" @@ -2345,7 +2345,7 @@ msgstr "" msgid "TLS ALPN" msgstr "" -#: htdocs/luci-static/resources/view/homeproxy/client.js:979 +#: htdocs/luci-static/resources/view/homeproxy/client.js:980 #: htdocs/luci-static/resources/view/homeproxy/node.js:1030 #: htdocs/luci-static/resources/view/homeproxy/server.js:560 msgid "TLS SNI" @@ -2365,21 +2365,21 @@ msgstr "" msgid "TLS record fragment" msgstr "" -#: htdocs/luci-static/resources/view/homeproxy/client.js:988 +#: htdocs/luci-static/resources/view/homeproxy/client.js:989 msgid "" "Tag of a another server to resolve the domain name in the address. Required " "if address contains domain." msgstr "" -#: htdocs/luci-static/resources/view/homeproxy/client.js:1027 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1028 msgid "Tag of an outbound for connecting to the dns server." msgstr "" -#: htdocs/luci-static/resources/view/homeproxy/client.js:1375 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1376 msgid "Tag of the outbound to download rule set." msgstr "" -#: htdocs/luci-static/resources/view/homeproxy/client.js:1155 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1156 msgid "Tag of the target dns server." msgstr "" @@ -2466,7 +2466,7 @@ msgid "" "than as a single rule sub-item." msgstr "" -#: htdocs/luci-static/resources/view/homeproxy/client.js:1075 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1076 msgid "" "The default rule uses the following matching logic:
(domain || " "domain_suffix || domain_keyword || domain_regex) &&
(port " @@ -2482,7 +2482,7 @@ msgid "" msgstr "" #: htdocs/luci-static/resources/view/homeproxy/client.js:447 -#: htdocs/luci-static/resources/view/homeproxy/client.js:1020 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1021 msgid "The domain strategy for resolving the domain name in the address." msgstr "" @@ -2539,7 +2539,7 @@ msgstr "" msgid "The network interface to bind to." msgstr "" -#: htdocs/luci-static/resources/view/homeproxy/client.js:967 +#: htdocs/luci-static/resources/view/homeproxy/client.js:968 msgid "The path of the DNS server." msgstr "" @@ -2561,7 +2561,7 @@ msgstr "" msgid "The port of the DNS server." msgstr "" -#: htdocs/luci-static/resources/view/homeproxy/client.js:1215 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1216 msgid "The response code." msgstr "" @@ -2665,7 +2665,7 @@ msgid "Tun TCP/UDP" msgstr "" #: htdocs/luci-static/resources/view/homeproxy/client.js:947 -#: htdocs/luci-static/resources/view/homeproxy/client.js:1333 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1334 #: htdocs/luci-static/resources/view/homeproxy/node.js:427 #: htdocs/luci-static/resources/view/homeproxy/server.js:175 msgid "Type" @@ -2673,7 +2673,7 @@ msgstr "" #: htdocs/luci-static/resources/view/homeproxy/client.js:639 #: htdocs/luci-static/resources/view/homeproxy/client.js:948 -#: htdocs/luci-static/resources/view/homeproxy/client.js:1100 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1101 #: htdocs/luci-static/resources/view/homeproxy/server.js:868 msgid "UDP" msgstr "" @@ -2745,11 +2745,11 @@ msgstr "" msgid "Update failed." msgstr "" -#: htdocs/luci-static/resources/view/homeproxy/client.js:1391 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1392 msgid "Update interval" msgstr "" -#: htdocs/luci-static/resources/view/homeproxy/client.js:1392 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1393 msgid "Update interval of rule set." msgstr "" @@ -2810,12 +2810,12 @@ msgid "" "given." msgstr "" -#: htdocs/luci-static/resources/view/homeproxy/client.js:980 +#: htdocs/luci-static/resources/view/homeproxy/client.js:981 msgid "Used to verify the hostname on the returned certificates." msgstr "" #: htdocs/luci-static/resources/view/homeproxy/client.js:642 -#: htdocs/luci-static/resources/view/homeproxy/client.js:1114 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1115 msgid "User" msgstr "" @@ -2843,7 +2843,7 @@ msgstr "" msgid "WAN DNS (read from interface)" msgstr "" -#: htdocs/luci-static/resources/view/homeproxy/client.js:1463 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1464 msgid "WAN IP Policy" msgstr "" @@ -2936,7 +2936,7 @@ msgstr "" #: htdocs/luci-static/resources/view/homeproxy/client.js:195 #: htdocs/luci-static/resources/view/homeproxy/client.js:230 #: htdocs/luci-static/resources/view/homeproxy/client.js:504 -#: htdocs/luci-static/resources/view/homeproxy/client.js:1356 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1357 #: htdocs/luci-static/resources/view/homeproxy/node.js:488 #: htdocs/luci-static/resources/view/homeproxy/node.js:1131 #: htdocs/luci-static/resources/view/homeproxy/server.js:235 @@ -3022,8 +3022,8 @@ msgstr "" #: htdocs/luci-static/resources/view/homeproxy/client.js:518 #: htdocs/luci-static/resources/view/homeproxy/client.js:521 -#: htdocs/luci-static/resources/view/homeproxy/client.js:1361 -#: htdocs/luci-static/resources/view/homeproxy/client.js:1364 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1362 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1365 #: htdocs/luci-static/resources/view/homeproxy/node.js:1356 #: htdocs/luci-static/resources/view/homeproxy/node.js:1359 msgid "valid URL" @@ -3033,8 +3033,8 @@ msgstr "" msgid "valid base64 key with %d characters" msgstr "" -#: htdocs/luci-static/resources/view/homeproxy/client.js:1506 -#: htdocs/luci-static/resources/view/homeproxy/client.js:1538 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1507 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1539 msgid "valid hostname" msgstr "" diff --git a/small/luci-app-homeproxy/po/zh_Hans/homeproxy.po b/small/luci-app-homeproxy/po/zh_Hans/homeproxy.po index ea1eaec200..68d3e066ac 100644 --- a/small/luci-app-homeproxy/po/zh_Hans/homeproxy.po +++ b/small/luci-app-homeproxy/po/zh_Hans/homeproxy.po @@ -25,7 +25,7 @@ msgid "4 or 6. Not limited if empty." msgstr "4 或 6。留空不限制。" #: htdocs/luci-static/resources/view/homeproxy/client.js:775 -#: htdocs/luci-static/resources/view/homeproxy/client.js:1209 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1210 msgid "" "%s will be temporarily overwritten to %s after 50 " "triggers in 30s if not enabled." @@ -48,11 +48,11 @@ msgstr "API 令牌" msgid "Accept any if empty." msgstr "留空则不校验。" -#: htdocs/luci-static/resources/view/homeproxy/client.js:1137 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1138 msgid "Accept empty query response" msgstr "接受空查询响应" -#: htdocs/luci-static/resources/view/homeproxy/client.js:1398 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1399 msgid "Access Control" msgstr "访问控制" @@ -65,11 +65,11 @@ msgid "Access key secret" msgstr "访问密钥" #: htdocs/luci-static/resources/view/homeproxy/client.js:669 -#: htdocs/luci-static/resources/view/homeproxy/client.js:1145 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1146 msgid "Action" msgstr "操作" -#: htdocs/luci-static/resources/view/homeproxy/client.js:1055 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1056 msgid "Add a DNS rule" msgstr "新增 DNS 规则" @@ -89,7 +89,7 @@ msgstr "新增路由节点" msgid "Add a routing rule" msgstr "新增路由规则" -#: htdocs/luci-static/resources/view/homeproxy/client.js:1319 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1320 msgid "Add a rule set" msgstr "新增规则集" @@ -97,7 +97,7 @@ msgstr "新增规则集" msgid "Add a server" msgstr "新增服务器" -#: htdocs/luci-static/resources/view/homeproxy/client.js:974 +#: htdocs/luci-static/resources/view/homeproxy/client.js:975 msgid "Additional headers to be sent to the DNS server." msgstr "发送到 DNS 服务器的附加标头。" @@ -106,11 +106,11 @@ msgstr "发送到 DNS 服务器的附加标头。" msgid "Address" msgstr "地址" -#: htdocs/luci-static/resources/view/homeproxy/client.js:987 +#: htdocs/luci-static/resources/view/homeproxy/client.js:988 msgid "Address resolver" msgstr "地址解析器" -#: htdocs/luci-static/resources/view/homeproxy/client.js:1019 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1020 msgid "Address strategy" msgstr "地址解析策略" @@ -174,7 +174,7 @@ msgstr "替代 HTTPS 端口" msgid "An error occurred during updating subscriptions: %s" msgstr "更新订阅时发生错误:%s" -#: htdocs/luci-static/resources/view/homeproxy/client.js:1226 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1227 msgid "Answer" msgstr "回答" @@ -189,7 +189,7 @@ msgstr "AnyTLS 填充方案。" #: htdocs/luci-static/resources/view/homeproxy/client.js:799 #: htdocs/luci-static/resources/view/homeproxy/client.js:909 -#: htdocs/luci-static/resources/view/homeproxy/client.js:1194 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1195 msgid "" "Append a edns0-subnet OPT extra record with the specified IP " "prefix to every query by default.
If value is an IP address instead of " @@ -258,23 +258,23 @@ msgstr "Base64" msgid "Based on google/gvisor." msgstr "基于 google/gvisor。" -#: htdocs/luci-static/resources/view/homeproxy/client.js:1340 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1341 msgid "Binary file" msgstr "二进制文件" #: htdocs/luci-static/resources/view/homeproxy/client.js:453 -#: htdocs/luci-static/resources/view/homeproxy/client.js:1411 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1412 #: htdocs/luci-static/resources/view/homeproxy/server.js:874 msgid "Bind interface" msgstr "绑定接口" -#: htdocs/luci-static/resources/view/homeproxy/client.js:1412 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1413 msgid "" "Bind outbound traffic to specific interface. Leave empty to auto detect." msgstr "绑定出站流量至指定端口。留空自动检测。" #: htdocs/luci-static/resources/view/homeproxy/client.js:617 -#: htdocs/luci-static/resources/view/homeproxy/client.js:1105 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1106 msgid "BitTorrent" msgstr "BitTorrent" @@ -288,8 +288,8 @@ msgstr "封锁" #: htdocs/luci-static/resources/view/homeproxy/client.js:612 #: htdocs/luci-static/resources/view/homeproxy/client.js:640 -#: htdocs/luci-static/resources/view/homeproxy/client.js:1091 -#: htdocs/luci-static/resources/view/homeproxy/client.js:1101 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1092 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1102 #: htdocs/luci-static/resources/view/homeproxy/server.js:869 msgid "Both" msgstr "全部" @@ -415,7 +415,7 @@ msgstr "自定义路由" msgid "DNS" msgstr "DNS" -#: htdocs/luci-static/resources/view/homeproxy/client.js:1046 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1047 msgid "DNS Rules" msgstr "DNS 规则" @@ -431,7 +431,7 @@ msgstr "DNS 设置" msgid "DNS provider" msgstr "DNS 提供商" -#: htdocs/luci-static/resources/view/homeproxy/client.js:1055 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1056 msgid "DNS rule" msgstr "DNS 规则" @@ -446,7 +446,7 @@ msgid "DNS01 challenge" msgstr "DNS01 验证" #: htdocs/luci-static/resources/view/homeproxy/client.js:619 -#: htdocs/luci-static/resources/view/homeproxy/client.js:1106 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1107 msgid "DTLS" msgstr "DTLS" @@ -458,8 +458,8 @@ msgstr "调试" #: htdocs/luci-static/resources/view/homeproxy/client.js:433 #: htdocs/luci-static/resources/view/homeproxy/client.js:603 #: htdocs/luci-static/resources/view/homeproxy/client.js:755 -#: htdocs/luci-static/resources/view/homeproxy/client.js:1082 -#: htdocs/luci-static/resources/view/homeproxy/client.js:1380 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1083 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1381 #: htdocs/luci-static/resources/view/homeproxy/node.js:710 msgid "Default" msgstr "默认" @@ -468,8 +468,8 @@ msgstr "默认" #: htdocs/luci-static/resources/view/homeproxy/client.js:434 #: htdocs/luci-static/resources/view/homeproxy/client.js:756 #: htdocs/luci-static/resources/view/homeproxy/client.js:887 -#: htdocs/luci-static/resources/view/homeproxy/client.js:994 -#: htdocs/luci-static/resources/view/homeproxy/client.js:1160 +#: htdocs/luci-static/resources/view/homeproxy/client.js:995 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1161 msgid "Default DNS (issued by WAN)" msgstr "默认 DNS(由 WAN 下发)" @@ -508,33 +508,33 @@ msgstr "默认服务器名称" #: htdocs/luci-static/resources/view/homeproxy/client.js:364 #: htdocs/luci-static/resources/view/homeproxy/client.js:466 #: htdocs/luci-static/resources/view/homeproxy/client.js:684 -#: htdocs/luci-static/resources/view/homeproxy/client.js:1032 -#: htdocs/luci-static/resources/view/homeproxy/client.js:1381 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1033 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1382 #: htdocs/luci-static/resources/view/homeproxy/node.js:428 msgid "Direct" msgstr "直连" -#: htdocs/luci-static/resources/view/homeproxy/client.js:1513 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1514 msgid "Direct Domain List" msgstr "直连域名列表" -#: htdocs/luci-static/resources/view/homeproxy/client.js:1427 -#: htdocs/luci-static/resources/view/homeproxy/client.js:1472 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1428 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1473 msgid "Direct IPv4 IP-s" msgstr "直连 IPv4 地址" -#: htdocs/luci-static/resources/view/homeproxy/client.js:1430 -#: htdocs/luci-static/resources/view/homeproxy/client.js:1475 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1431 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1476 msgid "Direct IPv6 IP-s" msgstr "直连 IPv6 地址" -#: htdocs/luci-static/resources/view/homeproxy/client.js:1433 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1434 msgid "Direct MAC-s" msgstr "直连 MAC 地址" #: htdocs/luci-static/resources/view/homeproxy/client.js:123 #: htdocs/luci-static/resources/view/homeproxy/client.js:151 -#: htdocs/luci-static/resources/view/homeproxy/client.js:1421 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1422 #: htdocs/luci-static/resources/view/homeproxy/node.js:499 #: htdocs/luci-static/resources/view/homeproxy/node.js:555 #: htdocs/luci-static/resources/view/homeproxy/node.js:568 @@ -575,7 +575,7 @@ msgstr "禁用 TLS ALPN 认证" msgid "Disable UDP domain unmapping" msgstr "禁用 UDP 域名映射" -#: htdocs/luci-static/resources/view/homeproxy/client.js:1181 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1182 msgid "Disable cache and save cache in this query." msgstr "在本次查询中禁用缓存。" @@ -583,7 +583,7 @@ msgstr "在本次查询中禁用缓存。" msgid "Disable cache expire" msgstr "缓存永不过期" -#: htdocs/luci-static/resources/view/homeproxy/client.js:1180 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1181 msgid "Disable dns cache" msgstr "禁用 DNS 缓存" @@ -597,17 +597,17 @@ msgstr "" "字节。" #: htdocs/luci-static/resources/view/homeproxy/client.js:814 -#: htdocs/luci-static/resources/view/homeproxy/client.js:1250 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1251 msgid "Domain keyword" msgstr "域名关键词" #: htdocs/luci-static/resources/view/homeproxy/client.js:805 -#: htdocs/luci-static/resources/view/homeproxy/client.js:1241 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1242 msgid "Domain name" msgstr "域名" #: htdocs/luci-static/resources/view/homeproxy/client.js:818 -#: htdocs/luci-static/resources/view/homeproxy/client.js:1254 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1255 msgid "Domain regex" msgstr "域名正则表达式" @@ -617,7 +617,7 @@ msgstr "域名解析器" #: htdocs/luci-static/resources/view/homeproxy/client.js:347 #: htdocs/luci-static/resources/view/homeproxy/client.js:446 -#: htdocs/luci-static/resources/view/homeproxy/client.js:1173 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1174 msgid "Domain strategy" msgstr "域名解析策略" @@ -626,7 +626,7 @@ msgid "Domain strategy for resolving the domain names." msgstr "目标域名的解析策略。" #: htdocs/luci-static/resources/view/homeproxy/client.js:810 -#: htdocs/luci-static/resources/view/homeproxy/client.js:1246 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1247 msgid "Domain suffix" msgstr "域名后缀" @@ -638,7 +638,7 @@ msgstr "域名" msgid "Don't drop packets" msgstr "不丢弃数据包" -#: htdocs/luci-static/resources/view/homeproxy/client.js:1208 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1209 msgid "Don't drop requests" msgstr "不丢弃请求" @@ -657,8 +657,8 @@ msgstr "下载带宽(单位:Mbps)。" msgid "Drop packets" msgstr "丢弃数据包" -#: htdocs/luci-static/resources/view/homeproxy/client.js:1203 -#: htdocs/luci-static/resources/view/homeproxy/client.js:1210 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1204 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1211 msgid "Drop requests" msgstr "丢弃请求" @@ -710,7 +710,7 @@ msgstr "ECH 密钥" #: htdocs/luci-static/resources/view/homeproxy/client.js:798 #: htdocs/luci-static/resources/view/homeproxy/client.js:908 -#: htdocs/luci-static/resources/view/homeproxy/client.js:1193 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1194 msgid "EDNS Client subnet" msgstr "ENDS 客户端子网" @@ -739,8 +739,8 @@ msgstr "Email" #: htdocs/luci-static/resources/view/homeproxy/client.js:414 #: htdocs/luci-static/resources/view/homeproxy/client.js:590 #: htdocs/luci-static/resources/view/homeproxy/client.js:942 -#: htdocs/luci-static/resources/view/homeproxy/client.js:1069 -#: htdocs/luci-static/resources/view/homeproxy/client.js:1328 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1070 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1329 #: htdocs/luci-static/resources/view/homeproxy/server.js:148 #: htdocs/luci-static/resources/view/homeproxy/server.js:166 msgid "Enable" @@ -830,11 +830,11 @@ msgstr "错误" #: htdocs/luci-static/resources/view/homeproxy/client.js:504 #: htdocs/luci-static/resources/view/homeproxy/client.js:518 #: htdocs/luci-static/resources/view/homeproxy/client.js:521 -#: htdocs/luci-static/resources/view/homeproxy/client.js:1356 -#: htdocs/luci-static/resources/view/homeproxy/client.js:1361 -#: htdocs/luci-static/resources/view/homeproxy/client.js:1364 -#: htdocs/luci-static/resources/view/homeproxy/client.js:1506 -#: htdocs/luci-static/resources/view/homeproxy/client.js:1538 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1357 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1362 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1365 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1507 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1539 #: htdocs/luci-static/resources/view/homeproxy/node.js:488 #: htdocs/luci-static/resources/view/homeproxy/node.js:1131 #: htdocs/luci-static/resources/view/homeproxy/node.js:1302 @@ -858,7 +858,7 @@ msgstr "外部账户 MAC 密钥" msgid "External account key ID" msgstr "外部账户密钥标识符" -#: htdocs/luci-static/resources/view/homeproxy/client.js:1236 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1237 msgid "Extra records" msgstr "附加记录" @@ -899,7 +899,7 @@ msgstr "流控" msgid "For resolving domain name in the server address." msgstr "用于解析服务器地址中的域名。" -#: htdocs/luci-static/resources/view/homeproxy/client.js:1339 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1340 msgid "Format" msgstr "格式" @@ -928,15 +928,15 @@ msgstr "GFW 域名列表版本" msgid "GFWList" msgstr "GFWList" -#: htdocs/luci-static/resources/view/homeproxy/client.js:1445 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1446 msgid "Gaming mode IPv4 IP-s" msgstr "游戏模式 IPv4 地址" -#: htdocs/luci-static/resources/view/homeproxy/client.js:1447 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1448 msgid "Gaming mode IPv6 IP-s" msgstr "游戏模式 IPv6 地址" -#: htdocs/luci-static/resources/view/homeproxy/client.js:1450 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1451 msgid "Gaming mode MAC-s" msgstr "游戏模式 MAC 地址" @@ -958,15 +958,15 @@ msgstr "全局" msgid "Global padding" msgstr "全局填充" -#: htdocs/luci-static/resources/view/homeproxy/client.js:1452 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1453 msgid "Global proxy IPv4 IP-s" msgstr "全局代理 IPv4 地址" -#: htdocs/luci-static/resources/view/homeproxy/client.js:1455 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1456 msgid "Global proxy IPv6 IP-s" msgstr "全局代理 IPv6 地址" -#: htdocs/luci-static/resources/view/homeproxy/client.js:1458 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1459 msgid "Global proxy MAC-s" msgstr "全局代理 MAC 地址" @@ -987,7 +987,7 @@ msgid "Grant access to homeproxy configuration" msgstr "授予 homeproxy 访问 UCI 配置的权限" #: htdocs/luci-static/resources/view/homeproxy/client.js:620 -#: htdocs/luci-static/resources/view/homeproxy/client.js:1107 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1108 #: htdocs/luci-static/resources/view/homeproxy/node.js:430 #: htdocs/luci-static/resources/view/homeproxy/node.js:777 #: htdocs/luci-static/resources/view/homeproxy/server.js:177 @@ -996,8 +996,8 @@ msgid "HTTP" msgstr "HTTP" #: htdocs/luci-static/resources/view/homeproxy/client.js:952 -msgid "HTTP3" -msgstr "HTTP3" +msgid "HTTP/3" +msgstr "HTTP/3" #: htdocs/luci-static/resources/view/homeproxy/server.js:332 msgid "" @@ -1022,7 +1022,7 @@ msgstr "握手服务器地址" msgid "Handshake server port" msgstr "握手服务器端口" -#: htdocs/luci-static/resources/view/homeproxy/client.js:973 +#: htdocs/luci-static/resources/view/homeproxy/client.js:974 msgid "Headers" msgstr "标头" @@ -1071,7 +1071,7 @@ msgid "Host key algorithms" msgstr "主机密钥算法" #: htdocs/luci-static/resources/view/homeproxy/client.js:581 -#: htdocs/luci-static/resources/view/homeproxy/client.js:1060 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1061 msgid "Host/IP fields" msgstr "主机/IP 字段" @@ -1092,17 +1092,17 @@ msgid "Hysteria2" msgstr "Hysteria2" #: htdocs/luci-static/resources/view/homeproxy/client.js:830 -#: htdocs/luci-static/resources/view/homeproxy/client.js:1266 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1267 msgid "IP CIDR" msgstr "IP CIDR" #: htdocs/luci-static/resources/view/homeproxy/client.js:608 -#: htdocs/luci-static/resources/view/homeproxy/client.js:1088 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1089 msgid "IP version" msgstr "IP 版本" #: htdocs/luci-static/resources/view/homeproxy/client.js:610 -#: htdocs/luci-static/resources/view/homeproxy/client.js:1089 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1090 msgid "IPv4" msgstr "IPv4" @@ -1111,7 +1111,7 @@ msgid "IPv4 only" msgstr "仅 IPv4" #: htdocs/luci-static/resources/view/homeproxy/client.js:611 -#: htdocs/luci-static/resources/view/homeproxy/client.js:1090 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1091 msgid "IPv6" msgstr "IPv6" @@ -1219,7 +1219,7 @@ msgstr "独立缓存" msgid "Info" msgstr "信息" -#: htdocs/luci-static/resources/view/homeproxy/client.js:1404 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1405 msgid "Interface Control" msgstr "接口控制" @@ -1243,12 +1243,12 @@ msgid "" msgstr "发送心跳包以保持连接存活的时间间隔(单位:秒)。" #: htdocs/luci-static/resources/view/homeproxy/client.js:665 -#: htdocs/luci-static/resources/view/homeproxy/client.js:1141 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1142 msgid "Invert" msgstr "反转" #: htdocs/luci-static/resources/view/homeproxy/client.js:666 -#: htdocs/luci-static/resources/view/homeproxy/client.js:1142 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1143 msgid "Invert match result." msgstr "反转匹配结果" @@ -1256,15 +1256,15 @@ msgstr "反转匹配结果" msgid "Key path" msgstr "证书路径" -#: htdocs/luci-static/resources/view/homeproxy/client.js:1418 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1419 msgid "LAN IP Policy" msgstr "LAN IP 策略" #: htdocs/luci-static/resources/view/homeproxy/client.js:409 #: htdocs/luci-static/resources/view/homeproxy/client.js:585 #: htdocs/luci-static/resources/view/homeproxy/client.js:937 -#: htdocs/luci-static/resources/view/homeproxy/client.js:1064 -#: htdocs/luci-static/resources/view/homeproxy/client.js:1323 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1065 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1324 #: htdocs/luci-static/resources/view/homeproxy/node.js:422 #: htdocs/luci-static/resources/view/homeproxy/server.js:160 msgid "Label" @@ -1303,15 +1303,15 @@ msgstr "要测试的节点列表。" msgid "List of supported application level protocols, in order of preference." msgstr "支持的应用层协议协商列表,按顺序排列。" -#: htdocs/luci-static/resources/view/homeproxy/client.js:1227 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1228 msgid "List of text DNS record to respond as answers." msgstr "要响应的 DNS 记录列表。" -#: htdocs/luci-static/resources/view/homeproxy/client.js:1237 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1238 msgid "List of text DNS record to respond as extra records." msgstr "要响应的附加 DNS 记录列表。" -#: htdocs/luci-static/resources/view/homeproxy/client.js:1232 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1233 msgid "List of text DNS record to respond as name servers." msgstr "要响应的域名服务器(NS) DNS 记录列表。" @@ -1319,7 +1319,7 @@ msgstr "要响应的域名服务器(NS) DNS 记录列表。" msgid "Listen address" msgstr "监听地址" -#: htdocs/luci-static/resources/view/homeproxy/client.js:1406 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1407 msgid "Listen interfaces" msgstr "监听接口" @@ -1331,7 +1331,7 @@ msgstr "监听端口" msgid "Loading" msgstr "加载中" -#: htdocs/luci-static/resources/view/homeproxy/client.js:1334 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1335 msgid "Local" msgstr "本地" @@ -1363,11 +1363,11 @@ msgstr "主节点" msgid "Make IP CIDR in rule set used to match the source IP." msgstr "使规则集中的 IP CIDR 用于匹配源 IP。" -#: htdocs/luci-static/resources/view/homeproxy/client.js:1134 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1135 msgid "Make IP CIDR in rule sets match the source IP." msgstr "使规则集中的 IP CIDR 匹配源 IP。" -#: htdocs/luci-static/resources/view/homeproxy/client.js:1138 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1139 msgid "Make IP CIDR in rule-sets accept empty query response." msgstr "使规则集中的 IP CIDR 接受空查询响应。" @@ -1381,7 +1381,7 @@ msgstr "独立缓存每个 DNS 服务器的结果以供特殊用途。启用后 msgid "Masquerade" msgstr "伪装" -#: htdocs/luci-static/resources/view/homeproxy/client.js:1267 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1268 msgid "" "Match IP CIDR with query response. Current rule will be skipped if not match." msgstr "使用查询响应匹配 IP CIDR。如果不匹配,则跳过当前规则。" @@ -1391,90 +1391,90 @@ msgid "Match IP CIDR." msgstr "匹配 IP CIDR。" #: htdocs/luci-static/resources/view/homeproxy/client.js:811 -#: htdocs/luci-static/resources/view/homeproxy/client.js:1247 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1248 msgid "Match domain suffix." msgstr "匹配域名后缀。" #: htdocs/luci-static/resources/view/homeproxy/client.js:815 -#: htdocs/luci-static/resources/view/homeproxy/client.js:1251 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1252 msgid "Match domain using keyword." msgstr "使用关键词匹配域名。" #: htdocs/luci-static/resources/view/homeproxy/client.js:819 -#: htdocs/luci-static/resources/view/homeproxy/client.js:1255 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1256 msgid "Match domain using regular expression." msgstr "使用正则表达式匹配域名。" #: htdocs/luci-static/resources/view/homeproxy/client.js:806 -#: htdocs/luci-static/resources/view/homeproxy/client.js:1242 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1243 msgid "Match full domain." msgstr "匹配完整域名。" #: htdocs/luci-static/resources/view/homeproxy/client.js:854 -#: htdocs/luci-static/resources/view/homeproxy/client.js:1291 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1292 msgid "Match port range. Format as START:/:END/START:END." msgstr "匹配端口范围。格式为 START:/:END/START:END。" #: htdocs/luci-static/resources/view/homeproxy/client.js:849 -#: htdocs/luci-static/resources/view/homeproxy/client.js:1286 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1287 msgid "Match port." msgstr "匹配端口。" #: htdocs/luci-static/resources/view/homeproxy/client.js:835 -#: htdocs/luci-static/resources/view/homeproxy/client.js:1271 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1272 msgid "Match private IP" msgstr "匹配私有 IP" -#: htdocs/luci-static/resources/view/homeproxy/client.js:1272 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1273 msgid "Match private IP with query response." msgstr "使用查询响应匹配私有 IP。" #: htdocs/luci-static/resources/view/homeproxy/client.js:827 -#: htdocs/luci-static/resources/view/homeproxy/client.js:1263 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1264 msgid "Match private source IP" msgstr "匹配私有源 IP" #: htdocs/luci-static/resources/view/homeproxy/client.js:859 -#: htdocs/luci-static/resources/view/homeproxy/client.js:1296 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1297 msgid "Match process name." msgstr "匹配进程名。" #: htdocs/luci-static/resources/view/homeproxy/client.js:867 -#: htdocs/luci-static/resources/view/homeproxy/client.js:1304 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1305 msgid "Match process path using regular expression." msgstr "使用正则表达式匹配进程路径。" #: htdocs/luci-static/resources/view/homeproxy/client.js:863 -#: htdocs/luci-static/resources/view/homeproxy/client.js:1300 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1301 msgid "Match process path." msgstr "匹配进程路径。" -#: htdocs/luci-static/resources/view/homeproxy/client.js:1095 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1096 msgid "Match query type." msgstr "匹配请求类型。" #: htdocs/luci-static/resources/view/homeproxy/client.js:647 -#: htdocs/luci-static/resources/view/homeproxy/client.js:1119 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1120 msgid "Match rule set." msgstr "匹配规则集。" #: htdocs/luci-static/resources/view/homeproxy/client.js:823 -#: htdocs/luci-static/resources/view/homeproxy/client.js:1259 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1260 msgid "Match source IP CIDR." msgstr "匹配源 IP CIDR。" #: htdocs/luci-static/resources/view/homeproxy/client.js:844 -#: htdocs/luci-static/resources/view/homeproxy/client.js:1281 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1282 msgid "Match source port range. Format as START:/:END/START:END." msgstr "匹配源端口范围。格式为 START:/:END/START:END。" #: htdocs/luci-static/resources/view/homeproxy/client.js:839 -#: htdocs/luci-static/resources/view/homeproxy/client.js:1276 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1277 msgid "Match source port." msgstr "匹配源端口。" #: htdocs/luci-static/resources/view/homeproxy/client.js:643 -#: htdocs/luci-static/resources/view/homeproxy/client.js:1115 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1116 msgid "Match user name." msgstr "匹配用户名。" @@ -1526,8 +1526,8 @@ msgstr "最大流数量" #: htdocs/luci-static/resources/view/homeproxy/client.js:768 #: htdocs/luci-static/resources/view/homeproxy/client.js:776 -#: htdocs/luci-static/resources/view/homeproxy/client.js:1201 -#: htdocs/luci-static/resources/view/homeproxy/client.js:1210 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1202 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1211 #: htdocs/luci-static/resources/view/homeproxy/node.js:841 #: htdocs/luci-static/resources/view/homeproxy/server.js:452 msgid "Method" @@ -1562,7 +1562,7 @@ msgid "Mixed system TCP stack and gVisor UDP stack." msgstr "混合系统 TCP 栈和 gVisor UDP 栈。" #: htdocs/luci-static/resources/view/homeproxy/client.js:595 -#: htdocs/luci-static/resources/view/homeproxy/client.js:1074 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1075 msgid "Mode" msgstr "模式" @@ -1589,7 +1589,7 @@ msgstr "未运行" msgid "NOTE: Save current settings before updating subscriptions." msgstr "注意:更新订阅前先保存当前配置。" -#: htdocs/luci-static/resources/view/homeproxy/client.js:1231 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1232 msgid "NS" msgstr "NS" @@ -1602,7 +1602,7 @@ msgid "NaïveProxy" msgstr "NaïveProxy" #: htdocs/luci-static/resources/view/homeproxy/client.js:637 -#: htdocs/luci-static/resources/view/homeproxy/client.js:1098 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1099 #: htdocs/luci-static/resources/view/homeproxy/server.js:866 msgid "Network" msgstr "网络" @@ -1648,7 +1648,7 @@ msgstr "节点设置" msgid "Nodes" msgstr "节点" -#: htdocs/luci-static/resources/view/homeproxy/client.js:993 +#: htdocs/luci-static/resources/view/homeproxy/client.js:994 #: htdocs/luci-static/resources/view/homeproxy/node.js:737 #: htdocs/luci-static/resources/view/homeproxy/node.js:775 #: htdocs/luci-static/resources/view/homeproxy/server.js:386 @@ -1666,7 +1666,7 @@ msgstr "混淆密码" msgid "Obfuscate type" msgstr "混淆类型" -#: htdocs/luci-static/resources/view/homeproxy/client.js:1407 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1408 msgid "Only process traffic from specific interfaces. Leave empty for all." msgstr "只处理来自指定接口的流量。留空表示全部。" @@ -1675,14 +1675,14 @@ msgid "Only proxy mainland China" msgstr "仅代理中国大陆" #: htdocs/luci-static/resources/view/homeproxy/client.js:580 -#: htdocs/luci-static/resources/view/homeproxy/client.js:1059 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1060 msgid "Other fields" msgstr "其他字段" #: htdocs/luci-static/resources/view/homeproxy/client.js:460 #: htdocs/luci-static/resources/view/homeproxy/client.js:678 -#: htdocs/luci-static/resources/view/homeproxy/client.js:1026 -#: htdocs/luci-static/resources/view/homeproxy/client.js:1374 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1027 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1375 msgid "Outbound" msgstr "出站" @@ -1735,8 +1735,8 @@ msgstr "崩溃" msgid "Password" msgstr "密码" -#: htdocs/luci-static/resources/view/homeproxy/client.js:966 -#: htdocs/luci-static/resources/view/homeproxy/client.js:1345 +#: htdocs/luci-static/resources/view/homeproxy/client.js:967 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1346 #: htdocs/luci-static/resources/view/homeproxy/node.js:836 #: htdocs/luci-static/resources/view/homeproxy/node.js:869 #: htdocs/luci-static/resources/view/homeproxy/server.js:447 @@ -1773,7 +1773,7 @@ msgstr "插件参数" #: htdocs/luci-static/resources/view/homeproxy/client.js:848 #: htdocs/luci-static/resources/view/homeproxy/client.js:962 -#: htdocs/luci-static/resources/view/homeproxy/client.js:1285 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1286 #: htdocs/luci-static/resources/view/homeproxy/node.js:453 msgid "Port" msgstr "端口" @@ -1783,7 +1783,7 @@ msgid "Port %s alrealy exists!" msgstr "端口 %s 已存在!" #: htdocs/luci-static/resources/view/homeproxy/client.js:582 -#: htdocs/luci-static/resources/view/homeproxy/client.js:1061 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1062 msgid "Port fields" msgstr "端口字段" @@ -1792,7 +1792,7 @@ msgid "Port hopping interval in seconds." msgstr "端口跳跃间隔(单位:秒)。" #: htdocs/luci-static/resources/view/homeproxy/client.js:853 -#: htdocs/luci-static/resources/view/homeproxy/client.js:1290 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1291 msgid "Port range" msgstr "端口范围" @@ -1800,7 +1800,7 @@ msgstr "端口范围" msgid "Pre-shared key" msgstr "预共享密钥" -#: htdocs/luci-static/resources/view/homeproxy/client.js:1149 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1150 msgid "Predefined" msgstr "预定义" @@ -1822,27 +1822,27 @@ msgid "Private key passphrase" msgstr "私钥指纹" #: htdocs/luci-static/resources/view/homeproxy/client.js:583 -#: htdocs/luci-static/resources/view/homeproxy/client.js:1062 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1063 msgid "Process fields" msgstr "进程字段" #: htdocs/luci-static/resources/view/homeproxy/client.js:858 -#: htdocs/luci-static/resources/view/homeproxy/client.js:1295 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1296 msgid "Process name" msgstr "进程名" #: htdocs/luci-static/resources/view/homeproxy/client.js:862 -#: htdocs/luci-static/resources/view/homeproxy/client.js:1299 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1300 msgid "Process path" msgstr "进程路径" #: htdocs/luci-static/resources/view/homeproxy/client.js:866 -#: htdocs/luci-static/resources/view/homeproxy/client.js:1303 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1304 msgid "Process path (regex)" msgstr "进程路径(正则表达式)" #: htdocs/luci-static/resources/view/homeproxy/client.js:615 -#: htdocs/luci-static/resources/view/homeproxy/client.js:1103 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1104 #: htdocs/luci-static/resources/view/homeproxy/node.js:543 #: htdocs/luci-static/resources/view/homeproxy/node.js:951 #: htdocs/luci-static/resources/view/homeproxy/server.js:250 @@ -1859,33 +1859,33 @@ msgid "" "default in v2ray and cannot be disabled)." msgstr "协议参数。 如启用会随机浪费流量(在 v2ray 中默认启用并且无法禁用)。" -#: htdocs/luci-static/resources/view/homeproxy/client.js:1481 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1482 msgid "Proxy Domain List" msgstr "代理域名列表" -#: htdocs/luci-static/resources/view/homeproxy/client.js:1436 -#: htdocs/luci-static/resources/view/homeproxy/client.js:1465 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1437 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1466 msgid "Proxy IPv4 IP-s" msgstr "代理 IPv4 地址" -#: htdocs/luci-static/resources/view/homeproxy/client.js:1439 -#: htdocs/luci-static/resources/view/homeproxy/client.js:1468 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1440 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1469 msgid "Proxy IPv6 IP-s" msgstr "代理 IPv6 地址" -#: htdocs/luci-static/resources/view/homeproxy/client.js:1442 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1443 msgid "Proxy MAC-s" msgstr "代理 MAC 地址" -#: htdocs/luci-static/resources/view/homeproxy/client.js:1423 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1424 msgid "Proxy all except listed" msgstr "仅允许列表外" -#: htdocs/luci-static/resources/view/homeproxy/client.js:1420 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1421 msgid "Proxy filter mode" msgstr "代理过滤模式" -#: htdocs/luci-static/resources/view/homeproxy/client.js:1422 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1423 msgid "Proxy listed only" msgstr "仅允许列表内" @@ -1899,7 +1899,7 @@ msgstr "代理协议" #: htdocs/luci-static/resources/view/homeproxy/client.js:621 #: htdocs/luci-static/resources/view/homeproxy/client.js:953 -#: htdocs/luci-static/resources/view/homeproxy/client.js:1108 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1109 #: htdocs/luci-static/resources/view/homeproxy/node.js:712 #: htdocs/luci-static/resources/view/homeproxy/node.js:779 #: htdocs/luci-static/resources/view/homeproxy/server.js:405 @@ -1925,16 +1925,16 @@ msgstr "QUIC 最大双向并发流" msgid "QUIC stream receive window" msgstr "QUIC 流接收窗口" -#: htdocs/luci-static/resources/view/homeproxy/client.js:1094 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1095 msgid "Query type" msgstr "请求类型" -#: htdocs/luci-static/resources/view/homeproxy/client.js:1214 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1215 msgid "RCode" msgstr "RCode" #: htdocs/luci-static/resources/view/homeproxy/client.js:622 -#: htdocs/luci-static/resources/view/homeproxy/client.js:1109 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1110 msgid "RDP" msgstr "RDP" @@ -1974,7 +1974,7 @@ msgstr "如留空,则使用随机版本。" msgid "Recursive outbound detected!" msgstr "检测到递归出站!" -#: htdocs/luci-static/resources/view/homeproxy/client.js:1012 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1013 msgid "Recursive resolver detected!" msgstr "检测到递归解析器!" @@ -1999,11 +1999,11 @@ msgid "Region ID" msgstr "区域 ID" #: htdocs/luci-static/resources/view/homeproxy/client.js:672 -#: htdocs/luci-static/resources/view/homeproxy/client.js:1148 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1149 msgid "Reject" msgstr "拒绝" -#: htdocs/luci-static/resources/view/homeproxy/client.js:1335 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1336 msgid "Remote" msgstr "远程" @@ -2015,7 +2015,7 @@ msgstr "移除 %s 个节点" msgid "Remove all nodes from subscriptions" msgstr "移除所有订阅节点" -#: htdocs/luci-static/resources/view/homeproxy/client.js:1202 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1203 msgid "Reply with REFUSED" msgstr "回复 REFUSED" @@ -2048,22 +2048,22 @@ msgid "Reuse listener address." msgstr "复用监听地址。" #: htdocs/luci-static/resources/view/homeproxy/client.js:792 -#: htdocs/luci-static/resources/view/homeproxy/client.js:1186 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1187 msgid "Rewrite TTL" msgstr "重写 TTL" #: htdocs/luci-static/resources/view/homeproxy/client.js:793 -#: htdocs/luci-static/resources/view/homeproxy/client.js:1187 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1188 msgid "Rewrite TTL in DNS responses." msgstr "在 DNS 响应中重写 TTL。" #: htdocs/luci-static/resources/view/homeproxy/client.js:670 -#: htdocs/luci-static/resources/view/homeproxy/client.js:1146 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1147 msgid "Route" msgstr "路由" #: htdocs/luci-static/resources/view/homeproxy/client.js:671 -#: htdocs/luci-static/resources/view/homeproxy/client.js:1147 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1148 msgid "Route options" msgstr "路由选项" @@ -2095,33 +2095,33 @@ msgstr "路由端口" msgid "Routing rule" msgstr "路由规则" -#: htdocs/luci-static/resources/view/homeproxy/client.js:1310 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1311 msgid "Rule Set" msgstr "规则集" #: htdocs/luci-static/resources/view/homeproxy/client.js:646 -#: htdocs/luci-static/resources/view/homeproxy/client.js:1118 -#: htdocs/luci-static/resources/view/homeproxy/client.js:1319 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1119 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1320 msgid "Rule set" msgstr "规则集" #: htdocs/luci-static/resources/view/homeproxy/client.js:661 -#: htdocs/luci-static/resources/view/homeproxy/client.js:1133 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1134 msgid "Rule set IP CIDR as source IP" msgstr "规则集 IP CIDR 作为源 IP" -#: htdocs/luci-static/resources/view/homeproxy/client.js:1352 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1353 msgid "Rule set URL" msgstr "规则集 URL" #: htdocs/luci-static/resources/view/homeproxy/client.js:623 -#: htdocs/luci-static/resources/view/homeproxy/client.js:1110 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1111 #: htdocs/luci-static/resources/view/homeproxy/node.js:438 msgid "SSH" msgstr "SSH" #: htdocs/luci-static/resources/view/homeproxy/client.js:624 -#: htdocs/luci-static/resources/view/homeproxy/client.js:1111 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1112 msgid "STUN" msgstr "STUN" @@ -2155,7 +2155,7 @@ msgstr "保存当前设置" msgid "Save subscriptions settings" msgstr "保存订阅设置" -#: htdocs/luci-static/resources/view/homeproxy/client.js:1154 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1155 #: htdocs/luci-static/resources/view/homeproxy/server.js:156 msgid "Server" msgstr "服务器" @@ -2178,7 +2178,7 @@ msgstr "服务器设置" msgid "Service Status" msgstr "服务状态" -#: htdocs/luci-static/resources/view/homeproxy/client.js:1174 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1175 msgid "Set domain strategy for this query." msgstr "为此查询设置域名策略。" @@ -2200,7 +2200,7 @@ msgid "Sniffed client type (QUIC client type or SSH client name)." msgstr "嗅探到的客户端类型(QUIC 客户端类型或 SSH 客户端名称)。" #: htdocs/luci-static/resources/view/homeproxy/client.js:616 -#: htdocs/luci-static/resources/view/homeproxy/client.js:1104 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1105 msgid "" "Sniffed protocol, see Sniff for details." @@ -2230,21 +2230,21 @@ msgid "Socks5" msgstr "Socks5" #: htdocs/luci-static/resources/view/homeproxy/client.js:822 -#: htdocs/luci-static/resources/view/homeproxy/client.js:1258 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1259 msgid "Source IP CIDR" msgstr "源 IP CIDR" -#: htdocs/luci-static/resources/view/homeproxy/client.js:1341 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1342 msgid "Source file" msgstr "源文件" #: htdocs/luci-static/resources/view/homeproxy/client.js:838 -#: htdocs/luci-static/resources/view/homeproxy/client.js:1275 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1276 msgid "Source port" msgstr "源端口" #: htdocs/luci-static/resources/view/homeproxy/client.js:843 -#: htdocs/luci-static/resources/view/homeproxy/client.js:1280 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1281 msgid "Source port range" msgstr "源端口范围" @@ -2351,14 +2351,14 @@ msgstr "系统" #: htdocs/luci-static/resources/view/homeproxy/client.js:435 #: htdocs/luci-static/resources/view/homeproxy/client.js:757 #: htdocs/luci-static/resources/view/homeproxy/client.js:888 -#: htdocs/luci-static/resources/view/homeproxy/client.js:995 -#: htdocs/luci-static/resources/view/homeproxy/client.js:1161 +#: htdocs/luci-static/resources/view/homeproxy/client.js:996 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1162 msgid "System DNS" msgstr "系统 DNS" #: htdocs/luci-static/resources/view/homeproxy/client.js:638 #: htdocs/luci-static/resources/view/homeproxy/client.js:949 -#: htdocs/luci-static/resources/view/homeproxy/client.js:1099 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1100 #: htdocs/luci-static/resources/view/homeproxy/server.js:867 msgid "TCP" msgstr "TCP" @@ -2378,7 +2378,7 @@ msgstr "TCP/IP 协议栈。" #: htdocs/luci-static/resources/view/homeproxy/client.js:625 #: htdocs/luci-static/resources/view/homeproxy/client.js:950 -#: htdocs/luci-static/resources/view/homeproxy/client.js:1112 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1113 #: htdocs/luci-static/resources/view/homeproxy/node.js:1003 #: htdocs/luci-static/resources/view/homeproxy/server.js:532 msgid "TLS" @@ -2389,7 +2389,7 @@ msgstr "TLS" msgid "TLS ALPN" msgstr "TLS ALPN" -#: htdocs/luci-static/resources/view/homeproxy/client.js:979 +#: htdocs/luci-static/resources/view/homeproxy/client.js:980 #: htdocs/luci-static/resources/view/homeproxy/node.js:1030 #: htdocs/luci-static/resources/view/homeproxy/server.js:560 msgid "TLS SNI" @@ -2409,7 +2409,7 @@ msgstr "不强制执行 TLS。如未配置 TLS,将使用纯 HTTP 1.1。" msgid "TLS record fragment" msgstr "TLS 记录分片" -#: htdocs/luci-static/resources/view/homeproxy/client.js:988 +#: htdocs/luci-static/resources/view/homeproxy/client.js:989 msgid "" "Tag of a another server to resolve the domain name in the address. Required " "if address contains domain." @@ -2417,15 +2417,15 @@ msgstr "" "用于解析本 DNS 服务器的域名的另一个 DNS 服务器的标签。如果服务器地址包括域名" "则必须。" -#: htdocs/luci-static/resources/view/homeproxy/client.js:1027 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1028 msgid "Tag of an outbound for connecting to the dns server." msgstr "用于连接到 DNS 服务器的出站标签。" -#: htdocs/luci-static/resources/view/homeproxy/client.js:1375 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1376 msgid "Tag of the outbound to download rule set." msgstr "用于下载规则集的出站标签。" -#: htdocs/luci-static/resources/view/homeproxy/client.js:1155 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1156 msgid "Tag of the target dns server." msgstr "目标 DNS 服务器标签。" @@ -2521,7 +2521,7 @@ msgstr "" "source_port_range)
&&
其他字段。此外,包含的所有规则" "集会被合并而不是独立生效。" -#: htdocs/luci-static/resources/view/homeproxy/client.js:1075 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1076 msgid "" "The default rule uses the following matching logic:
(domain || " "domain_suffix || domain_keyword || domain_regex) &&
(port " @@ -2542,7 +2542,7 @@ msgid "" msgstr "用于解析国内域名的 DNS 服务器。支持 UDP、TCP、DoH、DoQ、DoT。" #: htdocs/luci-static/resources/view/homeproxy/client.js:447 -#: htdocs/luci-static/resources/view/homeproxy/client.js:1020 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1021 msgid "The domain strategy for resolving the domain name in the address." msgstr "用于解析本 DNS 服务器的域名的策略。" @@ -2599,7 +2599,7 @@ msgstr "为 ARM64/AMD64 设计的现代 ImmortalWrt 代理平台。" msgid "The network interface to bind to." msgstr "绑定到的网络接口。" -#: htdocs/luci-static/resources/view/homeproxy/client.js:967 +#: htdocs/luci-static/resources/view/homeproxy/client.js:968 msgid "The path of the DNS server." msgstr "DNS 服务器的路径。" @@ -2621,7 +2621,7 @@ msgstr "必须是唯一端口。" msgid "The port of the DNS server." msgstr "DNS 服务器的端口。" -#: htdocs/luci-static/resources/view/homeproxy/client.js:1215 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1216 msgid "The response code." msgstr "响应代码。" @@ -2734,7 +2734,7 @@ msgid "Tun TCP/UDP" msgstr "Tun TCP/UDP" #: htdocs/luci-static/resources/view/homeproxy/client.js:947 -#: htdocs/luci-static/resources/view/homeproxy/client.js:1333 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1334 #: htdocs/luci-static/resources/view/homeproxy/node.js:427 #: htdocs/luci-static/resources/view/homeproxy/server.js:175 msgid "Type" @@ -2742,7 +2742,7 @@ msgstr "类型" #: htdocs/luci-static/resources/view/homeproxy/client.js:639 #: htdocs/luci-static/resources/view/homeproxy/client.js:948 -#: htdocs/luci-static/resources/view/homeproxy/client.js:1100 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1101 #: htdocs/luci-static/resources/view/homeproxy/server.js:868 msgid "UDP" msgstr "UDP" @@ -2814,11 +2814,11 @@ msgstr "更新 %s 个订阅" msgid "Update failed." msgstr "更新失败。" -#: htdocs/luci-static/resources/view/homeproxy/client.js:1391 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1392 msgid "Update interval" msgstr "更新间隔" -#: htdocs/luci-static/resources/view/homeproxy/client.js:1392 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1393 msgid "Update interval of rule set." msgstr "规则集更新间隔。" @@ -2879,12 +2879,12 @@ msgid "" "given." msgstr "用于验证返回证书上的主机名。如允许不安全连接,此配置无效。" -#: htdocs/luci-static/resources/view/homeproxy/client.js:980 +#: htdocs/luci-static/resources/view/homeproxy/client.js:981 msgid "Used to verify the hostname on the returned certificates." msgstr "用于验证返回证书上的主机名。" #: htdocs/luci-static/resources/view/homeproxy/client.js:642 -#: htdocs/luci-static/resources/view/homeproxy/client.js:1114 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1115 msgid "User" msgstr "用户" @@ -2912,7 +2912,7 @@ msgstr "VMess" msgid "WAN DNS (read from interface)" msgstr "WAN DNS(从接口获取)" -#: htdocs/luci-static/resources/view/homeproxy/client.js:1463 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1464 msgid "WAN IP Policy" msgstr "WAN IP 策略" @@ -3005,7 +3005,7 @@ msgstr "gVisor" #: htdocs/luci-static/resources/view/homeproxy/client.js:195 #: htdocs/luci-static/resources/view/homeproxy/client.js:230 #: htdocs/luci-static/resources/view/homeproxy/client.js:504 -#: htdocs/luci-static/resources/view/homeproxy/client.js:1356 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1357 #: htdocs/luci-static/resources/view/homeproxy/node.js:488 #: htdocs/luci-static/resources/view/homeproxy/node.js:1131 #: htdocs/luci-static/resources/view/homeproxy/server.js:235 @@ -3092,8 +3092,8 @@ msgstr "有效 DNS 服务器地址" #: htdocs/luci-static/resources/view/homeproxy/client.js:518 #: htdocs/luci-static/resources/view/homeproxy/client.js:521 -#: htdocs/luci-static/resources/view/homeproxy/client.js:1361 -#: htdocs/luci-static/resources/view/homeproxy/client.js:1364 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1362 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1365 #: htdocs/luci-static/resources/view/homeproxy/node.js:1356 #: htdocs/luci-static/resources/view/homeproxy/node.js:1359 msgid "valid URL" @@ -3103,8 +3103,8 @@ msgstr "有效网址" msgid "valid base64 key with %d characters" msgstr "包含 %d 个字符的有效 base64 密钥" -#: htdocs/luci-static/resources/view/homeproxy/client.js:1506 -#: htdocs/luci-static/resources/view/homeproxy/client.js:1538 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1507 +#: htdocs/luci-static/resources/view/homeproxy/client.js:1539 msgid "valid hostname" msgstr "有效主机名" diff --git a/small/luci-app-homeproxy/root/etc/homeproxy/resources/china_ip4.txt b/small/luci-app-homeproxy/root/etc/homeproxy/resources/china_ip4.txt index b22589eadc..f1c13b5b90 100644 --- a/small/luci-app-homeproxy/root/etc/homeproxy/resources/china_ip4.txt +++ b/small/luci-app-homeproxy/root/etc/homeproxy/resources/china_ip4.txt @@ -42,8 +42,7 @@ 8.144.0.0/14 8.148.0.0/19 8.148.36.0/22 -8.148.40.0/23 -8.148.43.0/24 +8.148.40.0/22 8.148.64.0/18 8.148.128.0/17 8.149.0.0/16 @@ -154,6 +153,7 @@ 40.251.225.0/24 40.251.227.0/24 40.251.228.0/24 +42.0.128.0/17 42.4.0.0/14 42.48.0.0/15 42.51.0.0/16 @@ -215,12 +215,14 @@ 43.102.128.0/21 43.102.136.0/22 43.102.144.0/20 -43.109.1.0/24 -43.109.2.0/23 -43.109.4.0/24 +43.109.0.0/22 +43.109.4.0/23 43.109.9.0/24 +43.109.12.0/23 43.109.15.0/24 43.109.17.0/24 +43.109.31.0/24 +43.109.32.0/24 43.109.34.0/24 43.109.36.0/24 43.136.0.0/13 @@ -419,6 +421,7 @@ 45.113.24.0/22 45.113.40.0/22 45.113.200.0/22 +45.113.206.0/24 45.114.189.0/24 45.115.44.0/22 45.115.144.0/22 @@ -460,6 +463,7 @@ 45.147.6.0/24 45.151.47.0/24 45.157.88.0/24 +45.192.21.0/24 45.195.6.0/24 45.197.131.0/24 45.202.64.0/22 @@ -548,7 +552,6 @@ 49.64.0.0/11 49.112.0.0/13 49.120.0.0/14 -49.128.203.0/24 49.128.220.0/24 49.128.223.0/24 49.140.0.0/15 @@ -604,7 +607,6 @@ 58.24.0.0/15 58.30.0.0/15 58.32.0.0/11 -58.66.192.0/18 58.67.128.0/17 58.68.236.0/24 58.68.247.0/24 @@ -934,7 +936,8 @@ 103.3.136.0/21 103.3.152.0/21 103.4.56.0/22 -103.5.192.0/22 +103.5.192.0/23 +103.5.194.0/24 103.6.220.0/22 103.7.140.0/23 103.8.8.0/22 @@ -1087,7 +1090,6 @@ 103.53.211.0/24 103.55.172.0/22 103.55.228.0/22 -103.56.32.0/22 103.56.60.0/22 103.56.76.0/22 103.56.100.0/22 @@ -1100,6 +1102,7 @@ 103.59.124.0/22 103.59.148.0/22 103.59.164.0/22 +103.59.168.0/23 103.60.32.0/22 103.60.164.0/22 103.60.228.0/23 @@ -1131,6 +1134,7 @@ 103.71.232.0/22 103.72.113.0/24 103.72.172.0/24 +103.72.224.0/21 103.73.48.0/24 103.73.116.0/22 103.73.136.0/21 @@ -1154,6 +1158,7 @@ 103.78.228.0/22 103.79.24.0/22 103.79.200.0/22 +103.79.228.0/24 103.81.4.0/22 103.81.48.0/22 103.81.72.0/22 @@ -1286,7 +1291,9 @@ 103.133.128.0/23 103.134.136.0/22 103.135.160.0/22 -103.135.192.0/21 +103.135.192.0/23 +103.135.195.0/24 +103.135.196.0/22 103.137.60.0/24 103.138.156.0/23 103.139.136.0/23 @@ -1350,7 +1357,6 @@ 103.174.94.0/23 103.175.197.0/24 103.177.28.0/23 -103.177.44.0/24 103.179.78.0/23 103.180.108.0/23 103.181.234.0/24 @@ -1541,15 +1547,12 @@ 103.242.130.0/24 103.242.168.0/23 103.242.172.0/22 -103.242.200.0/24 -103.242.202.0/24 103.242.212.0/22 103.243.136.0/22 103.243.252.0/22 103.244.59.0/24 103.244.64.0/22 103.244.80.0/22 -103.244.164.0/22 103.244.232.0/22 103.245.128.0/22 103.246.152.0/22 @@ -1820,8 +1823,9 @@ 113.44.0.0/16 113.45.0.0/18 113.45.64.0/19 -113.45.96.0/20 -113.45.112.0/21 +113.45.96.0/22 +113.45.104.0/21 +113.45.112.0/22 113.45.120.0/22 113.45.128.0/17 113.46.0.0/16 @@ -1833,7 +1837,7 @@ 113.47.112.0/20 113.47.128.0/18 113.47.204.0/22 -113.47.220.0/22 +113.47.216.0/21 113.47.232.0/21 113.47.248.0/21 113.48.48.0/20 @@ -1958,6 +1962,7 @@ 114.135.0.0/16 114.138.0.0/15 114.141.128.0/18 +114.142.136.0/21 114.196.0.0/15 114.212.0.0/14 114.216.0.0/13 @@ -1991,6 +1996,7 @@ 115.174.64.0/19 115.175.0.0/18 115.175.64.0/19 +115.175.96.0/21 115.175.104.0/22 115.175.108.0/23 115.175.110.0/24 @@ -1998,7 +2004,7 @@ 115.175.128.0/18 115.175.192.0/19 115.175.224.0/20 -115.175.248.0/21 +115.175.252.0/22 115.182.0.0/15 115.190.0.0/16 115.191.0.0/18 @@ -2019,6 +2025,7 @@ 116.66.36.0/24 116.66.48.0/23 116.66.53.0/24 +116.66.54.0/23 116.66.98.0/24 116.66.120.0/24 116.66.123.0/24 @@ -2053,6 +2060,7 @@ 116.154.0.0/15 116.162.0.0/16 116.163.0.0/18 +116.165.0.0/16 116.167.0.0/16 116.168.0.0/15 116.171.0.0/16 @@ -2084,6 +2092,7 @@ 116.198.0.0/18 116.198.64.0/21 116.198.72.0/22 +116.198.96.0/19 116.198.144.0/20 116.198.160.0/20 116.198.176.0/21 @@ -2175,7 +2184,7 @@ 117.124.98.0/24 117.124.231.0/24 117.124.232.0/22 -117.124.237.0/24 +117.124.236.0/23 117.124.240.0/23 117.124.242.0/24 117.126.0.0/16 @@ -2218,8 +2227,6 @@ 118.126.140.0/23 118.126.142.0/24 118.132.0.0/14 -118.143.199.0/24 -118.143.215.0/24 118.144.0.0/16 118.145.0.0/19 118.145.32.0/20 @@ -2656,7 +2663,6 @@ 123.8.0.0/13 123.49.192.0/23 123.49.194.0/24 -123.49.224.0/24 123.49.240.0/24 123.49.242.0/23 123.52.0.0/14 @@ -2677,7 +2683,8 @@ 123.58.64.0/24 123.58.96.0/19 123.58.160.0/20 -123.58.180.0/22 +123.58.180.0/24 +123.58.182.0/23 123.58.184.0/24 123.58.186.0/23 123.58.188.0/22 @@ -2759,10 +2766,7 @@ 124.112.0.0/13 124.126.0.0/15 124.128.0.0/13 -124.151.0.0/17 -124.151.128.0/18 -124.151.193.0/24 -124.151.224.0/19 +124.151.0.0/16 124.152.0.0/16 124.160.0.0/13 124.172.0.0/15 @@ -2920,7 +2924,6 @@ 140.250.0.0/16 140.255.0.0/16 143.14.49.0/24 -143.20.66.0/24 143.20.147.0/24 143.64.0.0/16 144.0.0.0/16 @@ -2929,7 +2932,8 @@ 144.36.146.0/23 144.48.64.0/22 144.48.180.0/22 -144.48.184.0/24 +144.48.184.0/23 +144.48.186.0/24 144.48.212.0/22 144.48.252.0/22 144.52.0.0/16 @@ -2985,7 +2989,6 @@ 154.8.48.0/20 154.8.128.0/17 154.19.43.0/24 -154.38.104.0/22 154.48.237.0/24 154.72.42.0/24 154.72.44.0/24 @@ -2996,12 +2999,11 @@ 154.208.144.0/20 154.208.160.0/21 154.208.172.0/23 -154.213.4.0/23 155.102.0.0/23 155.102.2.0/24 155.102.4.0/23 155.102.9.0/24 -155.102.10.0/23 +155.102.10.0/24 155.102.12.0/22 155.102.16.0/22 155.102.20.0/24 @@ -3012,7 +3014,8 @@ 155.102.32.0/19 155.102.72.0/24 155.102.89.0/24 -155.102.98.0/23 +155.102.90.0/24 +155.102.99.0/24 155.102.100.0/23 155.102.111.0/24 155.102.112.0/21 @@ -3028,7 +3031,9 @@ 155.102.171.0/24 155.102.173.0/24 155.102.174.0/23 -155.102.176.0/20 +155.102.176.0/22 +155.102.180.0/23 +155.102.184.0/23 155.102.193.0/24 155.102.194.0/23 155.102.196.0/23 @@ -3038,6 +3043,7 @@ 155.102.204.0/22 155.102.208.0/22 155.102.212.0/23 +155.102.214.0/24 155.102.216.0/22 155.102.220.0/23 155.102.224.0/19 @@ -3087,6 +3093,7 @@ 160.30.150.0/23 160.30.230.0/23 160.83.110.0/24 +160.187.128.0/23 160.191.0.0/24 160.202.152.0/22 160.202.212.0/22 @@ -3110,7 +3117,7 @@ 163.53.128.0/22 163.53.168.0/22 163.61.202.0/23 -163.61.214.0/24 +163.61.214.0/23 163.125.0.0/16 163.142.0.0/16 163.177.0.0/16 @@ -3135,8 +3142,7 @@ 163.181.66.0/23 163.181.69.0/24 163.181.71.0/24 -163.181.72.0/23 -163.181.74.0/24 +163.181.72.0/22 163.181.77.0/24 163.181.78.0/23 163.181.80.0/22 @@ -3176,7 +3182,7 @@ 163.181.196.0/22 163.181.200.0/21 163.181.209.0/24 -163.181.210.0/24 +163.181.210.0/23 163.181.212.0/22 163.181.216.0/21 163.181.224.0/23 @@ -3190,10 +3196,11 @@ 163.181.248.0/21 163.204.0.0/16 163.223.178.0/23 +163.227.40.0/24 163.228.0.0/16 163.244.246.0/24 165.99.4.0/24 -165.101.70.0/24 +165.101.70.0/23 165.101.122.0/23 166.111.0.0/16 167.139.0.0/16 @@ -3359,7 +3366,6 @@ 185.75.174.0/24 185.234.212.0/24 188.131.128.0/17 -192.55.46.0/24 192.140.160.0/19 192.140.208.0/21 192.144.128.0/17 @@ -3545,11 +3551,9 @@ 203.8.30.0/24 203.12.91.0/24 203.12.93.0/24 -203.12.95.0/24 203.12.204.0/23 203.13.80.0/23 203.15.0.0/20 -203.25.48.0/24 203.25.52.0/24 203.25.208.0/20 203.32.48.0/23 @@ -3767,7 +3771,6 @@ 203.156.192.0/18 203.160.104.0/22 203.160.109.0/24 -203.160.110.0/23 203.160.129.0/24 203.160.192.0/24 203.160.196.0/24 @@ -3846,7 +3849,6 @@ 206.54.9.0/24 206.54.10.0/23 206.54.12.0/22 -207.226.154.0/24 210.2.0.0/23 210.2.4.0/24 210.5.0.0/19 @@ -4163,8 +4165,7 @@ 218.240.128.0/19 218.240.160.0/21 218.240.168.0/24 -218.240.176.0/21 -218.240.184.0/24 +218.240.176.0/20 218.241.16.0/21 218.241.96.0/20 218.241.112.0/22 @@ -4270,7 +4271,8 @@ 220.154.0.0/20 220.154.16.0/22 220.154.128.0/22 -220.154.132.0/24 +220.154.132.0/23 +220.154.134.0/24 220.154.140.0/24 220.154.144.0/24 220.160.0.0/12 diff --git a/small/luci-app-homeproxy/root/etc/homeproxy/resources/china_ip4.ver b/small/luci-app-homeproxy/root/etc/homeproxy/resources/china_ip4.ver index 36336a9cd5..e026ac301e 100644 --- a/small/luci-app-homeproxy/root/etc/homeproxy/resources/china_ip4.ver +++ b/small/luci-app-homeproxy/root/etc/homeproxy/resources/china_ip4.ver @@ -1 +1 @@ -20251021033250 +20251109033819 diff --git a/small/luci-app-homeproxy/root/etc/homeproxy/resources/china_ip6.txt b/small/luci-app-homeproxy/root/etc/homeproxy/resources/china_ip6.txt index 1b74559cad..144c5dae87 100644 --- a/small/luci-app-homeproxy/root/etc/homeproxy/resources/china_ip6.txt +++ b/small/luci-app-homeproxy/root/etc/homeproxy/resources/china_ip6.txt @@ -87,13 +87,11 @@ 2400:9380:9201::/48 2400:9380:9202::/48 2400:9380:9220::/47 -2400:9380:9240::/47 +2400:9380:9240::/48 2400:9380:9250::/47 2400:9380:9260::/48 2400:9380:9271::/48 -2400:9380:9272::/48 2400:9380:9280::/47 -2400:9380:9282::/48 2400:9380:92b0::/45 2400:95e0::/48 2400:9600:8800::/48 @@ -138,6 +136,7 @@ 2401:5c20:10::/48 2401:70e0::/32 2401:71c0::/48 +2401:7660::/48 2401:7700::/32 2401:7e00::/32 2401:8be0::/48 @@ -177,9 +176,7 @@ 2401:ec00::/32 2401:f860:86::/47 2401:f860:88::/47 -2401:f860:91::/48 -2401:f860:92::/47 -2401:f860:94::/48 +2401:f860:90::/45 2401:f860:100::/40 2401:fa00:40::/43 2402:840:d000::/46 @@ -368,16 +365,18 @@ 2404:2280:265::/48 2404:2280:266::/47 2404:2280:268::/45 -2404:2280:270::/46 -2404:2280:274::/47 -2404:2280:277::/48 +2404:2280:270::/45 2404:2280:278::/48 2404:2280:27a::/47 2404:2280:27c::/47 2404:2280:27f::/48 2404:2280:282::/48 -2404:2280:289::/48 +2404:2280:284::/47 +2404:2280:288::/47 2404:2280:28a::/48 +2404:2280:28c::/48 +2404:2280:296::/47 +2404:2280:298::/48 2404:3700::/48 2404:4dc0::/32 2404:6380::/48 @@ -452,17 +451,19 @@ 2406:280::/32 2406:840:9000::/44 2406:840:9961::/48 -2406:840:9962::/47 +2406:840:9963::/48 2406:840:996c::/48 2406:840:e080::/44 2406:840:e0cf::/48 -2406:840:e0e0::/46 +2406:840:e0e1::/48 2406:840:e0e4::/47 -2406:840:e0e8::/48 2406:840:e10f::/48 2406:840:e14f::/48 2406:840:e201::/48 -2406:840:e230::/44 +2406:840:e231::/48 +2406:840:e233::/48 +2406:840:e234::/48 +2406:840:e23b::/48 2406:840:e260::/48 2406:840:e2cf::/48 2406:840:e620::/47 @@ -476,7 +477,6 @@ 2406:840:eb0f::/48 2406:840:ee40::/47 2406:840:ee44::/48 -2406:840:ee4b::/48 2406:840:ee4d::/48 2406:840:eee5::/48 2406:840:f200::/47 @@ -484,6 +484,8 @@ 2406:840:f380::/44 2406:840:fc80::/44 2406:840:fcd0::/48 +2406:840:fcf0::/46 +2406:840:fcf4::/47 2406:840:fd40::/42 2406:840:fd80::/44 2406:840:fd9f::/48 @@ -675,83 +677,51 @@ 2408:8374::/30 2408:8378::/31 2408:837a::/32 -2408:8406::/42 -2408:8406:40::/43 2408:8406:c0::/42 2408:8406:100::/41 2408:8406:180::/42 -2408:8406:c00::/42 -2408:8406:c40::/43 2408:8406:cc0::/42 2408:8406:d00::/41 2408:8406:d80::/42 -2408:8406:1800::/42 -2408:8406:1840::/43 2408:8406:18c0::/42 2408:8406:1900::/41 2408:8406:1980::/42 -2408:8406:2400::/42 -2408:8406:2440::/43 2408:8406:24c0::/42 2408:8406:2500::/41 2408:8406:2580::/42 -2408:8406:3000::/42 -2408:8406:3040::/43 2408:8406:30c0::/42 2408:8406:3100::/41 2408:8406:3180::/42 -2408:8406:3c00::/42 -2408:8406:3c40::/43 2408:8406:3cc0::/42 2408:8406:3d00::/41 2408:8406:3d80::/42 -2408:8406:4800::/42 -2408:8406:4840::/43 2408:8406:48c0::/42 2408:8406:4900::/41 2408:8406:4980::/42 -2408:8406:5400::/42 -2408:8406:5440::/43 2408:8406:54c0::/42 2408:8406:5500::/41 2408:8406:5580::/42 -2408:8406:6000::/42 -2408:8406:6040::/43 2408:8406:60c0::/42 2408:8406:6100::/41 2408:8406:6180::/42 -2408:8406:6c00::/42 -2408:8406:6c40::/43 2408:8406:6cc0::/42 2408:8406:6d00::/41 2408:8406:6d80::/42 -2408:8406:7800::/42 -2408:8406:7840::/43 2408:8406:78c0::/42 2408:8406:7900::/41 2408:8406:7980::/42 -2408:8406:8400::/42 -2408:8406:8440::/43 2408:8406:84c0::/42 2408:8406:8500::/41 2408:8406:8580::/42 -2408:8406:9000::/42 -2408:8406:9040::/43 2408:8406:90c0::/42 2408:8406:9100::/41 2408:8406:9180::/42 -2408:8406:9c00::/42 -2408:8406:9c40::/43 2408:8406:9cc0::/42 2408:8406:9d00::/41 2408:8406:9d80::/42 -2408:8406:a800::/42 -2408:8406:a840::/43 2408:8406:a8c0::/42 2408:8406:a900::/41 2408:8406:a980::/42 -2408:8406:b400::/42 -2408:8406:b440::/43 2408:8406:b4c0::/42 2408:8406:b500::/41 2408:8406:b580::/42 @@ -1204,12 +1174,15 @@ 240e::/20 2602:2e0:ff::/48 2602:f7ee:ee::/48 +2602:f92a:1314::/48 +2602:f92a:a471::/48 2602:f92a:a478::/48 2602:f92a:dead::/48 2602:f92a:e100::/44 2602:f93b:400::/38 -2602:f9ba:a8::/48 2602:f9ba:10c::/48 +2602:fab0:11::/48 +2602:fed2:7051::/48 2602:feda:1bf::/48 2602:feda:1d1::/48 2602:feda:1df::/48 @@ -1256,10 +1229,8 @@ 2a04:f580:9270::/48 2a04:f580:9280::/48 2a04:f580:9290::/48 -2a06:1180:1000::/48 2a06:3603::/32 2a06:3604::/30 -2a06:9f81:4600::/42 2a06:9f81:4640::/43 2a06:a005:260::/43 2a06:a005:280::/43 @@ -1270,10 +1241,9 @@ 2a09:b280:ff81::/48 2a09:b280:ff83::/48 2a09:b280:ff84::/47 -2a0a:2840:20::/43 -2a0a:2840:2000::/47 -2a0a:2842::/32 +2a0a:2840::/30 2a0a:2845:aab8::/46 +2a0a:2845:d647::/48 2a0a:2846::/48 2a0a:6040:ec00::/40 2a0a:6044:6600::/40 @@ -1281,6 +1251,7 @@ 2a0b:4340:a6::/48 2a0b:4b81:1001::/48 2a0b:4e07:b8::/47 +2a0c:9a40:84e0::/48 2a0c:9a40:8fc1::/48 2a0c:9a40:8fc2::/47 2a0c:9a40:8fc4::/48 @@ -1307,17 +1278,13 @@ 2a0e:aa07:e15f::/48 2a0e:aa07:e16a::/48 2a0e:aa07:e1a0::/44 -2a0e:aa07:e1e1::/48 -2a0e:aa07:e1e2::/48 -2a0e:aa07:e1e5::/48 -2a0e:aa07:e1e6::/48 +2a0e:aa07:e1e0::/44 2a0e:aa07:e200::/44 2a0e:aa07:e210::/48 2a0e:aa07:e21c::/47 2a0e:aa07:e220::/44 -2a0e:aa07:f0d0::/46 +2a0e:aa07:f0d1::/48 2a0e:aa07:f0d4::/47 -2a0e:aa07:f0d8::/48 2a0e:aa07:f0de::/47 2a0e:b107:12b::/48 2a0e:b107:272::/48 @@ -1326,29 +1293,27 @@ 2a0e:b107:dce::/48 2a0e:b107:178d::/48 2a0e:b107:178e::/48 +2a0f:1cc5:20::/44 +2a0f:1cc5:f00::/46 2a0f:5707:ac00::/47 +2a0f:6284:300::/40 +2a0f:6284:400::/42 +2a0f:6284:440::/43 2a0f:6284:4b00::/40 -2a0f:7803:f5d0::/44 -2a0f:7803:f5e0::/43 -2a0f:7803:f680::/43 -2a0f:7803:f6a0::/44 -2a0f:7803:f7c0::/42 -2a0f:7803:f800::/43 -2a0f:7803:f840::/44 +2a0f:6284:4c30::/48 +2a0f:6284:4c40::/43 +2a0f:6284:4c60::/44 +2a0f:6284:4c80::/43 +2a0f:7803:f680::/44 2a0f:7803:fa21::/48 2a0f:7803:fa22::/47 2a0f:7803:fa24::/46 -2a0f:7803:faf3::/48 2a0f:7803:fe81::/48 2a0f:7803:fe82::/48 -2a0f:7807::/32 2a0f:7d07::/32 2a0f:85c1:ba5::/48 -2a0f:85c1:bfe::/48 -2a0f:85c1:ca0::/44 2a0f:85c1:ce1::/48 2a0f:85c1:cf1::/48 -2a0f:85c1:d90::/48 2a0f:9400:6110::/48 2a0f:9400:7700::/48 2a0f:ac00::/29 @@ -1356,8 +1321,7 @@ 2a10:ccc0:d00::/46 2a10:ccc0:d0a::/47 2a10:ccc0:d0c::/47 -2a10:ccc6:66c8::/47 -2a10:ccc6:66ca::/48 +2a10:ccc6:66c8::/48 2a10:ccc6:66cc::/46 2a12:f8c3::/36 2a13:1800::/48 @@ -1366,26 +1330,34 @@ 2a13:1800:300::/44 2a13:1801:180::/43 2a13:a5c3:ff21::/48 -2a13:a5c3:ff50::/44 2a13:a5c7:1800::/40 2a13:a5c7:2100::/48 2a13:a5c7:2102::/48 2a13:a5c7:2121::/48 2a13:a5c7:2801::/48 2a13:a5c7:3108::/48 -2a13:a5c7:31a0::/43 +2a13:a5c7:31a0::/44 +2a13:a5c7:31b0::/46 +2a13:a5c7:31b4::/47 +2a13:a5c7:31b6::/48 +2a13:a5c7:31b8::/45 2a13:a5c7:3301::/48 2a13:a5c7:3304::/48 -2a13:a5c7:3306::/48 -2a13:aac4:f000::/44 +2a13:a5c7:3306::/47 +2a13:aac4:f00d::/48 2a14:7c0:4a01::/48 +2a14:7c0:5103::/48 2a14:4c41::/32 2a14:67c1:20::/44 2a14:67c1:70::/48 2a14:67c1:73::/48 2a14:67c1:74::/48 -2a14:67c1:702::/48 +2a14:67c1:702::/47 2a14:67c1:704::/48 +2a14:67c1:800::/48 +2a14:67c1:802::/47 +2a14:67c1:804::/48 +2a14:67c1:806::/47 2a14:67c1:a010::/44 2a14:67c1:a020::/48 2a14:67c1:a023::/48 @@ -1394,12 +1366,7 @@ 2a14:67c1:a02f::/48 2a14:67c1:a040::/47 2a14:67c1:a064::/48 -2a14:67c1:a091::/48 -2a14:67c1:a093::/48 -2a14:67c1:a094::/46 -2a14:67c1:a098::/47 2a14:67c1:a100::/43 -2a14:67c1:a125::/48 2a14:67c1:a144::/48 2a14:67c1:b000::/48 2a14:67c1:b065::/48 @@ -1414,10 +1381,10 @@ 2a14:67c1:b140::/48 2a14:67c1:b4a1::/48 2a14:67c1:b4a2::/48 -2a14:67c1:b4a8::/48 +2a14:67c1:b4a8::/47 +2a14:67c1:b4aa::/48 2a14:67c1:b4c0::/45 -2a14:67c1:b4d0::/44 -2a14:67c1:b4e0::/43 +2a14:67c1:b4e0::/44 2a14:67c1:b500::/47 2a14:67c1:b549::/48 2a14:67c1:b561::/48 @@ -1431,10 +1398,10 @@ 2a14:67c1:b599::/48 2a14:67c1:b5a1::/48 2a14:67c1:c300::/40 -2a14:7580:740::/44 2a14:7580:750::/47 -2a14:7580:9200::/40 -2a14:7580:9400::/39 +2a14:7580:9206::/48 +2a14:7580:9208::/48 +2a14:7580:9220::/44 2a14:7580:d000::/37 2a14:7580:d800::/39 2a14:7580:da00::/40 @@ -1444,13 +1411,14 @@ 2a14:7580:fff7::/48 2a14:7580:fffa::/48 2a14:7581:ffb::/48 -2a14:7581:30b5::/48 +2a14:7581:30b6::/48 2a14:7581:3100::/40 2a14:7581:3401::/48 2a14:7583:f201::/48 2a14:7583:f203::/48 +2a14:7583:f204::/48 2a14:7583:f300::/46 -2a14:7583:f304::/47 +2a14:7583:f305::/48 2a14:7583:f460::/44 2a14:7583:f4f1::/48 2a14:7583:f4fe::/48 diff --git a/small/luci-app-homeproxy/root/etc/homeproxy/resources/china_ip6.ver b/small/luci-app-homeproxy/root/etc/homeproxy/resources/china_ip6.ver index 36336a9cd5..e026ac301e 100644 --- a/small/luci-app-homeproxy/root/etc/homeproxy/resources/china_ip6.ver +++ b/small/luci-app-homeproxy/root/etc/homeproxy/resources/china_ip6.ver @@ -1 +1 @@ -20251021033250 +20251109033819 diff --git a/small/luci-app-homeproxy/root/etc/homeproxy/resources/china_list.txt b/small/luci-app-homeproxy/root/etc/homeproxy/resources/china_list.txt index 7d319c0a3a..4ae005a40e 100644 --- a/small/luci-app-homeproxy/root/etc/homeproxy/resources/china_list.txt +++ b/small/luci-app-homeproxy/root/etc/homeproxy/resources/china_list.txt @@ -102,7 +102,6 @@ 010dsmzyy.com 010fang.net 010gaokao.com -010gkb.com 010huaer.com 010huashi.com 010jianzhan.com @@ -452,7 +451,6 @@ 0523tx.net 0523zp.com 0523zz.com -05245353.com 05273.com 0527zp.com 0527zz.com @@ -1840,7 +1838,6 @@ 168mlj.com 168moliao.com 168rcw.com -168shoubiao.com 168tea.com 168tex.com 168trucker.com @@ -2344,7 +2341,6 @@ 1977088.com 197784.com 197854.com -197c.com 198358.com 19840423.com 198434.com @@ -2456,7 +2452,6 @@ 1huwai.me 1hwz.com 1ij6ut.com -1iohncj.xyz 1iptv.com 1iuh5l.com 1j1x.com @@ -2481,7 +2476,6 @@ 1kx.me 1kxun.com 1kyx.com -1l0xphj.xyz 1l1.cc 1lan.tv 1law.vip @@ -2515,7 +2509,6 @@ 1nfinite.ai 1nmob.com 1nongjing.com -1nsou.com 1nyz.com 1o1o.xyz 1o26.com @@ -3121,7 +3114,6 @@ 27xuexiao.com 28.com 281010.com -28123.com 28126.cc 281669.vip 281826.vip @@ -3159,7 +3151,6 @@ 292775.com 29293.com 293.net -294041.com 29592.net 296u.com 29797.com @@ -3177,7 +3168,6 @@ 2apzhfa.xyz 2av7.com 2b26.com -2b8d3zt.xyz 2bkw.com 2broear.com 2bulu.com @@ -3210,7 +3200,6 @@ 2f.com 2fc5.com 2fz1.com -2fzb.com 2gdt.com 2gei.com 2girls1finger.org @@ -3274,7 +3263,6 @@ 2tubaobao.xyz 2tx.com 2u3v4w5x6y.com -2ua2xqu.xyz 2umj.com 2ut7.com 2v8d.com @@ -3422,7 +3410,6 @@ 31xs.net 31yarn.com 31yr.com -31zhi5f.xyz 320921.com 320g.com 321.net @@ -3851,6 +3838,7 @@ 36267.vip 362728tdg.com 363.com +363.hk 363.net 363120.com 363210.com @@ -3861,6 +3849,7 @@ 364000.com 364365889.com 365.com +365.hk 36500.com 36500.net 365128.com @@ -3974,7 +3963,6 @@ 36706.com 3673.com 367edu.com -367w37c.xyz 36840.com 36885.vip 3688km.com @@ -4102,7 +4090,6 @@ 38hot.net 38hp.com 38hzt.com -38ljkoi.xyz 38mhw.com 38ra.com 38xs.com @@ -4214,7 +4201,6 @@ 3dmxku.com 3dnew.com 3doe.com -3dqvcli.xyz 3drrr.com 3dsdce.com 3dsjw.com @@ -4370,7 +4356,6 @@ 3vjuyuan.com 3vsheji.com 3vyd.com -3wads.com 3wcoffee.com 3wen.com 3wfocus.com @@ -4729,7 +4714,6 @@ 4hgame.com 4hii.net 4hmodel.com -4hou.com 4hpy.com 4inlook.com 4jplus.com @@ -4996,7 +4980,6 @@ 51callu.net 51camel.com 51caocao.net -51cc.net 51ccd.com 51ccdn.com 51cck.com @@ -5269,7 +5252,6 @@ 51mingyan.net 51minsheng.com 51miz.com -51mkf.com 51mmt.com 51mnq.com 51mo.com @@ -5477,7 +5459,6 @@ 51xcrc.com 51xiancheng.com 51xianwan.com -51xiaohua.com 51xiaolu.com 51xingjy.com 51xinhu.com @@ -5491,7 +5472,6 @@ 51xuediannao.com 51xuetang.com 51xuetongxin.com -51xuewen.com 51xuexiaoyi.com 51xxsp.com 51y5.com @@ -6090,7 +6070,6 @@ 560wf.com 5611.com 56114.com -561218.com 56135.com 56156.com 5618.co @@ -6215,7 +6194,6 @@ 580jz.net 580k.com 580tequan.com -58161.com 58188.com 58199.com 582116.com @@ -6483,7 +6461,6 @@ 5ilrc.com 5iluying.com 5imeishi.com -5imoban.net 5imomo.com 5imusic.com 5imx.com @@ -6892,7 +6869,6 @@ 66cn.com 66d6.com 66ds.net -66f.com 66good.com 66han.com 66huigo.com @@ -7092,7 +7068,6 @@ 6ict.com 6ie6.com 6ifang.com -6ivrkvu.xyz 6juzi.com 6k11.com 6k6g.com @@ -7120,7 +7095,6 @@ 6pifa.net 6pingm.com 6puppy.xyz -6qyxeob.xyz 6r8c86z4jh.icu 6ren.com 6rencn.com @@ -7172,6 +7146,7 @@ 7-vk.com 7-wx.com 70.cc +70.net 700618.com 70098.com 700kan.cc @@ -7359,7 +7334,6 @@ 75ww.com 75xn.com 76065.com -76107448.com 7618.com 761a.com 7631.com @@ -7436,7 +7410,6 @@ 7788.com 7788js.com 7788sky.com -7788xj.com 7789.com 778buy.com 7790.com @@ -7508,7 +7481,6 @@ 78tp.com 78v.com 78yx.net -79-79.com 793360.com 793688.com 79432.com @@ -7871,12 +7843,10 @@ 835444.cc 835images21.com 835images28.com -835images3.com 835images32.com 835images38.com 835images48.com 835images55.com -835images6.com 835images61.com 835images73.com 835images76.com @@ -7928,7 +7898,6 @@ 853lab.com 854255.com 8558.org -855fff.com 85657777.com 85679999.com 857yx.com @@ -8129,7 +8098,6 @@ 8899.net 88993aaa.com 88995799.com -88999.com 8899yyy.vip 889mi.com 88bank.com @@ -8142,8 +8110,8 @@ 88h3.com 88hom.com 88ht.com -88hu.com 88icon.com +88ipa.com 88j84.com 88k.site 88koo.com @@ -8207,7 +8175,6 @@ 8btm.com 8cname.com 8cnet.com -8ddao.com 8dei.com 8dexpress.com 8dn.com @@ -8248,7 +8215,6 @@ 8l8e.com 8lag.com 8le8le.com -8letian.com 8lhx.com 8liuxing.com 8lj.cc @@ -8819,7 +8785,6 @@ 95links.com 95ns.net 95px.com -95s8tke.xyz 95shubao.info 95to59.com 95xiu.com @@ -8989,8 +8954,6 @@ 98du.com 98ep.com 98eye.com -98fp.com -98jx.com 98k4.com 98kpm.com 98lm.com @@ -9011,7 +8974,6 @@ 98znz.com 98zw.com 99.com -99069292.com 99114.com 99118.com 9911yx.com @@ -9034,6 +8996,7 @@ 995120.net 99520.love 996.com +996404.xyz 9965dns.com 9966.com 9966.org @@ -9318,7 +9281,6 @@ 9w1an.com 9w9.com 9wad.com -9wan8.com 9wee.com 9wee.net 9wuli.com @@ -9385,11 +9347,9 @@ a21yishion.com a2dongman.com a2wx.icu a3p4.net -a4enwyh.xyz a4s6.com a4size.net a5.net -a5100.com a5399.com a5600.com a5b.cc @@ -9528,7 +9488,6 @@ abcydia.com abcys8.com abd007.com abddn.com -abdstem.com abe-sz.com abe-tech.com abeacon.com @@ -9675,7 +9634,6 @@ acirclea.com acirno.com acjw.net ackjled.com -aclife.net acloud.com acloudbaas.com acloudrender.com @@ -9868,6 +9826,7 @@ adpfm513.com adplusx.com adpolestar.net adpsh.com +adqtt.net adquan.com ads8.com adsalecdn.com @@ -10565,7 +10524,6 @@ aiit.me aiitec.com aiiup.com aiizen.net -aijfc.com aiji66.com aijiajiankang.com aijianji.com @@ -10649,7 +10607,6 @@ aimsen.com aimu-app.com ainas.cc ainiapp.com -ainingjiaoyu.com ainirobot.com ainiseo.com ainiu.net @@ -10772,6 +10729,7 @@ aishangyangyu.com aisharenet.com aishengji.com aishenhua.com +aishenqi.net aishuge.cc aishuge.la aishukong.com @@ -10801,7 +10759,6 @@ aistar666.com aistudio-app.com aisx.cc aisy.com -aitansuo.com aitaotu.com aitcfw.com aite.xyz @@ -10944,7 +10901,6 @@ aizuna.com aizuopin.com aizusheng.com ajansspor.com -ajbbkf.com ajbcloud.com ajbtv.com ajcass.com @@ -11466,6 +11422,7 @@ alltoall.net alltobid.com alltopposts.com alltosun.com +alltuu.cc alltuu.com allvalue.com allwellsports.com @@ -11591,7 +11548,6 @@ amplly.com ampmake.com ampxl.com amqyl.com -ams-ic.com amsky.cc amsoveasea.com amssro.net @@ -11628,7 +11584,6 @@ an68.com analog.com analogfoundries.com analysysdata.com -analyticskey.com anan123.vip anandoor.com anandzhang.com @@ -11646,7 +11601,6 @@ ancbk.com ancda.com anchnet.com ancii.com -ancloud.xin ancun.com anda-cn.com anda-tech.com @@ -11863,7 +11817,6 @@ anran233.com anrangas.com anranhs.com anrayer.com -anren.live anren.org anrenmind.com anrenxmed.com @@ -13326,7 +13279,6 @@ ayalm.com ayatuan.com aybwg.org aycav.com -aycgs.com aycgu.com aychfy.com ayctgy.com @@ -14351,7 +14303,6 @@ basunlighting.com bat-sz.com batchat.com batengtiyu1.com -bathome.net batian.net batman.plus batmanit.com @@ -14411,7 +14362,6 @@ bb-game.com bb-hy.com bb-pco.com bb06.com -bb2024.com bb39977653.com bbanp.com bbaod.com @@ -14560,6 +14510,7 @@ bcfy188.com bcgf.cc bcghotel.com bchdemo.site +bchlkj.com bchrt.com bcisz.org bcitb.com @@ -14687,7 +14638,6 @@ bdspacetime.com bdstar.com bdstatic.cc bdstatic.com -bdstatlc.com bdsye.com bdsytime.com bdszh.vip @@ -14779,7 +14729,6 @@ beelink.com beencounter.com beep365.com beeplay123.com -beer-ui.com beeshow.tv beespal.com beestor.com @@ -14981,7 +14930,6 @@ belllan.com belloai.com beloj.com beltandroadforum.org -beltb2b.com beltxman.com bemanicn.com bemfa.com @@ -15161,7 +15109,6 @@ bestugali.com bestv6.com bestvcdn.com bestvcdn.net -bestvideocloud.com bestviewstock.com bestvist.com bestwa.com @@ -15239,7 +15186,6 @@ bfgho.com bfhmj.com bfikuncdn.com bfjr.com -bfjxmj.com bfnbgame.com bfnxxcdn.com bfqh.com @@ -16105,7 +16051,6 @@ bjbpi.com bjbrew.com bjbtfu.com bjbus.com -bjbxg8.com bjbywx.com bjbzc.com bjbzszxy.com @@ -17271,6 +17216,7 @@ botemotor.com botnet.cc botny.com botocard.com +boton-tech.com botongedu.com botongr.com botorange.com @@ -17318,6 +17264,7 @@ boyi.info boyikang.com boying360.com boyingsj.com +boyinhotel.com boyishu.me boylondonchina.com boyoucy.com @@ -17332,7 +17279,6 @@ boyue.com boyuecasting.com boyuemobile.com boyuesh.com -boyuguandao.com boyunso.com boyuntu.com boyuonline.com @@ -17529,7 +17475,6 @@ bsmz.net bsnljt.com bspapp.com bsping.com -bsqipei.com bsquant.com bsrczpw.com bsrkt.com @@ -17659,7 +17604,6 @@ btzbjt.com btzhcc.com btzthb.com btzyc.com -bu21lgz.xyz buaaer.com bubaigei.com bubalusplus.com @@ -17886,7 +17830,6 @@ bxshopya.com bxshscc.xyz bxsnews.com bxtag.com -bxv8.com bxwatch.com bxwljt.com bxwst.com @@ -18667,7 +18610,6 @@ caochai.net caochen.net caogen.com caogenb2b.com -caogenban.com caogong.org caohai.com caohaifeng.com @@ -18735,7 +18677,7 @@ cardqu.com cardyang.com care110.com caredear.com -career-js.com +careduka.com careerchina.com careerexe.com careerintlinc.com @@ -18938,6 +18880,7 @@ cbtimer.com cburi.com cbvac.com cbvvt.com +cbvx8.com cbxs.net cby.me cbzr.com @@ -19199,7 +19142,6 @@ ccpitbj.org ccpitbm.org ccpitbuild.org ccpitcq.org -ccpitcsc.org ccpitecc.com ccpitfujian.org ccpitgs.com @@ -19414,7 +19356,6 @@ cddengji.com cddgg.com cddgg.net cddjip.com -cddk8.com cddlhx.com cddlkj.net cddq120.com @@ -19459,7 +19400,6 @@ cdhaiguang.com cdhfund.com cdhglsc.com cdhgr.com -cdhjsd.com cdhjsw.com cdhke.com cdhkxy.com @@ -19493,6 +19433,7 @@ cdkeynogap.com cdkf.com cdkjbg.com cdkjw.org +cdks.run cdkyfc.com cdlaobing.com cdlbmy.com @@ -20021,6 +19962,7 @@ ceydz.com ceyice.net ceyige.com cezhu.net +cf-china.info cf-ns.com cf-ns.net cf-ns.site @@ -20075,7 +20017,6 @@ cflpla.com cfluid.com cfm119.com cfmcc.com -cfmcjr6.xyz cfmmc.com cfmogu.com cfmoto.com @@ -20569,7 +20510,6 @@ chcoin.com chcompass.com chcontrol.com chcpay.com -chczp.com chda.net chdajob.com chdelphin.com @@ -20650,7 +20590,6 @@ chehui.com chejianding.com chejingjie.com chekuaipai.com -chelaike.com chelajanitorial.com chelangauto.com chelifang.com @@ -20739,7 +20678,6 @@ chengfengboli.com chengfengerlai.com chenggnet.com chenggongguiji.com -chengguw.com chenghai.cc chenghct.com chenghen.com @@ -20862,6 +20800,7 @@ chenyou123.com chenyu.me chenyudong.com chenyuemz.com +chenyuwulian.com chenyyds.com chenzao.com chenzhicheng.com @@ -22023,7 +21962,6 @@ chinatiredealer.com chinatla.com chinatlzm.com chinatmco.com -chinatmic.com chinatongjia.com chinatopbrands.net chinatoplon.com @@ -22716,6 +22654,7 @@ cibonet.com cibresearch.com cibuser.com cic-js.com +cicadayun.com cicaf.com cicba.net cicc.com @@ -23022,7 +22961,6 @@ cjjnff.com cjjygr.com cjk3d.net cjkhd.com -cjkiexpo.org cjkihgroup.com cjkjks.com cjkt.com @@ -23548,7 +23486,6 @@ cmiotcd.com cmiyu.com cmjz.net cmlog.com -cmlong.com cmltzz.com cmmaap.com cmmchn.com @@ -23674,6 +23611,7 @@ cn-zhentai.com cn-zhongrui.com cn.bing.com cn.bing.net +cn.eset.com cn.mm.bing.net cn.net cn.online.standardchartered.com @@ -24093,7 +24031,6 @@ cniiib.com cnimg.elex.com cnimporter.com cninfo.net -cninfos.com cninj.com cninnovatel.com cninsure.net @@ -24170,7 +24107,6 @@ cnkgraph.com cnkh.com cnki.net cnki.vip -cnkibk.com cnkicheck.info cnkidoi.com cnkidoi.net @@ -24285,7 +24221,6 @@ cnns.net cnntzr.com cnnuo.com cnnx.net -cnobol.com cnod.net cnoddt.com cnoic.com @@ -24297,7 +24232,6 @@ cnonjx.com cnonline.org cnoocengineering.com cnoocltd.com -cnookr.com cnool.net cnopendata.com cnops.xyz @@ -24500,7 +24434,6 @@ cntries.com cntronics.com cntslawfirm.com cntuw.com -cntv-5.com cntv.com cntvan.com cntwg.com @@ -24879,6 +24812,7 @@ cometagame.com comeyes.com comflowy.com comfolite.com +comfylink.com comiai.com comic520.com comicdd.com @@ -25328,7 +25262,6 @@ cqbondrite.com cqbosai.com cqbshyy.com cqbwjc.net -cqbygg.com cqbys.com cqc-ts.com cqc.so @@ -25394,7 +25327,6 @@ cqdky.com cqdongnanhospital.com cqdongyang.com cqdpt.com -cqdqsy.com cqdting.com cqduoliu.com cqdzw.com @@ -25543,7 +25475,6 @@ cqjizhi.com cqjj.net cqjjnet.com cqjkhb.com -cqjltx.com cqjlyy.net cqjnjs.com cqjnkgjt.com @@ -26157,7 +26088,6 @@ cs-cjl.com cs-cydq.com cs-jinwei.com cs-pos.com -cs-show.com cs-video.com cs-xf.com cs0799.com @@ -26209,6 +26139,7 @@ cscjedu.com csclc.com cscmgg.com csct-china.com +cscxsemi.com csd568.com csdc.info csdczx.com @@ -26861,7 +26792,6 @@ cxmt.com cxmtc.net cxnyjt.com cxnykjy.com -cxorg.com cxory.com cxpharm.com cxqex.com @@ -27068,7 +26998,6 @@ czbanbantong.com czbank.com czbcpaint.com czbq.net -czbsfx.com czbtv.com czbx18.com czcarbon.com @@ -27230,7 +27159,6 @@ d.cg d.design d00.net d03jd.com -d0efbrm.xyz d163.net d17.cc d1cm.com @@ -27442,7 +27370,6 @@ dahuatech.com dahuawang.com dahuhg.com dahuifuwu.com -dahulu.com dahunet.com dahuodong.com dai-shi.com @@ -27462,6 +27389,7 @@ daidongxi.com daief.tech daigege.com daigou.com +daigraphia.com daihaobiao.com daihing.com daijuchuang.net @@ -27784,7 +27712,6 @@ daokers.com daokeyuedu.com daokoudai.com daomengad.com -daomengg.com daomengren.com daomicfo.com daomuol.com @@ -27904,7 +27831,6 @@ datadragon.net dataduoduo.com dataesb.com dataeye.com -datafocus.ai datafun.vip datag.vip datagear.tech @@ -28005,7 +27931,6 @@ daxuejia.com daxuejiayou.com daxuelu.com daxuepc.com -daxueshi.com daxuesoutijiang.com daxuetian.com daxuewang.com @@ -28062,6 +27987,7 @@ dayiwater.com dayong.name dayoo.com dayrui.com +dayscamera.com daysou.com dayspringpharma.com dayss.com @@ -28199,8 +28125,14 @@ dckygroup.com dcloud.io dcloud.xin dcloudlive.com +dcloudlive.net dclouds.cloud +dcloudsp.com +dcloudsp.net dcloudstc.com +dcloudstc.net +dcloudvod.com +dcloudvod.net dclygroup.com dcmagcn.com dcmk17.com @@ -28431,7 +28363,6 @@ deepermobile.com deepfast.com deepin-ai.com deepin.com -deepin.io deepin.org deepinghost.com deepinmind.com @@ -28476,7 +28407,6 @@ deheheng.com deheng.com dehengclinic.com dehenglaw.com -dehongtech.com dehsm.com dehua.net dehuaca.com @@ -28826,7 +28756,6 @@ dg-dx.com dg-hanxin.com dg-mall.com dg-niuniu.com -dg-paas.com dg-tcm.com dg11185.com dg121.com @@ -29340,7 +29269,6 @@ dijianggroup.com dijingchao.com dijiuban.com dijiuke.com -dijunsm.com dikalon.com dikeqc.com dili360.com @@ -31667,7 +31595,6 @@ e0514.com e0575.com e0734.com e0838.com -e0hhk12.xyz e12345.com e1288.com e1299.com @@ -32209,7 +32136,6 @@ edlcaster.com edmcn.net edmseller.com edns.com -edo-bijiben.com edojia.com edong.com edongeejiao.com @@ -32269,7 +32195,6 @@ edujianshe.com edujiaoyu.com edukuang.com edulawonline.com -eduli.net edumail.pub edumine.net edumq.com @@ -32592,7 +32517,6 @@ ejustcn.com ejy365.com ek-edu.com ek1ng.com -ekaid.com ekaidian.com ekan001.com ekang99.com @@ -33181,7 +33105,6 @@ esdxcg.com esemseo.com esenagro.com esensoft.com -esfimg.com esgforum.com esgz.com eshangle.com @@ -33445,7 +33368,6 @@ event.msi.com eventown.com eveqbow.xyz ever9527.com -everbox.com everbox.net everbright.com everbright21.com @@ -33823,7 +33745,6 @@ f315.cc f32365.com f3322.net f3322.org -f3knp1j.xyz f41g.com f526.cc f52o04oylrbmfw.com @@ -34154,7 +34075,6 @@ fanqiesdkpic.com fanqiesdkstatic.com fanqiesdkvod.com fanqietianqi.com -fanqietuan.com fanqievv.com fanqiewin10.com fanqiexitong.com @@ -34227,7 +34147,6 @@ fanyu.com fanyu.work fanyuip.com fanzehua.com -fanzhanqun.com fanzhidu.com fanzhiyang.com fapharm.com @@ -34572,7 +34491,6 @@ feidee.com feidee.net feidi.com feidiao.com -feidieshuo.cc feidou.com feie.work feierlaiedu.com @@ -35836,6 +35754,7 @@ fou.net foumobile.com founder.com founder.net +founderaipu.com founderbn.com founderchip.com foundereagle.com @@ -36121,7 +36040,6 @@ fscjkj.net fscm.tech fscmjt.com fscsps.com -fsdaton.com fsdxzhpt.com fsecity.com fseig.com @@ -36439,7 +36357,6 @@ funvba.com funwear.com funxun.com funyard-hotels.com -funyqq.com funzm.com fupanwang.com fupin832.com @@ -36479,7 +36396,6 @@ futunn.com future-sh.com futureengineer.org futureprize.org -futurescircle.com futurescontest.com futustatic.com fututools.com @@ -36838,6 +36754,7 @@ g-medon.com g-spin.com g-tar.com g-var.com +g00gle.vip g052m43e2ghn.com g1080.com g12345.com @@ -36867,7 +36784,6 @@ g59p.com g5h4.com g5kj.com g66667777.com -g6a7qkh.xyz g77775555.com g77776666.com g80mx.com @@ -37076,7 +36992,6 @@ gangyu.org gangyuan.com ganhao.vip ganhuoche.com -ganhuodaquan.com ganji.com ganjiangrc.com ganjiangvpn.com @@ -38080,7 +37995,6 @@ gemelai.com gemii.cc gemini-galaxy.com gemini530.net -geminight.com gemjz.com gemled-tech.com gempharmatech.com @@ -39203,7 +39117,6 @@ gogofly.com gogokid.com gogolinux.com gogooffer.com -gogopzh.com gogoqq.com gogoup.com goherbalfood.com @@ -39224,7 +39137,6 @@ gokuai.com golang8.com golangapi.com golanger.com -golanghome.com golangroadmap.com golangw.com golaravel.com @@ -40243,7 +40155,6 @@ guanguser.com guangwaifu.com guangwei.com guangxi910.com -guangxibaobao.com guangxibiaoxie.com guangxicarbon.com guangxichunhui.com @@ -40611,7 +40522,6 @@ guolannewmaterial.com guole.fun guoli.com guolianchem.com -guoliangjie.com guolianglab.org guolin.tech guolisec.com @@ -40640,7 +40550,6 @@ guoqi365.com guoqinwang.com guorentao.com guorongfei.com -guoruiinfo.com guoruijx.com guoshengtech.com guoshi.com @@ -40986,7 +40895,6 @@ gxchengyun.com gxchlrf.com gxchr.com gxchuanghua.com -gxchuangrong.com gxchuanlan.com gxchuen.com gxchunmao.com @@ -41505,7 +41413,6 @@ gxhztqt.com gxhzxk.com gxhzxw.com gxhzyd.com -gxhzzgx.com gxi.ink gxiang.org gxibvc.net @@ -41585,7 +41492,6 @@ gxjigeyuan.com gxjihu.com gxjinan.com gxjingsheng.com -gxjingu.com gxjinhai.com gxjinhuiauto.com gxjinjiang.com @@ -41605,7 +41511,6 @@ gxjjfds.com gxjjfjt.com gxjjgy.com gxjjh.com -gxjjjs.com gxjjyb.com gxjkamc.com gxjkhj.com @@ -42096,7 +42001,6 @@ gxrasafety.com gxrayhome.com gxrc.com gxrcda.com -gxrcdl.com gxrcgs.com gxrcosta.com gxrcpx.com @@ -42120,7 +42024,6 @@ gxrnzb.com gxroad.com gxrongpin.com gxrongwang.com -gxrongxin.com gxrqsjhz.com gxrsjc.com gxrskyy.com @@ -42575,7 +42478,6 @@ gxylct.com gxyldfyy.com gxylgyx.com gxylink.com -gxyljd.com gxyljf.com gxyllc.com gxylms.com @@ -43051,7 +42953,6 @@ gzgcg.com gzgdkq.com gzgdwl.com gzgelandi.com -gzgema.com gzghic.com gzghyy.com gzgj.net @@ -43518,7 +43419,6 @@ h-zl.net h0588.com h0591.com h0758.net -h0fmfp3.xyz h12.net h12345.com h128.com @@ -43650,6 +43550,7 @@ haeye.net hafei.com hafuyoufk.com hagaozhong.com +hagibis.com haguan.com haguworld.com haha168.com @@ -43736,7 +43637,6 @@ haigoose.com haigouyan.com haigugroup.com haigui001.com -haihelashes.com haihepharma.com haihetour.com haihuainternational.com @@ -44529,7 +44429,6 @@ haowusong.com haowutuijian.com haowuyunji.com haoxg.net -haoxiake.com haoxiana.com haoxiangmachine.com haoxiangyundong.com @@ -45705,7 +45604,6 @@ hellobanma.com hellobi.com hellobike.com hellobiye.com -hellobtc.com hellocq.com hellocq.net hellodive.com @@ -45929,7 +45827,10 @@ herllamo-med.com herllamo.com hermod1.com hero-geek.com +hero.com herocoming.com +heroesports.com +herogame.com herohr.net heroic-ltd.com heroje.com @@ -45979,7 +45880,6 @@ heu8.com heungkong.com heuvan.com hewaner.com -hewanyao.com hewascreen.com heweather.com heweather.net @@ -46036,7 +45936,6 @@ heyix.com heymeo.net heymeowfm.com heymore.com -heymuer.com heyou51.com heyplus.com heyria.com @@ -46226,7 +46125,6 @@ hgk-group.com hglaser.com hgmai.com hgmri.com -hgmsjt.cc hgnc.net hgo06070uyi.com hgo06071uyi.com @@ -47044,7 +46942,6 @@ hmqjsb.com hmrczp.com hmreuj.com hmrsrc.com -hmsem.com hmsemi.com hmszkj.com hmtgo.com @@ -47539,7 +47436,6 @@ hobbyboss.com hobosgroup.com hocheymed.com hochitech.com -hockinghillshomestead.com hocode.com hocodo.com hodgen-china.com @@ -47621,7 +47517,6 @@ homekoocdn.com homelandhotel.com homelandol.com homesir110.com -hometeda.com hometex114.com hometexjoin.com hometexnet.com @@ -47758,7 +47653,6 @@ hongshang-led.com hongsheng-group.com hongshi88.com hongshigroup.com -hongshikai.com hongshipaint.com hongshizi.org hongshn.xyz @@ -49331,7 +49225,6 @@ huifengzhuzao.com huifenqi.com huifu.com huifudashi.com -huifuhuo.com huifusihai.com huifutz.com huifuzhinan.com @@ -49427,6 +49320,7 @@ huinkj.net huion.com huiqia.net huiqianfan.com +huiqibaike.com huiqiyidiantong.com huiqiyu.com huiqk.com @@ -49720,6 +49614,7 @@ huohuacdn.com huohuahudong.com huohudun.com huohuo.com +huoideas.com huoji.com huojiaba.com huojitui.com @@ -49843,6 +49738,7 @@ hutaow.com hutegy.com hutew.com hutong-school.com +hutong360.com hutongcdn.com hutoufeng.net hutui9.com @@ -50103,13 +49999,11 @@ hxtk.com hxtrip.com hxtxxw.com hxtzgroup.com -hxweb.net hxwglm.com hxwzhs.com hxx.net hxxkw.org hxxl6.com -hxycxx.com hxyd.cc hxydup.com hxyjw.com @@ -50151,7 +50045,6 @@ hybase.com hybbs.net hybbtree.com hybssy.com -hybzm.com hyc.com hyccw.com hycdn.com @@ -51504,7 +51397,6 @@ idocv.com idodb.com idol001.com idolmoba.com -idolyx.com idom.me idong.ren idongde.com @@ -51989,7 +51881,6 @@ ijingdi.com ijinshan.com ijinzhuan.com ijishu.cc -ijiujiao.com ijiwei.com ijiwen.com ijizhi.com @@ -52317,7 +52208,6 @@ imlianai.com imliuyi.com imlizhi.com immeee.com -immersivetranslate.com immfast.com immi520.com immiexpo.com @@ -52494,7 +52384,6 @@ inferoey.com infertilitybridge.com infimotion.com infineon-autoeco.com -infineon.com infini-ai.com infinisign.com infinitescript.com @@ -52540,7 +52429,6 @@ infuseku.xyz infyniclick.com infzm.com ing10bbs.com -ing2ing.com ingageapp.com ingags.com ingaoyt.biz @@ -52569,6 +52457,7 @@ initialview.com initjj.com initkk.com initpp.com +initqq.com initroot.com initrr.com initvv.com @@ -52780,7 +52669,6 @@ ioneball.com ionewu.com iongentherapeutics.com iooeoo.com -iooiooi.com iooqoo.com ioozu.com iopenhec.com @@ -52831,7 +52719,6 @@ iotxx.com iotyeas.com iotyes.com iouluo.com -iovia-pmj.com ioxray.com ioxunyun.com ip-cdn.com @@ -53172,7 +53059,6 @@ ishowchina.com ishowx.com ishubao.org ishugui.com -ishuhui.com ishuhui.net ishuirong.com ishuiyun.com @@ -53621,7 +53507,6 @@ iwanbei.com iwanboy.com iwangding.com iwangnan.com -iwangzha.com iwanoutdoor.com iwanshow.com iwanws.com @@ -54565,7 +54450,6 @@ jh-dzcl.com jh-sh.com jh-trace.com jh-uav.com -jh011.com jh0516.com jh3737.com jh3j.com @@ -54945,7 +54829,6 @@ jianpu99.net jianpuku.com jianpuw.com jianq.com -jianqi88.net jianqiaochina.com jianqimao.com jianqiyl.com @@ -55109,6 +54992,7 @@ jiawuzi.com jiaxianggame.com jiaxianghudong.com jiaxiangxm.com +jiaxiao.pub jiaxiao100.com jiaxiaozhijia.com jiaxiaozhilian.com @@ -55775,7 +55659,6 @@ jinmixuetang.com jinmogame.com jinmuinfo.com jinnong.cc -jinnun.com jinpacs.com jinpai365.com jinpanlab.com @@ -55800,7 +55683,6 @@ jinquanpharm.com jinqunla.com jinr.com jinri.red -jinridandong.com jinridiaoyu.com jinriguanzhu.cc jinrilife.com @@ -56243,7 +56125,6 @@ jizhida.com jizhihd.com jizhihezi.com jizhimobi.com -jizhiyingxiao.net jizhiyouke.com jizhouyoupin.com jizhuba.com @@ -56745,7 +56626,6 @@ jnxtzdh.com jnxydefsxx.com jnyczx.com jnydgm.com -jnyjfdz.com jnyng.com jnyyjt.com jnzcsyj.com @@ -56829,7 +56709,6 @@ jocund-gift.com jodoll.com joe92.com joessem.com -jogjamedianet.com johhan.com johnlz.com johnmedia.com @@ -57911,6 +57790,7 @@ juexiaotime.com juexinw.com jueywo.com jufa-composite.com +jufa.vip jufaanli.com jufair.com jufeng313.com @@ -58831,7 +58711,6 @@ k913.com k99.cc ka20.com ka5188.com -kaa88888.cc kaaass.net kaadas.com kaayou.com @@ -59426,7 +59305,6 @@ kedaifu.com kedang.net kedanm.com kedaotech.com -kedayikao.com kede-auto.com kede.com kedefamen.com @@ -60134,7 +60012,6 @@ kltpump.com klub11.com klv5qu.com klvtu.com -klwt.net klwxq.com klx-tech.com klxksci.com @@ -60315,6 +60192,7 @@ kongduan.com kongfz.com kongge.com kongjianjia.com +kongjibusiness.com kongjie.com kongjieshijie.com kongjitang.com @@ -60323,7 +60201,6 @@ kongkangroup.com konglei.com konglonggu.com kongming-inc.com -kongmt.com kongqinengrebeng.com kongquecheng.com kongqueyuzd.cc @@ -61386,7 +61263,6 @@ laiqy.com laird-tek.com laisai.com laisesupply.com -laishikouqiang.com laishui.info laisizuji.com laisj.com @@ -61408,6 +61284,7 @@ laixuexi.cc laiyagushi.com laiye.com laiyifen.com +laiyincat.com laiyouhui.net laiyouxi.com laiytech.com @@ -61870,6 +61747,7 @@ law-wei.com law01.net law6888.com lawasst.com +lawaxi.net lawbang.com lawbridge.org lawbus.net @@ -61968,6 +61846,7 @@ lbsrmyy.com lbswjt.com lbszx.com lbtek.com +lbu.cc lbv1.com lbwbw.com lbx777.com @@ -62334,6 +62213,7 @@ lei001.com leiaomold.com leibei.cc leiboyiqi.com +leidacj.com leidianip.com leifengshi120.com leigod.com @@ -63105,7 +62985,6 @@ lifediary.shop lifeeu.com lifegc.com lifegreenmedical.com -lifeinjungle.com lifeng.in lifengshoe.com lifeofguangzhou.com @@ -63321,6 +63200,7 @@ lingla.com linglingkaimen.com linglingmo.site linglong.dev +linglong.space linglongart.com linglonglife.com linglongtech.com @@ -63800,6 +63680,7 @@ liuxuekw.com liuxueshijie.com liuxuesmd.com liuxuetown.com +liuxuewind.com liuxueyun.com liuxuezx.com liuxx.com @@ -63812,7 +63693,6 @@ liuyiguo.com liuyimin4.com liuyixiang.com liuyua.xyz -liuyuechuan.com liuyunliumeng.com liuyuntian.com liuzaoqi.com @@ -63875,7 +63755,6 @@ liwuzhi.art lixcx.com lixfaf.com lixiaedu.com -lixianedu.net lixiang.com lixiangcaifu.com lixianghuanbao.com @@ -63973,7 +63852,6 @@ ljhjgc.com ljhjny.com ljia.com ljia.net -ljimg.com ljjcyy.com ljjhfw34.fun ljjlb.net @@ -63990,7 +63868,6 @@ ljmeng.site ljmyy120.com ljqhju.com ljqxjjhbc.com -ljraj.com ljrbw.com ljs.fun ljsdk.com @@ -64438,7 +64315,6 @@ longsan.com longshanchemical.com longshangrc.com longsheng.com -longsheng.pw longsheng988.com longshine.com longsok.com @@ -64512,7 +64388,6 @@ lookao.com lookbaby.com lookbravo.com lookchem.com -lookfor.one lookgame.com looking-car.com lookr.cc @@ -64729,7 +64604,6 @@ lrswl.com lrt-tech.com lrts.me lrvin.com -lrwxjji.com ls-doll.com ls-gb.com ls-hospital.com @@ -64841,7 +64715,6 @@ lsxnm.com lsxrmtzx.com lsxuantong.com lsxxkj.net -lsxz.org lsyart.com lsyhh.com lsys2002.com @@ -65192,7 +65065,6 @@ luxiangba.com luxiangdong.com luxiangwu.net luxianpo.com -luxiao.com luxiaoche.com luxichemical.com luxiwang.com @@ -65573,6 +65445,7 @@ lyjyjt.com lyjys.com lylangchao.com lyldhg.com +lylend.com lylhkq.com lylme.com lylxjxc.com @@ -65623,7 +65496,6 @@ lysyzx.com lyszls.com lyszxyy.com lythw.com -lytning.xyz lytoufang.com lytpw.com lytq.com @@ -65634,7 +65506,6 @@ lyunweb.com lyunx.com lyvnee.com lywanban.com -lywdm.com lywenlv.com lywf.me lywhxy.com @@ -65954,7 +65825,6 @@ ma.run ma3office.com ma3you.com ma5000.com -ma6zlvb.xyz maa.plus maanhui.com maasdk.com @@ -66234,6 +66104,7 @@ maka.mobi makaevent.com makaidong.com makaiqian.com +make-w0rld-static.club makeapp.co makeblock.com makecn.net @@ -66354,6 +66225,7 @@ mangxia.com mangxuewang.com mangzhongbrand.com mangzitian.com +mangzx.com manhinggroup.com manhua1.com manhua365.com @@ -66460,7 +66332,6 @@ maopaoya.com maopuyouxi.com maoqitian.com maoqiumail.com -maoshanf.com maoshanger.com maotao.net maotiangroup.com @@ -66582,7 +66453,6 @@ mashiro.me mashrabiya-screen.com masiao.com masikkk.com -masinen.com masjfc.com masjinquan.com maslink.com @@ -66803,7 +66673,6 @@ mc-test.com mc-user.com mc-xborder.com mc.cc -mc1314.com mc520.com mc91.com mc9y.net @@ -67559,7 +67428,6 @@ mevionchina.com mew.fun mewx.art mexicopanama.com -meximexi.me mexingroup.com mexontec.net mexxum.com @@ -67813,7 +67681,6 @@ micang.com micblo.com mice-gz.org micecn.com -michael-j.net michaelapp.com michoi.com michong.com @@ -68790,6 +68657,7 @@ mofangshe.com mofangwang.com mofangyu.com mofanodes.com +mofashi.ltd mofavideo.com mofazhu.com moffettai.com @@ -69415,7 +69283,6 @@ muchunkang.com mudanauto.com mudgj.com mudiaotx.com -mudijigou.com mudongguang.com mudotarot.com mudu.com @@ -69555,6 +69422,7 @@ mvoicer.com mvote.net mvpdj.com mvpmeta.com +mvpmob.com mvprpg.com mvpsky.com mvs-intel.com @@ -69574,8 +69442,6 @@ mwcname.com mweda.com mwemp.com mwjournalchina.com -mwjpk.com -mwkhjc.com mwrf.net mwrfabc.com mwstore.com @@ -69617,7 +69483,6 @@ mxitie.com mxitres.com mxj.cx mxjd.com -mxjsjx.com mxjtedu.com mxjyxx.com mxk.cc @@ -70151,6 +70016,7 @@ naifei.pro naifenzhiku.com naijian.net nail-auto.com +nails7.com naimal.com naimei.com naipan.com @@ -70211,7 +70077,6 @@ nanchigroup.com nanchu.com nanchunhz.com nandaauto.com -nandagang.cc nandasoft-its.com nandasoft.com nandiu.com @@ -70343,7 +70208,6 @@ naozhong.net naozhong.org napengzn.com napiantian.com -napthetocchien.com naqing-tech.com naquan.com naquan.org @@ -70354,7 +70218,6 @@ narcissoshotel.com naris-china.com narkii.com narochina.com -narrowad.com naruto.red narwal.com narwaltech.com @@ -70372,7 +70235,6 @@ naslab.club nastcorp.com nasyeo.com nasyun.com -nasyy.com nat123.com natachem.com natapp.cc @@ -70556,7 +70418,6 @@ nbuser.com nbvps.net nbwaf.net nbwan.net -nbwb.net nbwbw.com nbweldingtorch.com nbwelldon.com @@ -71187,6 +71048,7 @@ niaocms.com niaogebiji.com niaola.com niaoquan.fun +niaosuangao.online niaowoclub.com niaoyun.com niba.com @@ -71446,6 +71308,7 @@ nj-qiyiguo.net nj-reagent.com nj-ss.com nj-tencentclb.cloud +nj-tencentclb.com nj-test.com nj-tongrentang.com nj-tops.com @@ -71839,7 +71702,6 @@ njtrq.com njtst.com njuchem.com njued.com -njuftp.org njuoe.com njupco.com njust.pub @@ -72261,7 +72123,6 @@ nnpml.com nnpnzx.com nnpp.vip nnpurapple.com -nnqbhb.com nnqh.net nnqianfan.com nnqmjy.com @@ -72293,7 +72154,6 @@ nnshenghua.com nnshzhg.com nnsirui.com nnsjcgs.com -nnsjl.com nnslx.com nnslzy.com nnsmk.com @@ -72508,7 +72368,6 @@ noops.me nooshen.com nootoo.com nooxion.com -nopis.org noposion.com nor-land.com noratechpharma.com @@ -72743,7 +72602,6 @@ ntdingke.com ntdjk.com ntdsyy.com ntdvf.com -ntefyxq.com ntes53.com ntesmail.com ntesunn.com @@ -73036,7 +72894,6 @@ nziku.com nzkd.com nzlw.com nzmice.com -nzpzi0y.xyz nzqyowk.com nzrlzy.com nzsensing.com @@ -73172,6 +73029,7 @@ ocn187.com ocnttv.com ocpuritech.com ocsjs.com +ocssaas.com oct-asia.com oct-cts.com octbay.com @@ -73326,6 +73184,7 @@ ojidacp.com ojkjt.com ojpal.com ok-meeting.com +ok-skins.com ok0415.com ok06.com ok096.com @@ -73689,7 +73548,6 @@ opatseg.com opcool.com opdown.com opectek.com -open-adx.com open-ct.com open-douyin.com open-falcon.com @@ -73755,6 +73613,7 @@ openwbs.com openwrt.ai openwrt.pro openxiaoniu.com +openxsea.com operachina.com operatorcom.com opfed.com @@ -73992,7 +73851,6 @@ otpub.com otqyzk7mx2t8.com ott4china.com ottai.com -ottclub.com ottcn.com ottcn.help ottffss.net @@ -74000,7 +73858,6 @@ ottshopping.net ottssp.com otype.com ou163.com -ou45ehw.xyz ou99.com ouapi.com oubauneereid.com @@ -74046,7 +73903,6 @@ ouou.com ouou.icu ououbet.com ouougo.com -oupa-tech.com oupaigroup.com oupeng.com oupeng9.com @@ -74551,7 +74407,6 @@ paopaosz.com paopaozd.com paoshuba.cc paoshuba.org -paoxq.com paoxue.com paozhengtong.com paozw.org @@ -74701,7 +74556,6 @@ pbtsl.com pbtt.net pbtxt.com pbyz.net -pbzhl.com pc-120.com pc-daily.com pc.wiki @@ -74939,7 +74793,6 @@ peiyou.com peiyouwang.com peiyue.com peizi.com -pejgzc.com pejxjy.com pekhongyuan.com peksung.com @@ -75549,7 +75402,6 @@ pj.com pj39800.com pj50.com pj57.com -pjb9gv9.xyz pjbest.com pjcn.org pjf.name @@ -75562,6 +75414,7 @@ pjjyzx.com pjlyds.com pjob.net pjtime.com +pjtka.com pk106.com pk137.com pk2234.com @@ -75682,6 +75535,7 @@ playwonderful.com playwxgame.com playyx.com playzy.com +plb1.com plbig.com plc100.com plc11.com @@ -75775,7 +75629,6 @@ pmxsd.com pmyes.com pmyuanxing.com pn1waq.com -pn7yv9y.xyz pnetp.org pnfang.com pnfq.com @@ -75785,7 +75638,6 @@ pngsucai.com pnol.net pnst8.com pntagkyy.com -pntagsyy.com pntkyy.com pntryy.com pnty1688.com @@ -76029,7 +75881,6 @@ pp373.com pp51.com pp540.com pp63.com -pp77.com pp8.com pp918.com pp9l.com @@ -76351,7 +76202,6 @@ ptfe-rod.com ptfish.com ptfish.org ptgcn.com -pthb668.com pthceshi.com pthejzb.com pthksw.com @@ -76790,7 +76640,6 @@ qcenglish.com qcgm.net qcgq168.com qchcm.com -qcheng.cc qches.com qchouses.com qchxt.com @@ -77399,6 +77248,7 @@ qiaohumall.com qiaoji8.com qiaojiamuxian.com qiaojiang.tv +qiaolianyimin.com qiaolishuiwu.com qiaomaren.com qiaomi.com @@ -77693,6 +77543,7 @@ qingdouw.com qingf001.com qingfanqie.com qingfeichina.com +qingfengchuxing.com qingfengjiaoyu.com qingflow.com qingfo.com @@ -77768,7 +77619,6 @@ qingrenw.com qingruanit.net qingruyun.com qingshanpaper.com -qingshanzl.com qingshigame.com qingshou.online qingshow.net @@ -77916,7 +77766,6 @@ qiqjc.com qiqu.cc qiquanwl.com qiquha.com -qiquhudong.com qiqumaker.com qiquw.info qiquwen.com @@ -78203,6 +78052,7 @@ qlxiaozhan.com qlxyedu.com qlxzj.com qlydw.com +qlyjt.com qlyygl.com qlyyqd.com qlzygs.com @@ -78514,7 +78364,6 @@ qrzxx.com qs-jt.net qs12315.com qs5.org -qs71lc6.xyz qs921.com qsap-group.com qsbank.cc @@ -78567,6 +78416,7 @@ qszs.com qszt.com qszt.net qt-edu.com +qt.com qt119.com qt56yun.com qt6.com @@ -79015,6 +78865,7 @@ quickpark.cc quicksdk.com quicksdk.net quickswan.com +quicktvui.com quickwis.com quilimen.com quimg.com @@ -79252,7 +79103,6 @@ qxw18.com qxwoiv.com qxwz.com qxxsjk.com -qxxzf.com qxy777.com qxycy.com qxyjssb.com @@ -80277,6 +80127,7 @@ rikua.com rili11.com rilijingling.com rilingpec.com +riliri.com rilvtong.com rim20.com rimaiwang.com @@ -80368,6 +80219,7 @@ rjfeng.com rjghome.com rjh0.com rjhcsoft.com +rjitxy.com rjlqq.com rjoy.com rjpharm.com @@ -80624,7 +80476,6 @@ root1111.com rootcloud.com rootguide.org rootintech.com -rootop.org rootopen.com rootzhushou.com roouoo.com @@ -80714,7 +80565,6 @@ rrbjt.com rrbus.com rrchem.com rrcimg.com -rrdiaoyu.com rrdtz.com rrfccx.com rrfed.com @@ -81507,7 +81357,6 @@ sangfor.org sangforcloud.com sangfordns.com sangle.com -sanglianju.com sangmifort.com sangon.com sangongzai.net @@ -82108,6 +81957,7 @@ sclanyingkj.com sclf.org sclive.net scll.cc +scloudgda.com sclrjc.com sclsnk.com sclssz.com @@ -82673,6 +82523,7 @@ sdstet.com sdstg.com sdstrong.com sdstslyy.com +sdstudy.vip sdswitch.com sdswtz.com sdsxwz.net @@ -83525,7 +83376,6 @@ shandonglanhua.com shandongqinuo.com shandongruyi.com shandongsannong.com -shandongtianmai.com shandongyunpin.com shandw.com shanedit.com @@ -83890,7 +83740,6 @@ shavingbrush-china.com shavpn.amd.com shavpn2.amd.com shawdo.com -shawdubie.com shawnzeng.com shaxian.biz shayugg.com @@ -84048,6 +83897,7 @@ shelterdome.net shelwee.com shen-grh.com shen-nao.com +shen-xi.com shen321.com shenanhui.com shenbabao.com @@ -84417,7 +84267,6 @@ shicaidai.com shicaizhanlan.com shicaotangchina.com shicehao.com -shichang.biz shichangbu.com shichengbao.com shichengyi.com @@ -84513,7 +84362,6 @@ shikelang.cc shikongdaoyu.com shiku.co shilehui.com -shileizcc.com shileizuji.com shilian.com shilian.net @@ -85609,6 +85457,7 @@ shyuwl.com shyuzhai.com shywly.com shyx-bio.com +shyxhy.com shyxi5.com shyxwz.com shyy6688.com @@ -85884,7 +85733,6 @@ sinadaxue.com sinaedge.com sinaemc.com sinaft.com -sinaif.com sinaimg.com sinajs.com sinalog.com @@ -85894,7 +85742,6 @@ sinanet.com sinanya.com sinaquyong.com sinas3.com -sinas3.net sinashow.com sinastorage.com sinasws.com @@ -85919,7 +85766,6 @@ sinforcon.com sinfotek.com singaporepaya.com singbon.com -singcareful.com singchy.com singdown.com singfosolar.com @@ -85960,7 +85806,6 @@ sino-life.com sino-manager.com sino-pharm.com sino-pigment.com -sino-rainbow.cc sino-sfcc.com sino-tcm.com sino-trading.com @@ -87404,7 +87249,6 @@ soukuyou.com soulapp.me soulgame.mobi soulsky.net -soultravels.com soulu365.com souluo.net souluojie.com @@ -87761,7 +87605,6 @@ srw00.com srworld.net srx3.net srxiayunbusiness.com -srxjyxxw.com srxww.com srxzz.com srygz.com @@ -87902,7 +87745,6 @@ sstlp.com sswater.com sswchina.com sswl315.com -sswlfs.com ssws.tv ssxcycy.com ssxf.net @@ -88077,6 +87919,7 @@ steamboxs.com steamchina.com steamcn.com steamdd.com +steamdt.com steamhost.info steammm.com steampp.net @@ -88235,12 +88078,10 @@ sturgeonnews.com stutimes.com stvf.com stvgame.com -stvue.com stwj.com stwyxh.com stxfjs.com stxsw.com -styadmin.com stylecdn.com stylechina.com stylemafiadaily.com @@ -88358,6 +88199,7 @@ suhongzhan.com suhuikj.com suhuishou.com sui.com +sui.me suibao-jiaozhu.com suibao.com suibiji.com @@ -88502,13 +88344,11 @@ sungari1995.com sungent.com sungesoft.com sungine.com -sunglassesandgoggles.com sunglow-tec.com sungoal.org sungoedu.com sungroup-energy.com sungshu.com -sunguoqi.com sunhan.vip sunhante.com sunhepower.com @@ -88791,7 +88631,6 @@ surveyunion.com survivor99.com surwit.com suryee.com -sus33.com suseage.com sushijiameng.com sushiyanglao.com @@ -89033,7 +88872,6 @@ sxdagang.com sxddy.com sxdkj.com sxds.com -sxdygbjy.com sxdyrq.com sxdz029.com sxdzyp.com @@ -89262,7 +89100,6 @@ sybj.com sybxpu.com sybygx.com sycaijing.com -sycbbs.com sycdtz.com sychlon.com sycontroller.com @@ -89316,7 +89153,6 @@ syhsfzl.com syhsxb.com syhuayang.com syhzdj.net -syhzml.com syhzx.com syhzzf.com syiae.com @@ -89456,7 +89292,6 @@ syxzhongyi.com syyan.site syyc.com syygjs.com -syygyf.net syyjs.com syylfh.com syyqls.com @@ -89796,6 +89631,7 @@ szhaochuang.com szharmony.com szhb.org szhddq.com +szhdy.com szhdyic.com szhenglian.com szhetai.com @@ -90661,6 +90497,7 @@ tandehao.com tanewmaterial.com tang-lei.com tanganlingshi.com +tangbai.cc tangbolitangci.com tangchendoor.com tangdaoya.com @@ -90753,7 +90590,6 @@ tao-star.com tao-studio.net tao-wu.com tao008.com -tao1.co tao123.com tao3.cc tao33.com @@ -91007,7 +90843,6 @@ tayohya.com tazai.com tazhe.com tazts.com -tb.pub tb51.net tb58.net tbadc.com @@ -91020,7 +90855,6 @@ tbh5.com tbhcc.com tbhelper.com tbinq.com -tbjfw.com tbjt18.com tbjtss.com tbk-app.com @@ -91038,7 +90872,6 @@ tbqjx.com tbreeden.com tbs321.com tbsandbox.com -tbshare123.com tbsite.net tbt-tuning.com tbt168.com @@ -91200,7 +91033,6 @@ td98.com tdances.com tdatamaster.com tdbbj.com -tdbbs.net tdchats.us tdchatvip.us tddmp.com @@ -91364,6 +91196,7 @@ tedastock.com teddymobile.net tedushi.com tedx.net +tedy.cc teejia.com teeqee.com tefact.com @@ -91950,7 +91783,6 @@ thztv.net thzu.cc ti-node.com ti-solar.com -ti.com ti0s.com ti4la.icu tiamaes.com @@ -92114,7 +91946,6 @@ tianqunnet.com tianrkl.com tianrow.com tianruihr.com -tianrunjiaze.com tianrunshunteng.com tianruo.net tianruoyun.com @@ -92295,7 +92126,6 @@ tiehuatu.com tiejiang.org tiejiapai.com tiejiong.com -tiejp.com tiejunmedia.com tiekuangshi.com tielemao.com @@ -93120,6 +92950,7 @@ tooseo.com tootour.com toouoo.com top-cnc.com +top-dianjingfeng.com top-elan.com top-shanghai.com top-trust.com @@ -93586,7 +93417,6 @@ trhly.com trhos.com trhui.com trhxt.com -trickypen.com triggerdelivery.com trimmoits.com trinasolar.com @@ -93617,6 +93447,7 @@ trisfal.com tristarinc.com triton-games.com tritoninfo.net +trizenai.com trizinfo.tech trizlaser.com trizmed.com @@ -93735,7 +93566,6 @@ tscichina.com tscorona.com tsdaodao.com tsdjg.com -tsdjq.com tsdxb.com tsefang.com tses.net @@ -93951,6 +93781,7 @@ ttxsonline.com ttxuanpai.com ttxx8888.com ttyec.com +ttyfp.com ttyfund.com ttyinfo.com ttyingqiu.com @@ -94121,7 +93952,6 @@ tujiandan.com tujidu.com tujixiazai.com tujuren.com -tuke8.com tuke88.com tukeai.com tukedu.com @@ -94301,7 +94131,6 @@ tuyoujp.com tuyoumi.com tuyouvpn.com tuyouxinxi.net -tuyusheji.com tuzhan.com tuzhan.net tuzhanai.com @@ -94338,7 +94167,6 @@ tvkuai.com tvmao.com tvmcloud.com tvmining.com -tvniao.com tvoao.com tvos.com tvt.im @@ -94674,7 +94502,6 @@ u-lights.com u-link.org u-mro.com u-om.com -u-onewatch.com u-qun.com u-road.com u-softtech.com @@ -94717,9 +94544,7 @@ u72.net u7u9.com u88.com u8ad.com -u8dnv.net u8e.com -u8p2swz.xyz u8see.com u8sy.com u8yx.com @@ -94758,6 +94583,7 @@ ubibibi.com ubicdn.com ubiquant.com ubismartparcel.com +ubits.club ubixai.com ubixioe.com ubja.vip @@ -94908,6 +94734,7 @@ uewaf.com uez.com uf-crm.com uf-tobacco.com +ufancycase.com ufanw.com ufcap.com ufcs.com @@ -96074,7 +95901,6 @@ veryhappy.pw veryhuo.com veryide.com veryim.com -veryitman.com verykuai.com verym.com veryns.com @@ -96415,7 +96241,6 @@ vitagou.com vitagou.hk vitalgen.com vitalxyz.com -vitamio.net vitarn.com vitasoy-chn.com vitechliu.com @@ -96441,7 +96266,6 @@ vivosjpt.com vivotc.com vivst.com viwik.com -viwipiediema.com vixiu.com vixue.com viyouhui.com @@ -96690,7 +96514,6 @@ voycn.com vp3u.com vp6.co vpabrand.com -vpadn.com vpal.com vpalstatic.com vpanso.com @@ -96949,7 +96772,6 @@ w-e.cc w-pool.com w-zhong.com w032.com -w0512.com w0663.com w0lker.com w10a.com @@ -96958,7 +96780,6 @@ w123w.com w18.net w1989.com w218.com -w2985nq.xyz w2bc.com w2gou.com w2n5cu58rn.com @@ -96998,7 +96819,6 @@ waaku.com waakuu.com waasee.com wabcw.info -wabisabidomus.com wabuw.com wacai.com wacai365.com @@ -98554,7 +98374,6 @@ wenwo.com wenwu8.com wenwuchina.com wenxiaha.com -wenxiang.org wenxiaobai.com wenxiaoyou.com wenxiaozhan.com @@ -98572,7 +98391,6 @@ wenxuefan.net wenxuem.com wenxuemi6.com wenxuemm.com -wenxueonline.com wenxuesk.com wenxuesk.info wenxuesk.net @@ -98804,6 +98622,7 @@ wh6yy.com wh6z.com wh702g.ren whabl.net +whaee.com whafxh.org whagcg.com whairport.com @@ -98930,8 +98749,6 @@ whguanshan.com whguo.com whgwbn.net whgyt.com -whh3355.com -whh9988.com whhaifang.com whhaiyue.com whhbxh.org @@ -99074,7 +98891,6 @@ whnfc.com who.cx who2o.com whoami.akamai.net -whocool.com whoisreminder.net whoisspy.ai wholefreshposts.com @@ -99641,7 +99457,6 @@ wjinmiao.com wjjfjt.com wjjyxxw.com wjlxmedia.com -wjlyhj.com wjmh8.com wjnin.cc wjqcw.com @@ -100226,7 +100041,6 @@ woyaogexing.com woyaojiaju.com woyaoqiudai.com woyaosai.com -woyaosouti.com woyaozhan.com woying.com woyo.com @@ -100661,7 +100475,6 @@ wukaikai.tech wukao.com wukong.com wukong.la -wukongapi.com wukongbjb.com wukongkf.com wukongks.com @@ -101141,6 +100954,7 @@ wxw120.com wxwerp.com wxwjk5.com wxwmdq.com +wxworklive.com wxwtblg.com wxwzt.com wxxfltg.com @@ -101413,7 +101227,6 @@ x-tetris.com x-vsion.com x-xiangsh.com x0769.com -x0y081e.xyz x11263.com x11296.com x118.net @@ -101460,7 +101273,6 @@ x8ds.com x8sb.com x9393.com xa-bank.com -xa-expoon.com xa-online.com xa-psj.com xa.com @@ -101628,7 +101440,6 @@ xbdtly.com xbdym.com xbequge.com xbeta.info -xbetgames37.com xbext.com xbfashion.com xbfnet.com @@ -101980,7 +101791,6 @@ xftclub.com xftransa.com xfun233.com xfusion.com -xfw0594.com xfwdc.com xfwed.com xfwindow.com @@ -102403,7 +102213,6 @@ xianyugouwu.com xianyuso.com xianyuvr.com xianyuwang.com -xianyuwenhua.com xianyuyouxi.com xianzhanget.com xianzhi.net @@ -102542,7 +102351,6 @@ xiaogushi.com xiaoh.me xiaohack.org xiaohansong.com -xiaohaoyun.com xiaohe-jiankang.com xiaohe666.com xiaoheihegame.com @@ -102618,7 +102426,6 @@ xiaolanben.com xiaolangtt.com xiaolantiao.com xiaole.com -xiaoleidm.com xiaoleimob.com xiaolianbao.com xiaoliangkou.com @@ -102663,7 +102470,6 @@ xiaomape.com xiaomark.com xiaomashijia.com xiaomaxitong.com -xiaomayi.co xiaomayi.net xiaomazhixing.com xiaomei.cc @@ -103007,7 +102813,6 @@ xielijiaoyu.com xieliqun.com xiemm.com xiesk.com -xieso.net xietonghuaxue.com xiexiaoyuan.com xiexin.com @@ -103077,7 +102882,6 @@ xikoutourism.com xikrs.com xikuan.com xikuqi.com -xiladaili.com xilaijian.com xilaiping.com xilanggufen.com @@ -103350,7 +103154,6 @@ xingyao.com xingyaocq.com xingyaomob.com xingyaoss.com -xingyaox.com xingye.work xingye1.com xingyeace.com @@ -103653,7 +103456,6 @@ xinxjs.com xinxue-edu.com xinxuejy.com xinxunwang.com -xinxunwei.com xinxyun.com xinya.me xinyali.net @@ -104390,6 +104192,7 @@ xmzjtjckmy.com xmzmmr.com xmzmy.com xmzs.org +xmzsyg.site xmzwdgm.com xmzyark.com xmzzy.net @@ -104416,7 +104219,6 @@ xn--48s50dpwnbh95ah07i.com xn--4gq0d69oba129b9wd94ey8bs83ji3c3q7hoka.org xn--4gq1d760bszbgdv5p12rhq5bx2yc.net xn--4lwr21d.com -xn--4oqr35flvp.com xn--4qwqc04pn0lg9h.com xn--4xup5j.com xn--54q23ckxiyx0e.com @@ -104510,7 +104312,6 @@ xn--fiqs8s xn--fiqs8s60s3soq8cx0uohm.com xn--fiqs8sr9ge7eb4b28vo92a.com xn--fiqu59c0hf2sy.net -xn--fiqv1i07mt46b.com xn--fiqv94di0c54ipe.net xn--fiqw8jl3h7xc25m753d.link xn--fiqx7ci2whnj.com @@ -104572,6 +104373,7 @@ xn--rhqv96g xn--rht439a44bdyk.com xn--rhtr03fbrm.com xn--riqi041otpd.com +xn--rpv331d.com xn--rss237b.com xn--rss404ac6aj60e.net xn--rsss0ke5ghnj.com @@ -104600,7 +104402,6 @@ xn--vhq3m33sbqhpsmtnuxfq.com xn--vhq3mr8b802a.net xn--vhq4ut2dsxd5xqnicjxxo55a756aovhik0aunm.com xn--vhq72yfwbt0elp2cpkhtld55g73l1o6a.com -xn--vhqa63bt1h.com xn--vhqqbz2p62hm92e04p.com xn--vhqu1kbz3bnbi.com xn--vhquv @@ -104630,7 +104431,6 @@ xn--xkr999cp4fv97a.com xn--xkrs9ba41r.com xn--y6q834d2k3al4h.com xn--y8jhmm6gn.moe -xn--yet74fr8g.com xn--ygtp21bwyedsq.com xn--yhqq38bmov17mqxi.com xn--ykr169cm1pskt.com @@ -104839,7 +104639,6 @@ xsgame99.com xsgongju.com xsgrq.com xsgtvacct.com -xsh520.com xshellcn.com xshengyan.com xshenshu.com @@ -104900,7 +104699,6 @@ xsser.date xsshuku.com xsskw.com xsslyjt.com -xssyidc.com xssz.net xsteach.com xsti.net @@ -104982,7 +104780,6 @@ xtrapowercn.com xtrc.net xtrunc.com xtsfuke.com -xtsjj.net xttaff.com xttblog.com xttz.com @@ -105165,6 +104962,7 @@ xueqiu360.com xuerong.com xuesai.net xuesax.com +xuesexs.com xueshanlinghu.com xuesheng.com xueshiyun.com @@ -105643,7 +105441,6 @@ xy36z.com xy3yy.com xy58.net xy599.com -xy77.live xy980.net xyb2b.com xybch123.com @@ -105986,7 +105783,6 @@ y-feng.com y-i-y.com y-lotus.com y-os.net -y.cool y.to y007.com y0mwy.icu @@ -106477,7 +106273,6 @@ yb-able.com yb1518.com yb1867.com yb3.cc -yb505.in yb983.com yb999.com yba120.com @@ -106505,7 +106300,6 @@ ybgkz.com ybgz.com ybhdmob.com ybi.net -ybin.cc ybirds.com ybj.com ybjjsgc.com @@ -106673,7 +106467,6 @@ ycshengquan.com ycsjtjt.com ycsound.com ycsrc.com -ycsrcsc.com ycsthqrmyy.com ycsystem.com ycsyy.com @@ -106777,7 +106570,6 @@ ydtad.com ydtbl.com ydtnotary.com ydtqd.com -ydu6.com yduav.com ydwatch.com ydx2.com @@ -106945,7 +106737,6 @@ yesoulchina.com yespearl.com yespik.com yespmp.com -yespublishers.com yestar.com yestar1992.com yestarcorp.com @@ -107907,7 +107698,6 @@ yiqipaipingtai.com yiqishai.com yiqishanyuan.com yiqiso.com -yiqisooimg.com yiqisou.net yiqistore.com yiqitp.com @@ -108035,7 +107825,6 @@ yiwanzhushou.com yiwealth.com yiweb.com yiweiads.com -yiweilaogumin.com yiweishi.com yiwenyida.com yiwenyizhi.com @@ -108201,7 +107990,6 @@ yjctrip.com yjdatasos.com yjdzm.com yjegf.com -yjfl.net yjfs8.com yjfy.com yjgf.com @@ -108223,7 +108011,6 @@ yjlin4.com yjlink.cc yjliquan.com yjllq.com -yjluyun.com yjmuseum.com yjopen.com yjpal.com @@ -108558,7 +108345,6 @@ ymzsl.com ymzy.games yn-tcm-hospital.com yn-tobacco.com -yn12396.com yn2007.com yn58.com ynaec.com @@ -108613,7 +108399,6 @@ ynkcfc.com ynkgyy.com ynkm88.com ynkmit.com -ynkmjj.com ynlmsc.pw ynlygf.com ynmbwl.com @@ -109512,7 +109297,6 @@ yryz.net yrz.name yrzjw.com ys-fj.com -ys-spt.com ys.cc ys001.com ys0431.net @@ -109534,7 +109318,6 @@ ysbopet.com ysbz168.com yscase.com ysch.cc -yschn.com ysclass.net yscq.com yscro.com @@ -109940,7 +109723,6 @@ yueduwen.com yueduwu.com yueduwuxianpic.com yueduyun.com -yueduyy.com yuegongyutu.com yuegowu.com yuegui.shop @@ -110097,7 +109879,6 @@ yui06130shga.com yui06131shga.com yui06161shga.com yui06171shga.com -yuiapi.com yujia.com yujiahui.com yujianai520.com @@ -110385,6 +110166,7 @@ yunlitz.com yunliunet.com yunlsp.com yunlucn.cc +yunma99.com yunmai.com yunmayi.com yunmc.vip @@ -110464,6 +110246,7 @@ yunshow.com yunshtk.com yunshunxx.com yunshuren.com +yunshuwh.com yunsiya.com yunsom.com yunsong.com @@ -110533,6 +110316,7 @@ yunxinsvr.com yunxinvcloud.com yunxinvideo.com yunxiren.com +yunxish.com yunxiu.com yunxs.com yunxuetang.com @@ -110941,7 +110725,6 @@ yxzu.com yxzxgy.com yxzzd.com yy.com -yy07.com yy11.com yy138.com yy1690.com @@ -111284,6 +111067,7 @@ yzzxjyjt.com yzzxxz.com yzzy-online.com yzzy20-play.com +yzzy29-play.com yzzyimages.com z-bank.com z-henergy.com @@ -111440,7 +111224,6 @@ zaoqiangzhiheng.com zaowandushu.com zaowuyun.com zaoyang.org -zaoys.com zaozuo.com zapak.com zapyamobile.com @@ -112167,7 +111950,6 @@ zgsepri.com zgserver.com zgshenglu.com zgshgs.com -zgshifu.com zgshige.com zgshige.net zgshjj.com @@ -112201,7 +111983,6 @@ zgszglfh.com zgszjs.com zgtaining.com zgtcc.com -zgtcpt.shop zgtcyswh.com zgtghccl.com zgtianlong.com @@ -112222,7 +112003,6 @@ zgw.com zgweimeng.com zgwhfe.com zgwlwx.com -zgwss.com zgwstxc.com zgwt.co zgwxj.com @@ -112341,7 +112121,6 @@ zhanbanji.com zhanbuba.com zhanchenyouqi.com zhanchily.com -zhandao.net zhandaren.com zhandian88.com zhandodo.com @@ -112746,7 +112525,6 @@ zhengzhaopai.com zhengzhenxx.com zhengzhou42195.com zhengzhoubus.com -zhengzhoulvxing.com zhengzhoutools.com zhengzhoutx.com zhengzhouyunmei.com @@ -112784,6 +112562,7 @@ zhenstyle.com zhensuo.tv zhentaigroup.com zhentan.la +zhentoo.com zhenweiexpo.com zhenwu.com zhenxiad.com @@ -112801,7 +112580,6 @@ zhenyouliao.com zhenyoumei.com zhenyuansoft.com zhenyunpan.com -zhenzhi365.com zhenzhuchanfu.com zheshenet.com zhetao.com @@ -113388,6 +113166,7 @@ zhonglianguanwei.com zhongliangxny.com zhonglianhuashu.com zhonglianhuaxin.com +zhonglianyx.com zhongliusp.com zhongliuyiyuan.com zhonglue-consulting.com @@ -113561,7 +113340,6 @@ zhoulingjie.com zhoupu123.com zhoupudata.com zhouql.vip -zhoutoucg.com zhouweitong.site zhouxianghb.com zhouxiaoben.info @@ -113636,6 +113414,7 @@ zhuanhuamao.com zhuanhuanqi.com zhuanhuanqi.net zhuaniao.com +zhuaninc.com zhuankeapp.com zhuankebang.com zhuankezu.com @@ -113674,7 +113453,6 @@ zhubajie.la zhubangbang.com zhubao.com zhubao668.com -zhubaopub.com zhubaowo.com zhubian.com zhubiaoju.com @@ -113850,7 +113628,6 @@ zhuoyuechenxing.com zhuoyuegame.com zhuoyuesuoxue.com zhuoyuezhongxue.com -zhuoyunkang.com zhuozhan.com zhuozhengsoft.com zhuozhoufangchan.com @@ -113888,7 +113665,6 @@ zhuxuezi.com zhuye.kim zhuye.xyz zhuye123.com -zhuyeshouhushen.com zhuyili.org zhuyitai.com zhuyst.cc @@ -113944,7 +113720,6 @@ zhyfkj.com zhyg.org zhyi828.com zhyingxiao.com -zhyjmpwh.com zhylwx.vip zhylyy.com zhyouliang.com @@ -114496,7 +114271,6 @@ zjjinzi.com zjjizhi.com zjjjtec.com zjjky.com -zjjlfny.com zjjlvyou8264.com zjjm.net zjjmtl.com @@ -114742,7 +114516,6 @@ zjtyphoon.com zjtzcx.com zjtzedu.com zjtzwater.com -zju1.com zju88.org zjubh.com zjuers.com @@ -114823,7 +114596,6 @@ zjyonder.com zjyoutian.com zjyq.cc zjysgroup.com -zjystec.com zjytxl.com zjyxzzs.com zjyyc.com @@ -115022,7 +114794,6 @@ zly169.com zlygjzx.com zlygu.com zlysgl.com -zlyzs.com zlzlzsl.com zlzscq.com zlzt.com @@ -115091,7 +114862,6 @@ zmrenwu.com zmrmbc.xyz zmsq.com zmssh.com -zmt.me zmtc.com zmtpc.com zmtquan.com @@ -115337,6 +115107,7 @@ zpm.so zpmc.com zpmg.com zpparts.com +zppzo.com zprc.cc zpstar.com zpt966033.com @@ -115353,7 +115124,6 @@ zq84.com zqagr.com zqaqxh.com zqase.com -zqbe.net zqbubi.xyz zqbykj.com zqcaf.com @@ -115486,7 +115256,6 @@ zseoo.com zsex.ltd zsezt.com zsfund.com -zsfyedu.com zsfzjs.com zsg6.com zsgai.com @@ -116111,7 +115880,6 @@ zyan.cc zyan456.com zyanzn.com zyark.com -zyauct.com zyautoe.com zybang.com zybaoan.com @@ -116500,6 +116268,7 @@ a2.mzstatic.com a3.mzstatic.com a4.mzstatic.com a5.mzstatic.com +activation-v2.kaspersky.com adcdownload.apple.com adcdownload.apple.com.akadns.net admob-cn.com @@ -116602,6 +116371,7 @@ crashlyticsreports-pa.googleapis.com crl-lb.apple.com.akadns.net crl.apple.com crl.globalsign.net +crl.kaspersky.com crl.pki.goog crls.pki.goog csi.gstatic.com @@ -116623,6 +116393,26 @@ discussionschinese.apple.com dl.dell.com dl.google.com dl.l.google.com +dnl-00.geo.kaspersky.com +dnl-01.geo.kaspersky.com +dnl-02.geo.kaspersky.com +dnl-03.geo.kaspersky.com +dnl-04.geo.kaspersky.com +dnl-05.geo.kaspersky.com +dnl-06.geo.kaspersky.com +dnl-07.geo.kaspersky.com +dnl-08.geo.kaspersky.com +dnl-09.geo.kaspersky.com +dnl-10.geo.kaspersky.com +dnl-11.geo.kaspersky.com +dnl-12.geo.kaspersky.com +dnl-13.geo.kaspersky.com +dnl-14.geo.kaspersky.com +dnl-15.geo.kaspersky.com +dnl-16.geo.kaspersky.com +dnl-17.geo.kaspersky.com +dnl-18.geo.kaspersky.com +dnl-19.geo.kaspersky.com docs.microsoft.com doubleclick-cn.net doubleclick.net @@ -116757,6 +116547,10 @@ itunesconnect.apple.com js-cdn.music.apple.com kc.kexinshe.com km.support.apple.com +ksn-cinfo-geo.kaspersky-labs.com +ksn-file-geo.kaspersky-labs.com +ksn-url-geo.kaspersky-labs.com +ksn-verdict-geo.kaspersky-labs.com l2-uberproxy.corp.google.com learn.microsoft.com logger-dev.corp.google.com @@ -116806,7 +116600,27 @@ oscdn.origin-apple.com.akadns.net osxapps.itunes.apple.com osxapps.itunes.g.aaplimg.com p.cdn.persaas.dell.com +p00.upd.kaspersky.com +p01.upd.kaspersky.com +p02.upd.kaspersky.com +p03.upd.kaspersky.com +p04.upd.kaspersky.com +p05.upd.kaspersky.com +p06.upd.kaspersky.com +p07.upd.kaspersky.com +p08.upd.kaspersky.com +p09.upd.kaspersky.com p1-juejin.byteimg.com +p10.upd.kaspersky.com +p11.upd.kaspersky.com +p12.upd.kaspersky.com +p13.upd.kaspersky.com +p14.upd.kaspersky.com +p15.upd.kaspersky.com +p16.upd.kaspersky.com +p17.upd.kaspersky.com +p18.upd.kaspersky.com +p19.upd.kaspersky.com p2-juejin.byteimg.com p3-juejin.byteimg.com p3-novel.byteimg.com @@ -116860,7 +116674,27 @@ res-1.cdn.office.net res.cdn.office.net reserve-prime.apple.com s.mzstatic.com +s00.upd.kaspersky.com +s01.upd.kaspersky.com +s02.upd.kaspersky.com +s03.upd.kaspersky.com +s04.upd.kaspersky.com +s05.upd.kaspersky.com +s06.upd.kaspersky.com +s07.upd.kaspersky.com +s08.upd.kaspersky.com +s09.upd.kaspersky.com s1.mzstatic.com +s10.upd.kaspersky.com +s11.upd.kaspersky.com +s12.upd.kaspersky.com +s13.upd.kaspersky.com +s14.upd.kaspersky.com +s15.upd.kaspersky.com +s16.upd.kaspersky.com +s17.upd.kaspersky.com +s18.upd.kaspersky.com +s19.upd.kaspersky.com s2.mzstatic.com s3.mzstatic.com s4.mzstatic.com diff --git a/small/luci-app-homeproxy/root/etc/homeproxy/resources/china_list.ver b/small/luci-app-homeproxy/root/etc/homeproxy/resources/china_list.ver index acb36f1e7b..b0c1abd18e 100644 --- a/small/luci-app-homeproxy/root/etc/homeproxy/resources/china_list.ver +++ b/small/luci-app-homeproxy/root/etc/homeproxy/resources/china_list.ver @@ -1 +1 @@ -202510202212 +202511082212 diff --git a/small/luci-app-homeproxy/root/etc/homeproxy/resources/gfw_list.txt b/small/luci-app-homeproxy/root/etc/homeproxy/resources/gfw_list.txt index ae4b109f18..c29d0c6844 100644 --- a/small/luci-app-homeproxy/root/etc/homeproxy/resources/gfw_list.txt +++ b/small/luci-app-homeproxy/root/etc/homeproxy/resources/gfw_list.txt @@ -1273,9 +1273,7 @@ deezer.com definebabe.com deja.com delcamp.net -delicious.com demo.unlock-music.dev -democrats.org demosisto.hk deno.dev depositphotos.com @@ -1346,6 +1344,7 @@ dnvod.tv doc.new docker.com docker.io +dockerstatus.com docs.deno.com docs.new doctorvoice.org @@ -1732,6 +1731,7 @@ flagsonline.it flecheinthepeche.fr fleshbot.com fleursdeslettres.com +flexclip.com flexpool.io flgjustice.org flickr.com @@ -2649,6 +2649,7 @@ imagefap.com imageflea.com imageglass.org images-gaytube.com +images.prismic.io imageshack.us imagevenue.com imagezilla.net @@ -4752,6 +4753,7 @@ telegraph.co.uk telesco.pe tellapart.com tellme.pw +temu.com tenacy.com tenor.com tensorflow.org diff --git a/small/luci-app-homeproxy/root/etc/homeproxy/resources/gfw_list.ver b/small/luci-app-homeproxy/root/etc/homeproxy/resources/gfw_list.ver index acb36f1e7b..b0c1abd18e 100644 --- a/small/luci-app-homeproxy/root/etc/homeproxy/resources/gfw_list.ver +++ b/small/luci-app-homeproxy/root/etc/homeproxy/resources/gfw_list.ver @@ -1 +1 @@ -202510202212 +202511082212 diff --git a/small/luci-app-nikki/Makefile b/small/luci-app-nikki/Makefile index d2250572c9..6b6ca3bb2a 100644 --- a/small/luci-app-nikki/Makefile +++ b/small/luci-app-nikki/Makefile @@ -1,6 +1,6 @@ include $(TOPDIR)/rules.mk -PKG_VERSION:=1.24.3 +PKG_VERSION:=1.24.4 LUCI_TITLE:=LuCI Support for nikki LUCI_DEPENDS:=+luci-base +nikki diff --git a/small/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js b/small/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js index 36ee5cfbd5..6c1f34e5a8 100644 --- a/small/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js +++ b/small/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js @@ -249,6 +249,10 @@ return view.extend({ o.datatype = 'cidr4'; o.placeholder = _('Unmodified'); + o = s.taboption('dns', form.Value, 'fake_ip6_range', _('Fake-IP6 Range')); + o.datatype = 'cidr6'; + o.placeholder = _('Unmodified'); + o = s.taboption('dns', form.Flag, 'fake_ip_filter', _('Overwrite Fake-IP Filter')); o.rmempty = false; diff --git a/small/luci-app-nikki/po/templates/nikki.pot b/small/luci-app-nikki/po/templates/nikki.pot index 778067cb59..c52617bd46 100644 --- a/small/luci-app-nikki/po/templates/nikki.pot +++ b/small/luci-app-nikki/po/templates/nikki.pot @@ -31,7 +31,7 @@ msgstr "" msgid "Allow Lan" msgstr "" -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:263 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:267 msgid "Allow Mode" msgstr "" @@ -48,19 +48,19 @@ msgstr "" msgid "App Version" msgstr "" -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:486 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:490 msgid "Append Rule" msgstr "" -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:417 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:421 msgid "Append Rule Provider" msgstr "" -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:473 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:477 msgid "Behavior" msgstr "" -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:262 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:266 msgid "Block Mode" msgstr "" @@ -143,15 +143,15 @@ msgstr "" msgid "Debug Log" msgstr "" -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:509 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:513 msgid "Destination IP" msgstr "" -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:513 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:517 msgid "Destination IP Geo" msgstr "" -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:510 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:514 msgid "Destination Port" msgstr "" @@ -181,15 +181,15 @@ msgstr "" #: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:208 #: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:229 #: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:239 -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:268 -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:274 -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:280 -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:286 -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:292 -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:361 -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:367 -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:373 -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:560 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:272 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:278 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:284 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:290 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:296 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:365 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:371 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:377 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:565 #: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/proxy.js:38 #: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/proxy.js:45 msgid "Disable" @@ -211,32 +211,32 @@ msgstr "" msgid "Disable TCP Keep Alive" msgstr "" -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:277 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:281 msgid "DoH Prefer HTTP/3" msgstr "" -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:309 -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:504 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:313 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:508 msgid "Domain Name" msgstr "" -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:512 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:516 msgid "Domain Name Geo" msgstr "" -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:507 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:511 msgid "Domain Name Keyword" msgstr "" -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:508 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:512 msgid "Domain Name Regex" msgstr "" -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:505 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:509 msgid "Domain Name Suffix" msgstr "" -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:506 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:510 msgid "Domain Name Wildcard" msgstr "" @@ -248,27 +248,27 @@ msgstr "" msgid "Edit DNS Hijacks" msgstr "" -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:255 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:259 msgid "Edit Fake-IP Filters" msgstr "" -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:298 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:302 msgid "Edit Hosts" msgstr "" -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:340 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:344 msgid "Edit Nameserver Policies" msgstr "" -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:317 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:321 msgid "Edit Nameservers" msgstr "" -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:420 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:424 msgid "Edit Rule Providers" msgstr "" -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:489 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:493 msgid "Edit Rules" msgstr "" @@ -295,23 +295,23 @@ msgstr "" #: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:226 #: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:230 #: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:240 -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:269 -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:275 -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:281 -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:287 -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:293 -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:306 -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:325 -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:348 -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:358 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:273 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:279 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:285 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:291 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:297 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:310 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:329 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:352 #: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:362 -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:368 -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:374 -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:400 -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:428 -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:497 -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:561 -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:569 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:366 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:372 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:378 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:404 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:432 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:501 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:566 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:574 #: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/proxy.js:33 #: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/proxy.js:66 #: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/proxy.js:77 @@ -332,11 +332,11 @@ msgstr "" msgid "External Control Config" msgstr "" -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:265 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:269 msgid "Fake-IP Cache" msgstr "" -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:259 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:263 msgid "Fake-IP Filter Mode" msgstr "" @@ -348,19 +348,23 @@ msgstr "" msgid "Fake-IP Range" msgstr "" +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:252 +msgid "Fake-IP6 Range" +msgstr "" + #: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/app.js:132 msgid "Fast Reload" msgstr "" -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:467 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:471 msgid "File Format" msgstr "" -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:461 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:465 msgid "File Path" msgstr "" -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:455 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:459 msgid "File Size Limit" msgstr "" @@ -373,7 +377,7 @@ msgstr "" msgid "File:" msgstr "" -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:379 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:383 msgid "Force Sniff Domain Name" msgstr "" @@ -394,39 +398,39 @@ msgstr "" msgid "Generate & Download" msgstr "" -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:539 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:544 msgid "GeoData Loader" msgstr "" -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:533 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:538 msgid "GeoIP Format" msgstr "" -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:554 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:559 msgid "GeoIP(ASN) Url" msgstr "" -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:551 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:556 msgid "GeoIP(DAT) Url" msgstr "" -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:548 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:553 msgid "GeoIP(MMDB) Url" msgstr "" -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:545 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:550 msgid "GeoSite Url" msgstr "" -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:557 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:562 msgid "GeoX Auto Update" msgstr "" -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:531 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:536 msgid "GeoX Config" msgstr "" -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:563 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:568 msgid "GeoX Update Interval" msgstr "" @@ -478,7 +482,7 @@ msgstr "" msgid "IPv6 Proxy" msgstr "" -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:386 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:390 msgid "Ignore Sniff Domain Name" msgstr "" @@ -515,12 +519,12 @@ msgstr "" msgid "Match Process" msgstr "" -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:351 -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:515 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:355 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:519 msgid "Matcher" msgstr "" -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:543 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:548 msgid "Memory Conservative Loader" msgstr "" @@ -532,7 +536,7 @@ msgstr "" msgid "Mixin Config" msgstr "" -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:567 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:572 msgid "Mixin File Content" msgstr "" @@ -544,12 +548,12 @@ msgstr "" msgid "Mode" msgstr "" -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:434 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:438 msgid "Name" msgstr "" -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:335 -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:354 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:339 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:358 msgid "Nameserver" msgstr "" @@ -558,12 +562,12 @@ msgstr "" msgid "Nikki" msgstr "" -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:526 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:530 msgid "No Resolve" msgstr "" -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:448 -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:519 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:452 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:523 msgid "Node" msgstr "" @@ -595,35 +599,35 @@ msgstr "" msgid "Overwrite DNS Hijack" msgstr "" -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:412 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:416 msgid "Overwrite Destination" msgstr "" -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:252 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:256 msgid "Overwrite Fake-IP Filter" msgstr "" -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:376 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:380 msgid "Overwrite Force Sniff Domain Name" msgstr "" -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:295 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:299 msgid "Overwrite Hosts" msgstr "" -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:383 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:387 msgid "Overwrite Ignore Sniff Domain Name" msgstr "" -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:314 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:318 msgid "Overwrite Nameserver" msgstr "" -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:337 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:341 msgid "Overwrite Nameserver Policy" msgstr "" -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:390 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:394 msgid "Overwrite Sniff By Protocol" msgstr "" @@ -631,11 +635,11 @@ msgstr "" msgid "Password" msgstr "" -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:569 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:574 msgid "Please go to the editor tab to edit the file for mixin" msgstr "" -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:409 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:413 msgid "Port" msgstr "" @@ -643,7 +647,7 @@ msgstr "" msgid "Prefer" msgstr "" -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:511 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:515 msgid "Process Name" msgstr "" @@ -656,7 +660,7 @@ msgstr "" msgid "Profile for Startup" msgstr "" -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:403 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:407 msgid "Protocol" msgstr "" @@ -699,7 +703,7 @@ msgstr "" msgid "Remote" msgstr "" -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:271 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:275 msgid "Respect Rules" msgstr "" @@ -711,7 +715,7 @@ msgstr "" msgid "Router Proxy" msgstr "" -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:415 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:419 msgid "Rule Config" msgstr "" @@ -723,7 +727,7 @@ msgstr "" msgid "Rule Provider:" msgstr "" -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:503 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:507 msgid "Rule Set" msgstr "" @@ -756,19 +760,19 @@ msgstr "" msgid "Skip System IPv6 Check" msgstr "" -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:393 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:397 msgid "Sniff By Protocol" msgstr "" -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:370 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:374 msgid "Sniff Pure IP" msgstr "" -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:364 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:368 msgid "Sniff Redir-Host" msgstr "" -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:356 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:360 msgid "Sniffer Config" msgstr "" @@ -784,7 +788,7 @@ msgstr "" msgid "Stack Size Soft Limit" msgstr "" -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:542 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:547 msgid "Standard Loader" msgstr "" @@ -867,9 +871,9 @@ msgstr "" msgid "Transparent Proxy with Mihomo on OpenWrt." msgstr "" -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:328 -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:437 -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:501 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:332 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:441 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:505 msgid "Type" msgstr "" @@ -938,23 +942,24 @@ msgstr "" #: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:238 #: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:244 #: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:250 -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:261 -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:267 -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:273 -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:279 -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:285 -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:291 -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:360 -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:366 -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:372 -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:535 -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:541 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:254 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:265 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:271 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:277 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:283 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:289 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:295 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:364 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:370 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:376 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:540 #: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:546 -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:549 -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:552 -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:555 -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:559 -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:565 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:551 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:554 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:557 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:560 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:564 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:570 msgid "Unmodified" msgstr "" @@ -970,7 +975,7 @@ msgstr "" msgid "Update Dashboard" msgstr "" -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:480 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:484 msgid "Update Interval" msgstr "" @@ -978,15 +983,15 @@ msgstr "" msgid "Upload Profile" msgstr "" -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:443 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:447 msgid "Url" msgstr "" -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:289 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:293 msgid "Use Hosts" msgstr "" -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:283 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:287 msgid "Use System Hosts" msgstr "" diff --git a/small/luci-app-nikki/po/zh_Hans/nikki.po b/small/luci-app-nikki/po/zh_Hans/nikki.po index c47b926d64..ecbd21aa82 100644 --- a/small/luci-app-nikki/po/zh_Hans/nikki.po +++ b/small/luci-app-nikki/po/zh_Hans/nikki.po @@ -38,7 +38,7 @@ msgstr "全部端口" msgid "Allow Lan" msgstr "允许局域网访问" -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:263 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:267 msgid "Allow Mode" msgstr "白名单模式" @@ -55,19 +55,19 @@ msgstr "插件日志" msgid "App Version" msgstr "插件版本" -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:486 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:490 msgid "Append Rule" msgstr "追加规则" -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:417 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:421 msgid "Append Rule Provider" msgstr "追加规则提供者" -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:473 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:477 msgid "Behavior" msgstr "行为" -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:262 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:266 msgid "Block Mode" msgstr "黑名单模式" @@ -150,15 +150,15 @@ msgstr "DNS 模式" msgid "Debug Log" msgstr "调试日志" -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:509 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:513 msgid "Destination IP" msgstr "目标 IP" -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:513 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:517 msgid "Destination IP Geo" msgstr "目标 IP(Geo)" -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:510 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:514 msgid "Destination Port" msgstr "目标端口" @@ -188,15 +188,15 @@ msgstr "直连模式" #: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:208 #: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:229 #: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:239 -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:268 -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:274 -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:280 -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:286 -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:292 -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:361 -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:367 -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:373 -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:560 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:272 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:278 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:284 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:290 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:296 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:365 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:371 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:377 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:565 #: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/proxy.js:38 #: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/proxy.js:45 msgid "Disable" @@ -218,32 +218,32 @@ msgstr "禁用回环检测" msgid "Disable TCP Keep Alive" msgstr "禁用 TCP Keep Alive" -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:277 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:281 msgid "DoH Prefer HTTP/3" msgstr "DoH 优先 HTTP/3" -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:309 -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:504 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:313 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:508 msgid "Domain Name" msgstr "域名" -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:512 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:516 msgid "Domain Name Geo" msgstr "域名(Geo)" -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:507 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:511 msgid "Domain Name Keyword" msgstr "域名(关键字)" -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:508 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:512 msgid "Domain Name Regex" msgstr "域名(正则表达式)" -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:505 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:509 msgid "Domain Name Suffix" msgstr "域名(后缀)" -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:506 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:510 msgid "Domain Name Wildcard" msgstr "域名(通配符)" @@ -255,27 +255,27 @@ msgstr "编辑身份验证" msgid "Edit DNS Hijacks" msgstr "编辑 DNS 劫持" -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:255 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:259 msgid "Edit Fake-IP Filters" msgstr "编辑 Fake-IP 过滤列表" -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:298 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:302 msgid "Edit Hosts" msgstr "编辑 Hosts" -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:340 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:344 msgid "Edit Nameserver Policies" msgstr "编辑 DNS 服务器查询策略" -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:317 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:321 msgid "Edit Nameservers" msgstr "编辑 DNS 服务器" -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:420 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:424 msgid "Edit Rule Providers" msgstr "编辑规则提供者" -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:489 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:493 msgid "Edit Rules" msgstr "编辑规则" @@ -302,23 +302,23 @@ msgstr "编辑器" #: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:226 #: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:230 #: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:240 -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:269 -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:275 -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:281 -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:287 -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:293 -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:306 -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:325 -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:348 -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:358 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:273 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:279 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:285 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:291 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:297 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:310 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:329 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:352 #: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:362 -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:368 -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:374 -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:400 -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:428 -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:497 -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:561 -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:569 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:366 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:372 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:378 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:404 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:432 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:501 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:566 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:574 #: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/proxy.js:33 #: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/proxy.js:66 #: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/proxy.js:77 @@ -339,11 +339,11 @@ msgstr "到期时间" msgid "External Control Config" msgstr "外部控制配置" -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:265 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:269 msgid "Fake-IP Cache" msgstr "Fake-IP 缓存" -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:259 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:263 msgid "Fake-IP Filter Mode" msgstr "Fake-IP 过滤模式" @@ -355,19 +355,23 @@ msgstr "Fake-IP Ping 劫持" msgid "Fake-IP Range" msgstr "Fake-IP 范围" +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:252 +msgid "Fake-IP6 Range" +msgstr "Fake-IP6 范围" + #: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/app.js:132 msgid "Fast Reload" msgstr "快速重载" -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:467 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:471 msgid "File Format" msgstr "文件格式" -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:461 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:465 msgid "File Path" msgstr "文件路径" -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:455 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:459 msgid "File Size Limit" msgstr "文件大小限制" @@ -380,7 +384,7 @@ msgstr "用于混入的文件" msgid "File:" msgstr "文件:" -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:379 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:383 msgid "Force Sniff Domain Name" msgstr "强制嗅探的域名" @@ -401,39 +405,39 @@ msgstr "全局配置" msgid "Generate & Download" msgstr "生成并下载" -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:539 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:544 msgid "GeoData Loader" msgstr "GeoData 加载器" -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:533 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:538 msgid "GeoIP Format" msgstr "GeoIP 格式" -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:554 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:559 msgid "GeoIP(ASN) Url" msgstr "GeoIP(ASN) 下载地址" -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:551 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:556 msgid "GeoIP(DAT) Url" msgstr "GeoIP(DAT) 下载地址" -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:548 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:553 msgid "GeoIP(MMDB) Url" msgstr "GeoIP(MMDB) 下载地址" -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:545 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:550 msgid "GeoSite Url" msgstr "GeoSite 下载地址" -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:557 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:562 msgid "GeoX Auto Update" msgstr "定时更新GeoX文件" -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:531 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:536 msgid "GeoX Config" msgstr "GeoX 配置" -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:563 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:568 msgid "GeoX Update Interval" msgstr "GeoX 文件更新间隔" @@ -485,7 +489,7 @@ msgstr "IPv6 DNS 劫持" msgid "IPv6 Proxy" msgstr "IPv6 代理" -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:386 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:390 msgid "Ignore Sniff Domain Name" msgstr "忽略嗅探的域名" @@ -522,12 +526,12 @@ msgstr "最大传输单元" msgid "Match Process" msgstr "匹配进程" -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:351 -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:515 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:355 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:519 msgid "Matcher" msgstr "匹配" -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:543 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:548 msgid "Memory Conservative Loader" msgstr "为内存受限设备优化的加载器" @@ -539,7 +543,7 @@ msgstr "混合端口" msgid "Mixin Config" msgstr "混入配置" -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:567 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:572 msgid "Mixin File Content" msgstr "混入文件内容" @@ -551,12 +555,12 @@ msgstr "混入选项" msgid "Mode" msgstr "模式" -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:434 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:438 msgid "Name" msgstr "名称" -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:335 -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:354 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:339 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:358 msgid "Nameserver" msgstr "DNS 服务器" @@ -565,12 +569,12 @@ msgstr "DNS 服务器" msgid "Nikki" msgstr "Nikki" -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:526 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:530 msgid "No Resolve" msgstr "不解析" -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:448 -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:519 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:452 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:523 msgid "Node" msgstr "节点" @@ -602,35 +606,35 @@ msgstr "覆盖身份验证" msgid "Overwrite DNS Hijack" msgstr "覆盖 DNS 劫持" -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:412 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:416 msgid "Overwrite Destination" msgstr "将嗅探结果作为连接目标" -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:252 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:256 msgid "Overwrite Fake-IP Filter" msgstr "覆盖 Fake-IP 过滤列表" -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:376 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:380 msgid "Overwrite Force Sniff Domain Name" msgstr "覆盖强制嗅探的域名" -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:295 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:299 msgid "Overwrite Hosts" msgstr "覆盖 Hosts" -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:383 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:387 msgid "Overwrite Ignore Sniff Domain Name" msgstr "覆盖忽略嗅探的域名" -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:314 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:318 msgid "Overwrite Nameserver" msgstr "覆盖 DNS 服务器" -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:337 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:341 msgid "Overwrite Nameserver Policy" msgstr "覆盖 DNS 服务器查询策略" -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:390 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:394 msgid "Overwrite Sniff By Protocol" msgstr "覆盖按协议嗅探" @@ -638,11 +642,11 @@ msgstr "覆盖按协议嗅探" msgid "Password" msgstr "密码" -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:569 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:574 msgid "Please go to the editor tab to edit the file for mixin" msgstr "请前往编辑器标签编辑用于混入的文件" -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:409 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:413 msgid "Port" msgstr "端口" @@ -650,7 +654,7 @@ msgstr "端口" msgid "Prefer" msgstr "优先" -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:511 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:515 msgid "Process Name" msgstr "进程名" @@ -663,7 +667,7 @@ msgstr "配置文件" msgid "Profile for Startup" msgstr "用于启动的配置文件" -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:403 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:407 msgid "Protocol" msgstr "协议" @@ -706,7 +710,7 @@ msgstr "重载服务" msgid "Remote" msgstr "远程" -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:271 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:275 msgid "Respect Rules" msgstr "遵循分流规则" @@ -718,7 +722,7 @@ msgstr "重启服务" msgid "Router Proxy" msgstr "路由器代理" -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:415 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:419 msgid "Rule Config" msgstr "规则配置" @@ -730,7 +734,7 @@ msgstr "规则模式" msgid "Rule Provider:" msgstr "规则提供者:" -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:503 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:507 msgid "Rule Set" msgstr "规则集" @@ -763,19 +767,19 @@ msgstr "滚动到底部" msgid "Skip System IPv6 Check" msgstr "跳过系统 IPv6 检查" -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:393 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:397 msgid "Sniff By Protocol" msgstr "按协议嗅探" -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:370 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:374 msgid "Sniff Pure IP" msgstr "嗅探纯 IP 连接" -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:364 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:368 msgid "Sniff Redir-Host" msgstr "嗅探 Redir-Host 流量" -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:356 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:360 msgid "Sniffer Config" msgstr "嗅探器配置" @@ -791,7 +795,7 @@ msgstr "栈大小硬限制" msgid "Stack Size Soft Limit" msgstr "栈大小软限制" -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:542 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:547 msgid "Standard Loader" msgstr "标准加载器" @@ -874,9 +878,9 @@ msgstr "总量" msgid "Transparent Proxy with Mihomo on OpenWrt." msgstr "在 OpenWrt 上使用 Mihomo 进行透明代理。" -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:328 -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:437 -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:501 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:332 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:441 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:505 msgid "Type" msgstr "类型" @@ -945,23 +949,24 @@ msgstr "无限制" #: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:238 #: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:244 #: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:250 -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:261 -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:267 -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:273 -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:279 -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:285 -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:291 -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:360 -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:366 -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:372 -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:535 -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:541 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:254 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:265 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:271 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:277 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:283 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:289 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:295 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:364 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:370 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:376 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:540 #: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:546 -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:549 -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:552 -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:555 -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:559 -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:565 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:551 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:554 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:557 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:560 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:564 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:570 msgid "Unmodified" msgstr "不修改" @@ -977,7 +982,7 @@ msgstr "更新时间" msgid "Update Dashboard" msgstr "更新面板" -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:480 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:484 msgid "Update Interval" msgstr "更新间隔" @@ -985,15 +990,15 @@ msgstr "更新间隔" msgid "Upload Profile" msgstr "上传配置文件" -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:443 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:447 msgid "Url" msgstr "下载地址" -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:289 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:293 msgid "Use Hosts" msgstr "使用 Hosts" -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:283 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:287 msgid "Use System Hosts" msgstr "使用系统的 Hosts" diff --git a/small/luci-app-nikki/po/zh_Hant/nikki.po b/small/luci-app-nikki/po/zh_Hant/nikki.po index fdf725255e..cf53ece7b2 100644 --- a/small/luci-app-nikki/po/zh_Hant/nikki.po +++ b/small/luci-app-nikki/po/zh_Hant/nikki.po @@ -38,7 +38,7 @@ msgstr "所有埠" msgid "Allow Lan" msgstr "允許區域網路存取" -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:263 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:267 msgid "Allow Mode" msgstr "白名單模式" @@ -55,19 +55,19 @@ msgstr "應用程式日誌" msgid "App Version" msgstr "應用程式版本" -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:486 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:490 msgid "Append Rule" msgstr "追加規則" -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:417 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:421 msgid "Append Rule Provider" msgstr "追加規則提供者" -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:473 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:477 msgid "Behavior" msgstr "行為" -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:262 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:266 msgid "Block Mode" msgstr "黑名單模式" @@ -150,15 +150,15 @@ msgstr "DNS 模式" msgid "Debug Log" msgstr "除錯日誌" -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:509 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:513 msgid "Destination IP" msgstr "目標 IP" -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:513 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:517 msgid "Destination IP Geo" msgstr "目標 IP(地理位置)" -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:510 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:514 msgid "Destination Port" msgstr "目標埠" @@ -188,15 +188,15 @@ msgstr "直連模式" #: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:208 #: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:229 #: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:239 -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:268 -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:274 -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:280 -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:286 -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:292 -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:361 -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:367 -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:373 -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:560 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:272 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:278 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:284 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:290 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:296 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:365 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:371 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:377 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:565 #: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/proxy.js:38 #: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/proxy.js:45 msgid "Disable" @@ -218,32 +218,32 @@ msgstr "停用迴路檢測" msgid "Disable TCP Keep Alive" msgstr "停用 TCP Keep Alive" -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:277 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:281 msgid "DoH Prefer HTTP/3" msgstr "DoH 優先使用 HTTP/3" -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:309 -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:504 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:313 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:508 msgid "Domain Name" msgstr "網域名稱" -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:512 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:516 msgid "Domain Name Geo" msgstr "網域名稱(地理位置)" -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:507 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:511 msgid "Domain Name Keyword" msgstr "網域名稱(關鍵字)" -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:508 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:512 msgid "Domain Name Regex" msgstr "網域名稱(正則表達式)" -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:505 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:509 msgid "Domain Name Suffix" msgstr "網域名稱(後綴)" -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:506 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:510 msgid "Domain Name Wildcard" msgstr "網域名稱(通配符)" @@ -255,27 +255,27 @@ msgstr "編輯身分驗證" msgid "Edit DNS Hijacks" msgstr "編輯 DNS 劫持" -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:255 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:259 msgid "Edit Fake-IP Filters" msgstr "編輯 Fake-IP 過濾清單" -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:298 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:302 msgid "Edit Hosts" msgstr "編輯 Hosts" -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:340 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:344 msgid "Edit Nameserver Policies" msgstr "編輯 DNS 伺服器查詢策略" -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:317 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:321 msgid "Edit Nameservers" msgstr "編輯 DNS 伺服器" -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:420 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:424 msgid "Edit Rule Providers" msgstr "編輯規則提供者" -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:489 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:493 msgid "Edit Rules" msgstr "編輯規則" @@ -302,23 +302,23 @@ msgstr "編輯器" #: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:226 #: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:230 #: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:240 -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:269 -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:275 -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:281 -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:287 -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:293 -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:306 -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:325 -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:348 -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:358 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:273 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:279 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:285 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:291 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:297 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:310 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:329 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:352 #: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:362 -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:368 -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:374 -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:400 -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:428 -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:497 -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:561 -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:569 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:366 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:372 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:378 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:404 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:432 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:501 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:566 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:574 #: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/proxy.js:33 #: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/proxy.js:66 #: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/proxy.js:77 @@ -339,11 +339,11 @@ msgstr "到期時間" msgid "External Control Config" msgstr "外部控制設定" -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:265 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:269 msgid "Fake-IP Cache" msgstr "Fake-IP 快取" -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:259 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:263 msgid "Fake-IP Filter Mode" msgstr "Fake-IP 過濾模式" @@ -355,19 +355,23 @@ msgstr "Fake-IP Ping 劫持" msgid "Fake-IP Range" msgstr "Fake-IP 範圍" +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:252 +msgid "Fake-IP6 Range" +msgstr "Fake-IP6 範圍" + #: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/app.js:132 msgid "Fast Reload" msgstr "快速重載" -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:467 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:471 msgid "File Format" msgstr "檔案格式" -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:461 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:465 msgid "File Path" msgstr "檔案路徑" -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:455 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:459 msgid "File Size Limit" msgstr "檔案大小限制" @@ -380,7 +384,7 @@ msgstr "用於混入的檔案" msgid "File:" msgstr "檔案:" -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:379 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:383 msgid "Force Sniff Domain Name" msgstr "強制嗅探的網域名稱" @@ -401,39 +405,39 @@ msgstr "一般設定" msgid "Generate & Download" msgstr "生成並下載" -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:539 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:544 msgid "GeoData Loader" msgstr "GeoData 載入器" -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:533 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:538 msgid "GeoIP Format" msgstr "GeoIP 格式" -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:554 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:559 msgid "GeoIP(ASN) Url" msgstr "GeoIP(ASN) 下載網址" -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:551 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:556 msgid "GeoIP(DAT) Url" msgstr "GeoIP(DAT) 下載網址" -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:548 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:553 msgid "GeoIP(MMDB) Url" msgstr "GeoIP(MMDB) 下載網址" -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:545 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:550 msgid "GeoSite Url" msgstr "GeoSite 下載網址" -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:557 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:562 msgid "GeoX Auto Update" msgstr "定時更新 GeoX 檔案" -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:531 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:536 msgid "GeoX Config" msgstr "GeoX 設定" -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:563 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:568 msgid "GeoX Update Interval" msgstr "GeoX 檔案更新間隔" @@ -485,7 +489,7 @@ msgstr "IPv6 DNS 劫持" msgid "IPv6 Proxy" msgstr "IPv6 代理" -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:386 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:390 msgid "Ignore Sniff Domain Name" msgstr "忽略嗅探的網域名稱" @@ -522,12 +526,12 @@ msgstr "最大傳輸單元" msgid "Match Process" msgstr "匹配程序" -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:351 -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:515 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:355 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:519 msgid "Matcher" msgstr "匹配器" -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:543 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:548 msgid "Memory Conservative Loader" msgstr "為記憶體受限裝置最佳化的載入器" @@ -539,7 +543,7 @@ msgstr "混合埠" msgid "Mixin Config" msgstr "混入設定" -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:567 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:572 msgid "Mixin File Content" msgstr "混入檔案內容" @@ -551,12 +555,12 @@ msgstr "混入選項" msgid "Mode" msgstr "模式" -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:434 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:438 msgid "Name" msgstr "名稱" -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:335 -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:354 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:339 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:358 msgid "Nameserver" msgstr "DNS 伺服器" @@ -565,12 +569,12 @@ msgstr "DNS 伺服器" msgid "Nikki" msgstr "Nikki" -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:526 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:530 msgid "No Resolve" msgstr "不解析" -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:448 -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:519 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:452 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:523 msgid "Node" msgstr "節點" @@ -602,35 +606,35 @@ msgstr "覆寫身分驗證" msgid "Overwrite DNS Hijack" msgstr "覆寫 DNS 劫持" -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:412 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:416 msgid "Overwrite Destination" msgstr "將嗅探結果作為連線目標" -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:252 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:256 msgid "Overwrite Fake-IP Filter" msgstr "覆寫 Fake-IP 過濾清單" -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:376 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:380 msgid "Overwrite Force Sniff Domain Name" msgstr "覆寫強制嗅探的網域名稱" -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:295 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:299 msgid "Overwrite Hosts" msgstr "覆寫 Hosts" -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:383 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:387 msgid "Overwrite Ignore Sniff Domain Name" msgstr "覆寫忽略嗅探的網域名稱" -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:314 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:318 msgid "Overwrite Nameserver" msgstr "覆寫 DNS 伺服器" -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:337 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:341 msgid "Overwrite Nameserver Policy" msgstr "覆寫 DNS 伺服器查詢策略" -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:390 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:394 msgid "Overwrite Sniff By Protocol" msgstr "覆寫按協定嗅探" @@ -638,11 +642,11 @@ msgstr "覆寫按協定嗅探" msgid "Password" msgstr "密碼" -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:569 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:574 msgid "Please go to the editor tab to edit the file for mixin" msgstr "請前往編輯器標籤編輯用於混入的檔案" -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:409 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:413 msgid "Port" msgstr "埠" @@ -650,7 +654,7 @@ msgstr "埠" msgid "Prefer" msgstr "優先" -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:511 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:515 msgid "Process Name" msgstr "程序名稱" @@ -663,7 +667,7 @@ msgstr "設定檔" msgid "Profile for Startup" msgstr "用於啟動的設定檔" -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:403 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:407 msgid "Protocol" msgstr "協定" @@ -706,7 +710,7 @@ msgstr "重新載入服務" msgid "Remote" msgstr "遠端" -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:271 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:275 msgid "Respect Rules" msgstr "遵循分流規則" @@ -718,7 +722,7 @@ msgstr "重新啟動服務" msgid "Router Proxy" msgstr "路由器代理" -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:415 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:419 msgid "Rule Config" msgstr "規則設定" @@ -730,7 +734,7 @@ msgstr "規則模式" msgid "Rule Provider:" msgstr "規則提供者:" -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:503 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:507 msgid "Rule Set" msgstr "規則集" @@ -763,19 +767,19 @@ msgstr "捲動到底部" msgid "Skip System IPv6 Check" msgstr "跳過系統 IPv6 檢查" -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:393 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:397 msgid "Sniff By Protocol" msgstr "按協定嗅探" -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:370 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:374 msgid "Sniff Pure IP" msgstr "嗅探純 IP 連線" -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:364 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:368 msgid "Sniff Redir-Host" msgstr "嗅探 Redir-Host 流量" -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:356 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:360 msgid "Sniffer Config" msgstr "嗅探器設定" @@ -791,7 +795,7 @@ msgstr "" msgid "Stack Size Soft Limit" msgstr "" -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:542 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:547 msgid "Standard Loader" msgstr "標準載入器" @@ -874,9 +878,9 @@ msgstr "總計" msgid "Transparent Proxy with Mihomo on OpenWrt." msgstr "在 OpenWrt 上使用 Mihomo 進行透明代理." -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:328 -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:437 -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:501 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:332 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:441 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:505 msgid "Type" msgstr "類型" @@ -945,23 +949,24 @@ msgstr "無限制" #: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:238 #: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:244 #: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:250 -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:261 -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:267 -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:273 -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:279 -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:285 -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:291 -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:360 -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:366 -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:372 -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:535 -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:541 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:254 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:265 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:271 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:277 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:283 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:289 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:295 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:364 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:370 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:376 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:540 #: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:546 -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:549 -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:552 -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:555 -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:559 -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:565 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:551 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:554 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:557 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:560 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:564 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:570 msgid "Unmodified" msgstr "不修改" @@ -977,7 +982,7 @@ msgstr "更新時間" msgid "Update Dashboard" msgstr "更新儀表板" -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:480 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:484 msgid "Update Interval" msgstr "更新間隔" @@ -985,15 +990,15 @@ msgstr "更新間隔" msgid "Upload Profile" msgstr "上傳設定檔" -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:443 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:447 msgid "Url" msgstr "下載網址" -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:289 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:293 msgid "Use Hosts" msgstr "使用 Hosts" -#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:283 +#: applications/luci-app-nikki/htdocs/luci-static/resources/view/nikki/mixin.js:287 msgid "Use System Hosts" msgstr "使用系統的 Hosts" diff --git a/small/luci-app-passwall/luasrc/model/cbi/passwall/client/acl_config.lua b/small/luci-app-passwall/luasrc/model/cbi/passwall/client/acl_config.lua index 41b2e2bfd7..50f5c36b3d 100644 --- a/small/luci-app-passwall/luasrc/model/cbi/passwall/client/acl_config.lua +++ b/small/luci-app-passwall/luasrc/model/cbi/passwall/client/acl_config.lua @@ -22,6 +22,7 @@ local port_validate = function(self, value, t) end local nodes_table = {} +local shunt_list = {} for k, e in ipairs(api.get_valid_nodes()) do nodes_table[#nodes_table + 1] = e end @@ -202,6 +203,9 @@ o:depends({ _tcp_node_bool = "1" }) for k, v in pairs(nodes_table) do s.fields["tcp_node"]:value(v.id, v["remark"]) s.fields["udp_node"]:value(v.id, v["remark"]) + if v.protocol and v.protocol == "_shunt" then + shunt_list[#shunt_list + 1] = v + end end o = s:option(DummyValue, "_udp_node_bool", "") @@ -313,11 +317,7 @@ o.default = "0" o:depends({ _tcp_node_bool = "1" }) ---- DNS Forward Mode -o = s:option(ListValue, "dns_mode", translate("Filter Mode"), - "" .. translate( - "If the node uses Xray/Sing-Box shunt, select the matching filter mode (Xray/Sing-Box).") .. - "") -o:depends({ _tcp_node_bool = "1" }) +o = s:option(ListValue, "dns_mode", translate("Filter Mode")) if api.is_finded("dns2socks") then o:value("dns2socks", "dns2socks") end @@ -327,6 +327,19 @@ end if has_xray then o:value("xray", "Xray") end +o.remove = function(self, section) + local f = s.fields["tcp_node"] + local id_val = f and f:formvalue(section) or "" + if id_val == "" then + return m:del(section, self.option) + end + for k, v in pairs(shunt_list) do + if v.id == id_val then + local new_val = (v.type == "Xray") and "xray" or "sing-box" + return m:set(section, self.option, new_val) + end + end +end o = s:option(ListValue, "xray_dns_mode", translate("Request protocol")) o:value("tcp", "TCP") @@ -439,4 +452,21 @@ o:value("direct", translate("Direct DNS")) o.description = desc .. "" o:depends({dns_shunt = "dnsmasq", tcp_proxy_mode = "proxy", chn_list = "direct"}) +for k, v in pairs(nodes_table) do + if v.protocol and v.protocol ~= "_shunt" then + s.fields["dns_mode"]:depends({ _tcp_node_bool = "1", tcp_node = v.id }) + end +end +for k, v in pairs(shunt_list) do + if v.type == "Xray" and has_xray then + s.fields["xray_dns_mode"]:depends({ _tcp_node_bool = "1", tcp_node = v.id }) + end + if v.type == "sing-box" and has_singbox then + s.fields["singbox_dns_mode"]:depends({ _tcp_node_bool = "1", tcp_node = v.id }) + end + if has_xray or has_singbox then + s.fields["remote_dns_client_ip"]:depends({ tcp_node = v.id }) + end +end + return m diff --git a/small/luci-app-passwall/luasrc/model/cbi/passwall/client/global.lua b/small/luci-app-passwall/luasrc/model/cbi/passwall/client/global.lua index 79106a35fb..bcb8b47a7f 100644 --- a/small/luci-app-passwall/luasrc/model/cbi/passwall/client/global.lua +++ b/small/luci-app-passwall/luasrc/model/cbi/passwall/client/global.lua @@ -322,11 +322,37 @@ o:depends("direct_dns_mode", "tcp") o = s:taboption("DNS", Flag, "filter_proxy_ipv6", translate("Filter Proxy Host IPv6"), translate("Experimental feature.")) o.default = "0" +-- TCP分流时dns过滤模式保存逻辑 +function dns_mode_save(section) + for k, v in pairs(shunt_list) do + local f = s.fields[v.id .. "-type"] + if f then + local type_val = f:formvalue(section) + if type_val and (type_val == "Xray" or type_val == "sing-box") then + local dns_shunt_val = s.fields["dns_shunt"]:formvalue(section) + local dns_mode_val = (dns_shunt_val ~= "smartdns") and "dns_mode" or "smartdns_dns_mode" + local current_val = m:get(section, dns_mode_val) or "" + local new_val = (type_val == "Xray") and "xray" or "sing-box" + + if current_val ~= new_val then + m:set(section, dns_mode_val, new_val) + m:del(section, (dns_mode_val == "dns_mode") and "smartdns_dns_mode" or "dns_mode") + end + + local dns_field = s.fields[type_val == "Xray" and "xray_dns_mode" or "singbox_dns_mode"] + local v2ray_dns_mode = dns_field and dns_field:formvalue(section) + if v2ray_dns_mode and m:get(section, "v2ray_dns_mode") ~= v2ray_dns_mode then + m:set(section, "v2ray_dns_mode", v2ray_dns_mode) + end + + break + end + end + end +end + ---- DNS Forward Mode -o = s:taboption("DNS", ListValue, "dns_mode", translate("Filter Mode"), - "" .. translate( - "If the node uses Xray/Sing-Box shunt, select the matching filter mode (Xray/Sing-Box).") .. - "") +o = s:taboption("DNS", ListValue, "dns_mode", translate("Filter Mode")) o:value("udp", translatef("Requery DNS By %s", "UDP")) o:value("tcp", translatef("Requery DNS By %s", "TCP")) if api.is_finded("dns2socks") then @@ -338,16 +364,19 @@ end if has_xray then o:value("xray", "Xray") end -if api.is_finded("smartdns") then - o:depends({ dns_shunt = "smartdns", ['!reverse'] = true }) +o:depends({ dns_shunt = "chinadns-ng", tcp_node = "" }) +o:depends({ dns_shunt = "dnsmasq", tcp_node = "" }) +o.remove = function(self, section) + local f = s.fields["smartdns_dns_mode"] + if f and f:formvalue(section) then + return m:del(section, self.option) + end + dns_mode_save(section) end ---- SmartDNS Forward Mode if api.is_finded("smartdns") then - o = s:taboption("DNS", ListValue, "smartdns_dns_mode", translate("Filter Mode"), - "" .. translate( - "If the node uses Xray/Sing-Box shunt, select the matching filter mode (Xray/Sing-Box).") .. - "") + o = s:taboption("DNS", ListValue, "smartdns_dns_mode", translate("Filter Mode")) o:value("socks", "Socks") if has_singbox then o:value("sing-box", "Sing-Box") @@ -355,7 +384,14 @@ if api.is_finded("smartdns") then if has_xray then o:value("xray", "Xray") end - o:depends({ dns_shunt = "smartdns" }) + o:depends({ dns_shunt = "smartdns", tcp_node = "" }) + o.remove = function(self, section) + local f = s.fields["dns_mode"] + if f and f:formvalue(section) then + return m:del(section, self.option) + end + dns_mode_save(section) + end o = s:taboption("DNS", DynamicList, "smartdns_remote_dns", translate("Remote DNS")) o:value("tcp://1.1.1.1") @@ -400,7 +436,7 @@ if api.is_finded("smartdns") then end end -o = s:taboption("DNS", ListValue, "xray_dns_mode", translate("Request protocol")) +o = s:taboption("DNS", ListValue, "xray_dns_mode", translate("Remote DNS") .. " " .. translate("Request protocol")) o:value("tcp", "TCP") o:value("tcp+doh", "TCP + DoH (" .. translate("A/AAAA type") .. ")") o:depends("dns_mode", "xray") @@ -414,7 +450,7 @@ o.write = function(self, section, value) end end -o = s:taboption("DNS", ListValue, "singbox_dns_mode", translate("Request protocol")) +o = s:taboption("DNS", ListValue, "singbox_dns_mode", translate("Remote DNS") .. " " .. translate("Request protocol")) o:value("tcp", "TCP") o:value("doh", "DoH") o:depends("dns_mode", "sing-box") @@ -733,6 +769,21 @@ for k, v in pairs(nodes_table) do else s2.fields["node"]:value(v.id, v["remark"]) end + + if v.protocol and v.protocol ~= "_shunt" then + s.fields["dns_mode"]:depends({ dns_shunt = "chinadns-ng", tcp_node = v.id }) + s.fields["dns_mode"]:depends({ dns_shunt = "dnsmasq", tcp_node = v.id }) + if api.is_finded("smartdns") then + s.fields["smartdns_dns_mode"]:depends({ dns_shunt = "smartdns", tcp_node = v.id }) + end + end +end + +for k, v in pairs(shunt_list) do + s.fields["xray_dns_mode"]:depends({ [v.id .. "-type"] = "Xray", tcp_node = v.id }) + s.fields["singbox_dns_mode"]:depends({ [v.id .. "-type"] = "sing-box", tcp_node = v.id }) + s.fields["remote_dns_client_ip"]:depends({ tcp_node = v.id }) + s.fields["remote_fakedns"]:depends({ tcp_node = v.id }) end m:append(Template(appname .. "/global/footer")) diff --git a/small/luci-app-passwall/luasrc/passwall/util_xray.lua b/small/luci-app-passwall/luasrc/passwall/util_xray.lua index 7399c38ed2..22b18b1d74 100644 --- a/small/luci-app-passwall/luasrc/passwall/util_xray.lua +++ b/small/luci-app-passwall/luasrc/passwall/util_xray.lua @@ -1301,6 +1301,7 @@ function gen_config(var) end end + local dns_rule_position = 1 if dns_listen_port then table.insert(inbounds, { listen = "127.0.0.1", @@ -1334,16 +1335,18 @@ function gen_config(var) }, outboundTag = "dns-out" }) + dns_rule_position = dns_rule_position + 1 end if COMMON.default_outbound_tag == "direct" then if direct_dns_udp_server or direct_dns_tcp_server then - table.insert(routing.rules, { + table.insert(routing.rules, dns_rule_position, { inboundTag = { "dns-global-direct" }, outboundTag = "direct" }) + dns_rule_position = dns_rule_position + 1 end end @@ -1376,11 +1379,12 @@ function gen_config(var) balancerTag = nil end table.insert(dns.servers, dns_server) - table.insert(routing.rules, { + table.insert(routing.rules, dns_rule_position, { inboundTag = { dns_server.tag }, outboundTag = outboundTag, balancerTag = balancerTag }) + dns_rule_position = dns_rule_position + 1 end end end @@ -1394,11 +1398,12 @@ function gen_config(var) _outboundTag = "direct" _balancerTag = nil end - table.insert(routing.rules, { + table.insert(routing.rules, dns_rule_position, { inboundTag = { "dns-global" }, balancerTag = _balancerTag, outboundTag = _outboundTag }) + dns_rule_position = dns_rule_position + 1 local default_rule_index = nil for index, value in ipairs(routing.rules) do diff --git a/small/luci-app-passwall/po/zh-cn/passwall.po b/small/luci-app-passwall/po/zh-cn/passwall.po index ceb30f36ca..01123842a5 100644 --- a/small/luci-app-passwall/po/zh-cn/passwall.po +++ b/small/luci-app-passwall/po/zh-cn/passwall.po @@ -127,9 +127,6 @@ msgstr "您只需要在SmartDNS配置好国内DNS分组,并设置重定向或 msgid "Filter Mode" msgstr "过滤模式" -msgid "If the node uses Xray/Sing-Box shunt, select the matching filter mode (Xray/Sing-Box)." -msgstr "当节点使用 Xray/Sing-Box 分流时,过滤模式需对应选择 Xray/Sing-Box 。" - msgid "A/AAAA type" msgstr "A/AAAA 类型" diff --git a/small/luci-app-passwall/root/usr/share/passwall/app.sh b/small/luci-app-passwall/root/usr/share/passwall/app.sh index db6ccbec07..2af28dc06c 100755 --- a/small/luci-app-passwall/root/usr/share/passwall/app.sh +++ b/small/luci-app-passwall/root/usr/share/passwall/app.sh @@ -2147,24 +2147,6 @@ stop() { rm -rf /tmp/lock/${CONFIG}_socks_auto_switch* rm -rf /tmp/lock/${CONFIG}_lease2hosts* echolog "清空并关闭相关程序和缓存完成。" - # 根据分流节点类型自动调整 DNS 过滤模式 - local _tcp_node=$(config_t_get global tcp_node) - if [ -n "$_tcp_node" ]; then - local _protocol=$(config_n_get $_tcp_node protocol) - if [ "$_protocol" = "_shunt" ]; then - local _type=$(config_n_get $_tcp_node type) - local _dns_mode=$(config_t_get global dns_mode) - local _new_dns_mode - [ "$_type" = "Xray" ] && _new_dns_mode="xray" - [ "$_type" = "sing-box" ] && _new_dns_mode="sing-box" - if [ -n "$_new_dns_mode" ] && [ "$_dns_mode" != "$_new_dns_mode" ]; then - uci -q set ${CONFIG}.@global[0].dns_mode="$_new_dns_mode" - uci -q set ${CONFIG}.@global[0].v2ray_dns_mode="tcp" - uci -q commit ${CONFIG} - echolog "* 检测到 TCP 节点为 $_type 分流,强制修改 DNS 过滤模式为 $_type !" - fi - fi - fi exit 0 } diff --git a/small/luci-app-passwall/root/usr/share/passwall/iptables.sh b/small/luci-app-passwall/root/usr/share/passwall/iptables.sh index 526ddafd94..d1f4fbc8fd 100755 --- a/small/luci-app-passwall/root/usr/share/passwall/iptables.sh +++ b/small/luci-app-passwall/root/usr/share/passwall/iptables.sh @@ -980,17 +980,20 @@ add_firewall_rule() { $ipt_n -I PREROUTING 1 -j PSW_DNS fi + $ipt_m -N PSW_DIVERT + $ipt_m -A PSW_DIVERT -j MARK --set-mark 1 + $ipt_m -A PSW_DIVERT -j ACCEPT + $ipt_m -N PSW_RULE $ipt_m -A PSW_RULE -j CONNMARK --restore-mark $ipt_m -A PSW_RULE -m mark --mark 1 -j RETURN - $ipt_m -A PSW_RULE -p tcp -m tcp --syn -j MARK --set-xmark 1 - $ipt_m -A PSW_RULE -p udp -m conntrack --ctstate NEW,RELATED -j MARK --set-xmark 1 + $ipt_m -A PSW_RULE -p tcp -m tcp --tcp-flags FIN,SYN,RST,ACK SYN -j MARK --set-xmark 1 + $ipt_m -A PSW_RULE -p udp -m conntrack --ctstate NEW -j MARK --set-xmark 1 $ipt_m -A PSW_RULE -j CONNMARK --save-mark $ipt_m -N PSW $ipt_m -A PSW $(dst $IPSET_LAN) -j RETURN $ipt_m -A PSW $(dst $IPSET_VPS) -j RETURN - $ipt_m -A PSW -m conntrack --ctdir REPLY -j RETURN [ ! -z "${WAN_IP}" ] && { $ipt_m -A PSW $(comment "WAN_IP_RETURN") -d "${WAN_IP}" -j RETURN @@ -999,11 +1002,11 @@ add_firewall_rule() { unset WAN_IP insert_rule_before "$ipt_m" "PREROUTING" "mwan3" "-j PSW" + insert_rule_before "$ipt_m" "PREROUTING" "PSW" "-p tcp -m socket -j PSW_DIVERT" $ipt_m -N PSW_OUTPUT $ipt_m -A PSW_OUTPUT $(dst $IPSET_LAN) -j RETURN $ipt_m -A PSW_OUTPUT $(dst $IPSET_VPS) -j RETURN - $ipt_m -A PSW_OUTPUT -m conntrack --ctdir REPLY -j RETURN [ -n "$IPT_APPEND_DNS" ] && { local local_dns dns_address dns_port @@ -1050,29 +1053,32 @@ add_firewall_rule() { $ip6t_n -I PREROUTING 1 -j PSW_DNS fi + $ip6t_m -N PSW_DIVERT + $ip6t_m -A PSW_DIVERT -j MARK --set-mark 1 + $ip6t_m -A PSW_DIVERT -j ACCEPT + $ip6t_m -N PSW_RULE $ip6t_m -A PSW_RULE -j CONNMARK --restore-mark $ip6t_m -A PSW_RULE -m mark --mark 1 -j RETURN - $ip6t_m -A PSW_RULE -p tcp -m tcp --syn -j MARK --set-xmark 1 - $ip6t_m -A PSW_RULE -p udp -m conntrack --ctstate NEW,RELATED -j MARK --set-xmark 1 + $ip6t_m -A PSW_RULE -p tcp -m tcp --tcp-flags FIN,SYN,RST,ACK SYN -j MARK --set-xmark 1 + $ip6t_m -A PSW_RULE -p udp -m conntrack --ctstate NEW -j MARK --set-xmark 1 $ip6t_m -A PSW_RULE -j CONNMARK --save-mark $ip6t_m -N PSW $ip6t_m -A PSW $(dst $IPSET_LAN6) -j RETURN $ip6t_m -A PSW $(dst $IPSET_VPS6) -j RETURN - $ip6t_m -A PSW -m conntrack --ctdir REPLY -j RETURN WAN6_IP=$(get_wan6_ip) [ ! -z "${WAN6_IP}" ] && $ip6t_m -A PSW $(comment "WAN6_IP_RETURN") -d ${WAN6_IP} -j RETURN unset WAN6_IP insert_rule_before "$ip6t_m" "PREROUTING" "mwan3" "-j PSW" + insert_rule_before "$ip6t_m" "PREROUTING" "PSW" "-p tcp -m socket -j PSW_DIVERT" $ip6t_m -N PSW_OUTPUT $ip6t_m -A PSW_OUTPUT -m mark --mark 0xff -j RETURN $ip6t_m -A PSW_OUTPUT $(dst $IPSET_LAN6) -j RETURN $ip6t_m -A PSW_OUTPUT $(dst $IPSET_VPS6) -j RETURN - $ip6t_m -A PSW_OUTPUT -m conntrack --ctdir REPLY -j RETURN [ "${USE_BLOCK_LIST}" = "1" ] && $ip6t_m -A PSW_OUTPUT $(dst $IPSET_BLOCK6) -j DROP [ "${USE_DIRECT_LIST}" = "1" ] && $ip6t_m -A PSW_OUTPUT $(dst $IPSET_WHITE6) -j RETURN @@ -1309,7 +1315,7 @@ del_firewall_rule() { $ipt -D $chain $index 2>/dev/null done done - for chain in "PSW" "PSW_OUTPUT" "PSW_DNS" "PSW_RULE"; do + for chain in "PSW" "PSW_OUTPUT" "PSW_DIVERT" "PSW_DNS" "PSW_RULE"; do $ipt -F $chain 2>/dev/null $ipt -X $chain 2>/dev/null done @@ -1363,7 +1369,7 @@ gen_include() { [ -z "${_ipt}" ] && return echo "*$2" - ${_ipt}-save -t $2 | grep "PSW" | grep -v "\-j PSW$" | sed -e "s/^-A \(OUTPUT\|PREROUTING\)/-I \1 1/" + ${_ipt}-save -t $2 | grep "PSW" | grep -v "\-j PSW$" | grep -v "mangle\-OUTPUT\-PSW" | grep -v "socket \-j PSW_DIVERT$" | sed -e "s/^-A \(OUTPUT\|PREROUTING\)/-I \1 1/" echo 'COMMIT' } local __ipt="" @@ -1384,6 +1390,7 @@ gen_include() { [ -z "${is_tproxy}" ] && \$(${MY_PATH} insert_rule_after "$ipt_n" "PREROUTING" "prerouting_rule" "-p tcp -j PSW") \$(${MY_PATH} insert_rule_before "$ipt_m" "PREROUTING" "mwan3" "-j PSW") + \$(${MY_PATH} insert_rule_before "$ipt_m" "PREROUTING" "PSW" "-p tcp -m socket -j PSW_DIVERT") WAN_IP=\$(${MY_PATH} get_wan_ip) @@ -1416,6 +1423,7 @@ gen_include() { [ "$accept_icmpv6" = "1" ] && $ip6t_n -A PREROUTING -p ipv6-icmp -j PSW \$(${MY_PATH} insert_rule_before "$ip6t_m" "PREROUTING" "mwan3" "-j PSW") + \$(${MY_PATH} insert_rule_before "$ip6t_m" "PREROUTING" "PSW" "-p tcp -m socket -j PSW_DIVERT") PR_INDEX=\$(${MY_PATH} RULE_LAST_INDEX "$ip6t_m" PSW WAN6_IP_RETURN -1) if [ \$PR_INDEX -ge 0 ]; then diff --git a/small/luci-app-passwall/root/usr/share/passwall/nftables.sh b/small/luci-app-passwall/root/usr/share/passwall/nftables.sh index e2db320719..e2934432af 100755 --- a/small/luci-app-passwall/root/usr/share/passwall/nftables.sh +++ b/small/luci-app-passwall/root/usr/share/passwall/nftables.sh @@ -986,6 +986,10 @@ add_firewall_rule() { nft_output_chain="PSW_OUTPUT_MANGLE" fi + nft "add chain $NFTABLE_NAME PSW_DIVERT" + nft "flush chain $NFTABLE_NAME PSW_DIVERT" + nft "add rule $NFTABLE_NAME PSW_DIVERT meta l4proto tcp socket transparent 1 mark set 1 counter accept" + nft "add chain $NFTABLE_NAME PSW_DNS" nft "flush chain $NFTABLE_NAME PSW_DNS" if [ $(config_t_get global dns_redirect "1") = "0" ]; then @@ -1001,8 +1005,8 @@ add_firewall_rule() { nft "flush chain $NFTABLE_NAME PSW_RULE" nft "add rule $NFTABLE_NAME PSW_RULE meta mark set ct mark counter" nft "add rule $NFTABLE_NAME PSW_RULE meta mark 1 counter return" - nft "add rule $NFTABLE_NAME PSW_RULE tcp flags syn meta mark set mark and 0x0 xor 0x1 counter" - nft "add rule $NFTABLE_NAME PSW_RULE meta l4proto udp ct state new,related meta mark set mark and 0x0 xor 0x1 counter" + nft "add rule $NFTABLE_NAME PSW_RULE tcp flags &(fin|syn|rst|ack) == syn meta mark set mark and 0x0 xor 0x1 counter" + nft "add rule $NFTABLE_NAME PSW_RULE meta l4proto udp ct state new meta mark set mark and 0x0 xor 0x1 counter" nft "add rule $NFTABLE_NAME PSW_RULE ct mark set mark counter" #ipv4 tproxy mode and udp @@ -1010,13 +1014,11 @@ add_firewall_rule() { nft "flush chain $NFTABLE_NAME PSW_MANGLE" nft "add rule $NFTABLE_NAME PSW_MANGLE ip daddr @$NFTSET_LAN counter return" nft "add rule $NFTABLE_NAME PSW_MANGLE ip daddr @$NFTSET_VPS counter return" - nft "add rule $NFTABLE_NAME PSW_MANGLE ct direction reply counter return" nft "add chain $NFTABLE_NAME PSW_OUTPUT_MANGLE" nft "flush chain $NFTABLE_NAME PSW_OUTPUT_MANGLE" nft "add rule $NFTABLE_NAME PSW_OUTPUT_MANGLE ip daddr @$NFTSET_LAN counter return" nft "add rule $NFTABLE_NAME PSW_OUTPUT_MANGLE ip daddr @$NFTSET_VPS counter return" - nft "add rule $NFTABLE_NAME PSW_OUTPUT_MANGLE ct direction reply counter return" [ "${USE_BLOCK_LIST}" = "1" ] && nft "add rule $NFTABLE_NAME PSW_OUTPUT_MANGLE ip daddr @$NFTSET_BLOCK counter drop" [ "${USE_DIRECT_LIST}" = "1" ] && nft "add rule $NFTABLE_NAME PSW_OUTPUT_MANGLE ip daddr @$NFTSET_WHITE counter return" @@ -1025,6 +1027,7 @@ add_firewall_rule() { # jump chains nft "add rule $NFTABLE_NAME mangle_prerouting ip protocol udp counter jump PSW_MANGLE" [ -n "${is_tproxy}" ] && nft "add rule $NFTABLE_NAME mangle_prerouting ip protocol tcp counter jump PSW_MANGLE" + insert_rule_before "$NFTABLE_NAME" "mangle_prerouting" "PSW_MANGLE" "counter jump PSW_DIVERT" #ipv4 tcp redirect mode [ -z "${is_tproxy}" ] && { @@ -1075,13 +1078,11 @@ add_firewall_rule() { nft "flush chain $NFTABLE_NAME PSW_MANGLE_V6" nft "add rule $NFTABLE_NAME PSW_MANGLE_V6 ip6 daddr @$NFTSET_LAN6 counter return" nft "add rule $NFTABLE_NAME PSW_MANGLE_V6 ip6 daddr @$NFTSET_VPS6 counter return" - nft "add rule $NFTABLE_NAME PSW_MANGLE_V6 ct direction reply counter return" nft "add chain $NFTABLE_NAME PSW_OUTPUT_MANGLE_V6" nft "flush chain $NFTABLE_NAME PSW_OUTPUT_MANGLE_V6" nft "add rule $NFTABLE_NAME PSW_OUTPUT_MANGLE_V6 ip6 daddr @$NFTSET_LAN6 counter return" nft "add rule $NFTABLE_NAME PSW_OUTPUT_MANGLE_V6 ip6 daddr @$NFTSET_VPS6 counter return" - nft "add rule $NFTABLE_NAME PSW_OUTPUT_MANGLE_V6 ct direction reply counter return" [ "${USE_BLOCK_LIST}" = "1" ] && nft "add rule $NFTABLE_NAME PSW_OUTPUT_MANGLE_V6 ip6 daddr @$NFTSET_BLOCK6 counter drop" [ "${USE_DIRECT_LIST}" = "1" ] && nft "add rule $NFTABLE_NAME PSW_OUTPUT_MANGLE_V6 ip6 daddr @$NFTSET_WHITE6 counter return" nft "add rule $NFTABLE_NAME PSW_OUTPUT_MANGLE_V6 meta mark 0xff counter return" @@ -1397,7 +1398,7 @@ gen_include() { local __nft=" " __nft=$(cat <<- EOF - [ -z "\$(nft list chain $NFTABLE_NAME mangle_prerouting | grep PSW)" ] && nft -f ${nft_chain_file} + [ -z "\$(nft list chain $NFTABLE_NAME mangle_prerouting | grep PSW_DIVERT)" ] && nft -f ${nft_chain_file} [ -z "${is_tproxy}" ] && { PR_INDEX=\$(sh ${MY_PATH} RULE_LAST_INDEX "$NFTABLE_NAME" PSW_NAT WAN_IP_RETURN -1) if [ \$PR_INDEX -ge 0 ]; then diff --git a/small/nikki/Makefile b/small/nikki/Makefile index 993e4a9d64..27605ad6f0 100644 --- a/small/nikki/Makefile +++ b/small/nikki/Makefile @@ -1,15 +1,15 @@ include $(TOPDIR)/rules.mk PKG_NAME:=nikki -PKG_VERSION:=2025.10.15 +PKG_VERSION:=2025.11.09 PKG_RELEASE:=1 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz PKG_SOURCE_SUBDIR:=$(PKG_NAME)-$(PKG_VERSION) PKG_SOURCE_PROTO:=git PKG_SOURCE_URL:=https://github.com/MetaCubeX/mihomo.git -PKG_SOURCE_VERSION:=v1.19.15 -PKG_MIRROR_HASH:=08f97911a7c601eb366c5ab29a7e7ce1f888601d22ed7f357c8732b10a4ec3e2 +PKG_SOURCE_VERSION:=v1.19.16 +PKG_MIRROR_HASH:=35893f8458d21fac840b150d94b8c60e3ce3a50769e196cbcf197f23a070c076 PKG_LICENSE:=GPL3.0+ PKG_MAINTAINER:=Joseph Mory diff --git a/small/nikki/files/uci-defaults/migrate.sh b/small/nikki/files/uci-defaults/migrate.sh index 1eee74e063..4651e561ac 100644 --- a/small/nikki/files/uci-defaults/migrate.sh +++ b/small/nikki/files/uci-defaults/migrate.sh @@ -140,12 +140,6 @@ uci show nikki | grep -o -E 'nikki\.@router_access_control\[[[:digit:]]+\]=route done done -# since v1.23.2 - -env_disable_safe_path_check=$(uci -q get nikki.env.disable_safe_path_check); [ -n "$env_disable_safe_path_check" ] && uci del nikki.env.disable_safe_path_check - -env_skip_system_ipv6_check=$(uci -q get nikki.env.skip_system_ipv6_check); [ -z "$env_skip_system_ipv6_check" ] && uci set nikki.env.skip_system_ipv6_check=0 - # since v1.23.3 uci show nikki | grep -o -E 'nikki\.@router_access_control\[[[:digit:]]+\]=router_access_control' | cut -d '=' -f 1 | while read -r router_access_control; do diff --git a/small/nikki/files/ucode/hijack.ut b/small/nikki/files/ucode/hijack.ut index 6dce502e6a..8bfe05388b 100644 --- a/small/nikki/files/ucode/hijack.ut +++ b/small/nikki/files/ucode/hijack.ut @@ -26,6 +26,7 @@ let dns_listen; let dns_port; let fake_ip_range; + let fake_ip6_range; if (profile['dns']) { dns_listen = profile['dns']['listen']; const dns_listen_rindex = rindex(dns_listen, ':'); @@ -33,6 +34,7 @@ dns_port = substr(dns_listen, dns_listen_rindex + 1); } fake_ip_range = profile['dns']['fake-ip-range']; + fake_ip6_range = profile['dns']['fake-ip-range6']; } let tun_device; @@ -445,20 +447,23 @@ table inet nikki { {% if (tcp_mode == 'redirect'): %} fib daddr type { local, broadcast, anycast, multicast } counter return ct direction reply counter return - ip daddr @reserved_ip counter return - ip6 daddr @reserved_ip6 counter return + ip daddr @reserved_ip {% if (fake_ip_range): %} ip daddr != {{ fake_ip_range }} {% endif %} counter return + ip6 daddr @reserved_ip6 {% if (fake_ip6_range): %} ip6 daddr != {{ fake_ip6_range }} {% endif %} counter return ip daddr @china_ip counter return ip6 daddr @china_ip6 counter return meta nfproto ipv4 meta l4proto . th dport != @proxy_dport {% if (fake_ip_range): %} ip daddr != {{ fake_ip_range }} {% endif %} counter return - meta nfproto ipv6 meta l4proto . th dport != @proxy_dport counter return + meta nfproto ipv6 meta l4proto . th dport != @proxy_dport {% if (fake_ip6_range): %} ip6 daddr != {{ fake_ip6_range }} {% endif %} counter return meta l4proto { tcp, udp } ip dscp @bypass_dscp {% if (fake_ip_range): %} ip daddr != {{ fake_ip_range }} {% endif %} counter return - meta l4proto { tcp, udp } ip6 dscp @bypass_dscp counter return + meta l4proto { tcp, udp } ip6 dscp @bypass_dscp {% if (fake_ip6_range): %} ip6 daddr != {{ fake_ip6_range }} {% endif %} counter return meta nfproto @proxy_nfproto jump router_redirect {% endif %} {% if (fake_ip_ping_hijack): %} {% if (fake_ip_range ): %} icmp type echo-request ip daddr {{ fake_ip_range }} counter redirect {% endif %} + {% if (fake_ip6_range ): %} + icmpv6 type echo-request ip6 daddr {{ fake_ip6_range }} counter redirect + {% endif %} {% endif %} } @@ -471,14 +476,14 @@ table inet nikki { {% endif %} fib daddr type { local, broadcast, anycast, multicast } counter return ct direction reply counter return - ip daddr @reserved_ip counter return - ip6 daddr @reserved_ip6 counter return + ip daddr @reserved_ip {% if (fake_ip_range): %} ip daddr != {{ fake_ip_range }} {% endif %} counter return + ip6 daddr @reserved_ip6 {% if (fake_ip6_range): %} ip6 daddr != {{ fake_ip6_range }} {% endif %} counter return ip daddr @china_ip counter return ip6 daddr @china_ip6 counter return meta nfproto ipv4 meta l4proto . th dport != @proxy_dport {% if (fake_ip_range): %} ip daddr != {{ fake_ip_range }} {% endif %} counter return - meta nfproto ipv6 meta l4proto . th dport != @proxy_dport counter return + meta nfproto ipv6 meta l4proto . th dport != @proxy_dport {% if (fake_ip6_range): %} ip6 daddr != {{ fake_ip6_range }} {% endif %} counter return meta l4proto { tcp, udp } ip dscp @bypass_dscp {% if (fake_ip_range): %} ip daddr != {{ fake_ip_range }} {% endif %} counter return - meta l4proto { tcp, udp } ip6 dscp @bypass_dscp counter return + meta l4proto { tcp, udp } ip6 dscp @bypass_dscp {% if (fake_ip6_range): %} ip6 daddr != {{ fake_ip6_range }} {% endif %} counter return {% if (length(dns_hijack_nfproto) > 0): %} meta nfproto @dns_hijack_nfproto meta l4proto { tcp, udp } th dport 53 counter return {% endif %} @@ -514,20 +519,23 @@ table inet nikki { {% if (tcp_mode == 'redirect'): %} fib daddr type { local, broadcast, anycast, multicast } counter return ct direction reply counter return - ip daddr @reserved_ip counter return - ip6 daddr @reserved_ip6 counter return + ip daddr @reserved_ip {% if (fake_ip_range): %} ip daddr != {{ fake_ip_range }} {% endif %} counter return + ip6 daddr @reserved_ip6 {% if (fake_ip6_range): %} ip6 daddr != {{ fake_ip6_range }} {% endif %} counter return ip daddr @china_ip counter return ip6 daddr @china_ip6 counter return meta nfproto ipv4 meta l4proto . th dport != @proxy_dport {% if (fake_ip_range): %} ip daddr != {{ fake_ip_range }} {% endif %} counter return - meta nfproto ipv6 meta l4proto . th dport != @proxy_dport counter return + meta nfproto ipv6 meta l4proto . th dport != @proxy_dport {% if (fake_ip6_range): %} ip6 daddr != {{ fake_ip6_range }} {% endif %} counter return meta l4proto { tcp, udp } ip dscp @bypass_dscp {% if (fake_ip_range): %} ip daddr != {{ fake_ip_range }} {% endif %} counter return - meta l4proto { tcp, udp } ip6 dscp @bypass_dscp counter return + meta l4proto { tcp, udp } ip6 dscp @bypass_dscp {% if (fake_ip6_range): %} ip6 daddr != {{ fake_ip6_range }} {% endif %} counter return iifname @lan_inbound_device meta nfproto @proxy_nfproto jump lan_redirect {% endif %} {% if (fake_ip_ping_hijack): %} {% if (fake_ip_range): %} icmp type echo-request ip daddr {{ fake_ip_range }} counter redirect {% endif %} + {% if (fake_ip6_range ): %} + icmpv6 type echo-request ip6 daddr {{ fake_ip6_range }} counter redirect + {% endif %} {% endif %} } @@ -535,14 +543,14 @@ table inet nikki { type filter hook prerouting priority mangle; policy accept; fib daddr type { local, broadcast, anycast, multicast } counter return ct direction reply counter return - ip daddr @reserved_ip counter return - ip6 daddr @reserved_ip6 counter return + ip daddr @reserved_ip {% if (fake_ip_range): %} ip daddr != {{ fake_ip_range }} {% endif %} counter return + ip6 daddr @reserved_ip6 {% if (fake_ip6_range): %} ip6 daddr != {{ fake_ip6_range }} {% endif %} counter return ip daddr @china_ip counter return ip6 daddr @china_ip6 counter return meta nfproto ipv4 meta l4proto . th dport != @proxy_dport {% if (fake_ip_range): %} ip daddr != {{ fake_ip_range }} {% endif %} counter return - meta nfproto ipv6 meta l4proto . th dport != @proxy_dport counter return + meta nfproto ipv6 meta l4proto . th dport != @proxy_dport {% if (fake_ip6_range): %} ip6 daddr != {{ fake_ip6_range }} {% endif %} counter return meta l4proto { tcp, udp } ip dscp @bypass_dscp {% if (fake_ip_range): %} ip daddr != {{ fake_ip_range }} {% endif %} counter return - meta l4proto { tcp, udp } ip6 dscp @bypass_dscp counter return + meta l4proto { tcp, udp } ip6 dscp @bypass_dscp {% if (fake_ip6_range): %} ip6 daddr != {{ fake_ip6_range }} {% endif %} counter return {% if (length(dns_hijack_nfproto) > 0): %} meta nfproto @dns_hijack_nfproto meta l4proto { tcp, udp } th dport 53 counter return {% endif %} diff --git a/small/nikki/files/ucode/mixin.uc b/small/nikki/files/ucode/mixin.uc index 9a626115b3..fecc7c24e5 100644 --- a/small/nikki/files/ucode/mixin.uc +++ b/small/nikki/files/ucode/mixin.uc @@ -72,6 +72,7 @@ config['dns']['listen'] = uci.get('nikki', 'mixin', 'dns_listen'); config['dns']['ipv6'] = uci_bool(uci.get('nikki', 'mixin', 'dns_ipv6')); config['dns']['enhanced-mode'] = uci.get('nikki', 'mixin', 'dns_mode'); config['dns']['fake-ip-range'] = uci.get('nikki', 'mixin', 'fake_ip_range'); +config['dns']['fake-ip-range6'] = uci.get('nikki', 'mixin', 'fake_ip6_range'); if (uci_bool(uci.get('nikki', 'mixin', 'fake_ip_filter'))) { config['dns']['fake-ip-filter'] = uci_array(uci.get('nikki', 'mixin', 'fake_ip_filters')); } diff --git a/small/v2ray-geodata/Makefile b/small/v2ray-geodata/Makefile index 9a4623e1b8..95c10f2ef4 100644 --- a/small/v2ray-geodata/Makefile +++ b/small/v2ray-geodata/Makefile @@ -21,13 +21,13 @@ define Download/geoip HASH:=2445b44d9ae3ab9a867c9d1e0e244646c4c378622e14b9afaf3658ecf46a40b9 endef -GEOSITE_VER:=20251108093039 +GEOSITE_VER:=20251109074743 GEOSITE_FILE:=dlc.dat.$(GEOSITE_VER) define Download/geosite URL:=https://github.com/v2fly/domain-list-community/releases/download/$(GEOSITE_VER)/ URL_FILE:=dlc.dat FILE:=$(GEOSITE_FILE) - HASH:=bfe4add56d708c8f5e2e4af9f39bc048f68b0539355ad639252c922124efcacc + HASH:=7d69224640bc6dedefa2c7206971f0129e91452028ce263b3026a7639defa926 endef GEOSITE_IRAN_VER:=202511030041 diff --git a/v2rayn/v2rayN/Directory.Build.props b/v2rayn/v2rayN/Directory.Build.props index 3bb4af7ae8..2e863e42ef 100644 --- a/v2rayn/v2rayN/Directory.Build.props +++ b/v2rayn/v2rayN/Directory.Build.props @@ -1,7 +1,7 @@ - 7.16.0 + 7.16.1 diff --git a/v2rayn/v2rayN/ServiceLib/Common/Utils.cs b/v2rayn/v2rayN/ServiceLib/Common/Utils.cs index 5fb1402342..1712b40c8d 100644 --- a/v2rayn/v2rayN/ServiceLib/Common/Utils.cs +++ b/v2rayn/v2rayN/ServiceLib/Common/Utils.cs @@ -998,7 +998,7 @@ public class Utils public static bool IsLinux() => OperatingSystem.IsLinux(); - public static bool IsOSX() => OperatingSystem.IsMacOS(); + public static bool IsMacOS() => OperatingSystem.IsMacOS(); public static bool IsNonWindows() => !OperatingSystem.IsWindows(); @@ -1020,7 +1020,7 @@ public class Utils { try { - if (IsWindows() || IsOSX()) + if (IsWindows() || IsMacOS()) { return false; } diff --git a/v2rayn/v2rayN/ServiceLib/Handler/AutoStartupHandler.cs b/v2rayn/v2rayN/ServiceLib/Handler/AutoStartupHandler.cs index 82e945171b..bc86cd7f90 100644 --- a/v2rayn/v2rayN/ServiceLib/Handler/AutoStartupHandler.cs +++ b/v2rayn/v2rayN/ServiceLib/Handler/AutoStartupHandler.cs @@ -26,7 +26,7 @@ public static class AutoStartupHandler await SetTaskLinux(); } } - else if (Utils.IsOSX()) + else if (Utils.IsMacOS()) { await ClearTaskOSX(); diff --git a/v2rayn/v2rayN/ServiceLib/Handler/Fmt/Hysteria2Fmt.cs b/v2rayn/v2rayN/ServiceLib/Handler/Fmt/Hysteria2Fmt.cs index adcd3114b5..c8d6a71af6 100644 --- a/v2rayn/v2rayN/ServiceLib/Handler/Fmt/Hysteria2Fmt.cs +++ b/v2rayn/v2rayN/ServiceLib/Handler/Fmt/Hysteria2Fmt.cs @@ -45,7 +45,7 @@ public class Hysteria2Fmt : BaseFmt } var dicQuery = new Dictionary(); ToUriQueryLite(item, ref dicQuery); - + if (item.Path.IsNotEmpty()) { dicQuery.Add("obfs", "salamander"); diff --git a/v2rayn/v2rayN/ServiceLib/Handler/SysProxy/SysProxyHandler.cs b/v2rayn/v2rayN/ServiceLib/Handler/SysProxy/SysProxyHandler.cs index 426945e0aa..21453591e7 100644 --- a/v2rayn/v2rayN/ServiceLib/Handler/SysProxy/SysProxyHandler.cs +++ b/v2rayn/v2rayN/ServiceLib/Handler/SysProxy/SysProxyHandler.cs @@ -33,7 +33,7 @@ public static class SysProxyHandler await ProxySettingLinux.SetProxy(Global.Loopback, port, exceptions); break; - case ESysProxyType.ForcedChange when Utils.IsOSX(): + case ESysProxyType.ForcedChange when Utils.IsMacOS(): await ProxySettingOSX.SetProxy(Global.Loopback, port, exceptions); break; @@ -45,7 +45,7 @@ public static class SysProxyHandler await ProxySettingLinux.UnsetProxy(); break; - case ESysProxyType.ForcedClear when Utils.IsOSX(): + case ESysProxyType.ForcedClear when Utils.IsMacOS(): await ProxySettingOSX.UnsetProxy(); break; diff --git a/v2rayn/v2rayN/ServiceLib/Helper/HttpClientHelper.cs b/v2rayn/v2rayN/ServiceLib/Helper/HttpClientHelper.cs index 0c9bd47078..9bc38c0195 100644 --- a/v2rayn/v2rayN/ServiceLib/Helper/HttpClientHelper.cs +++ b/v2rayn/v2rayN/ServiceLib/Helper/HttpClientHelper.cs @@ -48,7 +48,6 @@ public class HttpClientHelper } return await httpClient.GetStringAsync(url); } - public async Task PutAsync(string url, Dictionary headers) { @@ -72,6 +71,4 @@ public class HttpClientHelper { await httpClient.DeleteAsync(url); } - - } diff --git a/v2rayn/v2rayN/ServiceLib/Manager/CertPemManager.cs b/v2rayn/v2rayN/ServiceLib/Manager/CertPemManager.cs index 449592a700..9421aabf4d 100644 --- a/v2rayn/v2rayN/ServiceLib/Manager/CertPemManager.cs +++ b/v2rayn/v2rayN/ServiceLib/Manager/CertPemManager.cs @@ -202,7 +202,7 @@ public class CertPemManager /// /// Get certificate in PEM format from a server with CA pinning validation /// - public async Task<(string?, string?)> GetCertPemAsync(string target, string serverName, int timeout = 10) + public async Task<(string?, string?)> GetCertPemAsync(string target, string serverName, int timeout = 4) { try { @@ -216,7 +216,13 @@ public class CertPemManager using var ssl = new SslStream(client.GetStream(), false, ValidateServerCertificate); - await ssl.AuthenticateAsClientAsync(serverName); + var sslOptions = new SslClientAuthenticationOptions + { + TargetHost = serverName, + RemoteCertificateValidationCallback = ValidateServerCertificate + }; + + await ssl.AuthenticateAsClientAsync(sslOptions, cts.Token); var remote = ssl.RemoteCertificate; if (remote == null) @@ -242,7 +248,7 @@ public class CertPemManager /// /// Get certificate chain in PEM format from a server with CA pinning validation /// - public async Task<(List, string?)> GetCertChainPemAsync(string target, string serverName, int timeout = 10) + public async Task<(List, string?)> GetCertChainPemAsync(string target, string serverName, int timeout = 4) { var pemList = new List(); try @@ -257,7 +263,13 @@ public class CertPemManager using var ssl = new SslStream(client.GetStream(), false, ValidateServerCertificate); - await ssl.AuthenticateAsClientAsync(serverName); + var sslOptions = new SslClientAuthenticationOptions + { + TargetHost = serverName, + RemoteCertificateValidationCallback = ValidateServerCertificate + }; + + await ssl.AuthenticateAsClientAsync(sslOptions, cts.Token); if (ssl.RemoteCertificate is not X509Certificate2 certChain) { @@ -330,10 +342,74 @@ public class CertPemManager return TrustedCaThumbprints.Contains(rootThumbprint); } - public string ExportCertToPem(X509Certificate2 cert) + public static string ExportCertToPem(X509Certificate2 cert) { var der = cert.Export(X509ContentType.Cert); - var b64 = Convert.ToBase64String(der, Base64FormattingOptions.InsertLineBreaks); + var b64 = Convert.ToBase64String(der); return $"-----BEGIN CERTIFICATE-----\n{b64}\n-----END CERTIFICATE-----\n"; } + + /// + /// Parse concatenated PEM certificates string into a list of individual certificates + /// Normalizes format: removes line breaks from base64 content for better compatibility + /// + /// Concatenated PEM certificates string (supports both \r\n and \n line endings) + /// List of individual PEM certificate strings with normalized format + public static List ParsePemChain(string pemChain) + { + var certs = new List(); + if (string.IsNullOrWhiteSpace(pemChain)) + { + return certs; + } + + // Normalize line endings (CRLF -> LF) at the beginning + pemChain = pemChain.Replace("\r\n", "\n").Replace("\r", "\n"); + + const string beginMarker = "-----BEGIN CERTIFICATE-----"; + const string endMarker = "-----END CERTIFICATE-----"; + + var index = 0; + while (index < pemChain.Length) + { + var beginIndex = pemChain.IndexOf(beginMarker, index, StringComparison.Ordinal); + if (beginIndex == -1) + break; + + var endIndex = pemChain.IndexOf(endMarker, beginIndex, StringComparison.Ordinal); + if (endIndex == -1) + break; + + // Extract certificate content + var base64Start = beginIndex + beginMarker.Length; + var base64Content = pemChain.Substring(base64Start, endIndex - base64Start); + + // Remove all whitespace from base64 content + base64Content = new string(base64Content.Where(c => !char.IsWhiteSpace(c)).ToArray()); + + // Reconstruct with clean format: BEGIN marker + base64 (no line breaks) + END marker + var normalizedCert = $"{beginMarker}\n{base64Content}\n{endMarker}\n"; + certs.Add(normalizedCert); + + // Move to next certificate + index = endIndex + endMarker.Length; + } + + return certs; + } + + /// + /// Concatenate a list of PEM certificates into a single string + /// + /// List of individual PEM certificate strings + /// Concatenated PEM certificates string + public static string ConcatenatePemChain(IEnumerable pemList) + { + if (pemList == null) + { + return string.Empty; + } + + return string.Concat(pemList); + } } diff --git a/v2rayn/v2rayN/ServiceLib/Manager/CoreAdminManager.cs b/v2rayn/v2rayN/ServiceLib/Manager/CoreAdminManager.cs index 6c54e1e1f3..254688e47a 100644 --- a/v2rayn/v2rayN/ServiceLib/Manager/CoreAdminManager.cs +++ b/v2rayn/v2rayN/ServiceLib/Manager/CoreAdminManager.cs @@ -67,7 +67,7 @@ public class CoreAdminManager try { - var shellFileName = Utils.IsOSX() ? Global.KillAsSudoOSXShellFileName : Global.KillAsSudoLinuxShellFileName; + var shellFileName = Utils.IsMacOS() ? Global.KillAsSudoOSXShellFileName : Global.KillAsSudoLinuxShellFileName; var shFilePath = await FileUtils.CreateLinuxShellFile("kill_as_sudo.sh", EmbedUtils.GetEmbedText(shellFileName), true); if (shFilePath.Contains(' ')) { diff --git a/v2rayn/v2rayN/ServiceLib/Resx/ResUI.Designer.cs b/v2rayn/v2rayN/ServiceLib/Resx/ResUI.Designer.cs index dca8f3cd15..f9d9493e17 100644 --- a/v2rayn/v2rayN/ServiceLib/Resx/ResUI.Designer.cs +++ b/v2rayn/v2rayN/ServiceLib/Resx/ResUI.Designer.cs @@ -2599,8 +2599,10 @@ namespace ServiceLib.Resx { } /// - /// 查找类似 Server certificate (PEM format, optional). Entering a certificate will pin it. - ///Do not use the "Fetch Certificate" button when "Allow Insecure" is enabled. 的本地化字符串。 + /// 查找类似 Server Certificate (PEM format, optional) + ///When specified, the certificate will be pinned, and "Allow Insecure" will be disabled. + /// + ///The "Get Certificate" action may fail if a self-signed certificate is used or if the system contains an untrusted or malicious CA. 的本地化字符串。 /// public static string TbCertPinningTips { get { @@ -3850,6 +3852,15 @@ namespace ServiceLib.Resx { } } + /// + /// 查找类似 macOS displays this in the Dock (requires restart) 的本地化字符串。 + /// + public static string TbSettingsMacOSShowInDock { + get { + return ResourceManager.GetString("TbSettingsMacOSShowInDock", resourceCulture); + } + } + /// /// 查找类似 Main layout orientation (requires restart) 的本地化字符串。 /// diff --git a/v2rayn/v2rayN/ServiceLib/Resx/ResUI.fa-Ir.resx b/v2rayn/v2rayN/ServiceLib/Resx/ResUI.fa-Ir.resx index 299f6f9feb..67504966af 100644 --- a/v2rayn/v2rayN/ServiceLib/Resx/ResUI.fa-Ir.resx +++ b/v2rayn/v2rayN/ServiceLib/Resx/ResUI.fa-Ir.resx @@ -1606,8 +1606,10 @@ Certificate Pinning - Server certificate (PEM format, optional). Entering a certificate will pin it. -Do not use the "Fetch Certificate" button when "Allow Insecure" is enabled. + Server Certificate (PEM format, optional) +When specified, the certificate will be pinned, and "Allow Insecure" will be disabled. + +The "Get Certificate" action may fail if a self-signed certificate is used or if the system contains an untrusted or malicious CA. Fetch Certificate @@ -1630,4 +1632,7 @@ Do not use the "Fetch Certificate" button when "Allow Insecure" is enabled. Custom system proxy script file path + + macOS displays this in the Dock (requires restart) + \ No newline at end of file diff --git a/v2rayn/v2rayN/ServiceLib/Resx/ResUI.fr.resx b/v2rayn/v2rayN/ServiceLib/Resx/ResUI.fr.resx index e2703fbc9b..41d086d809 100644 --- a/v2rayn/v2rayN/ServiceLib/Resx/ResUI.fr.resx +++ b/v2rayn/v2rayN/ServiceLib/Resx/ResUI.fr.resx @@ -1603,8 +1603,10 @@ Certificate Pinning - Certificat serveur (PEM, optionnel). L’ajout d’un certificat le fixe. -Ne pas utiliser « Obtenir le certificat » si « Autoriser non sécurisé » est activé. + Server Certificate (PEM format, optional) +When specified, the certificate will be pinned, and "Allow Insecure" will be disabled. + +The "Get Certificate" action may fail if a self-signed certificate is used or if the system contains an untrusted or malicious CA. Obtenir le certificat @@ -1627,4 +1629,7 @@ Ne pas utiliser « Obtenir le certificat » si « Autoriser non sécurisé » es Chemin script proxy système personnalisé - + + macOS displays this in the Dock (requires restart) + + \ No newline at end of file diff --git a/v2rayn/v2rayN/ServiceLib/Resx/ResUI.hu.resx b/v2rayn/v2rayN/ServiceLib/Resx/ResUI.hu.resx index dd6a6a6316..c71e741fb6 100644 --- a/v2rayn/v2rayN/ServiceLib/Resx/ResUI.hu.resx +++ b/v2rayn/v2rayN/ServiceLib/Resx/ResUI.hu.resx @@ -1606,8 +1606,10 @@ Certificate Pinning - Server certificate (PEM format, optional). Entering a certificate will pin it. -Do not use the "Fetch Certificate" button when "Allow Insecure" is enabled. + Server Certificate (PEM format, optional) +When specified, the certificate will be pinned, and "Allow Insecure" will be disabled. + +The "Get Certificate" action may fail if a self-signed certificate is used or if the system contains an untrusted or malicious CA. Fetch Certificate @@ -1630,4 +1632,7 @@ Do not use the "Fetch Certificate" button when "Allow Insecure" is enabled. Custom system proxy script file path + + macOS displays this in the Dock (requires restart) + \ No newline at end of file diff --git a/v2rayn/v2rayN/ServiceLib/Resx/ResUI.resx b/v2rayn/v2rayN/ServiceLib/Resx/ResUI.resx index a59d068e2d..66381a9059 100644 --- a/v2rayn/v2rayN/ServiceLib/Resx/ResUI.resx +++ b/v2rayn/v2rayN/ServiceLib/Resx/ResUI.resx @@ -1606,8 +1606,10 @@ Certificate Pinning - Server certificate (PEM format, optional). Entering a certificate will pin it. -Do not use the "Fetch Certificate" button when "Allow Insecure" is enabled. + Server Certificate (PEM format, optional) +When specified, the certificate will be pinned, and "Allow Insecure" will be disabled. + +The "Get Certificate" action may fail if a self-signed certificate is used or if the system contains an untrusted or malicious CA. Fetch Certificate @@ -1630,4 +1632,7 @@ Do not use the "Fetch Certificate" button when "Allow Insecure" is enabled. Custom system proxy script file path + + macOS displays this in the Dock (requires restart) + \ No newline at end of file diff --git a/v2rayn/v2rayN/ServiceLib/Resx/ResUI.ru.resx b/v2rayn/v2rayN/ServiceLib/Resx/ResUI.ru.resx index 59176fa3e1..2694db037f 100644 --- a/v2rayn/v2rayN/ServiceLib/Resx/ResUI.ru.resx +++ b/v2rayn/v2rayN/ServiceLib/Resx/ResUI.ru.resx @@ -1606,8 +1606,10 @@ Certificate Pinning - Server certificate (PEM format, optional). Entering a certificate will pin it. -Do not use the "Fetch Certificate" button when "Allow Insecure" is enabled. + Server Certificate (PEM format, optional) +When specified, the certificate will be pinned, and "Allow Insecure" will be disabled. + +The "Get Certificate" action may fail if a self-signed certificate is used or if the system contains an untrusted or malicious CA. Fetch Certificate @@ -1630,4 +1632,7 @@ Do not use the "Fetch Certificate" button when "Allow Insecure" is enabled. Custom system proxy script file path + + macOS displays this in the Dock (requires restart) + \ No newline at end of file diff --git a/v2rayn/v2rayN/ServiceLib/Resx/ResUI.zh-Hans.resx b/v2rayn/v2rayN/ServiceLib/Resx/ResUI.zh-Hans.resx index a58f3c573e..2f3d06222a 100644 --- a/v2rayn/v2rayN/ServiceLib/Resx/ResUI.zh-Hans.resx +++ b/v2rayn/v2rayN/ServiceLib/Resx/ResUI.zh-Hans.resx @@ -1603,8 +1603,10 @@ 固定证书 - 服务器证书(PEM 格式,可选)。填入后将固定该证书。 -启用“跳过证书验证”时,请勿使用 '获取证书'。 + 服务器证书(PEM 格式,可选) +当指定此证书后,将固定该证书,并禁用“跳过证书验证”选项。 + +“获取证书”操作可能失败,原因可能是使用了自签证书,或系统中存在不受信任或恶意的 CA。 获取证书 @@ -1627,4 +1629,7 @@ 自定义系统代理脚本文件路径 + + macOS 在 Dock 栏中显示 (需重启) + \ No newline at end of file diff --git a/v2rayn/v2rayN/ServiceLib/Resx/ResUI.zh-Hant.resx b/v2rayn/v2rayN/ServiceLib/Resx/ResUI.zh-Hant.resx index e76a044f0e..b45480a44a 100644 --- a/v2rayn/v2rayN/ServiceLib/Resx/ResUI.zh-Hant.resx +++ b/v2rayn/v2rayN/ServiceLib/Resx/ResUI.zh-Hant.resx @@ -1603,8 +1603,10 @@ Certificate Pinning - Server certificate (PEM format, optional). Entering a certificate will pin it. -Do not use the "Fetch Certificate" button when "Allow Insecure" is enabled. + Server Certificate (PEM format, optional) +When specified, the certificate will be pinned, and "Allow Insecure" will be disabled. + +The "Get Certificate" action may fail if a self-signed certificate is used or if the system contains an untrusted or malicious CA. Fetch Certificate @@ -1627,4 +1629,7 @@ Do not use the "Fetch Certificate" button when "Allow Insecure" is enabled. 自訂系統代理程式腳本檔案路徑 + + macOS 在 Dock 欄顯示 (需重啟) + \ No newline at end of file diff --git a/v2rayn/v2rayN/ServiceLib/Services/CoreConfig/Singbox/SingboxInboundService.cs b/v2rayn/v2rayN/ServiceLib/Services/CoreConfig/Singbox/SingboxInboundService.cs index 91f76ad9d3..76e90110ff 100644 --- a/v2rayn/v2rayN/ServiceLib/Services/CoreConfig/Singbox/SingboxInboundService.cs +++ b/v2rayn/v2rayN/ServiceLib/Services/CoreConfig/Singbox/SingboxInboundService.cs @@ -61,7 +61,7 @@ public partial class CoreConfigSingboxService } var tunInbound = JsonUtils.Deserialize(EmbedUtils.GetEmbedText(Global.TunSingboxInboundFileName)) ?? new Inbound4Sbox { }; - tunInbound.interface_name = Utils.IsOSX() ? $"utun{new Random().Next(99)}" : "singbox_tun"; + tunInbound.interface_name = Utils.IsMacOS() ? $"utun{new Random().Next(99)}" : "singbox_tun"; tunInbound.mtu = _config.TunModeItem.Mtu; tunInbound.auto_route = _config.TunModeItem.AutoRoute; tunInbound.strict_route = _config.TunModeItem.StrictRoute; diff --git a/v2rayn/v2rayN/ServiceLib/Services/CoreConfig/Singbox/SingboxOutboundService.cs b/v2rayn/v2rayN/ServiceLib/Services/CoreConfig/Singbox/SingboxOutboundService.cs index 4db9d7cbf0..9671dc7739 100644 --- a/v2rayn/v2rayN/ServiceLib/Services/CoreConfig/Singbox/SingboxOutboundService.cs +++ b/v2rayn/v2rayN/ServiceLib/Services/CoreConfig/Singbox/SingboxOutboundService.cs @@ -261,13 +261,7 @@ public partial class CoreConfigSingboxService } if (node.StreamSecurity == Global.StreamSecurity) { - var certs = node.Cert - ?.Split("-----END CERTIFICATE-----", StringSplitOptions.RemoveEmptyEntries) - .Select(s => s.TrimEx()) - .Where(s => !s.IsNullOrEmpty()) - .Select(s => s + "\n-----END CERTIFICATE-----") - .Select(s => s.Replace("\r\n", "\n")) - .ToList() ?? new(); + var certs = CertPemManager.ParsePemChain(node.Cert); if (certs.Count > 0) { tls.certificate = certs; diff --git a/v2rayn/v2rayN/ServiceLib/Services/CoreConfig/V2ray/V2rayOutboundService.cs b/v2rayn/v2rayN/ServiceLib/Services/CoreConfig/V2ray/V2rayOutboundService.cs index 73a3a1fd2d..351c7bf0fc 100644 --- a/v2rayn/v2rayN/ServiceLib/Services/CoreConfig/V2ray/V2rayOutboundService.cs +++ b/v2rayn/v2rayN/ServiceLib/Services/CoreConfig/V2ray/V2rayOutboundService.cs @@ -245,13 +245,6 @@ public partial class CoreConfigV2rayService var host = node.RequestHost.TrimEx(); var path = node.Path.TrimEx(); var sni = node.Sni.TrimEx(); - var certs = node.Cert - ?.Split("-----END CERTIFICATE-----", StringSplitOptions.RemoveEmptyEntries) - .Select(s => s.TrimEx()) - .Where(s => !s.IsNullOrEmpty()) - .Select(s => s + "\n-----END CERTIFICATE-----") - .Select(s => s.Replace("\r\n", "\n")) - .ToList() ?? new(); var useragent = ""; if (!_config.CoreBasicItem.DefUserAgent.IsNullOrEmpty()) { @@ -284,6 +277,7 @@ public partial class CoreConfigV2rayService { tlsSettings.serverName = Utils.String2List(host)?.First(); } + var certs = CertPemManager.ParsePemChain(node.Cert); if (certs.Count > 0) { var certsettings = new List(); diff --git a/v2rayn/v2rayN/ServiceLib/Services/UpdateService.cs b/v2rayn/v2rayN/ServiceLib/Services/UpdateService.cs index b5129fc7f3..fc636c60e9 100644 --- a/v2rayn/v2rayN/ServiceLib/Services/UpdateService.cs +++ b/v2rayn/v2rayN/ServiceLib/Services/UpdateService.cs @@ -313,7 +313,7 @@ public class UpdateService(Config config, Func updateFunc) _ => null, }; } - else if (Utils.IsOSX()) + else if (Utils.IsMacOS()) { return RuntimeInformation.ProcessArchitecture switch { diff --git a/v2rayn/v2rayN/ServiceLib/ViewModels/AddServerViewModel.cs b/v2rayn/v2rayN/ServiceLib/ViewModels/AddServerViewModel.cs index 221d28d0f7..804287c53b 100644 --- a/v2rayn/v2rayN/ServiceLib/ViewModels/AddServerViewModel.cs +++ b/v2rayn/v2rayN/ServiceLib/ViewModels/AddServerViewModel.cs @@ -2,8 +2,6 @@ namespace ServiceLib.ViewModels; public class AddServerViewModel : MyReactiveObject { - private string _certError = string.Empty; - [Reactive] public ProfileItem SelectedSource { get; set; } @@ -112,11 +110,11 @@ public class AddServerViewModel : MyReactiveObject } } - private void UpdateCertTip() + private void UpdateCertTip(string? errorMessage = null) { - CertTip = _certError.IsNullOrEmpty() + CertTip = errorMessage.IsNullOrEmpty() ? (Cert.IsNullOrEmpty() ? ResUI.CertNotSet : ResUI.CertSet) - : _certError; + : errorMessage; } private async Task FetchCert() @@ -137,17 +135,16 @@ public class AddServerViewModel : MyReactiveObject } if (!Utils.IsDomain(serverName)) { - _certError = ResUI.ServerNameMustBeValidDomain; - UpdateCertTip(); - _certError = string.Empty; + UpdateCertTip(ResUI.ServerNameMustBeValidDomain); return; } if (SelectedSource.Port > 0) { domain += $":{SelectedSource.Port}"; } - (Cert, _certError) = await CertPemManager.Instance.GetCertPemAsync(domain, serverName); - UpdateCertTip(); + string certError; + (Cert, certError) = await CertPemManager.Instance.GetCertPemAsync(domain, serverName); + UpdateCertTip(certError); } private async Task FetchCertChain() @@ -168,17 +165,16 @@ public class AddServerViewModel : MyReactiveObject } if (!Utils.IsDomain(serverName)) { - _certError = ResUI.ServerNameMustBeValidDomain; - UpdateCertTip(); - _certError = string.Empty; + UpdateCertTip(ResUI.ServerNameMustBeValidDomain); return; } if (SelectedSource.Port > 0) { domain += $":{SelectedSource.Port}"; } - (var certs, _certError) = await CertPemManager.Instance.GetCertChainPemAsync(domain, serverName); - UpdateCertTip(); - Cert = string.Join("\n", certs); + string certError; + (var certs, certError) = await CertPemManager.Instance.GetCertChainPemAsync(domain, serverName); + Cert = CertPemManager.ConcatenatePemChain(certs); + UpdateCertTip(certError); } } diff --git a/v2rayn/v2rayN/ServiceLib/ViewModels/MainWindowViewModel.cs b/v2rayn/v2rayN/ServiceLib/ViewModels/MainWindowViewModel.cs index ce68d96b7d..c3bb0fe362 100644 --- a/v2rayn/v2rayN/ServiceLib/ViewModels/MainWindowViewModel.cs +++ b/v2rayn/v2rayN/ServiceLib/ViewModels/MainWindowViewModel.cs @@ -62,6 +62,8 @@ public class MainWindowViewModel : MyReactiveObject [Reactive] public int TabMainSelectedIndex { get; set; } + [Reactive] public bool BlIsWindows { get; set; } + #endregion Menu #region Init @@ -70,6 +72,7 @@ public class MainWindowViewModel : MyReactiveObject { _config = AppManager.Instance.Config; _updateView = updateView; + BlIsWindows = Utils.IsWindows(); #region WhenAnyValue && ReactiveCommand @@ -511,7 +514,7 @@ public class MainWindowViewModel : MyReactiveObject { ProcUtils.ProcessStart("xdg-open", path); } - else if (Utils.IsOSX()) + else if (Utils.IsMacOS()) { ProcUtils.ProcessStart("open", path); } diff --git a/v2rayn/v2rayN/ServiceLib/ViewModels/OptionSettingViewModel.cs b/v2rayn/v2rayN/ServiceLib/ViewModels/OptionSettingViewModel.cs index 81f63d00e5..73ec268198 100644 --- a/v2rayn/v2rayN/ServiceLib/ViewModels/OptionSettingViewModel.cs +++ b/v2rayn/v2rayN/ServiceLib/ViewModels/OptionSettingViewModel.cs @@ -50,6 +50,7 @@ public class OptionSettingViewModel : MyReactiveObject [Reactive] public bool EnableUpdateSubOnlyRemarksExist { get; set; } [Reactive] public bool AutoHideStartup { get; set; } [Reactive] public bool Hide2TrayWhenClose { get; set; } + [Reactive] public bool MacOSShowInDock { get; set; } [Reactive] public bool EnableDragDropSort { get; set; } [Reactive] public bool DoubleClick2Activate { get; set; } [Reactive] public int AutoUpdateInterval { get; set; } @@ -69,6 +70,15 @@ public class OptionSettingViewModel : MyReactiveObject #endregion UI + #region UI visibility + + [Reactive] public bool BlIsWindows { get; set; } + [Reactive] public bool BlIsLinux { get; set; } + [Reactive] public bool BlIsIsMacOS { get; set; } + [Reactive] public bool BlIsNonWindows { get; set; } + + #endregion UI visibility + #region System proxy [Reactive] public bool notProxyLocalAddress { get; set; } @@ -108,6 +118,10 @@ public class OptionSettingViewModel : MyReactiveObject { _config = AppManager.Instance.Config; _updateView = updateView; + BlIsWindows = Utils.IsWindows(); + BlIsLinux = Utils.IsLinux(); + BlIsIsMacOS = Utils.IsMacOS(); + BlIsNonWindows = Utils.IsNonWindows(); SaveCmd = ReactiveCommand.CreateFromTask(async () => { @@ -169,6 +183,7 @@ public class OptionSettingViewModel : MyReactiveObject EnableUpdateSubOnlyRemarksExist = _config.UiItem.EnableUpdateSubOnlyRemarksExist; AutoHideStartup = _config.UiItem.AutoHideStartup; Hide2TrayWhenClose = _config.UiItem.Hide2TrayWhenClose; + MacOSShowInDock = _config.UiItem.MacOSShowInDock; EnableDragDropSort = _config.UiItem.EnableDragDropSort; DoubleClick2Activate = _config.UiItem.DoubleClick2Activate; AutoUpdateInterval = _config.GuiItem.AutoUpdateInterval; @@ -330,6 +345,7 @@ public class OptionSettingViewModel : MyReactiveObject _config.UiItem.EnableUpdateSubOnlyRemarksExist = EnableUpdateSubOnlyRemarksExist; _config.UiItem.AutoHideStartup = AutoHideStartup; _config.UiItem.Hide2TrayWhenClose = Hide2TrayWhenClose; + _config.UiItem.MacOSShowInDock = MacOSShowInDock; _config.GuiItem.AutoUpdateInterval = AutoUpdateInterval; _config.UiItem.EnableDragDropSort = EnableDragDropSort; _config.UiItem.DoubleClick2Activate = DoubleClick2Activate; diff --git a/v2rayn/v2rayN/ServiceLib/ViewModels/StatusBarViewModel.cs b/v2rayn/v2rayN/ServiceLib/ViewModels/StatusBarViewModel.cs index b7c2a1e744..7617ac6f87 100644 --- a/v2rayn/v2rayN/ServiceLib/ViewModels/StatusBarViewModel.cs +++ b/v2rayn/v2rayN/ServiceLib/ViewModels/StatusBarViewModel.cs @@ -504,7 +504,7 @@ public class StatusBarViewModel : MyReactiveObject { return AppManager.Instance.LinuxSudoPwd.IsNotEmpty(); } - else if (Utils.IsOSX()) + else if (Utils.IsMacOS()) { return AppManager.Instance.LinuxSudoPwd.IsNotEmpty(); } diff --git a/v2rayn/v2rayN/v2rayN.Desktop/Base/WindowBase.cs b/v2rayn/v2rayN/v2rayN.Desktop/Base/WindowBase.cs index 63b00036c9..d1419b306d 100644 --- a/v2rayn/v2rayN/v2rayN.Desktop/Base/WindowBase.cs +++ b/v2rayn/v2rayN/v2rayN.Desktop/Base/WindowBase.cs @@ -26,7 +26,7 @@ public class WindowBase : ReactiveWindow where TViewMode Height = sizeItem.Height; var workingArea = (Screens.ScreenFromWindow(this) ?? Screens.Primary).WorkingArea; - var scaling = (Utils.IsOSX() ? null : VisualRoot?.RenderScaling) ?? 1.0; + var scaling = (Utils.IsMacOS() ? null : VisualRoot?.RenderScaling) ?? 1.0; var x = workingArea.X + ((workingArea.Width - (Width * scaling)) / 2); var y = workingArea.Y + ((workingArea.Height - (Height * scaling)) / 2); diff --git a/v2rayn/v2rayN/v2rayN.Desktop/Views/AddServerWindow.axaml b/v2rayn/v2rayN/v2rayN.Desktop/Views/AddServerWindow.axaml index f01da56dc3..95c9891be2 100644 --- a/v2rayn/v2rayN/v2rayN.Desktop/Views/AddServerWindow.axaml +++ b/v2rayn/v2rayN/v2rayN.Desktop/Views/AddServerWindow.axaml @@ -800,9 +800,11 @@ + Text="{x:Static resx:ResUI.TbCertPinningTips}" + TextWrapping="Wrap" />